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