]> sjero.net Git - dccp2tcp/blobdiff - dccp2tcp.c
Keep debug output from slowing program down after massive losses
[dccp2tcp] / dccp2tcp.c
index c8cc769d1068397c0810ee30f2688785adf7f9f6..bbf729973186f8c7c08b80a79074936c73f08c13 100644 (file)
@@ -33,7 +33,7 @@ void process_packets();
 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
 int convert_packet(struct packet *new, const struct const_packet* old);
 unsigned int interp_ack_vect(u_char* hdr);
-u_int32_t initialize_seq(struct host *seq, __be16 source, __be32 initial);
+u_int32_t initialize_seq(struct host *seq, __be32 initial);
 u_int32_t add_new_seq(struct host *seq, __be32 num, int size, enum dccp_pkt_type type);
 u_int32_t convert_ack(struct host *seq, __be32 num);
 int acked_packet_size(struct host *seq, __be32 num);
@@ -202,14 +202,13 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                exit(1);
                return 0;
        }
-       if(old->length < sizeof(struct dccp_hdr) || new->length < sizeof(struct dccp_hdr)){
-               dbgprintf(0, "Error: Convert Packet Function given packet of wrong size!\n");
+       if(old->length < (sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)) || new->length < sizeof(struct dccp_hdr)){
+               dbgprintf(0, "Error: DCCP Packet Too short!\n");
                return 0;
        }
 
        /*cast header pointers*/
        tcph=(struct tcphdr*)new->data;
-       tcpopt=new->data + sizeof(struct tcphdr);
        dccph=(struct dccp_hdr*)old->data;
        dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
        dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
@@ -226,6 +225,17 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                return 0;
        }
 
+       /*Ensure packet is at least as large as DCCP header*/
+       if(old->length < dccph->dccph_doff*4){
+               dbgprintf(0, "Error: DCCP Header truncated\n");
+               return 0;
+       }
+       if(dccph->dccph_type!=DCCP_PKT_DATA &&
+                       old->length < (sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) +
+                       sizeof(struct dccp_hdr_ack_bits))){
+               dbgprintf(0, "Error: DCCP Packet Too short!\n");
+       }
+
        /*determine data length*/
        datalength=old->length - dccph->dccph_doff*4;
        pd=old->data + dccph->dccph_doff*4;
@@ -250,7 +260,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                                tcph->window=htons(0);
                        }
                        tcph->ack_seq=htonl(0);
-                       tcph->seq=htonl(initialize_seq(h1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
+                       tcph->seq=htonl(initialize_seq(h1, ntohl(dccphex->dccph_seq_low)));
                        tcph->syn=1;
                        tcph->ack=0;
                        tcph->fin=0;
@@ -258,6 +268,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
 
                        /* add Sack-permitted option, if relevant*/
                        if(sack){
+                               tcpopt=(u_char*)(new->data + tcph->doff*4);
                                *tcpopt=4;
                                tcpopt++;
                                *tcpopt=2;
@@ -276,7 +287,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                        if(yellow){
                                tcph->window=htons(0);
                        }
-                       tcph->seq=htonl(initialize_seq(h1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
+                       tcph->seq=htonl(initialize_seq(h1, ntohl(dccphex->dccph_seq_low)));
                        tcph->syn=1;
                        tcph->ack=1;
                        tcph->fin=0;
@@ -284,6 +295,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
 
                        /* add Sack-permitted option, if relevant*/
                        if(sack){
+                               tcpopt=(u_char*)(new->data + tcph->doff*4);
                                *tcpopt=4;
                                *(tcpopt+1)=2;
                                tcph->doff++;
@@ -312,7 +324,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                }
                if(sack){
                        if(sack!=2 || interp_ack_vect((u_char*)dccph)){
-                               ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
+                               ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
                        }
                }
 
@@ -345,7 +357,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                }
                if(sack){
                        if(sack!=2 || interp_ack_vect((u_char*)dccph)){
-                               ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
+                               ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
                        }
                }
 
@@ -377,7 +389,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                }
                if(sack){
                        if(sack!=2 || interp_ack_vect((u_char*)dccph)){
-                               ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
+                               ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
                        }
                }
 
@@ -406,7 +418,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                }
                if(sack){
                        if(sack!=2 || interp_ack_vect((u_char*)dccph)){
-                               ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
+                               ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
                        }
                }
 
@@ -434,7 +446,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                }
                if(sack){
                        if(sack!=2 || interp_ack_vect((u_char*)dccph)){
-                               ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
+                               ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
                        }
                }
 
@@ -462,7 +474,7 @@ int convert_packet(struct packet *new, const struct const_packet* old)
                }
                if(sack){
                        if(sack!=2 || interp_ack_vect((u_char*)dccph)){
-                               ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
+                               ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
                        }
                }
 
