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 ******************************************************************************/
34 /*Encapsulation Selection*/
35 void encap_sel(char* string){
36 if(strcmp(string, "udp")==0 || strcmp(string,"UDP")==0){ /*UDP*/
37 state.en_ops=&udp_encap;
40 if(strcmp(string, "dccp")==0 || strcmp(string,"DCCP")==0){ /*DCCP*/
41 state.en_ops=&dccp_encap;
44 if(strcmp(string, "sll")==0 || strcmp(string,"SLL")==0){ /*SLL (Linux Cooked Capture)*/
45 state.en_ops=&sll_encap;
48 printf("Encapsulation type: %s is not supported\n", string);
53 /*Fill the encapsulation structure*/
54 int fill_eip4_encap(struct eip4_en_p *eip, const u_char* data, int dlen, struct pcap_pkthdr *h){
56 if(eip==NULL || data==NULL || h==NULL || dlen < sizeof(struct ether_header)+sizeof(struct iphdr)){
57 dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation method given bad data!\n");
62 /* First time, allocate memory and copy libpcap header and encap headers
63 * this guarantees the IP "direction" of the encap headers */
64 memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
65 memcpy(eip->od, data,sizeof(struct ether_header)+sizeof(struct iphdr));
68 /* Just update the libpcap header (and associated timestamp)*/
69 memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
74 /* encapsulation manipulation after conversion */
75 int eip4_post(struct eip4_en_p *eip, int tlen, u_char* data){
78 /* Move data pointer to start of IPv4 header*/
79 data+=sizeof(struct ether_header);
81 /*Determine if the given length is reasonable*/
82 if((tlen+sizeof(struct iphdr)) > 0xFFFF){
83 dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
87 /*Adjust IPv4 header to account for packet's total length*/
88 iph=(struct iphdr*)data;
89 iph->tot_len=htons(sizeof(struct iphdr)+tlen);
93 /* Create a TCP three-way handshake */
94 int eip4_handshake(struct eip4_en_p *eip, struct pcap_pkthdr *h){
99 struct pcap_pkthdr nh;
103 if(h==NULL || state.en_priv==NULL || eip==NULL){
104 dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation handshake method given bad data!\n");
108 /*create new libpcap header*/
109 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
111 /*create buffer for new packet*/
112 ptr=data=malloc(MAX_PACKET);
114 dbgprintf(0,"Error: Couldn't allocate Memory\n");
118 /* 1)Create Syn Packet*/
119 /*make sure the packet is all zero*/
120 memset(data, 0, MAX_PACKET);
123 /*Set the libpcap header*/
124 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
125 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
126 nh.ts.tv_usec-=3000; /*Time comes from the first packet received, so make these packets earlier*/
128 /* Copy Ethernet and IP headers from private data area*/
129 /* These are headers from the first packet in the capture*/
130 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
133 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
136 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
139 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
140 tcph=(struct tcphdr*)ptr;
141 tcph->source=htons(1113);
142 tcph->dest=htons(1113);
144 tcph->check=htonl(0);
153 /*Initialize Sequence and Acknowledgment Numbers and Window*/
154 tcph->seq=htonl(state.seq_num++);
155 tcph->ack_seq=htonl(0);
156 tcph->window=htons(WIN_FACTOR);
158 /* Add SACK permitted option*/
159 ptr+=sizeof(struct tcphdr);
164 /*Save To Packet Capture*/
165 pcap_dump((u_char*)state.out,&nh, data);
168 /* 2)Create Syn,Ack Packet*/
169 /*make sure the packet is all zero*/
170 memset(data, 0, MAX_PACKET);
173 /*Set the libpcap header*/
174 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
175 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
176 nh.ts.tv_usec+=1000; /*This packet is 1/3rd closer to the first packet then the previous packet created*/
178 /* Copy Ethernet and IP headers from private data area*/
179 /* These are headers from the first packet in the capture*/
180 memcpy(data, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
182 /*Adjust IP header, including swapping source and destination*/
183 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
187 iph->saddr=iph->daddr;
189 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
192 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
193 tcph=(struct tcphdr*)ptr;
194 tcph->source=htons(1113);
195 tcph->dest=htons(1113);
197 tcph->check=htonl(0);
206 /*Initialize Sequence and Acknowledgement Numbers and Window*/
207 tcph->seq=htonl(state.ack_num++);
208 tcph->ack_seq=htonl(state.seq_num);
209 tcph->window=htons(WIN_FACTOR);
211 /* Add SACK permitted option*/
212 ptr+=sizeof(struct tcphdr);
217 /*Save To Packet Capture*/
218 pcap_dump((u_char*)state.out,&nh, data);
220 /* 3)Create Ack Packet*/
221 /*make sure the packet is all zero*/
222 memset(data, 0, MAX_PACKET);
225 /*Set the libpcap header*/
226 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
227 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
228 nh.ts.tv_usec+=1000; /*This packet is 2/3rds between SYN and first packet*/
230 /* Copy Ethernet and IP headers from private data area*/
231 /* These are headers from the first packet in the capture*/
232 memcpy(data, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
235 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
238 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
241 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
242 tcph=(struct tcphdr*)ptr;
243 tcph->source=htons(1113);
244 tcph->dest=htons(1113);
246 tcph->check=htonl(0);
255 /*Initialize Sequence and Acknowledgement numbers and window*/
256 tcph->seq=htonl(state.seq_num++);
257 tcph->ack_seq=htonl(state.ack_num);
258 tcph->window=htons(WIN_FACTOR);
260 /*Save To Packet Capture*/
261 pcap_dump((u_char*)state.out,&nh, data);
265 /* Create a TCP ending handshake */
266 int eip4_fin(struct eip4_en_p *eip){
271 struct pcap_pkthdr nh;
276 dbgprintf(1,"Error: Ethernet, IPv4 Encapsulation Finish method given invalid data!\n");
280 /*copy the libpcap header from private data area*/
281 memcpy(&nh, &eip->header, sizeof(struct pcap_pkthdr));
283 /*create buffer for new packet*/
284 ptr=data=malloc(MAX_PACKET);
286 dbgprintf(0,"Error: Couldn't allocate Memory\n");
290 /* 1)Create Fin Packet*/
291 /*make sure the packet is all zero*/
292 memset(data, 0, MAX_PACKET);
295 /*Set the libpcap header*/
296 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
297 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
298 nh.ts.tv_usec+=1000; /*Time is from the last packet in the capture; make this packet after that packet*/
300 /* Copy Ethernet and IP headers from private data area*/
301 /* These are headers from the first packet in the capture*/
302 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
305 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
308 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
311 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
312 tcph=(struct tcphdr*)ptr;
313 tcph->source=htons(1113);
314 tcph->dest=htons(1113);
316 tcph->check=htonl(0);
325 /* Adjust Sequence and Acknowledgment numbers and window*/
326 tcph->seq=htonl(++state.seq_num);
327 tcph->ack_seq=htonl(state.ack_num);
328 tcph->window=htons(WIN_FACTOR);
330 /*Update Sequence Number to include the fin packet in the sequence number space*/
333 /* Save To Packet Capture*/
334 pcap_dump((u_char*)state.out,&nh, data);
336 /* 2)Create Fin,Ack Packet*/
337 /*make sure the packet is all zero*/
338 memset(data, 0, MAX_PACKET);
341 /*Set the libpcap header*/
342 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
343 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
344 nh.ts.tv_usec+=1000; /*After the previous packet*/
346 /* Copy Ethernet and IP headers from private data area*/
347 /* These are headers from the first packet in the capture*/
348 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
350 /*Update IP header, including swapping source and destination addresses*/
351 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
355 iph->saddr=iph->daddr;
357 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
360 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
361 tcph=(struct tcphdr*)ptr;
362 tcph->source=htons(1113);
363 tcph->dest=htons(1113);
365 tcph->check=htonl(0);
374 /*Adjust Sequence and Acknowledgment numbers and window*/
375 tcph->seq=htonl(state.ack_num++);
376 tcph->ack_seq=htonl(state.seq_num);
377 tcph->window=htons(WIN_FACTOR);
379 /*Save To Packet Capture*/
380 pcap_dump((u_char*)state.out,&nh, data);
382 /* 3)Create Ack Packet*/
383 /*make sure the packet is all zero*/
384 memset(data, 0, MAX_PACKET);
387 /*Set the libpcap header*/
388 nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
389 nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
390 nh.ts.tv_usec+=1000; /*After the previous packet*/
392 /* Copy Ethernet and IP headers from private data area*/
393 /* These are headers from the first packet in the capture*/
394 memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
397 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
400 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
403 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
404 tcph=(struct tcphdr*)ptr;
405 tcph->source=htons(1113);
406 tcph->dest=htons(1113);
408 tcph->check=htonl(0);
417 /*Adjust Sequence and Acknowledgment numbers and window*/
418 tcph->seq=htonl(state.seq_num++);
419 tcph->ack_seq=htonl(state.ack_num);
420 tcph->window=htons(WIN_FACTOR);
422 /*Save To Packet Capture*/
423 pcap_dump((u_char*)state.out,&nh, data);