From: Samuel Jero Date: Sun, 11 Nov 2012 20:59:05 +0000 (-0500) Subject: IPv6 support! X-Git-Url: http://sjero.net/git/?p=dccp2tcp;a=commitdiff_plain;h=5d65c31ba16de1a71d2f54e40f2494e121d6836e IPv6 support! --- diff --git a/connections.c b/connections.c index 0edc451..4bc60f0 100644 --- a/connections.c +++ b/connections.c @@ -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); } diff --git a/dccp2tcp.c b/dccp2tcp.c index 17563f2..3df497e 100644 --- a/dccp2tcp.c +++ b/dccp2tcp.c @@ -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; } diff --git a/dccp2tcp.h b/dccp2tcp.h index c321f0b..7f106a5 100644 --- a/dccp2tcp.h +++ b/dccp2tcp.h @@ -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 736cf3a..1153e06 100644 --- 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 +#include /*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 09ee14d..baf092c 100644 --- 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_ */