@@ -505,7 +517,6 @@ unsigned int interp_ack_vect(u_char* hdr)
 
        /*parse options*/
        while(optlen > 0){
-               len=*(opt+1);
 
                /*One byte options (no length)*/
                if(*opt< 32){
@@ -514,6 +525,13 @@ unsigned int interp_ack_vect(u_char* hdr)
                        continue;
                }
 
+               /*Check option length*/
+               len=*(opt+1);
+               if(len > optlen){
+                       dbgprintf(0, "Warning: Option would extend into packet data\n");
+                       return additional;
+               }
+
                /*Ack Vector Option*/
                if(*opt==38 || *opt==39){
                        tmp=len-2;
@@ -534,7 +552,7 @@ unsigned int interp_ack_vect(u_char* hdr)
                                        bp+= (*cur & 0x3F)+1;
                                }
 
-                               if(((*cur& 0xF0)!= 0xC0) && ((*cur& 0xF0)!= 0x00) && ((*cur& 0xF0)!= 0x40)){
+                               if(((*cur& 0xC0)!= 0xC0) && ((*cur& 0xC0)!= 0x00) && ((*cur& 0xC0)!= 0x40)){
                                        dbgprintf(1, "Warning: Invalid Ack Vector!! (Linux will handle poorly!)\n");
                                }
                                tmp--;
@@ -552,7 +570,7 @@ return additional;
 
 
 /* Setup Sequence Number Structure*/
-u_int32_t initialize_seq(struct host *seq, __be16 source, __be32 initial)
+u_int32_t initialize_seq(struct host *seq, __be32 initial)
 {
        /*set default values*/
        seq->cur=0;
@@ -585,14 +603,19 @@ u_int32_t add_new_seq(struct host *seq, __be32 num, int size, enum dccp_pkt_type
        }
        
        if(seq->table==NULL){
-               dbgprintf(1, "Warning: Connection initialization incorrect\n");
-               return 0;
+               dbgprintf(1, "Warning: Connection uninitialized\n");
+               return initialize_seq(seq, num);
        }
 
        /*account for missing packets*/
+       if(num - seq->table[seq->cur].old +1 >=100){
+                       dbgprintf(1,"Missing more than 100 packets!\n");
+       }
        while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
                prev=seq->cur;
-               dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
+               if(num - seq->table[seq->cur].old +1 <100){
+                       dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
+               }
                seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
                seq->table[seq->cur].old=seq->table[prev].old+1;
                seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
@@ -631,6 +654,11 @@ u_int32_t convert_ack(struct host *seq, __be32 num)
                exit(1);
        }
 
+       if(seq->table==NULL){
+               dbgprintf(1, "Warning: Connection uninitialized\n");
+               initialize_seq(seq, num);
+       }
+
        /*loop through table looking for the DCCP ack number*/
        for(int i=0; i < seq->size; i++){
                if(seq->table[i].old==num){
@@ -651,6 +679,11 @@ int acked_packet_size(struct host *seq, __be32 num)
                exit(1);
        }
 
+       if(seq->table==NULL){
+               dbgprintf(1, "Warning: Connection uninitialized\n");
+               initialize_seq(seq, num);
+       }
+
        /*loop through table looking for the DCCP ack number*/
        for(int i=0; i < seq->size; i++){
                if(seq->table[i].old==num){
@@ -704,7 +737,6 @@ void ack_vect2sack(struct host *seq, struct tcphdr *tcph, u_char* tcpopts, u_cha
 
        /*parse options*/
        while(optlen > 0){
-               len=*(opt+1);
 
                /*One byte options (no length)*/
                if(*opt< 32){
@@ -713,6 +745,12 @@ void ack_vect2sack(struct host *seq, struct tcphdr *tcph, u_char* tcpopts, u_cha
                        continue;
                }
 
+               len=*(opt+1);
+               if(len > optlen){
+                       dbgprintf(0, "Warning: Option would extend into packet data\n");
+                       break;
+               }
+
                /*Ack Vector Option*/
                if(*opt==38 || *opt==39){
                        tmp=len-2;