]> sjero.net Git - ltp2tcp/blob - encap.c
Update headers in all files with GPL message
[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
32
33
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;
38                 return;
39         }
40         if(strcmp(string, "dccp")==0 || strcmp(string,"DCCP")==0){ /*DCCP*/
41                 state.en_ops=&dccp_encap;
42                 return;
43         }
44         if(strcmp(string, "sll")==0 || strcmp(string,"SLL")==0){ /*SLL (Linux Cooked Capture)*/
45                         state.en_ops=&sll_encap;
46                         return;
47                 }
48         printf("Encapsulation type: %s is not supported\n", string);
49         exit(1);
50 return;
51 };
52
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){
55         /*safety check*/
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");
58                 return -1;
59         }
60
61         if(eip->first==0){
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));
66                 eip->first=1;
67         }else{
68                 /* Just update the libpcap header (and associated timestamp)*/
69                 memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
70         }
71         return 0;
72 }
73
74 /* encapsulation manipulation after conversion */
75 int eip4_post(struct eip4_en_p *eip, int tlen, u_char* data){
76         struct iphdr *iph;
77
78         /* Move data pointer to start of IPv4 header*/
79         data+=sizeof(struct ether_header);
80
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");
84                         return -1;
85         }
86
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);
90         return 0;
91 }
92
93 /* Create a TCP three-way handshake */
94 int eip4_handshake(struct eip4_en_p *eip, struct pcap_pkthdr *h){
95         struct iphdr            *iph;
96         struct tcphdr           *tcph;
97         u_char                          *data;
98         u_char                          *ptr;
99         struct pcap_pkthdr      nh;
100         u_int32_t                       temp;
101
102         /*Safety Check*/
103         if(h==NULL || state.en_priv==NULL || eip==NULL){
104                 dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation handshake method given bad data!\n");
105                 return -1;
106         }
107
108         /*create new libpcap header*/
109         memcpy(&nh, h, sizeof(struct pcap_pkthdr));
110
111         /*create buffer for new packet*/
112         ptr=data=malloc(MAX_PACKET);
113         if(data==NULL){
114                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
115                 exit(1);
116         }
117
118         /* 1)Create Syn Packet*/
119                 /*make sure the packet is all zero*/
120                 memset(data, 0, MAX_PACKET);
121                 ptr=data;
122
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*/
127
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));
131
132                 /*Adjust IP header*/
133                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
134                 iph->protocol=6;
135                 iph->check=htonl(0);
136                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
137
138                 /*Build TCP header*/
139                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
140                 tcph=(struct tcphdr*)ptr;
141                 tcph->source=htons(1113);
142                 tcph->dest=htons(1113);
143                 tcph->doff=6;
144                 tcph->check=htonl(0);
145                 tcph->urg_ptr=0;
146                 tcph->urg=0;
147                 tcph->psh=0;
148                 tcph->fin=0;
149                 tcph->syn=1;
150                 tcph->rst=0;
151                 tcph->ack=0;
152
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);
157
158                 /* Add SACK permitted option*/
159                 ptr+=sizeof(struct tcphdr);
160                 *ptr=4;
161                 ptr++;
162                 *ptr=2;
163
164                 /*Save To Packet Capture*/
165                 pcap_dump((u_char*)state.out,&nh, data);
166
167
168         /* 2)Create Syn,Ack Packet*/
169                 /*make sure the packet is all zero*/
170                 memset(data, 0, MAX_PACKET);
171                 ptr=data;
172
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*/
177
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));
181
182                 /*Adjust IP header, including swapping source and destination*/
183                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
184                 iph->protocol=6;
185                 iph->check=htonl(0);
186                 temp=iph->saddr;
187                 iph->saddr=iph->daddr;
188                 iph->daddr=temp;
189                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
190
191                 /*Build TCP header*/
192                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
193                 tcph=(struct tcphdr*)ptr;
194                 tcph->source=htons(1113);
195                 tcph->dest=htons(1113);
196                 tcph->doff=6;
197                 tcph->check=htonl(0);
198                 tcph->urg_ptr=0;
199                 tcph->urg=0;
200                 tcph->psh=0;
201                 tcph->fin=0;
202                 tcph->syn=1;
203                 tcph->rst=0;
204                 tcph->ack=1;
205
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);
210
211                 /* Add SACK permitted option*/
212                 ptr+=sizeof(struct tcphdr);
213                 *ptr=4;
214                 ptr++;
215                 *ptr=2;
216
217                 /*Save To Packet Capture*/
218                 pcap_dump((u_char*)state.out,&nh, data);
219
220         /* 3)Create Ack Packet*/
221                 /*make sure the packet is all zero*/
222                 memset(data, 0, MAX_PACKET);
223                 ptr=data;
224
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*/
229
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));
233
234                 /*Adjust IP header*/
235                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
236                 iph->protocol=6;
237                 iph->check=htonl(0);
238                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
239
240                 /*Build TCP header*/
241                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
242                 tcph=(struct tcphdr*)ptr;
243                 tcph->source=htons(1113);
244                 tcph->dest=htons(1113);
245                 tcph->doff=5;
246                 tcph->check=htonl(0);
247                 tcph->urg_ptr=0;
248                 tcph->urg=0;
249                 tcph->psh=0;
250                 tcph->fin=0;
251                 tcph->syn=0;
252                 tcph->rst=0;
253                 tcph->ack=1;
254
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);
259
260                 /*Save To Packet Capture*/
261                 pcap_dump((u_char*)state.out,&nh, data);
262         return 0;
263 }
264
265 /* Create a TCP ending handshake */
266 int eip4_fin(struct eip4_en_p *eip){
267         struct iphdr            *iph;
268         struct tcphdr           *tcph;
269         u_char                          *data;
270         u_char                          *ptr;
271         struct pcap_pkthdr      nh;
272         u_int32_t                       temp;
273
274         /*Safety Check*/
275         if(eip==NULL){
276                 dbgprintf(1,"Error: Ethernet, IPv4 Encapsulation Finish method given invalid data!\n");
277                 return -1;
278         }
279
280         /*copy the libpcap header from private data area*/
281         memcpy(&nh, &eip->header, sizeof(struct pcap_pkthdr));
282
283         /*create buffer for new packet*/
284         ptr=data=malloc(MAX_PACKET);
285         if(data==NULL){
286                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
287                 exit(1);
288         }
289
290         /* 1)Create Fin Packet*/
291                 /*make sure the packet is all zero*/
292                 memset(data, 0, MAX_PACKET);
293                 ptr=data;
294
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*/
299
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));
303
304                 /*Adjust IP header*/
305                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
306                 iph->protocol=6;
307                 iph->check=htonl(0);
308                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
309
310                 /*Build TCP header*/
311                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
312                 tcph=(struct tcphdr*)ptr;
313                 tcph->source=htons(1113);
314                 tcph->dest=htons(1113);
315                 tcph->doff=5;
316                 tcph->check=htonl(0);
317                 tcph->urg_ptr=0;
318                 tcph->urg=0;
319                 tcph->psh=0;
320                 tcph->fin=1;
321                 tcph->syn=0;
322                 tcph->rst=0;
323                 tcph->ack=1;
324
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);
329
330                 /*Update Sequence Number to include the fin packet in the sequence number space*/
331                 state.seq_num++;
332
333                 /* Save To Packet Capture*/
334                 pcap_dump((u_char*)state.out,&nh, data);
335
336         /* 2)Create Fin,Ack Packet*/
337                 /*make sure the packet is all zero*/
338                 memset(data, 0, MAX_PACKET);
339                 ptr=data;
340
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*/
345
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));
349
350                 /*Update IP header, including swapping source and destination addresses*/
351                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
352                 iph->protocol=6;
353                 iph->check=htonl(0);
354                 temp=iph->saddr;
355                 iph->saddr=iph->daddr;
356                 iph->daddr=temp;
357                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
358
359                 /*Build TCP header*/
360                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
361                 tcph=(struct tcphdr*)ptr;
362                 tcph->source=htons(1113);
363                 tcph->dest=htons(1113);
364                 tcph->doff=5;
365                 tcph->check=htonl(0);
366                 tcph->urg_ptr=0;
367                 tcph->urg=0;
368                 tcph->psh=0;
369                 tcph->fin=1;
370                 tcph->syn=0;
371                 tcph->rst=0;
372                 tcph->ack=1;
373
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);
378
379                 /*Save To Packet Capture*/
380                 pcap_dump((u_char*)state.out,&nh, data);
381
382         /* 3)Create Ack Packet*/
383                 /*make sure the packet is all zero*/
384                 memset(data, 0, MAX_PACKET);
385                 ptr=data;
386
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*/
391
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));
395
396                 /*Update IP header*/
397                 iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
398                 iph->protocol=6;
399                 iph->check=htonl(0);
400                 iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
401
402                 /*Build TCP header*/
403                 ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
404                 tcph=(struct tcphdr*)ptr;
405                 tcph->source=htons(1113);
406                 tcph->dest=htons(1113);
407                 tcph->doff=5;
408                 tcph->check=htonl(0);
409                 tcph->urg_ptr=0;
410                 tcph->urg=0;
411                 tcph->psh=0;
412                 tcph->fin=0;
413                 tcph->syn=0;
414                 tcph->rst=0;
415                 tcph->ack=1;
416
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);
421
422                 /*Save To Packet Capture*/
423                 pcap_dump((u_char*)state.out,&nh, data);
424         return 0;
425 }