]> sjero.net Git - dccp2tcp/blobdiff - dccp2tcp.c
Add GNU GPL headers to all files
[dccp2tcp] / dccp2tcp.c
index 651d98bcce0965012b317e0f7e631fb516d4d6f2..c7f77e14be8a4c5163c4f7e5fe6896c767494cf5 100644 (file)
@@ -1,18 +1,31 @@
 /******************************************************************************
-Author: Samuel Jero
+Utility to convert a DCCP flow to a TCP flow for DCCP analysis via
+               tcptrace.
 
-Date: 7/2011
+Copyright (C) 2012  Samuel Jero <sj323707@ohio.edu>
 
-Description: Program to convert a DCCP flow to a TCP flow for DCCP analysis via
-               tcptrace.
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Author: Samuel Jero <sj323707@ohio.edu>
+Date: 11/2012
 
 Notes:
        1)CCID2 ONLY
        2)DCCP MUST use 48 bit sequence numbers
        3)Checksums are not computed (they are zeroed)
-       4)Only implements those packet types normally used in a session
+       4)DCCP DATA packets are not implemented (Linux doesn't use them)
        5)DCCP Ack packets show up as TCP packets containing one byte
-       6)Very little error checking of packet headers
 ******************************************************************************/
 #include "dccp2tcp.h"
 
@@ -28,12 +41,10 @@ struct connection *chead;   /*connection list*/
 
 
 
-void PcapSavePacket(struct pcap_pkthdr *h, u_char *data);
-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);
@@ -56,8 +67,9 @@ int main(int argc, char *argv[])
 
        /*loop through commandline options*/
        for(int i=1; i < argc; i++){
-               if(argv[i][0]!='-'){
-                       if(dfile==NULL){ /*assign first non-dash argument to the dccp file*/
+               if(argv[i][0]!='-' || (argv[i][0]=='-' && strlen(argv[i])==1)){
+                       if(dfile==NULL  || argv[i][0]=='-'){
+                               /*assign first non-dash (or only dash) argument to the dccp file*/
                                dfile=argv[i];
                        }else{
                                if(tfile==NULL){
@@ -131,6 +143,9 @@ int main(int argc, char *argv[])
        /*close files*/
        pcap_close(in);
        pcap_dump_close(out);
+
+       /*Delete all connections*/
+       cleanup_connections();
 return 0;
 }
 
@@ -154,8 +169,12 @@ void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *byte
        old.h=h;
        old.length=h->caplen;
        old.data=bytes;
+       old.dest_id=NULL;
+       old.src_id=NULL;
        new.h=&nh;
        new.length=MAX_PACKET;
+       new.dest_id=NULL;
+       new.src_id=NULL;
 
        /*create buffer for new packet*/
        new.data=ndata=malloc(MAX_PACKET);
@@ -202,8 +221,8 @@ 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;
        }
 
@@ -213,10 +232,12 @@ int convert_packet(struct packet *new, const struct const_packet* old)
        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));
 
-       dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)(((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
+       dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)
+                       (((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
 
        /*Get Hosts*/
-       if(get_host(new->src_id, new->dest_id, dccph->dccph_sport, dccph->dccph_dport, &h1, &h2)){
+       if(get_host(new->src_id, new->dest_id, new->id_len,
+                       dccph->dccph_sport, dccph->dccph_dport, &h1, &h2)){
                dbgprintf(0,"Error: Can't Get Hosts!\n");
                return 0;
        }
@@ -225,6 +246,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;
@@ -249,7 +281,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;
@@ -276,7 +308,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;
@@ -506,7 +538,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){
@@ -515,6 +546,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;
@@ -536,7 +574,7 @@ unsigned int interp_ack_vect(u_char* hdr)
                                }
 
                                if(((*cur& 0xC0)!= 0xC0) && ((*cur& 0xC0)!= 0x00) && ((*cur& 0xC0)!= 0x40)){
-                                       dbgprintf(1, "Warning: Invalid Ack Vector!! (Linux will handle poorly!) -- %X\n", *cur);
+                                       dbgprintf(1, "Warning: Invalid Ack Vector!! (Linux will handle poorly!)\n");
                                }
                                tmp--;
                                cur++;
@@ -553,7 +591,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;
@@ -587,13 +625,18 @@ 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 uninitialized\n");
-               return initialize_seq(seq, 0, num);
+               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;
@@ -634,7 +677,7 @@ u_int32_t convert_ack(struct host *seq, __be32 num)
 
        if(seq->table==NULL){
                dbgprintf(1, "Warning: Connection uninitialized\n");
-               initialize_seq(seq, 0, num);
+               initialize_seq(seq, num);
        }
 
        /*loop through table looking for the DCCP ack number*/
@@ -659,7 +702,7 @@ int acked_packet_size(struct host *seq, __be32 num)
 
        if(seq->table==NULL){
                dbgprintf(1, "Warning: Connection uninitialized\n");
-               initialize_seq(seq, 0, num);
+               initialize_seq(seq, num);
        }
 
        /*loop through table looking for the DCCP ack number*/
@@ -715,7 +758,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){
@@ -724,6 +766,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;