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 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
297 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
300 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
302 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
304 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
306 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),datalength,dccph->dccph_type));
308 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
311 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
312 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
324 npd=*nptr + tcph->doff*4;
325 memcpy(npd, pd, datalength);
328 len= tcph->doff*4 + datalength;
331 if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data
332 dbgprintf(2,"Packet Type: Ack\n");
333 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
335 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
337 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
339 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
341 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
342 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
343 printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
347 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
348 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
351 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
353 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
355 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
357 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
359 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
360 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
361 printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
365 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
366 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
377 len=tcph->doff*4 + 1;
380 if(dccph->dccph_type==DCCP_PKT_CLOSEREQ){//DCCP CLOSEREQ----Never seen in packet capture
381 dbgprintf(0,"DCCP CloseReq not yet implemented\n");
385 if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK
386 dbgprintf(2,"Packet Type: Close\n");
387 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
389 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
391 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
393 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
395 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
398 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
399 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
402 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
404 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
406 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
408 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
410 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
413 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
414 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
428 if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK)
429 dbgprintf(2,"Packet Type: Reset\n");
430 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
432 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
434 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
436 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
438 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
441 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
442 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
445 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
447 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
449 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
451 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
453 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
456 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
457 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
471 if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC
472 dbgprintf(2,"Packet Type: Sync\n");
473 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
475 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
477 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
479 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
481 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
483 tcph->window=htons(0);
486 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
487 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
490 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
492 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
494 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
496 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
498 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
500 tcph->window=htons(0);
503 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
504 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
518 if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK
519 dbgprintf(2,"Packet Type: SyncAck\n");
520 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
522 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
524 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
526 tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
528 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
530 tcph->window=htons(0);
533 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
534 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
537 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
539 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
541 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
543 tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
545 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
547 tcph->window=htons(0);
550 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
551 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
565 if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture
566 dbgprintf(0,"Invalid DCCP Packet!!\n");
575 /*Parse Ack Vector Options
576 * Returns the Number of packets since last recorded loss*/
577 unsigned int interp_ack_vect(u_char* hdr)
579 int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4;
580 //struct dccp_hdr_ext* e=(struct dccp_hdr_ext*)hdr + sizeof(struct dccp_hdr);
589 /*setup pointer to DCCP options and determine how long the options are*/
590 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
591 opt=hdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
597 /*One byte options (no length)*/
604 /*Ack Vector Option*/
605 if(*opt==38 || *opt==39){
608 /*loop through Vector*/
610 /*ack vector works BACKWARDS through time*/
612 /*keep track of total packets recieved and if
613 a packet is lost, subtract all packets received
615 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
620 if((*cur & 0xC0)==0x00){ //received packet
621 bp+= (*cur & 0x3F)+1;
624 if(((*cur& 0xF0)!= 0xC0) && ((*cur& 0xF0)!= 0x00) && ((*cur& 0xF0)!= 0x40)){
625 dbgprintf(1, "Warning: Invalid Ack Vector!! (Linux will handle poorly!)\n");
636 dbgprintf(2,"Ack vector adding: %i\n", additional);
641 /* Setup Sequence Number Structure*/
642 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial)
644 /*allocate structure*/
645 *seq=(struct seq_num*)malloc(sizeof(struct seq_num));
647 dbgprintf(0,"Can't Allocate Memory!\n");
651 /*set default values*/
657 (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ);
658 if((*seq)->table==NULL){
659 dbgprintf(0,"Can't Allocate Memory!\n");
663 /*add first sequence number*/
664 (*seq)->table[0].old=initial;
665 (*seq)->table[0].new=initial;
666 (*seq)->table[0].type=DCCP_PKT_REQUEST;
667 (*seq)->table[0].size=0;
672 /*Convert Sequence Numbers*/
673 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type)
677 dbgprintf(0,"ERROR NULL POINTER!\n");
681 /*account for missing packets*/
682 while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
684 dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
685 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
686 seq->table[seq->cur].old=seq->table[prev].old+1;
687 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
688 seq->table[seq->cur].size=size;
689 seq->table[seq->cur].type=type;
693 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
694 seq->table[seq->cur].old=num;
695 seq->table[seq->cur].size=size;
696 seq->table[seq->cur].type=type;
697 if(seq->table[prev].type==DCCP_PKT_REQUEST || seq->table[prev].type==DCCP_PKT_RESPONSE){
698 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
699 seq->table[seq->cur].size=1;
700 return seq->table[prev].new + seq->table[prev].size+1;
702 if(type==DCCP_PKT_DATA || type==DCCP_PKT_DATAACK || type==DCCP_PKT_ACK){
703 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
704 return seq->table[seq->cur].new+1;
706 if(type==DCCP_PKT_SYNC || type==DCCP_PKT_SYNCACK){
707 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
708 return seq->table[seq->cur].new;
710 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
711 return seq->table[seq->cur].new +1;
715 /*Convert Ack Numbers*/
716 u_int32_t convert_ack(struct seq_num *seq, __be32 num)
719 dbgprintf(0,"ERROR NULL POINTER!\n");
723 /*loop through table looking for the DCCP ack number*/
724 for(int i=0; i < seq->size; i++){
725 if(seq->table[i].old==num){
726 return seq->table[i].new + seq->table[i].size + 1; /*TCP acks the sequence number plus 1*/
730 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
735 /* Get size of packet being acked*/
736 int acked_packet_size(struct seq_num *seq, __be32 num)
739 dbgprintf(0,"ERROR NULL POINTER!\n");
743 /*loop through table looking for the DCCP ack number*/
744 for(int i=0; i < seq->size; i++){
745 if(seq->table[i].old==num){
746 return seq->table[i].size;
750 dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
755 /*Ack Vector to SACK Option*/
756 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack)
758 int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
775 /*setup pointer to DCCP options and determine how long the options are*/
776 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
777 opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
779 /*setup tcp pointers*/
788 /*setup tcp control variables*/
798 /*One byte options (no length)*/
805 /*Ack Vector Option*/
806 if(*opt==38 || *opt==39){
809 /*loop through Vector*/
811 /*ack vector works BACKWARDS through time*/
813 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
814 if(cont){ /*end a SACK run, if one is started*/
815 bR=convert_ack(seq, bp);
825 bp= bp - (*cur & 0x3F)- 1;
828 if((*cur & 0xC0)==0x00){ //received packet
829 if(!cont){ /*if no SACK run and we can start another one, do so*/
831 bL=convert_ack(seq, bp);
837 bp = bp -(*cur & 0x3F)- 1;
848 /*if we are in the middle of a SACK run, close it*/
850 bR=convert_ack(seq, bp);
858 /*adjust length if the option is actually added*/
866 void dbgprintf(int level, const char *fmt, ...)
871 vfprintf(stderr, fmt, args);