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