1 /******************************************************************************
2 Utility to convert a LTP flow to a TCP flow for LTP analysis via tcptrace.
3 <SLL, IPv4, UDP> encapsulation functions
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 ******************************************************************************/
32 #include <netinet/udp.h>
38 /*SLL encapsulation private data structure*/
41 struct pcap_pkthdr header;
42 u_char od[sizeof(struct sll_header)+sizeof(struct iphdr)+sizeof(struct udphdr)];
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){
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");
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));
61 /* Just update the libpcap header (and associated timestamp)*/
62 memcpy(&slip->header, h, sizeof(struct pcap_pkthdr));
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)
71 struct sll_header *slh;
75 if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
76 dbgprintf(0,"Error: SLL Encapsulation given bad data!\n");
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");
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");
95 if(fill_sllip4_encap((struct sll_en_p*)state.en_priv, *odata, *olength, h)<0){
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);
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");
111 /* Check That this is IPv4 and that UDP is next*/
112 iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
114 dbgprintf(1, "Note: Packet is not IPv4\n");
117 if(iph->protocol!=0x11){
118 dbgprintf(1, "Note: Packet is not UDP\n");
122 /*set ip to indicate that tcp is next protocol*/
126 /* Adjust libpcap headers*/
127 h->caplen=sizeof(struct sll_header) +sizeof(struct iphdr);
128 h->len=sizeof(struct sll_header) +sizeof(struct iphdr);
130 /*Adjust packet length*/
131 udph=(struct udphdr*)*odata;
132 *olength=ntohs(udph->len);
134 /*Adjust New Packet Length*/
135 *nlength-=sizeof(struct sll_header) +sizeof(struct iphdr);
137 /*Move Packet Pointer past UDP header*/
138 *odata+=sizeof(struct udphdr);
142 /* encapsulation manipulation after conversion */
143 int sll_encap_post(int tlen, u_char *data)
147 /* Move data pointer to start of IPv4 header*/
148 data+=sizeof(struct sll_header);
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");
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);
162 /* Create a TCP three-way handshake */
163 int sll_encap_handshake(struct pcap_pkthdr *h)
169 struct pcap_pkthdr nh;
171 struct sll_en_p *slip=(struct sll_en_p*)state.en_priv;
175 if(h==NULL || state.en_priv==NULL){
176 dbgprintf(1, "Error: SLL, IPv4 Encapsulation handshake method given bad data!\n");
180 /*create new libpcap header*/
181 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
183 /*create buffer for new packet*/
184 ptr=data=malloc(MAX_PACKET);
186 dbgprintf(0,"Error: Couldn't allocate Memory\n");
190 /* 1)Create Syn Packet*/
191 /*make sure the packet is all zero*/
192 memset(data, 0, MAX_PACKET);
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*/
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));
205 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
208 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
211 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
212 tcph=(struct tcphdr*)ptr;
213 tcph->source=htons(1113);
214 tcph->dest=htons(1113);
216 tcph->check=htonl(0);
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);
230 /* Add SACK permitted option*/
231 ptr+=sizeof(struct tcphdr);
236 /*Save To Packet Capture*/
237 pcap_dump((u_char*)state.out,&nh, data);
240 /* 2)Create Syn,Ack Packet*/
241 /*make sure the packet is all zero*/
242 memset(data, 0, MAX_PACKET);
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*/
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));
254 /*Adjust IP header, including swapping source and destination*/
255 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
259 iph->saddr=iph->daddr;
261 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
264 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
265 tcph=(struct tcphdr*)ptr;
266 tcph->source=htons(1113);
267 tcph->dest=htons(1113);
269 tcph->check=htonl(0);
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);
283 /* Add SACK permitted option*/
284 ptr+=sizeof(struct tcphdr);
289 /*Save To Packet Capture*/
290 pcap_dump((u_char*)state.out,&nh, data);
292 /* 3)Create Ack Packet*/
293 /*make sure the packet is all zero*/
294 memset(data, 0, MAX_PACKET);
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*/
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));
307 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
310 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
313 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
314 tcph=(struct tcphdr*)ptr;
315 tcph->source=htons(1113);
316 tcph->dest=htons(1113);
318 tcph->check=htonl(0);
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);
332 /*Save To Packet Capture*/
333 pcap_dump((u_char*)state.out,&nh, data);
337 /* Create a TCP ending handshake */
344 struct pcap_pkthdr nh;
346 struct sll_en_p *slip=(struct sll_en_p*)state.en_priv;
350 dbgprintf(1,"Error: SLL, IPv4 Encapsulation Finish method given invalid data!\n");
354 /*copy the libpcap header from private data area*/
355 memcpy(&nh, &slip->header, sizeof(struct pcap_pkthdr));
357 /*create buffer for new packet*/
358 ptr=data=malloc(MAX_PACKET);
360 dbgprintf(0,"Error: Couldn't allocate Memory\n");
364 /* 1)Create Fin Packet*/
365 /*make sure the packet is all zero*/
366 memset(data, 0, MAX_PACKET);
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*/
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));
379 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
382 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
385 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
386 tcph=(struct tcphdr*)ptr;
387 tcph->source=htons(1113);
388 tcph->dest=htons(1113);
390 tcph->check=htonl(0);
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);
404 /*Update Sequence Number to include the fin packet in the sequence number space*/
407 /* Save To Packet Capture*/
408 pcap_dump((u_char*)state.out,&nh, data);
410 /* 2)Create Fin,Ack Packet*/
411 /*make sure the packet is all zero*/
412 memset(data, 0, MAX_PACKET);
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*/
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));
424 /*Update IP header, including swapping source and destination addresses*/
425 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
429 iph->saddr=iph->daddr;
431 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
434 ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
435 tcph=(struct tcphdr*)ptr;
436 tcph->source=htons(1113);
437 tcph->dest=htons(1113);
439 tcph->check=htonl(0);
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);
453 /*Save To Packet Capture*/
454 pcap_dump((u_char*)state.out,&nh, data);
456 /* 3)Create Ack Packet*/
457 /*make sure the packet is all zero*/
458 memset(data, 0, MAX_PACKET);
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*/
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));
471 iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
474 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
477 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
478 tcph=(struct tcphdr*)ptr;
479 tcph->source=htons(1113);
480 tcph->dest=htons(1113);
482 tcph->check=htonl(0);
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);
496 /*Save To Packet Capture*/
497 pcap_dump((u_char*)state.out,&nh, data);
504 /* The UDP Encapsulation Structure*/
505 struct encap_ops sll_encap = {
507 .post=sll_encap_post,
508 .handshake=sll_encap_handshake,