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, const u_char *odata, u_char *ndata);
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 ack);
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)
143 struct pcap_pkthdr nh;
145 /*create new libpcap header*/
146 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
148 /*create buffer for new packet*/
149 ndata=malloc(MAX_PACKET);
151 dbgprintf(0,"Error: Couldn't allocate Memory\n");
155 /*make sure the packet is all zero*/
156 memset(ndata, 0, MAX_PACKET);
158 /*do all the fancy conversions*/
159 convert_packet(&nh, bytes, ndata);
162 pcap_dump(user,&nh, ndata);
169 /*do all the dccp to tcp conversions*/
170 void convert_packet(struct pcap_pkthdr *h, const u_char *odata, u_char *ndata)
173 const u_char* ocur=odata;
174 int length=h->caplen;
177 struct dccp_hdr *dccph;
178 struct dccp_hdr_ext *dccphex;
179 struct dccp_hdr_ack_bits *dccphack;
185 /*copy ethernet and ip headers over*/
186 memcpy(ncur, ocur, sizeof(struct ether_header)+sizeof(struct iphdr) );
187 ocur+=sizeof(struct ether_header)+ sizeof(struct iphdr);
188 ncur+=sizeof(struct ether_header) +sizeof(struct iphdr);
189 length-=sizeof(struct ether_header) +sizeof(struct iphdr);
191 /*set ip to indicate that tcp is next protocol*/
192 iph= (struct iphdr *) (ncur - sizeof(struct iphdr));
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=ntohs(iph->tot_len) - sizeof(struct iphdr) - dccph->dccph_doff*4;
207 pd=odata + sizeof(struct ether_header)+sizeof(struct iphdr) + 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 /*make changes by packet type*/
222 if(dccph->dccph_type==DCCP_PKT_REQUEST){//DCCP REQUEST -->TCP SYN
223 dbgprintf(2,"Packet Type: Request\n");
226 tcph->window=htons(0);
228 tcph->ack_seq=htonl(0);
229 tcph->seq=htonl(initialize_seq(&s1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
235 /* add Sack-permitted option, if relevant*/
243 /*set libpcap header lengths*/
244 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
245 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
247 /*set length in ip header*/
248 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
251 if(dccph->dccph_type==DCCP_PKT_RESPONSE){//DCCP RESPONSE-->TCP SYN,ACK
252 dbgprintf(2,"Packet Type: Response\n");
253 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
255 tcph->window=htons(0);
257 tcph->seq=htonl(initialize_seq(&s2, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
263 /* add Sack-permitted option, if relevant*/
270 /*set libpcap header lengths*/
271 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
272 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
274 /*set length in ip header*/
275 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
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 && 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));
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) );
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));
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=ndata+ sizeof(struct ether_header)+sizeof(struct iphdr)+ tcph->doff*4;
320 memcpy(npd, pd, datalength);
322 /*set libpcap header lengths*/
323 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4 + datalength;
324 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4 + datalength;
326 /*set length in ip header*/
327 iph->tot_len=htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + datalength);
330 if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data
331 dbgprintf(2,"Packet Type: Ack\n");
332 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
334 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
336 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
338 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1));
340 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
341 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
342 printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
346 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
350 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
352 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
354 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1));
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)h->ts.tv_sec, (int)h->ts.tv_usec);
362 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
371 /*set libpcap header lengths*/
372 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+ 1;
373 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+ 1;
375 /*set length in ip header*/
376 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4+ 1);
379 if(dccph->dccph_type==DCCP_PKT_CLOSEREQ){//DCCP CLOSEREQ----Never seen in packet capture
380 dbgprintf(0,"DCCP CloseReq not yet implemented\n");
384 if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK
385 dbgprintf(2,"Packet Type: Close\n");
386 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
388 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
390 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
392 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1));
394 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
397 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
401 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
403 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
405 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1));
407 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
410 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
419 /*set libpcap header lengths*/
420 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
421 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
423 /*set length in ip header*/
424 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
427 if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK)
428 dbgprintf(2,"Packet Type: Reset\n");
429 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
431 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
433 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
435 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1));
437 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
440 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
444 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
446 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
448 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1));
450 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
453 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
462 /*set libpcap header lengths*/
463 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
464 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4;
466 /*set length in ip header*/
467 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4);
470 if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC
471 dbgprintf(2,"Packet Type: Sync\n");
472 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
474 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
476 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
478 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0));
480 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
482 tcph->window=htons(0);
485 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
489 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
491 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
493 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0));
495 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
497 tcph->window=htons(0);
500 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
509 /*set libpcap header lengths*/
510 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+ 0;
511 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+ 0;
513 /*set length in ip header*/
514 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4+0);
517 if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK
518 dbgprintf(2,"Packet Type: SyncAck\n");
519 if(s1 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
521 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
523 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
525 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0));
527 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
529 tcph->window=htons(0);
532 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
536 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
538 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
540 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0));
542 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
544 tcph->window=htons(0);
547 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
556 /*set libpcap header lengths*/
557 h->len=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+0;
558 h->caplen=sizeof(struct ether_header) + sizeof(struct iphdr) + tcph->doff*4+0;
560 /*set length in ip header*/
561 iph->tot_len=htons(sizeof(struct iphdr) + tcph->doff*4+0);
564 if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture
565 dbgprintf(0,"Invalid DCCP Packet!!\n");
572 /*Parse Ack Vector Options*/
573 unsigned int interp_ack_vect(u_char* hdr)
575 int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4;
576 //struct dccp_hdr_ext* e=(struct dccp_hdr_ext*)hdr + sizeof(struct dccp_hdr);
585 /*setup pointer to DCCP options and determine how long the options are*/
586 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
587 opt=hdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
593 /*One byte options (no length)*/
600 /*Ack Vector Option*/
601 if(*opt==38 || *opt==39){
604 /*loop through Vector*/
606 /*ack vector works BACKWARDS through time*/
608 /*keep track of total packets recieved and if
609 a packet is lost, subtract all packets received
611 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
616 if((*cur & 0xC0)==0x00){ //received packet
617 bp+= (*cur & 0x3F)+1;
628 dbgprintf(2,"Ack vector adding: %i\n", additional);
633 /* Setup Sequence Number Structure*/
634 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial)
636 /*allocate structure*/
637 *seq=(struct seq_num*)malloc(sizeof(struct seq_num));
639 dbgprintf(0,"Can't Allocate Memory!\n");
643 /*set default values*/
649 (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ);
650 if((*seq)->table==NULL){
651 dbgprintf(0,"Can't Allocate Memory!\n");
655 /*add first sequence number*/
656 (*seq)->table[0].old=initial;
657 (*seq)->table[0].new=initial;
658 (*seq)->table[0].size=1; /* size is actually zero; this is a convient way to get
659 these packets counted in the sequence number space*/
664 /*Convert Sequence Numbers*/
665 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size)
669 dbgprintf(0,"ERROR NULL POINTER!\n");
673 /*account for missing packets*/
674 while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
676 dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
677 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
678 seq->table[seq->cur].old=seq->table[prev].old+1;
679 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
680 seq->table[seq->cur].size=size;
684 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
685 seq->table[seq->cur].old=num;
686 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
687 seq->table[seq->cur].size=size;
688 return seq->table[seq->cur].new;
692 /*Convert Ack Numbers*/
693 u_int32_t convert_ack(struct seq_num *seq, __be32 num)
696 dbgprintf(0,"ERROR NULL POINTER!\n");
700 /*loop through table looking for the DCCP ack number*/
701 for(int i=0; i < seq->size; i++){
702 if(seq->table[i].old==num){
703 return seq->table[i].new +1; /*TCP acks the sequence number plus 1*/
707 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
712 /* Get size of packet being acked*/
713 int acked_packet_size(struct seq_num *seq, __be32 num)
716 dbgprintf(0,"ERROR NULL POINTER!\n");
720 /*loop through table looking for the DCCP ack number*/
721 for(int i=0; i < seq->size; i++){
722 if(seq->table[i].old==num){
723 return seq->table[i].size;
727 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
732 /*Ack Vector to SACK Option*/
733 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack)
735 int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
752 /*setup pointer to DCCP options and determine how long the options are*/
753 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
754 opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
756 /*setup tcp pointers*/
765 /*setup tcp control variables*/
775 /*One byte options (no length)*/
782 /*Ack Vector Option*/
783 if(*opt==38 || *opt==39){
786 /*loop through Vector*/
788 /*ack vector works BACKWARDS through time*/
790 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
791 if(cont){ /*end a SACK run, if one is started*/
792 bR=convert_ack(seq, bp);
802 bp= bp - (*cur & 0x3F)- 1;
805 if((*cur & 0xC0)==0x00){ //received packet
806 if(!cont){ /*if no SACK run and we can start another one, do so*/
808 bL=convert_ack(seq, bp);
814 bp = bp -(*cur & 0x3F)- 1;
825 /*if we are in the middle of a SACK run, close it*/
827 bR=convert_ack(seq, bp);
835 /*adjust length if the option is actually added*/
843 void dbgprintf(int level, const char *fmt, ...)
848 vfprintf(stderr, fmt, args);