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