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