]> sjero.net Git - dccp2tcp/commitdiff
IPv6 support!
authorSamuel Jero <sj323707@ohio.edu>
Sun, 11 Nov 2012 20:59:05 +0000 (15:59 -0500)
committerSamuel Jero <sj323707@ohio.edu>
Sun, 11 Nov 2012 20:59:05 +0000 (15:59 -0500)
connections.c
dccp2tcp.c
dccp2tcp.h
encap.c
encap.h

index 0edc451ba60c4209d50eaeaede55c6210a658848..4bc60f04f3684d989bc19b5bd309956252944f7e 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
 Author: Samuel Jero
 
-Date: 11/2011
+Date: 11/2012
 
 Description: Functions for differentiating different DCCP connections.
 
@@ -9,12 +9,13 @@ Description: Functions for differentiating different DCCP connections.
 #include "dccp2tcp.h"
 
 /*Lookup a connection. If it doesn't exist, add a new connection and return it.*/
-int get_host(uint32_t src_id, uint32_t dest_id, int src_port, int dest_port, struct host **fwd, struct host **rev){
+int get_host(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest_port,
+               struct host **fwd, struct host **rev){
        struct connection *ptr;
 
        /*Empty list*/
        if(chead==NULL){
-               if(add_connection(src_id, dest_id, src_port, dest_port)==NULL){
+               if(add_connection(src_id, dest_id, id_len, src_port, dest_port)==NULL){
                        return 1;
                }
                *fwd=&chead->A;
@@ -25,13 +26,13 @@ int get_host(uint32_t src_id, uint32_t dest_id, int src_port, int dest_port, str
        /*Loop list looking for connection*/
        ptr=chead;
        while(ptr!=NULL){
-               if(ptr->A.id==src_id && ptr->A.port==src_port &&
+               if(memcmp(ptr->A.id,src_id,id_len)==0 && ptr->A.port==src_port &&
                                !(ptr->A.state==CLOSE && ptr->B.state==CLOSE)){
                        *fwd=&ptr->A;
                        *rev=&ptr->B;
                        return 0;
                }
-               if(ptr->B.id==src_id && ptr->B.port==src_port &&
+               if(memcmp(ptr->B.id,src_id,id_len)==0 && ptr->B.port==src_port &&
                                !(ptr->B.state==CLOSE && ptr->A.state==CLOSE)){
                        *fwd=&ptr->B;
                        *rev=&ptr->A;
@@ -41,7 +42,7 @@ int get_host(uint32_t src_id, uint32_t dest_id, int src_port, int dest_port, str
        }
 
        /*Add new connection*/
-       ptr=add_connection(src_id, dest_id, src_port, dest_port);
+       ptr=add_connection(src_id, dest_id, id_len, src_port, dest_port);
        if(ptr==NULL){
                return 1;
        }
@@ -51,7 +52,7 @@ int get_host(uint32_t src_id, uint32_t dest_id, int src_port, int dest_port, str
 }
 
 /*Add a connection. Return it. On failure, return NULL*/
-struct connection *add_connection(uint32_t src_id, uint32_t dest_id, int src_port, int dest_port){
+struct connection *add_connection(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest_port){
        struct connection *ptr;
        struct connection *prev;
 
@@ -74,10 +75,16 @@ struct connection *add_connection(uint32_t src_id, uint32_t dest_id, int src_por
        }
 
        /*Initialize*/
-       ptr->A.id=src_id;
+       ptr->A.id=malloc(id_len);
+       ptr->B.id=malloc(id_len);
+       if(ptr->A.id==NULL||ptr->B.id==NULL){
+               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+               exit(1);
+       }
+       memcpy(ptr->A.id,src_id,id_len);
        ptr->A.port=src_port;
        ptr->A.state=INIT;
-       ptr->B.id=dest_id;
+       memcpy(ptr->B.id,dest_id,id_len);
        ptr->B.port=dest_port;
        ptr->B.state=INIT;
 
@@ -101,6 +108,8 @@ void cleanup_connections(){
 
        while(ptr!=NULL){
                prev=ptr;
+               free(ptr->A.id);
+               free(ptr->B.id);
                ptr=ptr->next;
                free(prev);
        }
index 17563f2584a1a455eaa2c5972d709685f2eb9cdf..3df497e33659ef7a630f33df1f79bdaebad60983 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
 Author: Samuel Jero
 
-Date: 11/2011
+Date: 11/2012
 
 Description: Program to convert a DCCP flow to a TCP flow for DCCP analysis via
                tcptrace.
@@ -27,8 +27,6 @@ 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);
@@ -157,8 +155,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);
@@ -216,10 +218,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;
        }
index c321f0bd7b4b03411871ac9160f2ff4fafbd8234..7f106a5973f051220f6ad33a33006674109c95e3 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
 Author: Samuel Jero
 
-Date: 11/2011
+Date: 11/2012
 
 Description: Header file for program to convert a DCCP flow to a TCP flow for DCCP
                 analysis via tcptrace.
@@ -52,8 +52,9 @@ struct packet{
        struct pcap_pkthdr      *h;             /*libpcap header*/
        u_char                          *data;  /*Packet Data*/
        int                                     length; /*Packet length*/
-       uint32_t                        src_id; /*Source ID of packet*/
-       uint32_t                        dest_id; /*Destination ID of packet*/
+       int                                     id_len; /*Length of IDs*/
+       u_char                          *src_id; /*Source ID of packet*/
+       u_char                          *dest_id;/*Destination ID of packet*/
 };
 
 /*Constant Packet structure*/
@@ -61,8 +62,9 @@ struct const_packet{
        const struct pcap_pkthdr *h;    /*libpcap header*/
        const u_char                    *data;  /*Packet Data*/
        int                                             length; /*Packet length*/
-       uint32_t                                src_id; /*Source ID of packet*/
-       uint32_t                                dest_id;/*Destination ID of packet*/
+       int                                             id_len; /*Length of IDs*/
+       u_char                                  *src_id; /*Source ID of packet*/
+       u_char                                  *dest_id;/*Destination ID of packet*/
 };
 
 /*Connection states*/
@@ -74,7 +76,8 @@ enum con_state{
 
 /*Host---half of a connection*/
 struct host{
-       uint32_t                        id;             /*Host ID*/
+       int                                     id_len; /*Length of ID*/
+       u_char                          *id;    /*Host ID*/
        __be16                          port;   /*Host DCCP port*/
        struct tbl                      *table; /*Host Sequence Number Table*/
        int                                     size;   /*Size of Sequence Number Table*/
@@ -118,8 +121,10 @@ void dbgprintf(int level, const char *fmt, ...);
 int do_encap(int link, struct packet *new, const struct const_packet *old);
 
 /*Connection functions*/
-int get_host(uint32_t src_id, uint32_t dest_id, int src_port, int dest_port, struct host **fwd, struct host **rev);
-struct connection *add_connection(uint32_t src_id, uint32_t dest_id, int src_port, int dest_port);
+int get_host(u_char *src_id, u_char* dest_id, int id_len, int src_port, int dest_port,
+               struct host **fwd, struct host **rev);
+struct connection *add_connection(u_char *src_id, u_char* dest_id, int id_len,
+               int src_port, int dest_port);
 int update_state(struct host* hst, enum con_state st);
 void cleanup_connections();
 
diff --git a/encap.c b/encap.c
index 736cf3a3d06c3684dc757fe309c6aa9a23baa602..1153e0638e9a6cf4f1498bd7c14521124e6f3263 100644 (file)
--- a/encap.c
+++ b/encap.c
@@ -1,14 +1,15 @@
 /******************************************************************************
 Author: Samuel Jero
 
-Date: 11/2011
+Date: 11/2012
 
 Description: Encapsulation Functions for DCCP conversion to TCP
 
 ******************************************************************************/
 #include "dccp2tcp.h"
 #include "encap.h"
-#include "pcap/sll.h"
+#include <pcap/sll.h>
+#include <netinet/ip6.h>
 
 /*Encapsulation start point and link layer selector*/
 int do_encap(int link, struct packet *new, const struct const_packet *old)
@@ -84,6 +85,11 @@ int ethernet_encap(struct packet *new, const struct const_packet *old)
                                                        return 0;
                                        }
                                        break;
+                       case ETHERTYPE_IPV6:
+                                       if(!ipv6_encap(&nnew, &nold)){
+                                                       return 0;
+                                       }
+                                       break;
                        default:
                                        dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
                                        return 0;
@@ -95,6 +101,87 @@ int ethernet_encap(struct packet *new, const struct const_packet *old)
 return 1;
 }
 
+/*IPv6 Encapsulation*/
+int ipv6_encap(struct packet *new, const struct const_packet *old)
+{
+               struct ip6_hdr          *iph;
+               struct packet           nnew;
+               struct const_packet     nold;
+
+               /*Safety checks*/
+               if(!new || !old || !new->data || !old->data || !new->h || !old->h){
+                       dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
+                       return 0;
+               }
+               if(old->length < sizeof(struct ip6_hdr) || new->length < sizeof(struct ip6_hdr)){
+                       dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
+                       return 0;
+               }
+
+               /*Copy IPv6 header over*/
+               memcpy(new->data, old->data, sizeof(struct ip6_hdr));
+
+               /*Cast Pointer*/
+               iph=(struct ip6_hdr*)(new->data);
+
+               /*Adjust pointers and lengths*/
+               nold.data= old->data + sizeof(struct ip6_hdr);
+               nnew.data= new->data +sizeof(struct ip6_hdr);
+               nold.length= old->length - sizeof(struct ip6_hdr);
+               nnew.length= new->length - sizeof(struct ip6_hdr);
+               nnew.h=new->h;
+               nold.h=old->h;
+
+               /*Confirm that this is IPv6*/
+               if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
+                       dbgprintf(1, "Note: Packet is not IPv6\n");
+                       return 0;
+               }
+
+               /*Select Next Protocol*/
+               switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
+                       case 33:
+                                       /*DCCP*/
+                                       nnew.id_len=16;
+                                       nnew.src_id=malloc(nnew.id_len);
+                                       nnew.dest_id=malloc(nnew.id_len);
+                                       if(nnew.src_id==NULL||nnew.dest_id==NULL){
+                                               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+                                               exit(1);
+                                       }
+                                       memcpy(nnew.src_id,&iph->ip6_src,nnew.id_len);
+                                       memcpy(nnew.dest_id,&iph->ip6_dst,nnew.id_len);
+                                       if(!convert_packet(&nnew, &nold)){
+                                               return 0;
+                                       }
+                                       break;
+                       default:
+                                       dbgprintf(1, "Unknown Next Protocol at IPv6\n");
+                                       return 0;
+                                       break;
+               }
+
+               /*set ip to indicate that TCP is next protocol*/
+               iph->ip6_ctlun.ip6_un1.ip6_un1_nxt=6;
+
+               /*Determine if computed length is reasonable*/
+               if(nnew.length > 0xFFFF){
+                               dbgprintf(1, "Error: Given TCP data length is too large for an IPv6 packet!\n");
+                               return 0;
+               }
+
+               /*Adjust IPv6 header to account for packet's total length*/
+               iph->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(new->length);
+
+               /*Adjust length*/
+               new->length=nnew.length + sizeof(struct ip6_hdr);
+
+               /*Cleanup*/
+               free(nnew.dest_id);
+               free(nnew.src_id);
+return 1;
+}
+
 /*IPv4 Encapsulation*/
 int ipv4_encap(struct packet *new, const struct const_packet *old)
 {
@@ -134,10 +221,17 @@ int ipv4_encap(struct packet *new, const struct const_packet *old)
 
                /*Select Next Protocol*/
                switch(iph->protocol){
-                       case 0x21:
+                       case 33:
                                        /*DCCP*/
-                                       nnew.src_id=iph->saddr;
-                                       nnew.dest_id=iph->daddr;
+                                       nnew.id_len=4;
+                                       nnew.src_id=malloc(nnew.id_len);
+                                       nnew.dest_id=malloc(nnew.id_len);
+                                       if(nnew.src_id==NULL||nnew.dest_id==NULL){
+                                               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+                                               exit(1);
+                                       }
+                                       memcpy(nnew.src_id,&iph->saddr,nnew.id_len);
+                                       memcpy(nnew.dest_id,&iph->daddr,nnew.id_len);
                                        if(!convert_packet(&nnew, &nold)){
                                                return 0;
                                        }
@@ -163,6 +257,10 @@ int ipv4_encap(struct packet *new, const struct const_packet *old)
 
                /*Adjust IPv4 header to account for packet's total length*/
                iph->tot_len=htons(new->length);
+
+               /*Cleanup*/
+               free(nnew.src_id);
+               free(nnew.dest_id);
 return 1;
 }
 
@@ -210,6 +308,11 @@ int linux_cooked_encap(struct packet *new, const struct const_packet *old)
                                                return 0;
                                }
                                break;
+               case ETHERTYPE_IPV6:
+                               if(!ipv6_encap(&nnew, &nold)){
+                                               return 0;
+                               }
+                               break;
                default:
                                dbgprintf(1, "Unknown Next Protocol at SLL\n");
                                return 0;
diff --git a/encap.h b/encap.h
index 09ee14d609b2f3a0b33421b49fdce202bfb478c8..baf092c93dbd4a34476dce3c0358192d8c9b7580 100644 (file)
--- a/encap.h
+++ b/encap.h
@@ -1,7 +1,7 @@
 /******************************************************************************
 Author: Samuel Jero
 
-Date: 11/2011
+Date: 11/2012
 
 Description: Header file for Encapsulation Functions for DCCP to TCP conversion
 
@@ -26,12 +26,14 @@ Description: Header file for Encapsulation Functions for DCCP to TCP conversion
  *                                             space AND must return with this parameter containing
  *                                             the length of the new packet at that layer.
  *
- *     uint32_t src_id:        This is an ID for the source host. If you are going to
+ *     int id_len:                     Length of the source and destination ID.
+ *
+ *     u_char *src_id:         This is an ID for the source host. If you are going to
  *                                             demultiplex DCCP on anything but Port Numbers, you
  *                                             need to set this field. Typically this would be an
  *                                             IP address.
  *
- *     uint32_t dest_id:       This is an ID for the destination host. If you are going to
+ *     u_char *dest_id:        This is an ID for the destination host. If you are going to
  *                                             demultiplex DCCP on anything but Port Numbers, you
  *                                             need to set this field. Typically this would be an
  *                                             IP address.
@@ -58,5 +60,6 @@ int convert_packet(struct packet *new, const struct const_packet *old);
 int ethernet_encap(struct packet *new, const struct const_packet *old);
 int linux_cooked_encap(struct packet *new, const struct const_packet *old);
 int ipv4_encap(struct packet *new, const struct const_packet *old);
+int ipv6_encap(struct packet *new, const struct const_packet *old);
 
 #endif /* ENCAP_H_ */