]> sjero.net Git - ltp2tcp/blob - sll_encap.c
Checksum Computation!!
[ltp2tcp] / sll_encap.c
1 /******************************************************************************
2 Utility to convert a LTP flow to a TCP flow for LTP analysis via tcptrace.
3 <SLL, IPv4, UDP> encapsulation functions
4
5 Copyright (C) 2013  Samuel Jero <sj323707@ohio.edu>
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 Author: Samuel Jero <sj323707@ohio.edu>
21 Date: 06/2013
22
23 Notes:
24         1)Only handles one LTP "connection". There isn't a good way to separate
25                 different LTP "connections" from new sessions of the same "connection".
26                 Use Tcpdump filters to separate connections. Libpcap filtering could also
27                 be added in ltp2tcp.
28         2)Uses some special types from Linux (u_char, u_int32_t)
29 ******************************************************************************/
30 #include "ltp2tcp.h"
31 #include <pcap/sll.h>
32 #include <netinet/udp.h>
33
34 extern int debug;
35
36
37
38 /*SLL encapsulation private data structure*/
39 struct sll_en_p{
40         int first;
41         struct pcap_pkthdr      header;
42         u_char                          od[sizeof(struct sll_header)+sizeof(struct iphdr)+sizeof(struct udphdr)];
43 };
44
45
46 /*Fill the encapsulation structure*/
47 int fill_sllip4_encap(struct sll_en_p *slip, const u_char* data, int dlen, struct pcap_pkthdr *h){
48         /*safety check*/
49         if(slip==NULL || data==NULL || h==NULL || dlen < sizeof(struct sll_header)+sizeof(struct iphdr)){
50                 dbgprintf(1, "Error: SLL, IPv4 Encapsulation method given bad data!\n");
51                 return -1;
52         }
53
54         if(slip->first==0){
55                 /* First time, allocate memory and copy libpcap header and encap headers
56                  * this guarantees the IP "direction" of the encap headers */
57                 memcpy(&slip->header, h, sizeof(struct pcap_pkthdr));
58                 memcpy(slip->od, data,sizeof(struct sll_header)+sizeof(struct iphdr));
59                 slip->first=1;
60         }else{
61                 /* Just update the libpcap header (and associated timestamp)*/
62                 memcpy(&slip->header, h, sizeof(struct pcap_pkthdr));
63         }
64         return 0;
65 }
66
67 /* encapsulation manipulation previous to packet conversion */
68 int sll_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
69 {
70         struct iphdr                    *iph;
71         struct sll_header               *slh;
72         struct udphdr                   *udph;
73
74         /*Safety checks*/
75         if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
76                 dbgprintf(0,"Error: SLL Encapsulation given bad data!\n");
77                 exit(1);
78         }
79         if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct udphdr)
80                         || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
81                         dbgprintf(0, "Error: SLL Encapsulation given packet of wrong size!\n");
82                         return -1;
83         }
84
85         /*initialize encapsulation private data*/
86         if(state.en_priv==NULL){
87                 /* First time, allocate memory and copy libpcap header and encap headers
88                  * this guarantees the IP "direction" of the encap headers */
89                 state.en_priv=malloc(sizeof(struct sll_en_p));
90                 if(state.en_priv==NULL){
91                         dbgprintf(0,"Error: Couldn't allocate Memory\n");
92                         exit(1);
93                 }
94         }
95         if(fill_sllip4_encap((struct sll_en_p*)state.en_priv, *odata, *olength, h)<0){
96                 return -1;
97         }
98
99         /*Copy SLL and IPv4 headers over*/
100         memcpy(*ndata, *odata, sizeof(struct sll_header)+sizeof(struct iphdr));
101         *odata+=sizeof(struct sll_header)+ sizeof(struct iphdr);
102         *ndata+=sizeof(struct sll_header)+ sizeof(struct iphdr);
103
104         /*Confirm that this is Ethernet and that IPv4 is next*/
105         slh=(struct sll_header*)(*odata -sizeof(struct sll_header)- sizeof(struct iphdr));
106         if(slh->sll_protocol!=htons(ETHERTYPE_IP)){
107                 dbgprintf(1, "Note: Packet not SLL or Not IPv4 next\n");
108                 return -1;
109         }
110
111         /* Check That this is IPv4 and that UDP is next*/
112         iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
113         if(iph->version!=4){
114                 dbgprintf(1, "Note: Packet is not IPv4\n");
115                 return -1;
116         }
117         if(iph->protocol!=0x11){
118                 dbgprintf(1, "Note: Packet is not UDP\n");
119                 return -1;
120         }
121
122         /*set ip to indicate that tcp is next protocol*/
123         iph->protocol=6;
124         iph->check=htonl(0);
125
126         /* Adjust libpcap headers*/
127         h->caplen=sizeof(struct sll_header) +sizeof(struct iphdr);
128         h->len=sizeof(struct sll_header) +sizeof(struct iphdr);
129
130         /*Adjust packet length*/
131         udph=(struct udphdr*)*odata;
132         *olength=ntohs(udph->len);
133
134         /*Adjust New Packet Length*/
135         *nlength-=sizeof(struct sll_header) +sizeof(struct iphdr);
136
137         /*Move Packet Pointer past UDP header*/
138         *odata+=sizeof(struct udphdr);
139 return 0;
140 }
141
142 /* encapsulation manipulation after conversion */
143 int sll_encap_post(int tlen, u_char *data)
144 {
145         struct iphdr *iph;
146
147         /* Move data pointer to start of IPv4 header*/
148         data+=sizeof(struct sll_header);
149
150         /*Determine if the given length is reasonable*/
151         if((tlen+sizeof(struct iphdr)) > 0xFFFF){
152                         dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
153                         return -1;
154         }
155
156         /*Adjust IPv4 header to account for packet's total length*/
157         iph=(struct iphdr*)data;
158         iph->tot_len=htons(sizeof(struct iphdr)+tlen);
159         return 0;
160 }
161
162 /* Create a TCP three-way handshake */
163 int sll_encap_handshake(struct pcap_pkthdr *h)
164 {
165         struct iphdr            *iph;
166         struct tcphdr           *tcph;
167         u_char                          *data;
168         u_char                          *ptr;
169         struct pcap_pkthdr      nh;
170         u_int32_t                       temp;
171         struct sll_en_p         *slip=(struct sll_en_p*)state.en_priv;
172
173
174         /*Safety Check*/
175         if(h==NULL || state.en_priv==NULL){
176                 dbgprintf(1, "Error: SLL, IPv4 Encapsulation handshake method given bad data!\n");
177                 return -1;
178         }
179
180         /*create new libpcap header*/
181         memcpy(&nh, h, sizeof(struct pcap_pkthdr));
182
183         /*create buffer for new packet*/
184         ptr=data=malloc(MAX_PACKET);
185         if(data==NULL){
186                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
187                 exit(1);
188         }
189
190         /* 1)Create Syn Packet*/
191                 /*make sure the packet is all zero*/
192                 memset(data, 0, MAX_PACKET);
193                 ptr=data;
194
195                 /*Set the libpcap header*/
196                 nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
197                 nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
198                 nh.ts.tv_usec-=3000; /*Time comes from the first packet received, so make these packets earlier*/
199
200                 /* Copy SLL and IP headers from private data area*/
201                 /* These are headers from the first packet in the capture*/
202                 memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
203
204                 /*Adjust IP header*/
205                 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
206                 iph->protocol=6;
207                 iph->check=htonl(0);
208                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
209
210                 /*Build TCP header*/
211                 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
212                 tcph=(struct tcphdr*)ptr;
213                 tcph->source=htons(1113);
214                 tcph->dest=htons(1113);
215                 tcph->doff=6;
216                 tcph->check=htonl(0);
217                 tcph->urg_ptr=0;
218                 tcph->urg=0;
219                 tcph->psh=0;
220                 tcph->fin=0;
221                 tcph->syn=1;
222                 tcph->rst=0;
223                 tcph->ack=0;
224
225                 /*Initialize Sequence and Acknowledgment Numbers and Window*/
226                 tcph->seq=htonl(state.seq_num++);
227                 tcph->ack_seq=htonl(0);
228                 tcph->window=htons(WIN_FACTOR);
229
230                 /* Add SACK permitted option*/
231                 ptr+=sizeof(struct tcphdr);
232                 *ptr=4;
233                 ptr++;
234                 *ptr=2;
235
236                 /*Save To Packet Capture*/
237                 pcap_dump((u_char*)state.out,&nh, data);
238
239
240         /* 2)Create Syn,Ack Packet*/
241                 /*make sure the packet is all zero*/
242                 memset(data, 0, MAX_PACKET);
243                 ptr=data;
244
245                 /*Set the libpcap header*/
246                 nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
247                 nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
248                 nh.ts.tv_usec+=1000; /*This packet is 1/3rd closer to the first packet then the previous packet created*/
249
250                 /* Copy SLL and IP headers from private data area*/
251                 /* These are headers from the first packet in the capture*/
252                 memcpy(data, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
253
254                 /*Adjust IP header, including swapping source and destination*/
255                 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
256                 iph->protocol=6;
257                 iph->check=htonl(0);
258                 temp=iph->saddr;
259                 iph->saddr=iph->daddr;
260                 iph->daddr=temp;
261                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
262
263                 /*Build TCP header*/
264                 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
265                 tcph=(struct tcphdr*)ptr;
266                 tcph->source=htons(1113);
267                 tcph->dest=htons(1113);
268                 tcph->doff=6;
269                 tcph->check=htonl(0);
270                 tcph->urg_ptr=0;
271                 tcph->urg=0;
272                 tcph->psh=0;
273                 tcph->fin=0;
274                 tcph->syn=1;
275                 tcph->rst=0;
276                 tcph->ack=1;
277
278                 /*Initialize Sequence and Acknowledgement Numbers and Window*/
279                 tcph->seq=htonl(state.ack_num++);
280                 tcph->ack_seq=htonl(state.seq_num);
281                 tcph->window=htons(WIN_FACTOR);
282
283                 /* Add SACK permitted option*/
284                 ptr+=sizeof(struct tcphdr);
285                 *ptr=4;
286                 ptr++;
287                 *ptr=2;
288
289                 /*Save To Packet Capture*/
290                 pcap_dump((u_char*)state.out,&nh, data);
291
292         /* 3)Create Ack Packet*/
293                 /*make sure the packet is all zero*/
294                 memset(data, 0, MAX_PACKET);
295                 ptr=data;
296
297                 /*Set the libpcap header*/
298                 nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
299                 nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
300                 nh.ts.tv_usec+=1000; /*This packet is 2/3rds between SYN and first packet*/
301
302                 /* Copy SLL and IP headers from private data area*/
303                 /* These are headers from the first packet in the capture*/
304                 memcpy(data, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
305
306                 /*Adjust IP header*/
307                 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
308                 iph->protocol=6;
309                 iph->check=htonl(0);
310                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
311
312                 /*Build TCP header*/
313                 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
314                 tcph=(struct tcphdr*)ptr;
315                 tcph->source=htons(1113);
316                 tcph->dest=htons(1113);
317                 tcph->doff=5;
318                 tcph->check=htonl(0);
319                 tcph->urg_ptr=0;
320                 tcph->urg=0;
321                 tcph->psh=0;
322                 tcph->fin=0;
323                 tcph->syn=0;
324                 tcph->rst=0;
325                 tcph->ack=1;
326
327                 /*Initialize Sequence and Acknowledgement numbers and window*/
328                 tcph->seq=htonl(state.seq_num++);
329                 tcph->ack_seq=htonl(state.ack_num);
330                 tcph->window=htons(WIN_FACTOR);
331
332                 /*Save To Packet Capture*/
333                 pcap_dump((u_char*)state.out,&nh, data);
334                 return 0;
335 }
336
337 /* Create a TCP ending handshake */
338 int sll_encap_fin()
339 {
340         struct iphdr            *iph;
341         struct tcphdr           *tcph;
342         u_char                          *data;
343         u_char                          *ptr;
344         struct pcap_pkthdr      nh;
345         u_int32_t                       temp;
346         struct sll_en_p         *slip=(struct sll_en_p*)state.en_priv;
347
348         /*Safety Check*/
349         if(slip==NULL){
350                 dbgprintf(1,"Error: SLL, IPv4 Encapsulation Finish method given invalid data!\n");
351                 return -1;
352         }
353
354         /*copy the libpcap header from private data area*/
355         memcpy(&nh, &slip->header, sizeof(struct pcap_pkthdr));
356
357         /*create buffer for new packet*/
358         ptr=data=malloc(MAX_PACKET);
359         if(data==NULL){
360                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
361                 exit(1);
362         }
363
364         /* 1)Create Fin Packet*/
365                 /*make sure the packet is all zero*/
366                 memset(data, 0, MAX_PACKET);
367                 ptr=data;
368
369                 /*Set the libpcap header*/
370                 nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
371                 nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
372                 nh.ts.tv_usec+=1000; /*Time is from the last packet in the capture; make this packet after that packet*/
373
374                 /* Copy Ethernet and IP headers from private data area*/
375                 /* These are headers from the first packet in the capture*/
376                 memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
377
378                 /*Adjust IP header*/
379                 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
380                 iph->protocol=6;
381                 iph->check=htonl(0);
382                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
383
384                 /*Build TCP header*/
385                 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
386                 tcph=(struct tcphdr*)ptr;
387                 tcph->source=htons(1113);
388                 tcph->dest=htons(1113);
389                 tcph->doff=5;
390                 tcph->check=htonl(0);
391                 tcph->urg_ptr=0;
392                 tcph->urg=0;
393                 tcph->psh=0;
394                 tcph->fin=1;
395                 tcph->syn=0;
396                 tcph->rst=0;
397                 tcph->ack=1;
398
399                 /* Adjust Sequence and Acknowledgment numbers and window*/
400                 tcph->seq=htonl(++state.seq_num);
401                 tcph->ack_seq=htonl(state.ack_num);
402                 tcph->window=htons(WIN_FACTOR);
403
404                 /*Update Sequence Number to include the fin packet in the sequence number space*/
405                 state.seq_num++;
406
407                 /* Save To Packet Capture*/
408                 pcap_dump((u_char*)state.out,&nh, data);
409
410         /* 2)Create Fin,Ack Packet*/
411                 /*make sure the packet is all zero*/
412                 memset(data, 0, MAX_PACKET);
413                 ptr=data;
414
415                 /*Set the libpcap header*/
416                 nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
417                 nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
418                 nh.ts.tv_usec+=1000; /*After the previous packet*/
419
420                 /* Copy Ethernet and IP headers from private data area*/
421                 /* These are headers from the first packet in the capture*/
422                 memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
423
424                 /*Update IP header, including swapping source and destination addresses*/
425                 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
426                 iph->protocol=6;
427                 iph->check=htonl(0);
428                 temp=iph->saddr;
429                 iph->saddr=iph->daddr;
430                 iph->daddr=temp;
431                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
432
433                 /*Build TCP header*/
434                 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
435                 tcph=(struct tcphdr*)ptr;
436                 tcph->source=htons(1113);
437                 tcph->dest=htons(1113);
438                 tcph->doff=5;
439                 tcph->check=htonl(0);
440                 tcph->urg_ptr=0;
441                 tcph->urg=0;
442                 tcph->psh=0;
443                 tcph->fin=1;
444                 tcph->syn=0;
445                 tcph->rst=0;
446                 tcph->ack=1;
447
448                 /*Adjust Sequence and Acknowledgment numbers and window*/
449                 tcph->seq=htonl(state.ack_num++);
450                 tcph->ack_seq=htonl(state.seq_num);
451                 tcph->window=htons(WIN_FACTOR);
452
453                 /*Save To Packet Capture*/
454                 pcap_dump((u_char*)state.out,&nh, data);
455
456         /* 3)Create Ack Packet*/
457                 /*make sure the packet is all zero*/
458                 memset(data, 0, MAX_PACKET);
459                 ptr=data;
460
461                 /*Set the libpcap header*/
462                 nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
463                 nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
464                 nh.ts.tv_usec+=1000; /*After the previous packet*/
465
466                 /* Copy Ethernet and IP headers from private data area*/
467                 /* These are headers from the first packet in the capture*/
468                 memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
469
470                 /*Update IP header*/
471                 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
472                 iph->protocol=6;
473                 iph->check=htonl(0);
474                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
475
476                 /*Build TCP header*/
477                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
478                 tcph=(struct tcphdr*)ptr;
479                 tcph->source=htons(1113);
480                 tcph->dest=htons(1113);
481                 tcph->doff=5;
482                 tcph->check=htonl(0);
483                 tcph->urg_ptr=0;
484                 tcph->urg=0;
485                 tcph->psh=0;
486                 tcph->fin=0;
487                 tcph->syn=0;
488                 tcph->rst=0;
489                 tcph->ack=1;
490
491                 /*Adjust Sequence and Acknowledgment numbers and window*/
492                 tcph->seq=htonl(state.seq_num++);
493                 tcph->ack_seq=htonl(state.ack_num);
494                 tcph->window=htons(WIN_FACTOR);
495
496                 /*Save To Packet Capture*/
497                 pcap_dump((u_char*)state.out,&nh, data);
498                 return 0;
499 }
500
501
502
503
504 /* The UDP Encapsulation Structure*/
505 struct encap_ops sll_encap = {
506         .pre=sll_encap_pre,
507         .post=sll_encap_post,
508         .handshake=sll_encap_handshake,
509         .fin=sll_encap_fin,
510 };