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