1 /******************************************************************************
6 Description: Program to convert a DCCP flow to a TCP flow for DCCP analysis via
10 1)Supports only a single DCCP contection per capture
11 2)Source Port!=Destination Port
12 3)DCCP MUST use 48 bit sequence numbers
13 4)Checksums are not computed (they are zeroed)
14 5)Only implements those packet types normally used in a session
15 6)DCCP Ack packets show up as TCP packets containing one byte
16 7)Very little error checking of packet headers
17 ******************************************************************************/
21 int debug=0; /*set to 1 to turn on debugging information*/
22 int yellow=0; /*tcptrace yellow line as currently acked packet*/
23 int green=0; /*tcptrace green line as currently acked packet*/
24 int sack=0; /*add TCP SACKS*/
26 pcap_t* in; /*libpcap input file discriptor*/
27 pcap_dumper_t *out; /*libpcap output file discriptor*/
28 struct seq_num *s1; /*sequence number structure for side one of connection*/
29 struct seq_num *s2; /*sequence number structure for side two of connection*/
33 void PcapSavePacket(struct pcap_pkthdr *h, u_char *data);
34 void process_packets();
35 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
36 void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u_char **odata, int *length);
37 unsigned int interp_ack_vect(u_char* hdr);
38 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial);
39 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type);
40 u_int32_t convert_ack(struct seq_num *seq, __be32 num);
41 int acked_packet_size(struct seq_num *seq, __be32 num);
42 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack);
45 /*Parse commandline options and open files*/
46 int main(int argc, char *argv[])
53 /*parse commandline options*/
54 if(argc<3 || argc > 9){
55 dbgprintf(0, "Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
59 /*loop through commandline options*/
60 for(int i=1; i < argc; i++){
62 if(dfile==NULL){ /*assign first non-dash argument to the dccp file*/
66 tfile=argv[i]; /*assign second non-dash argument to the dccp file*/
68 dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
73 if(argv[i][1]=='d' && strlen(argv[i])==2){ /*debug option*/
76 if(argv[i][1]=='y' && strlen(argv[i])==2){ /*yellow option*/
79 if(argv[i][1]=='g' && strlen(argv[i])==2){ /*green option*/
82 if(argv[i][1]=='s' && strlen(argv[i])==2){ /*sack option*/
88 if(dfile==NULL || tfile==NULL){
89 dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
93 /*all options validated*/
96 dbgprintf(1,"Debug On\n");
98 dbgprintf(1,"Tcptrace green line at highest acknowledgment\n");
100 dbgprintf(1,"Tcptrace green line at highest acknowledged acknowledgment\n");
103 dbgprintf(1,"Tcptrace yellow line at highest acknowledgment\n");
105 dbgprintf(1,"Tcptrace yellow line window value (a made up number)\n");
108 dbgprintf(1,"Adding TCP SACKS\n");
110 dbgprintf(1,"Input file: %s\n", dfile);
111 dbgprintf(1,"Output file: %s\n", tfile);
114 /*attempt to open input file*/
115 in=pcap_open_offline(dfile, erbuffer);
117 dbgprintf(0,"Error opening input file\n");
121 /*attempt to open output file*/
122 out=pcap_dump_open(in,tfile);
124 dbgprintf(0,"Error opening output file\n");
129 u_char *user=(u_char*)out;
130 pcap_loop(in, -1, handle_packet, user);
134 pcap_dump_close(out);
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)
146 struct pcap_pkthdr nh;
148 /*create new libpcap header*/
149 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
153 /*create buffer for new packet*/
154 nptr=ndata=malloc(MAX_PACKET);
156 dbgprintf(0,"Error: Couldn't allocate Memory\n");
160 /*make sure the packet is all zero*/
161 memset(nptr, 0, MAX_PACKET);
163 /*do all the fancy conversions*/
164 if(eth_ip_encap_pre(&nh, &nptr, &nlength, &bytes, &length)<0){
167 convert_packet(&nh, &nptr, &nlength, &bytes, &length);
168 if(eth_ip_encap_post(&nh, &ndata, &nlength)<0){
173 pcap_dump(user,&nh, ndata);
180 /*do all the dccp to tcp conversions*/
181 void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u_char **odata, int *length)
184 const u_char* ocur=*odata;
186 struct dccp_hdr *dccph;
187 struct dccp_hdr_ext *dccphex;
188 struct dccp_hdr_ack_bits *dccphack;
195 /*cast header pointers*/
196 tcph=(struct tcphdr*)ncur;
197 tcpopt=ncur+ sizeof(struct tcphdr);
198 dccph=(struct dccp_hdr*)ocur;
199 dccphex=(struct dccp_hdr_ext*)(ocur+sizeof(struct dccp_hdr));
200 dccphack=(struct dccp_hdr_ack_bits*)(ocur+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
202 dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)(((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
204 /*determine data length*/
205 datalength=*length - dccph->dccph_doff*4;
206 pd=*odata + dccph->dccph_doff*4;
208 /*set tcp standard features*/
209 tcph->source=dccph->dccph_sport;
210 tcph->dest=dccph->dccph_dport;
212 tcph->check=htonl(0);
215 /*Adjust TCP advertised window size*/
217 tcph->window=htons(30000);
220 /*Only accept the first connection*/
221 if(s1 && s2 && dccph->dccph_sport!=s1->addr && dccph->dccph_dport!=s1->addr){
225 /*make changes by packet type*/
226 if(dccph->dccph_type==DCCP_PKT_REQUEST){//DCCP REQUEST -->TCP SYN
227 dbgprintf(2,"Packet Type: Request\n");
230 tcph->window=htons(0);
232 tcph->ack_seq=htonl(0);
233 tcph->seq=htonl(initialize_seq(&s1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
239 /* add Sack-permitted option, if relevant*/
252 if(dccph->dccph_type==DCCP_PKT_RESPONSE){//DCCP RESPONSE-->TCP SYN,ACK
253 dbgprintf(2,"Packet Type: Response\n");
255 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
257 tcph->window=htons(0);
259 tcph->seq=htonl(initialize_seq(&s2, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
265 /* add Sack-permitted option, if relevant*/
277 if(dccph->dccph_type==DCCP_PKT_DATA){//DCCP DATA----Never seen in packet capture
278 dbgprintf(0,"DCCP Data packet not yet implemented\n");
282 if(dccph->dccph_type==DCCP_PKT_DATAACK){//DCCP DATAACK-->TCP ACK with data
283 dbgprintf(2,"Packet Type: DataAck\n");
284 if(s1 && s2 && dccph->dccph_sport==s1->addr){ //determine which side of connection is sending this packet
286 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
288 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
290 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
292 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
295 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
297 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
299 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
301 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
303 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),datalength,dccph->dccph_type));
305 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
308 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
318 npd=*ndata + tcph->doff*4;
319 memcpy(npd, pd, datalength);
322 len= tcph->doff*4 + datalength;
325 if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data
326 dbgprintf(2,"Packet Type: Ack\n");
327 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
329 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
331 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
333 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
335 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
336 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
337 printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
341 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
343 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
345 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
347 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
349 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
351 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
352 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
353 printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
357 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
367 len=tcph->doff*4 + 1;
370 if(dccph->dccph_type==DCCP_PKT_CLOSEREQ){//DCCP CLOSEREQ----Never seen in packet capture
371 dbgprintf(0,"DCCP CloseReq not yet implemented\n");
375 if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK
376 dbgprintf(2,"Packet Type: Close\n");
377 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
379 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
381 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
383 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
385 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
388 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
390 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
392 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
394 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
396 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
398 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
401 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
414 if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK)
415 dbgprintf(2,"Packet Type: Reset\n");
416 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
418 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
420 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
422 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
424 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
427 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
429 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
431 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
433 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
435 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
437 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
440 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
453 if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC
454 dbgprintf(2,"Packet Type: Sync\n");
455 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
457 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
459 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
461 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
463 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
465 tcph->window=htons(0);
468 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
470 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
472 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
474 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
476 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
478 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
480 tcph->window=htons(0);
483 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
496 if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK
497 dbgprintf(2,"Packet Type: SyncAck\n");
498 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
500 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
502 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
504 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
506 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
508 tcph->window=htons(0);
511 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
513 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
515 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
517 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
519 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
521 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
523 tcph->window=htons(0);
526 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
539 if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture
540 dbgprintf(0,"Invalid DCCP Packet!!\n");
549 /*Parse Ack Vector Options*/
550 unsigned int interp_ack_vect(u_char* hdr)
552 int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4;
553 //struct dccp_hdr_ext* e=(struct dccp_hdr_ext*)hdr + sizeof(struct dccp_hdr);
562 /*setup pointer to DCCP options and determine how long the options are*/
563 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
564 opt=hdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
570 /*One byte options (no length)*/
577 /*Ack Vector Option*/
578 if(*opt==38 || *opt==39){
581 /*loop through Vector*/
583 /*ack vector works BACKWARDS through time*/
585 /*keep track of total packets recieved and if
586 a packet is lost, subtract all packets received
588 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
593 if((*cur & 0xC0)==0x00){ //received packet
594 bp+= (*cur & 0x3F)+1;
605 dbgprintf(2,"Ack vector adding: %i\n", additional);
610 /* Setup Sequence Number Structure*/
611 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial)
613 /*allocate structure*/
614 *seq=(struct seq_num*)malloc(sizeof(struct seq_num));
616 dbgprintf(0,"Can't Allocate Memory!\n");
620 /*set default values*/
626 (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ);
627 if((*seq)->table==NULL){
628 dbgprintf(0,"Can't Allocate Memory!\n");
632 /*add first sequence number*/
633 (*seq)->table[0].old=initial;
634 (*seq)->table[0].new=initial;
635 (*seq)->table[0].type=DCCP_PKT_REQUEST;
636 (*seq)->table[0].size=0;
641 /*Convert Sequence Numbers*/
642 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type)
646 dbgprintf(0,"ERROR NULL POINTER!\n");
650 /*account for missing packets*/
651 while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
653 dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
654 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
655 seq->table[seq->cur].old=seq->table[prev].old+1;
656 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
657 seq->table[seq->cur].size=size;
658 seq->table[seq->cur].type=type;
662 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
663 seq->table[seq->cur].old=num;
664 seq->table[seq->cur].size=size;
665 seq->table[seq->cur].type=type;
666 if(seq->table[prev].type==DCCP_PKT_REQUEST || seq->table[prev].type==DCCP_PKT_RESPONSE){
667 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
668 seq->table[seq->cur].size=1;
669 return seq->table[prev].new + seq->table[prev].size+1;
671 if(type==DCCP_PKT_DATA || type==DCCP_PKT_DATAACK || type==DCCP_PKT_ACK){
672 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
673 return seq->table[seq->cur].new+1;
675 if(type==DCCP_PKT_SYNC || type==DCCP_PKT_SYNCACK){
676 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
677 return seq->table[seq->cur].new;
679 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
680 return seq->table[seq->cur].new +1;
684 /*Convert Ack Numbers*/
685 u_int32_t convert_ack(struct seq_num *seq, __be32 num)
688 dbgprintf(0,"ERROR NULL POINTER!\n");
692 /*loop through table looking for the DCCP ack number*/
693 for(int i=0; i < seq->size; i++){
694 if(seq->table[i].old==num){
695 return seq->table[i].new + seq->table[i].size + 1; /*TCP acks the sequence number plus 1*/
699 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
704 /* Get size of packet being acked*/
705 int acked_packet_size(struct seq_num *seq, __be32 num)
708 dbgprintf(0,"ERROR NULL POINTER!\n");
712 /*loop through table looking for the DCCP ack number*/
713 for(int i=0; i < seq->size; i++){
714 if(seq->table[i].old==num){
715 return seq->table[i].size;
719 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
724 /*Ack Vector to SACK Option*/
725 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack)
727 int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
744 /*setup pointer to DCCP options and determine how long the options are*/
745 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
746 opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
748 /*setup tcp pointers*/
757 /*setup tcp control variables*/
767 /*One byte options (no length)*/
774 /*Ack Vector Option*/
775 if(*opt==38 || *opt==39){
778 /*loop through Vector*/
780 /*ack vector works BACKWARDS through time*/
782 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
783 if(cont){ /*end a SACK run, if one is started*/
784 bR=convert_ack(seq, bp);
794 bp= bp - (*cur & 0x3F)- 1;
797 if((*cur & 0xC0)==0x00){ //received packet
798 if(!cont){ /*if no SACK run and we can start another one, do so*/
800 bL=convert_ack(seq, bp);
806 bp = bp -(*cur & 0x3F)- 1;
817 /*if we are in the middle of a SACK run, close it*/
819 bR=convert_ack(seq, bp);
827 /*adjust length if the option is actually added*/
835 void dbgprintf(int level, const char *fmt, ...)
840 vfprintf(stderr, fmt, args);