/******************************************************************************
Author: Samuel Jero
-Date: 11/2011
+Date: 11/2012
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;
/*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;
}
/*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;
}
}
/*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;
}
/*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;
while(ptr!=NULL){
prev=ptr;
+ free(ptr->A.id);
+ free(ptr->B.id);
ptr=ptr->next;
free(prev);
}
/******************************************************************************
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.
-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);
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);
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;
}
/******************************************************************************
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.
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*/
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*/
/*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*/
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();
/******************************************************************************
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)
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;
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)
{
/*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;
}
/*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;
}
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;
/******************************************************************************
Author: Samuel Jero
-Date: 11/2011
+Date: 11/2012
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.
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_ */