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 int convert_packet(struct pcap_pkthdr *h, u_char **nptr, int *nlength, const u_char **optr, 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;
149 /*Determine the link type for this packet*/
150 link_type=pcap_datalink(in);
152 /*create new libpcap header*/
153 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
157 /*create buffer for new packet*/
158 nptr=ndata=malloc(MAX_PACKET);
160 dbgprintf(0,"Error: Couldn't allocate Memory\n");
164 /*make sure the packet is all zero*/
165 memset(nptr, 0, MAX_PACKET);
167 /*do all the fancy conversions*/
168 if(!do_encap(link_type, &nh, &nptr, &nlength, &bytes, &length)){
174 pcap_dump(user,&nh, ndata);
181 /*do all the dccp to tcp conversions*/
182 int convert_packet(struct pcap_pkthdr *h, u_char **nptr, int *nlength, const u_char **optr, int *length)
185 const u_char* ocur=*optr;
187 struct dccp_hdr *dccph;
188 struct dccp_hdr_ext *dccphex;
189 struct dccp_hdr_ack_bits *dccphack;
196 /*cast header pointers*/
197 tcph=(struct tcphdr*)ncur;
198 tcpopt=ncur+ sizeof(struct tcphdr);
199 dccph=(struct dccp_hdr*)ocur;
200 dccphex=(struct dccp_hdr_ext*)(ocur+sizeof(struct dccp_hdr));
201 dccphack=(struct dccp_hdr_ack_bits*)(ocur+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
203 dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)(((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
205 /*determine data length*/
206 datalength=*length - dccph->dccph_doff*4;
207 pd=*optr + dccph->dccph_doff*4;
209 /*set tcp standard features*/
210 tcph->source=dccph->dccph_sport;
211 tcph->dest=dccph->dccph_dport;
213 tcph->check=htonl(0);
216 /*Adjust TCP advertised window size*/
218 tcph->window=htons(30000);
221 /*Only accept the first connection*/
222 if(s1 && s2 && dccph->dccph_sport!=s1->addr && dccph->dccph_dport!=s1->addr){
226 /*make changes by packet type*/
227 if(dccph->dccph_type==DCCP_PKT_REQUEST){//DCCP REQUEST -->TCP SYN
228 dbgprintf(2,"Packet Type: Request\n");
231 tcph->window=htons(0);
233 tcph->ack_seq=htonl(0);
234 tcph->seq=htonl(initialize_seq(&s1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
240 /* add Sack-permitted option, if relevant*/
253 if(dccph->dccph_type==DCCP_PKT_RESPONSE){//DCCP RESPONSE-->TCP SYN,ACK
254 dbgprintf(2,"Packet Type: Response\n");
256 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
258 tcph->window=htons(0);
260 tcph->seq=htonl(initialize_seq(&s2, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
266 /* add Sack-permitted option, if relevant*/
278 if(dccph->dccph_type==DCCP_PKT_DATA){//DCCP DATA----Never seen in packet capture
279 dbgprintf(0,"DCCP Data packet not yet implemented\n");
283 if(dccph->dccph_type==DCCP_PKT_DATAACK){//DCCP DATAACK-->TCP ACK with data
284 dbgprintf(2,"Packet Type: DataAck\n");
285 if(s1 && s2 && dccph->dccph_sport==s1->addr){ //determine which side of connection is sending this packet
287 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
289 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
291 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
293 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
296 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
298 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
300 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
302 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
304 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),datalength,dccph->dccph_type));
306 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
309 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
319 npd=*nptr + tcph->doff*4;
320 memcpy(npd, pd, datalength);
323 len= tcph->doff*4 + datalength;
326 if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data
327 dbgprintf(2,"Packet Type: Ack\n");
328 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
330 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
332 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
334 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
336 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
337 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
338 printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
342 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
344 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
346 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
348 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
350 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
352 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
353 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
354 printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
358 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
368 len=tcph->doff*4 + 1;
371 if(dccph->dccph_type==DCCP_PKT_CLOSEREQ){//DCCP CLOSEREQ----Never seen in packet capture
372 dbgprintf(0,"DCCP CloseReq not yet implemented\n");
376 if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK
377 dbgprintf(2,"Packet Type: Close\n");
378 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
380 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
382 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
384 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
386 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
389 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
391 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
393 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
395 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
397 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
399 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
402 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
415 if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK)
416 dbgprintf(2,"Packet Type: Reset\n");
417 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
419 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
421 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
423 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
425 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
428 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
430 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
432 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
434 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
436 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
438 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
441 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
454 if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC
455 dbgprintf(2,"Packet Type: Sync\n");
456 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
458 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
460 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
462 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
464 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
466 tcph->window=htons(0);
469 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
471 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
473 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
475 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
477 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
479 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
481 tcph->window=htons(0);
484 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
497 if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK
498 dbgprintf(2,"Packet Type: SyncAck\n");
499 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
501 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
503 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
505 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
507 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
509 tcph->window=htons(0);
512 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
514 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
516 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
518 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
520 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
522 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
524 tcph->window=htons(0);
527 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
540 if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture
541 dbgprintf(0,"Invalid DCCP Packet!!\n");
550 /*Parse Ack Vector Options*/
551 unsigned int interp_ack_vect(u_char* hdr)
553 int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4;
554 //struct dccp_hdr_ext* e=(struct dccp_hdr_ext*)hdr + sizeof(struct dccp_hdr);
563 /*setup pointer to DCCP options and determine how long the options are*/
564 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
565 opt=hdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
571 /*One byte options (no length)*/
578 /*Ack Vector Option*/
579 if(*opt==38 || *opt==39){
582 /*loop through Vector*/
584 /*ack vector works BACKWARDS through time*/
586 /*keep track of total packets recieved and if
587 a packet is lost, subtract all packets received
589 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
594 if((*cur & 0xC0)==0x00){ //received packet
595 bp+= (*cur & 0x3F)+1;
606 dbgprintf(2,"Ack vector adding: %i\n", additional);
611 /* Setup Sequence Number Structure*/
612 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial)
614 /*allocate structure*/
615 *seq=(struct seq_num*)malloc(sizeof(struct seq_num));
617 dbgprintf(0,"Can't Allocate Memory!\n");
621 /*set default values*/
627 (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ);
628 if((*seq)->table==NULL){
629 dbgprintf(0,"Can't Allocate Memory!\n");
633 /*add first sequence number*/
634 (*seq)->table[0].old=initial;
635 (*seq)->table[0].new=initial;
636 (*seq)->table[0].type=DCCP_PKT_REQUEST;
637 (*seq)->table[0].size=0;
642 /*Convert Sequence Numbers*/
643 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type)
647 dbgprintf(0,"ERROR NULL POINTER!\n");
651 /*account for missing packets*/
652 while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
654 dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
655 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
656 seq->table[seq->cur].old=seq->table[prev].old+1;
657 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
658 seq->table[seq->cur].size=size;
659 seq->table[seq->cur].type=type;
663 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
664 seq->table[seq->cur].old=num;
665 seq->table[seq->cur].size=size;
666 seq->table[seq->cur].type=type;
667 if(seq->table[prev].type==DCCP_PKT_REQUEST || seq->table[prev].type==DCCP_PKT_RESPONSE){
668 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
669 seq->table[seq->cur].size=1;
670 return seq->table[prev].new + seq->table[prev].size+1;
672 if(type==DCCP_PKT_DATA || type==DCCP_PKT_DATAACK || type==DCCP_PKT_ACK){
673 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
674 return seq->table[seq->cur].new+1;
676 if(type==DCCP_PKT_SYNC || type==DCCP_PKT_SYNCACK){
677 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
678 return seq->table[seq->cur].new;
680 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
681 return seq->table[seq->cur].new +1;
685 /*Convert Ack Numbers*/
686 u_int32_t convert_ack(struct seq_num *seq, __be32 num)
689 dbgprintf(0,"ERROR NULL POINTER!\n");
693 /*loop through table looking for the DCCP ack number*/
694 for(int i=0; i < seq->size; i++){
695 if(seq->table[i].old==num){
696 return seq->table[i].new + seq->table[i].size + 1; /*TCP acks the sequence number plus 1*/
700 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
705 /* Get size of packet being acked*/
706 int acked_packet_size(struct seq_num *seq, __be32 num)
709 dbgprintf(0,"ERROR NULL POINTER!\n");
713 /*loop through table looking for the DCCP ack number*/
714 for(int i=0; i < seq->size; i++){
715 if(seq->table[i].old==num){
716 return seq->table[i].size;
720 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
725 /*Ack Vector to SACK Option*/
726 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack)
728 int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
745 /*setup pointer to DCCP options and determine how long the options are*/
746 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
747 opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
749 /*setup tcp pointers*/
758 /*setup tcp control variables*/
768 /*One byte options (no length)*/
775 /*Ack Vector Option*/
776 if(*opt==38 || *opt==39){
779 /*loop through Vector*/
781 /*ack vector works BACKWARDS through time*/
783 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
784 if(cont){ /*end a SACK run, if one is started*/
785 bR=convert_ack(seq, bp);
795 bp= bp - (*cur & 0x3F)- 1;
798 if((*cur & 0xC0)==0x00){ //received packet
799 if(!cont){ /*if no SACK run and we can start another one, do so*/
801 bL=convert_ack(seq, bp);
807 bp = bp -(*cur & 0x3F)- 1;
818 /*if we are in the middle of a SACK run, close it*/
820 bR=convert_ack(seq, bp);
828 /*adjust length if the option is actually added*/
836 void dbgprintf(int level, const char *fmt, ...)
841 vfprintf(stderr, fmt, args);