]> sjero.net Git - ltp2tcp/blob - encap.c
Checksum Computation!!
[ltp2tcp] / encap.c
1 /******************************************************************************
2 Utility to convert a LTP flow to a TCP flow for LTP analysis via tcptrace.
3 Utility Functions for Encapsulation
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 "checksums.h"
32
33
34
35 /*Encapsulation Selection*/
36 void encap_sel(char* string){
37         if(strcmp(string, "udp")==0 || strcmp(string,"UDP")==0){ /*UDP*/
38                 state.en_ops=&udp_encap;
39                 return;
40         }
41         if(strcmp(string, "dccp")==0 || strcmp(string,"DCCP")==0){ /*DCCP*/
42                 state.en_ops=&dccp_encap;
43                 return;
44         }
45         if(strcmp(string, "sll")==0 || strcmp(string,"SLL")==0){ /*SLL (Linux Cooked Capture)*/
46                         state.en_ops=&sll_encap;
47                         return;
48                 }
49         printf("Encapsulation type: %s is not supported\n", string);
50         exit(1);
51 return;
52 };
53
54 /*Fill the encapsulation structure*/
55 int fill_eip4_encap(struct eip4_en_p *eip, const u_char* data, int dlen, struct pcap_pkthdr *h){
56         /*safety check*/
57         if(eip==NULL || data==NULL || h==NULL || dlen < sizeof(struct ether_header)+sizeof(struct iphdr)){
58                 dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation method given bad data!\n");
59                 return -1;
60         }
61
62         if(eip->first==0){
63                 /* First time, allocate memory and copy libpcap header and encap headers
64                  * this guarantees the IP "direction" of the encap headers */
65                 memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
66                 memcpy(eip->od, data,sizeof(struct ether_header)+sizeof(struct iphdr));
67                 eip->first=1;
68         }else{
69                 /* Just update the libpcap header (and associated timestamp)*/
70                 memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
71         }
72         return 0;
73 }
74
75 /* encapsulation manipulation after conversion */
76 int eip4_post(struct eip4_en_p *eip, int tlen, u_char* data){
77         struct iphdr *iph;
78         struct tcphdr *tcph;
79
80         /* Move data pointer to start of IPv4 header*/
81         data+=sizeof(struct ether_header);
82
83         /*Determine if the given length is reasonable*/
84         if((tlen+sizeof(struct iphdr)) > 0xFFFF){
85                         dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
86                         return -1;
87         }
88
89         /*Adjust IPv4 header to account for packet's total length*/
90         iph=(struct iphdr*)data;
91         iph->tot_len=htons(iph->ihl*4+tlen);
92
93         /*Compute IPv4 Checksum*/
94         iph->check=0;
95         iph->check=ipv4_chksum(data,iph->ihl*4);
96
97         /*Compute TCP Checksum*/
98         data+=iph->ihl*4;
99         tcph=(struct tcphdr*)data;
100         tcph->check=0;
101         tcph->check=ipv4_pseudohdr_chksum(data, tlen, (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
102         return 0;
103 }
104
105 /* Create a TCP three-way handshake */
106 int eip4_handshake(struct eip4_en_p *eip, struct pcap_pkthdr *h){
107         struct iphdr            *iph;
108         struct tcphdr           *tcph;
109         u_char                          *data;
110         u_char                          *ptr;
111         struct pcap_pkthdr      nh;
112         u_int32_t                       temp;
113
114         /*Safety Check*/
115         if(h==NULL || state.en_priv==NULL || eip==NULL){
116                 dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation handshake method given bad data!\n");
117                 return -1;
118         }
119
120         /*create new libpcap header*/
121         memcpy(&nh, h, sizeof(struct pcap_pkthdr));
122
123         /*create buffer for new packet*/
124         ptr=data=malloc(MAX_PACKET);
125         if(data==NULL){
126                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
127                 exit(1);
128         }
129
130         /* 1)Create Syn Packet*/
131                 /*make sure the packet is all zero*/
132                 memset(data, 0, MAX_PACKET);
133                 ptr=data;
134
135                 /*Set the libpcap header*/
136                 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
137                 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
138                 nh.ts.tv_usec-=3000; /*Time comes from the first packet received, so make these packets earlier*/
139
140                 /* Copy Ethernet and IP headers from private data area*/
141                 /* These are headers from the first packet in the capture*/
142                 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
143
144                 /*Adjust IP header*/
145                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
146                 iph->protocol=6;
147                 iph->check=htonl(0);
148                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
149
150                 /*Compute IPv4 Checksum*/
151                 iph->check=0;
152                 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
153
154                 /*Build TCP header*/
155                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
156                 tcph=(struct tcphdr*)ptr;
157                 tcph->source=htons(1113);
158                 tcph->dest=htons(1113);
159                 tcph->doff=6;
160                 tcph->check=htonl(0);
161                 tcph->urg_ptr=0;
162                 tcph->urg=0;
163                 tcph->psh=0;
164                 tcph->fin=0;
165                 tcph->syn=1;
166                 tcph->rst=0;
167                 tcph->ack=0;
168
169                 /*Initialize Sequence and Acknowledgment Numbers and Window*/
170                 tcph->seq=htonl(state.seq_num++);
171                 tcph->ack_seq=htonl(0);
172                 tcph->window=htons(WIN_FACTOR);
173
174                 /* Add SACK permitted option*/
175                 ptr+=sizeof(struct tcphdr);
176                 *ptr=4;
177                 ptr++;
178                 *ptr=2;
179
180                 /*Compute TCP Checksum*/
181                 tcph->check=0;
182                 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
183                                                                                 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
184
185                 /*Save To Packet Capture*/
186                 pcap_dump((u_char*)state.out,&nh, data);
187
188
189         /* 2)Create Syn,Ack Packet*/
190                 /*make sure the packet is all zero*/
191                 memset(data, 0, MAX_PACKET);
192                 ptr=data;
193
194                 /*Set the libpcap header*/
195                 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
196                 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
197                 nh.ts.tv_usec+=1000; /*This packet is 1/3rd closer to the first packet then the previous packet created*/
198
199                 /* Copy Ethernet and IP headers from private data area*/
200                 /* These are headers from the first packet in the capture*/
201                 memcpy(data, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
202
203                 /*Adjust IP header, including swapping source and destination*/
204                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
205                 iph->protocol=6;
206                 iph->check=htonl(0);
207                 temp=iph->saddr;
208                 iph->saddr=iph->daddr;
209                 iph->daddr=temp;
210                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
211
212                 /*Compute IPv4 Checksum*/
213                 iph->check=0;
214                 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
215
216                 /*Build TCP header*/
217                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
218                 tcph=(struct tcphdr*)ptr;
219                 tcph->source=htons(1113);
220                 tcph->dest=htons(1113);
221                 tcph->doff=6;
222                 tcph->check=htonl(0);
223                 tcph->urg_ptr=0;
224                 tcph->urg=0;
225                 tcph->psh=0;
226                 tcph->fin=0;
227                 tcph->syn=1;
228                 tcph->rst=0;
229                 tcph->ack=1;
230
231                 /*Initialize Sequence and Acknowledgement Numbers and Window*/
232                 tcph->seq=htonl(state.ack_num++);
233                 tcph->ack_seq=htonl(state.seq_num);
234                 tcph->window=htons(WIN_FACTOR);
235
236                 /* Add SACK permitted option*/
237                 ptr+=sizeof(struct tcphdr);
238                 *ptr=4;
239                 ptr++;
240                 *ptr=2;
241
242                 /*Compute TCP Checksum*/
243                 tcph->check=0;
244                 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4 ,
245                                                                         (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
246
247                 /*Save To Packet Capture*/
248                 pcap_dump((u_char*)state.out,&nh, data);
249
250         /* 3)Create Ack Packet*/
251                 /*make sure the packet is all zero*/
252                 memset(data, 0, MAX_PACKET);
253                 ptr=data;
254
255                 /*Set the libpcap header*/
256                 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
257                 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
258                 nh.ts.tv_usec+=1000; /*This packet is 2/3rds between SYN and first packet*/
259
260                 /* Copy Ethernet and IP headers from private data area*/
261                 /* These are headers from the first packet in the capture*/
262                 memcpy(data, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
263
264                 /*Adjust IP header*/
265                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
266                 iph->protocol=6;
267                 iph->check=htonl(0);
268                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
269
270                 /*Compute IPv4 Checksum*/
271                 iph->check=0;
272                 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
273
274                 /*Build TCP header*/
275                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
276                 tcph=(struct tcphdr*)ptr;
277                 tcph->source=htons(1113);
278                 tcph->dest=htons(1113);
279                 tcph->doff=5;
280                 tcph->check=htonl(0);
281                 tcph->urg_ptr=0;
282                 tcph->urg=0;
283                 tcph->psh=0;
284                 tcph->fin=0;
285                 tcph->syn=0;
286                 tcph->rst=0;
287                 tcph->ack=1;
288
289                 /*Initialize Sequence and Acknowledgement numbers and window*/
290                 tcph->seq=htonl(state.seq_num++);
291                 tcph->ack_seq=htonl(state.ack_num);
292                 tcph->window=htons(WIN_FACTOR);
293
294                 /*Compute TCP Checksum*/
295                 tcph->check=0;
296                 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
297                                                                 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
298
299                 /*Save To Packet Capture*/
300                 pcap_dump((u_char*)state.out,&nh, data);
301         return 0;
302 }
303
304 /* Create a TCP ending handshake */
305 int eip4_fin(struct eip4_en_p *eip){
306         struct iphdr            *iph;
307         struct tcphdr           *tcph;
308         u_char                          *data;
309         u_char                          *ptr;
310         struct pcap_pkthdr      nh;
311         u_int32_t                       temp;
312
313         /*Safety Check*/
314         if(eip==NULL){
315                 dbgprintf(1,"Error: Ethernet, IPv4 Encapsulation Finish method given invalid data!\n");
316                 return -1;
317         }
318
319         /*copy the libpcap header from private data area*/
320         memcpy(&nh, &eip->header, sizeof(struct pcap_pkthdr));
321
322         /*create buffer for new packet*/
323         ptr=data=malloc(MAX_PACKET);
324         if(data==NULL){
325                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
326                 exit(1);
327         }
328
329         /* 1)Create Fin Packet*/
330                 /*make sure the packet is all zero*/
331                 memset(data, 0, MAX_PACKET);
332                 ptr=data;
333
334                 /*Set the libpcap header*/
335                 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
336                 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
337                 nh.ts.tv_usec+=1000; /*Time is from the last packet in the capture; make this packet after that packet*/
338
339                 /* Copy Ethernet and IP headers from private data area*/
340                 /* These are headers from the first packet in the capture*/
341                 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
342
343                 /*Adjust IP header*/
344                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
345                 iph->protocol=6;
346                 iph->check=htonl(0);
347                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
348
349                 /*Compute IPv4 Checksum*/
350                 iph->check=0;
351                 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
352
353                 /*Build TCP header*/
354                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
355                 tcph=(struct tcphdr*)ptr;
356                 tcph->source=htons(1113);
357                 tcph->dest=htons(1113);
358                 tcph->doff=5;
359                 tcph->check=htonl(0);
360                 tcph->urg_ptr=0;
361                 tcph->urg=0;
362                 tcph->psh=0;
363                 tcph->fin=1;
364                 tcph->syn=0;
365                 tcph->rst=0;
366                 tcph->ack=1;
367
368                 /* Adjust Sequence and Acknowledgment numbers and window*/
369                 tcph->seq=htonl(++state.seq_num);
370                 tcph->ack_seq=htonl(state.ack_num);
371                 tcph->window=htons(WIN_FACTOR);
372
373                 /*Update Sequence Number to include the fin packet in the sequence number space*/
374                 state.seq_num++;
375
376                 /*Compute TCP Checksum*/
377                 tcph->check=0;
378                 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
379                                                                 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
380
381                 /* Save To Packet Capture*/
382                 pcap_dump((u_char*)state.out,&nh, data);
383
384         /* 2)Create Fin,Ack Packet*/
385                 /*make sure the packet is all zero*/
386                 memset(data, 0, MAX_PACKET);
387                 ptr=data;
388
389                 /*Set the libpcap header*/
390                 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
391                 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
392                 nh.ts.tv_usec+=1000; /*After the previous packet*/
393
394                 /* Copy Ethernet and IP headers from private data area*/
395                 /* These are headers from the first packet in the capture*/
396                 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
397
398                 /*Update IP header, including swapping source and destination addresses*/
399                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
400                 iph->protocol=6;
401                 iph->check=htonl(0);
402                 temp=iph->saddr;
403                 iph->saddr=iph->daddr;
404                 iph->daddr=temp;
405                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
406
407                 /*Compute IPv4 Checksum*/
408                 iph->check=0;
409                 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
410
411                 /*Build TCP header*/
412                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
413                 tcph=(struct tcphdr*)ptr;
414                 tcph->source=htons(1113);
415                 tcph->dest=htons(1113);
416                 tcph->doff=5;
417                 tcph->check=htonl(0);
418                 tcph->urg_ptr=0;
419                 tcph->urg=0;
420                 tcph->psh=0;
421                 tcph->fin=1;
422                 tcph->syn=0;
423                 tcph->rst=0;
424                 tcph->ack=1;
425
426                 /*Adjust Sequence and Acknowledgment numbers and window*/
427                 tcph->seq=htonl(state.ack_num++);
428                 tcph->ack_seq=htonl(state.seq_num);
429                 tcph->window=htons(WIN_FACTOR);
430
431                 /*Compute TCP Checksum*/
432                 tcph->check=0;
433                 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,sizeof(struct tcphdr),
434                                                                 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
435
436                 /*Save To Packet Capture*/
437                 pcap_dump((u_char*)state.out,&nh, data);
438
439         /* 3)Create Ack Packet*/
440                 /*make sure the packet is all zero*/
441                 memset(data, 0, MAX_PACKET);
442                 ptr=data;
443
444                 /*Set the libpcap header*/
445                 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
446                 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
447                 nh.ts.tv_usec+=1000; /*After the previous packet*/
448
449                 /* Copy Ethernet and IP headers from private data area*/
450                 /* These are headers from the first packet in the capture*/
451                 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
452
453                 /*Update IP header*/
454                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
455                 iph->protocol=6;
456                 iph->check=htonl(0);
457                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
458
459                 /*Compute IPv4 Checksum*/
460                 iph->check=0;
461                 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
462
463                 /*Build TCP header*/
464                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
465                 tcph=(struct tcphdr*)ptr;
466                 tcph->source=htons(1113);
467                 tcph->dest=htons(1113);
468                 tcph->doff=5;
469                 tcph->check=htonl(0);
470                 tcph->urg_ptr=0;
471                 tcph->urg=0;
472                 tcph->psh=0;
473                 tcph->fin=0;
474                 tcph->syn=0;
475                 tcph->rst=0;
476                 tcph->ack=1;
477
478                 /*Adjust Sequence and Acknowledgment numbers and window*/
479                 tcph->seq=htonl(state.seq_num++);
480                 tcph->ack_seq=htonl(state.ack_num);
481                 tcph->window=htons(WIN_FACTOR);
482
483                 /*Compute TCP Checksum*/
484                 tcph->check=0;
485                 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
486                                                                 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
487
488                 /*Save To Packet Capture*/
489                 pcap_dump((u_char*)state.out,&nh, data);
490         return 0;
491 }