1 /******************************************************************************
2 Utility to convert a LTP flow to a TCP flow for LTP analysis via tcptrace.
3 Utility Functions for Encapsulation
5 Copyright (C) 2013 Samuel Jero <sj323707@ohio.edu>
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.
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.
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/>.
20 Author: Samuel Jero <sj323707@ohio.edu>
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
28 2)Uses some special types from Linux (u_char, u_int32_t)
29 ******************************************************************************/
31 #include "checksums.h"
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;
41 if(strcmp(string, "dccp")==0 || strcmp(string,"DCCP")==0){ /*DCCP*/
42 state.en_ops=&dccp_encap;
45 if(strcmp(string, "sll")==0 || strcmp(string,"SLL")==0){ /*SLL (Linux Cooked Capture)*/
46 state.en_ops=&sll_encap;
49 printf("Encapsulation type: %s is not supported\n", string);
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){
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");
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));
69 /* Just update the libpcap header (and associated timestamp)*/
70 memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
75 /* encapsulation manipulation after conversion */
76 int eip4_post(struct eip4_en_p *eip, int tlen, u_char* data){
80 /* Move data pointer to start of IPv4 header*/
81 data+=sizeof(struct ether_header);
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");
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);
93 /*Compute IPv4 Checksum*/
95 iph->check=ipv4_chksum(data,iph->ihl*4);
97 /*Compute TCP Checksum*/
99 tcph=(struct tcphdr*)data;
101 tcph->check=ipv4_pseudohdr_chksum(data, tlen, (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
105 /* Create a TCP three-way handshake */
106 int eip4_handshake(struct eip4_en_p *eip, struct pcap_pkthdr *h){
111 struct pcap_pkthdr nh;
115 if(h==NULL || state.en_priv==NULL || eip==NULL){
116 dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation handshake method given bad data!\n");
120 /*create new libpcap header*/
121 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
123 /*create buffer for new packet*/
124 ptr=data=malloc(MAX_PACKET);
126 dbgprintf(0,"Error: Couldn't allocate Memory\n");
130 /* 1)Create Syn Packet*/
131 /*make sure the packet is all zero*/
132 memset(data, 0, MAX_PACKET);
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*/
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));
145 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
148 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
150 /*Compute IPv4 Checksum*/
152 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
155 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
156 tcph=(struct tcphdr*)ptr;
157 tcph->source=htons(1113);
158 tcph->dest=htons(1113);
160 tcph->check=htonl(0);
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);
174 /* Add SACK permitted option*/
175 ptr+=sizeof(struct tcphdr);
180 /*Compute TCP Checksum*/
182 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
183 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
185 /*Save To Packet Capture*/
186 pcap_dump((u_char*)state.out,&nh, data);
189 /* 2)Create Syn,Ack Packet*/
190 /*make sure the packet is all zero*/
191 memset(data, 0, MAX_PACKET);
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*/
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));
203 /*Adjust IP header, including swapping source and destination*/
204 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
208 iph->saddr=iph->daddr;
210 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
212 /*Compute IPv4 Checksum*/
214 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
217 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
218 tcph=(struct tcphdr*)ptr;
219 tcph->source=htons(1113);
220 tcph->dest=htons(1113);
222 tcph->check=htonl(0);
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);
236 /* Add SACK permitted option*/
237 ptr+=sizeof(struct tcphdr);
242 /*Compute TCP Checksum*/
244 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4 ,
245 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
247 /*Save To Packet Capture*/
248 pcap_dump((u_char*)state.out,&nh, data);
250 /* 3)Create Ack Packet*/
251 /*make sure the packet is all zero*/
252 memset(data, 0, MAX_PACKET);
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*/
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));
265 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
268 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
270 /*Compute IPv4 Checksum*/
272 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
275 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
276 tcph=(struct tcphdr*)ptr;
277 tcph->source=htons(1113);
278 tcph->dest=htons(1113);
280 tcph->check=htonl(0);
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);
294 /*Compute TCP Checksum*/
296 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
297 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
299 /*Save To Packet Capture*/
300 pcap_dump((u_char*)state.out,&nh, data);
304 /* Create a TCP ending handshake */
305 int eip4_fin(struct eip4_en_p *eip){
310 struct pcap_pkthdr nh;
315 dbgprintf(1,"Error: Ethernet, IPv4 Encapsulation Finish method given invalid data!\n");
319 /*copy the libpcap header from private data area*/
320 memcpy(&nh, &eip->header, sizeof(struct pcap_pkthdr));
322 /*create buffer for new packet*/
323 ptr=data=malloc(MAX_PACKET);
325 dbgprintf(0,"Error: Couldn't allocate Memory\n");
329 /* 1)Create Fin Packet*/
330 /*make sure the packet is all zero*/
331 memset(data, 0, MAX_PACKET);
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*/
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));
344 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
347 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
349 /*Compute IPv4 Checksum*/
351 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
354 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
355 tcph=(struct tcphdr*)ptr;
356 tcph->source=htons(1113);
357 tcph->dest=htons(1113);
359 tcph->check=htonl(0);
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);
373 /*Update Sequence Number to include the fin packet in the sequence number space*/
376 /*Compute TCP Checksum*/
378 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
379 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
381 /* Save To Packet Capture*/
382 pcap_dump((u_char*)state.out,&nh, data);
384 /* 2)Create Fin,Ack Packet*/
385 /*make sure the packet is all zero*/
386 memset(data, 0, MAX_PACKET);
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*/
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));
398 /*Update IP header, including swapping source and destination addresses*/
399 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
403 iph->saddr=iph->daddr;
405 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
407 /*Compute IPv4 Checksum*/
409 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
412 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
413 tcph=(struct tcphdr*)ptr;
414 tcph->source=htons(1113);
415 tcph->dest=htons(1113);
417 tcph->check=htonl(0);
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);
431 /*Compute TCP Checksum*/
433 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,sizeof(struct tcphdr),
434 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
436 /*Save To Packet Capture*/
437 pcap_dump((u_char*)state.out,&nh, data);
439 /* 3)Create Ack Packet*/
440 /*make sure the packet is all zero*/
441 memset(data, 0, MAX_PACKET);
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*/
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));
454 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
457 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
459 /*Compute IPv4 Checksum*/
461 iph->check=ipv4_chksum((u_char*)iph,iph->ihl*4);
464 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
465 tcph=(struct tcphdr*)ptr;
466 tcph->source=htons(1113);
467 tcph->dest=htons(1113);
469 tcph->check=htonl(0);
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);
483 /*Compute TCP Checksum*/
485 tcph->check=ipv4_pseudohdr_chksum((u_char*)tcph,tcph->doff*4,
486 (u_char*)&iph->daddr, (u_char*)&iph->saddr, iph->protocol);
488 /*Save To Packet Capture*/
489 pcap_dump((u_char*)state.out,&nh, data);