]> sjero.net Git - dccp2tcp/blob - dccp2tcp.c
Redesign Sequence number conversion system
[dccp2tcp] / dccp2tcp.c
1 /******************************************************************************
2 Author: Samuel Jero
3
4 Date: 2/2011
5
6 Description: Program to convert a DCCP flow to a TCP flow for DCCP analysis via
7                 tcptrace.
8
9 Notes:
10         1)Supports only a single DCCP contection per capture
11         2)Source Port!=Destination Port
12         3)DCCP MUST use 48 bit sequence numbers
13         4)Checksums are not computed (they are zeroed)
14         5)Only implements those packet types normally used in a session
15         6)DCCP Ack packets show up as TCP packets containing one byte
16         7)Very little error checking of packet headers
17 ******************************************************************************/
18 #include "dccp2tcp.h"
19
20
21 int debug=0;    /*set to 1 to turn on debugging information*/
22 int yellow=0;   /*tcptrace yellow line as currently acked packet*/
23 int green=0;    /*tcptrace green line as currently acked packet*/
24 int sack=0;             /*add TCP SACKS*/
25
26 pcap_t*         in;                     /*libpcap input file discriptor*/
27 pcap_dumper_t   *out;   /*libpcap output file discriptor*/
28 struct seq_num  *s1;    /*sequence number structure for side one of connection*/
29 struct seq_num  *s2;    /*sequence number structure for side two of connection*/
30
31
32
33 void PcapSavePacket(struct pcap_pkthdr *h, u_char *data);
34 void process_packets();
35 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
36 void convert_packet(struct pcap_pkthdr *h, const u_char *odata, u_char *ndata);
37 unsigned int interp_ack_vect(u_char* hdr);
38 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial);
39 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type);
40 u_int32_t convert_ack(struct seq_num *seq, __be32 num);
41 int acked_packet_size(struct seq_num *seq, __be32 num);
42 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack);
43
44
45 /*Parse commandline options and open files*/
46 int main(int argc, char *argv[])
47 {
48         char ebuf[200];
49         char *erbuffer=ebuf;
50         char *dfile=NULL;
51         char *tfile=NULL;
52
53         /*parse commandline options*/
54         if(argc<3 || argc > 9){
55                 dbgprintf(0, "Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
56                 exit(1);
57         }
58
59         /*loop through commandline options*/
60         for(int i=1; i < argc; i++){
61                 if(argv[i][0]!='-'){
62                         if(dfile==NULL){ /*assign first non-dash argument to the dccp file*/
63                                 dfile=argv[i];
64                         }else{
65                                 if(tfile==NULL){
66                                         tfile=argv[i]; /*assign second non-dash argument to the dccp file*/
67                                 }else{
68                                         dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
69                                         exit(1);
70                                 }
71                         }
72                 }else{
73                         if(argv[i][1]=='d' && strlen(argv[i])==2){ /*debug option*/
74                                 debug++;
75                         }
76                         if(argv[i][1]=='y' && strlen(argv[i])==2){ /*yellow option*/
77                                 yellow=1;
78                         }
79                         if(argv[i][1]=='g' && strlen(argv[i])==2){ /*green option*/
80                                 green=1;
81                         }
82                         if(argv[i][1]=='s' && strlen(argv[i])==2){ /*sack option*/
83                                 sack=1;
84                         }
85                 }
86         }
87         
88         if(dfile==NULL || tfile==NULL){
89                 dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
90                 exit(1);
91         }
92
93         /*all options validated*/
94
95         if(debug){
96                 dbgprintf(1,"Debug On\n");
97                 if(green){
98                         dbgprintf(1,"Tcptrace green line at highest acknowledgment\n");
99                 }else{
100                         dbgprintf(1,"Tcptrace green line at highest acknowledged acknowledgment\n");
101                 }
102                 if(yellow){
103                         dbgprintf(1,"Tcptrace yellow line at highest acknowledgment\n");
104                 }else{
105                         dbgprintf(1,"Tcptrace yellow line window value (a made up number)\n");
106                 }
107                 if(sack){
108                         dbgprintf(1,"Adding TCP SACKS\n");
109                 }
110                 dbgprintf(1,"Input file: %s\n", dfile);
111                 dbgprintf(1,"Output file: %s\n", tfile);
112         }
113
114         /*attempt to open input file*/
115         in=pcap_open_offline(dfile, erbuffer);
116         if(in==NULL){
117                 dbgprintf(0,"Error opening input file\n");
118                 exit(1);
119         }
120
121         /*attempt to open output file*/
122         out=pcap_dump_open(in,tfile);
123         if(out==NULL){
124                 dbgprintf(0,"Error opening output file\n");
125                 exit(1);
126         }
127
128         /*process packets*/
129         u_char *user=(u_char*)out;
130         pcap_loop(in, -1, handle_packet, user); 
131         
132         /*close files*/
133         pcap_close(in);
134         pcap_dump_close(out);
135 return 0;
136 }
137
138
139 /*call back function for pcap_loop--do basic packet handling*/
140 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
141 {
142         u_char *ndata;
143         struct pcap_pkthdr nh;
144
145         /*create new libpcap header*/
146         memcpy(&nh, h, sizeof(struct pcap_pkthdr));
147
148         /*create buffer for new packet*/
149         ndata=malloc(MAX_PACKET);
150         if(ndata==NULL){
151                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
152                 exit(1);
153         }
154
155         /*make sure the packet is all zero*/
156         memset(ndata, 0, MAX_PACKET);   
157         
158         /*do all the fancy conversions*/
159         convert_packet(&nh, bytes, ndata);
160
161         /*save packet*/
162         pcap_dump(user,&nh, ndata);
163
164         free(ndata);
165 return;
166 }
167
168
169 /*do all the dccp to tcp conversions*/
170 void convert_packet(struct pcap_pkthdr *h, const u_char *odata, u_char *ndata)
171 {       
172         u_char* ncur=ndata;
173         const u_char* ocur=odata;
174         int length=h->caplen;
175         struct iphdr *iph;
176         struct tcphdr *tcph;
177         struct dccp_hdr *dccph;
178         struct dccp_hdr_ext *dccphex;
179         struct dccp_hdr_ack_bits *dccphack;
180         int datalength;
181         const u_char* pd;
182         u_char* npd;
183         u_char* tcpopt;
184
185         /*copy ethernet and ip headers over*/
186         memcpy(ncur, ocur, sizeof(struct ether_header)+sizeof(struct iphdr) );
187         ocur+=sizeof(struct ether_header)+ sizeof(struct iphdr);
188         ncur+=sizeof(struct ether_header) +sizeof(struct iphdr);
189         length-=sizeof(struct ether_header) +sizeof(struct iphdr);
190
191         /*set ip to indicate that tcp is next protocol*/
192         iph= (struct iphdr *) (ncur - sizeof(struct iphdr));
193         iph->protocol=6;
194         iph->check=htonl(0);
195
196         /*cast header pointers*/
197         tcph=(struct tcphdr*)ncur;
198         tcpopt=ncur+ sizeof(struct tcphdr);
199         dccph=(struct dccp_hdr*)ocur;
200         dccphex=(struct dccp_hdr_ext*)(ocur+sizeof(struct dccp_hdr));
201         dccphack=(struct dccp_hdr_ack_bits*)(ocur+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
202
203         dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)(((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
204
205         /*determine data length*/
206         datalength=ntohs(iph->tot_len) - sizeof(struct iphdr) - dccph->dccph_doff*4;
207         pd=odata + sizeof(struct ether_header)+sizeof(struct iphdr) + dccph->dccph_doff*4;
208
209         /*set tcp standard features*/
210         tcph->source=dccph->dccph_sport;
211         tcph->dest=dccph->dccph_dport;
212         tcph->doff=5;
213         tcph->check=htonl(0);
214         tcph->urg_ptr=0;
215
216         /*Adjust TCP advertised window size*/
217         if(!yellow){
218                 tcph->window=htons(30000);
219         }
220
221         /*make changes by packet type*/
222         if(dccph->dccph_type==DCCP_PKT_REQUEST){//DCCP REQUEST -->TCP SYN
223                 dbgprintf(2,"Packet Type: Request\n");
224
225                 if(yellow){
226                         tcph->window=htons(0);
227                 }
228                 tcph->ack_seq=htonl(0);
229                 tcph->seq=htonl(initialize_seq(&s1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
230                 tcph->syn=1;
231                 tcph->ack=0;
232                 tcph->fin=0;
233                 tcph->rst=0;
234
235                 /* add Sack-permitted option, if relevant*/
236                 if(sack){
237                         *tcpopt=4;
238                         tcpopt++;
239                         *tcpopt=2;
240                         tcph->doff++;
241                 }
242
243                 /*set libpcap header lengths*/
244                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
245                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
246
247                 /*set length in ip header*/
248                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
249         }
250
251         if(dccph->dccph_type==DCCP_PKT_RESPONSE){//DCCP RESPONSE-->TCP SYN,ACK
252                 dbgprintf(2,"Packet Type: Response\n");
253                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
254                 if(yellow){
255                         tcph->window=htons(0);
256                 }
257                 tcph->seq=htonl(initialize_seq(&s2, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
258                 tcph->syn=1;
259                 tcph->ack=1;
260                 tcph->fin=0;
261                 tcph->rst=0;
262
263                 /* add Sack-permitted option, if relevant*/
264                 if(sack){
265                         *tcpopt=4;
266                         *(tcpopt+1)=2;
267                         tcph->doff++;
268                 }
269
270                 /*set libpcap header lengths*/
271                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
272                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
273
274                 /*set length in ip header*/
275                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
276         }
277
278         if(dccph->dccph_type==DCCP_PKT_DATA){//DCCP DATA----Never seen in packet capture
279                 dbgprintf(0,"DCCP Data packet not yet implemented\n");
280                 exit(1);
281         }
282
283         if(dccph->dccph_type==DCCP_PKT_DATAACK){//DCCP DATAACK-->TCP ACK with data
284                 dbgprintf(2,"Packet Type: DataAck\n");
285                 if(s1 && dccph->dccph_sport==s1->addr){ //determine which side of connection is sending this packet
286                         if(green){
287                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
288                         }else{
289                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
290                         }
291                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
292                         if(yellow){
293                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
294                         }
295                         if(sack){
296                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
297                         }
298                 }else{
299                         if(green){
300                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
301                         }else{
302                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
303                         }
304                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),datalength,dccph->dccph_type));
305                         if(yellow){
306                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
307                         }
308                         if(sack){
309                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
310                         }
311                 }
312
313                 tcph->syn=0;
314                 tcph->ack=1;
315                 tcph->fin=0;
316                 tcph->rst=0;
317
318                 /*copy data*/
319                 npd=ndata+ sizeof(struct ether_header)+sizeof(struct iphdr)+ tcph->doff*4;
320                 memcpy(npd, pd, datalength);
321
322                 /*set libpcap header lengths*/
323                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4 + datalength;
324                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4 + datalength;
325
326                 /*set length in ip header*/
327                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4 + datalength);
328         }
329
330         if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data
331                 dbgprintf(2,"Packet Type: Ack\n");
332                 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
333                         if(green){
334                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
335                         }else{
336                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
337                         }
338                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
339                         if(yellow){
340                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
341                                 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
342                                         printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
343                                 }
344                         }
345                         if(sack){
346                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
347                         }
348                 }else{
349                         if(green){
350                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
351                         }else{
352                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
353                         }
354                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
355                         if(yellow){
356                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
357                                 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
358                                         printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
359                                 }
360                         }
361                         if(sack){
362                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
363                         }
364                 }
365
366                 tcph->syn=0;
367                 tcph->ack=1;
368                 tcph->fin=0;
369                 tcph->rst=0;
370
371                 /*set libpcap header lengths*/
372                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4 + 1;
373                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4 + 1;
374
375                 /*set length in ip header*/
376                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4 + 1);
377         }
378
379         if(dccph->dccph_type==DCCP_PKT_CLOSEREQ){//DCCP CLOSEREQ----Never seen in packet capture
380                 dbgprintf(0,"DCCP CloseReq not yet implemented\n");
381                 exit(1);
382         }
383
384         if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK
385                 dbgprintf(2,"Packet Type: Close\n");
386                 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
387                         if(green){
388                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
389                         }else{
390                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
391                         }
392                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
393                         if(yellow){
394                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
395                         }
396                         if(sack){
397                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
398                         }
399                 }else{
400                         if(green){
401                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
402                         }else{
403                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
404                         }
405                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
406                         if(yellow){
407                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
408                         }
409                         if(sack){
410                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
411                         }
412                 }
413
414                 tcph->syn=0;
415                 tcph->ack=1;
416                 tcph->fin=1;
417                 tcph->rst=0;
418
419                 /*set libpcap header lengths*/
420                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
421                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
422
423                 /*set length in ip header*/
424                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
425         }
426
427         if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK)
428                 dbgprintf(2,"Packet Type: Reset\n");
429                 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
430                         if(green){
431                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
432                         }else{
433                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
434                         }
435                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
436                         if(yellow){
437                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
438                         }
439                         if(sack){
440                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
441                         }
442                 }else{
443                         if(green){
444                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
445                         }else{
446                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
447                         }
448                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
449                         if(yellow){
450                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
451                         }
452                         if(sack){
453                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
454                         }
455                 }
456
457                 tcph->syn=0;
458                 tcph->ack=1;
459                 tcph->fin=1;
460                 tcph->rst=0;
461
462                 /*set libpcap header lengths*/
463                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
464                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
465
466                 /*set length in ip header*/
467                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
468         }
469
470         if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC
471                 dbgprintf(2,"Packet Type: Sync\n");
472                 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
473                         if(green){
474                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
475                         }else{
476                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
477                         }
478                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
479                         if(yellow){
480                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
481                         }else{
482                                 tcph->window=htons(0);
483                         }
484                         if(sack){
485                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
486                         }
487                 }else{
488                         if(green){
489                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
490                         }else{
491                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
492                         }
493                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
494                         if(yellow){
495                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
496                         }else{
497                                 tcph->window=htons(0);
498                         }
499                         if(sack){
500                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
501                         }
502                 }
503
504                 tcph->syn=0;
505                 tcph->ack=1;
506                 tcph->fin=0;
507                 tcph->rst=0;
508
509                 /*set libpcap header lengths*/
510                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+ 0;
511                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+ 0;
512
513                 /*set length in ip header*/
514                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4+0);
515         }
516
517         if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK
518                 dbgprintf(2,"Packet Type: SyncAck\n");
519                 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
520                         if(green){
521                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
522                         }else{
523                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
524                         }
525                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
526                         if(yellow){
527                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
528                         }else{
529                                 tcph->window=htons(0);
530                         }
531                         if(sack){
532                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
533                         }
534                 }else{
535                         if(green){
536                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
537                         }else{
538                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
539                         }
540                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
541                         if(yellow){
542                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
543                         }else{
544                                 tcph->window=htons(0);
545                         }
546                         if(sack){
547                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
548                         }
549                 }
550
551                 tcph->syn=0;
552                 tcph->ack=1;
553                 tcph->fin=0;
554                 tcph->rst=0;
555
556                 /*set libpcap header lengths*/
557                 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+0;
558                 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+0;
559
560                 /*set length in ip header*/
561                 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4+0);
562         }
563
564         if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture
565                 dbgprintf(0,"Invalid DCCP Packet!!\n");
566                 exit(1);
567         }
568 return;
569 }
570
571
572 /*Parse Ack Vector Options*/
573 unsigned int interp_ack_vect(u_char* hdr)
574 {
575         int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4;
576         //struct dccp_hdr_ext* e=(struct dccp_hdr_ext*)hdr + sizeof(struct dccp_hdr);
577         int optlen;
578         int len;
579         int tmp;
580         int bp=0;
581         int additional=0;
582         u_char* opt;
583         u_char* cur;
584
585         /*setup pointer to DCCP options and determine how long the options are*/
586         optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
587         opt=hdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
588
589         /*parse options*/
590         while(optlen > 0){
591                 len=*(opt+1);
592
593                 /*One byte options (no length)*/
594                 if(*opt< 32){
595                         optlen--;
596                         opt++;
597                         continue;
598                 }
599
600                 /*Ack Vector Option*/
601                 if(*opt==38 || *opt==39){
602                         tmp=len-2;
603                         cur=opt+2;
604                         /*loop through Vector*/
605                         while(tmp > 0){
606                                 /*ack vector works BACKWARDS through time*/
607
608                                 /*keep track of total packets recieved and if
609                                 a packet is lost, subtract all packets received
610                                 after that*/
611                                 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
612                                         bp+=(*cur & 0x3F)+1;
613                                         additional= -bp;
614                                 }
615                                         
616                                 if((*cur & 0xC0)==0x00){ //received packet
617                                         bp+= (*cur & 0x3F)+1;
618                                 }
619                                 tmp--;
620                                 cur++;
621                         }
622                 }
623                 
624                 optlen-=len;
625                 opt+=len;
626         }
627
628         dbgprintf(2,"Ack vector adding: %i\n", additional);
629 return additional;
630 }
631
632
633 /* Setup Sequence Number Structure*/
634 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial)
635 {
636         /*allocate structure*/
637         *seq=(struct seq_num*)malloc(sizeof(struct seq_num));
638         if(*seq==NULL){
639                 dbgprintf(0,"Can't Allocate Memory!\n");
640                 exit(1);
641         }
642
643         /*set default values*/
644         (*seq)->cur=0;
645         (*seq)->addr=source;
646         (*seq)->size=TBL_SZ;
647         
648         /*allocate table*/
649         (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ);
650         if((*seq)->table==NULL){
651                 dbgprintf(0,"Can't Allocate Memory!\n");
652                 exit(1);
653         }
654
655         /*add first sequence number*/
656         (*seq)->table[0].old=initial;
657         (*seq)->table[0].new=initial;
658         (*seq)->table[0].type=DCCP_PKT_REQUEST;
659         (*seq)->table[0].size=0;
660 return initial;
661 }
662
663
664 /*Convert Sequence Numbers*/
665 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type)
666 {
667         int prev;
668         if(seq==NULL){
669                 dbgprintf(0,"ERROR NULL POINTER!\n");
670                 exit(1);
671         }
672         
673         /*account for missing packets*/
674         while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
675                 prev=seq->cur;
676                 dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
677                 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
678                 seq->table[seq->cur].old=seq->table[prev].old+1;
679                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
680                 seq->table[seq->cur].size=size;
681                 seq->table[seq->cur].type=type;
682         }
683
684         prev=seq->cur;
685         seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
686         seq->table[seq->cur].old=num;
687         seq->table[seq->cur].size=size;
688         seq->table[seq->cur].type=type;
689         if(seq->table[prev].type==DCCP_PKT_REQUEST || seq->table[prev].type==DCCP_PKT_RESPONSE){
690                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
691                 seq->table[seq->cur].size=1;
692                 return seq->table[prev].new + seq->table[prev].size+1;
693         }
694         if(type==DCCP_PKT_DATA || type==DCCP_PKT_DATAACK || type==DCCP_PKT_ACK){
695                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
696                 return seq->table[seq->cur].new+1;
697         }
698         if(type==DCCP_PKT_SYNC || type==DCCP_PKT_SYNCACK){
699                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
700                 return seq->table[seq->cur].new;
701         }
702         seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
703 return seq->table[seq->cur].new +1;
704 }
705
706
707 /*Convert Ack Numbers*/
708 u_int32_t convert_ack(struct seq_num *seq, __be32 num)
709 {
710         if(seq==NULL){
711                 dbgprintf(0,"ERROR NULL POINTER!\n");
712                 exit(1);
713         }
714
715         /*loop through table looking for the DCCP ack number*/
716         for(int i=0; i < seq->size; i++){
717                 if(seq->table[i].old==num){
718                         return  seq->table[i].new + seq->table[i].size + 1; /*TCP acks the sequence number plus 1*/
719                 }
720         }
721         
722         dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
723 return 0;
724 }
725
726
727 /* Get size of packet being acked*/
728 int acked_packet_size(struct seq_num *seq, __be32 num)
729 {
730         if(seq==NULL){
731                 dbgprintf(0,"ERROR NULL POINTER!\n");
732                 exit(1);
733         }
734
735         /*loop through table looking for the DCCP ack number*/
736         for(int i=0; i < seq->size; i++){
737                 if(seq->table[i].old==num){
738                         return  seq->table[i].size;
739                 }
740         }
741         
742         dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
743 return 0;
744 }
745
746
747 /*Ack Vector to SACK Option*/
748 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack)
749 {
750         int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
751         int optlen;
752         int len;
753         int tmp;
754         __be32 bp;
755         u_char* temp;
756         u_char* opt;
757         u_char* cur;
758         u_char* tlen;
759         u_int32_t bL=0;
760         u_int32_t bR;
761         u_int32_t* pL;
762         u_int32_t* pR;
763         int num_blocks;
764         int cont;
765         int isopt;
766         
767         /*setup pointer to DCCP options and determine how long the options are*/
768         optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
769         opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
770
771         /*setup tcp pointers*/
772         num_blocks=2;
773         *tcpopts=5;
774         tlen=tcpopts+1;
775         temp=tlen;
776         temp++;
777         pL=(u_int32_t*)temp;
778         pR=pL+1;
779
780         /*setup tcp control variables*/
781         bp=dccpack;
782         cont=0;
783         *tlen=2;
784         isopt=0;
785
786         /*parse options*/
787         while(optlen > 0){
788                 len=*(opt+1);
789
790                 /*One byte options (no length)*/
791                 if(*opt< 32){
792                         optlen--;
793                         opt++;
794                         continue;
795                 }
796
797                 /*Ack Vector Option*/
798                 if(*opt==38 || *opt==39){
799                         tmp=len-2;
800                         cur=opt+2;
801                         /*loop through Vector*/
802                         while(tmp > 0){
803                                 /*ack vector works BACKWARDS through time*/
804
805                                 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
806                                         if(cont){ /*end a SACK run, if one is started*/
807                                                 bR=convert_ack(seq, bp);
808                                                 cont=0;
809                                                 num_blocks--;
810                                                 *pR=htonl(bR);
811                                                 *pL=htonl(bL);
812                                                 tcph->doff+=2;
813                                                 *tlen+=8;
814                                                 pL=pR+1;
815                                                 pR=pL+1;                        
816                                         }
817                                         bp= bp - (*cur & 0x3F)- 1;
818                                 }
819                                         
820                                 if((*cur & 0xC0)==0x00){ //received packet
821                                         if(!cont){ /*if no SACK run and we can start another one, do so*/
822                                                 if(num_blocks>0){
823                                                         bL=convert_ack(seq, bp);
824                                                         isopt=1;
825                                                         cont=1;
826
827                                                 }
828                                         }
829                                         bp =  bp -(*cur & 0x3F)- 1;
830                                 }
831                                 tmp--;
832                                 cur++;
833                         }
834                 }
835                 
836                 optlen-=len;
837                 opt+=len;
838         }
839
840         /*if we are in the middle of a SACK run, close it*/
841         if(cont){
842                 bR=convert_ack(seq, bp);
843                 *pR=htonl(bR);
844                 *pL=htonl(bL);
845                 tcph->doff+=2;
846                 *tlen+=8;
847                 cont=0;
848         }
849
850         /*adjust length if the option is actually added*/
851         if(isopt){
852                 tcph->doff+=1;
853         }
854 return;
855 }
856
857 /*Debug Printf*/
858 void dbgprintf(int level, const char *fmt, ...)
859 {
860     va_list args;
861     if(debug>=level){
862         va_start(args, fmt);
863         vfprintf(stderr, fmt, args);
864         va_end(args);
865     }
866 }