Skip to content

Commit

Permalink
Add IPv6 TCP/UDP flow support
Browse files Browse the repository at this point in the history
  • Loading branch information
ecsv committed Feb 12, 2014
1 parent 0cccfff commit 10e96c4
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
18 changes: 18 additions & 0 deletions flow_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ static unsigned int hash_5tuple(struct af_6tuple af_6tuple)
hash1 = hashf(&af_6tuple.ip1.v4, 4, hash1);
hash1 = hashf(&af_6tuple.ip2.v4, 4, hash1);
break;
case AF_INET6:
hash1 = hashf(&af_6tuple.ip1.v6, 16, hash1);
hash1 = hashf(&af_6tuple.ip2.v6, 16, hash1);
break;
}
if (af_6tuple.port1)
hash1 = hashf(&af_6tuple.port1, 2, hash1);
Expand All @@ -107,6 +111,10 @@ static unsigned int hash_5tuple(struct af_6tuple af_6tuple)
hash2 = hashf(&af_6tuple.ip2.v4, 4, hash2);
hash2 = hashf(&af_6tuple.ip1.v4, 4, hash2);
break;
case AF_INET6:
hash2 = hashf(&af_6tuple.ip2.v6, 16, hash2);
hash2 = hashf(&af_6tuple.ip1.v6, 16, hash2);
break;
}
if (af_6tuple.port2)
hash2 = hashf(&af_6tuple.port2, 2, hash2);
Expand Down Expand Up @@ -137,6 +145,16 @@ static int compare_5tuple(struct af_6tuple af1, struct af_6tuple af2)
af1.port1 == af2.port2 && af1.port2 == af2.port1)
return 1;
break;
case AF_INET6:
if (memcmp(&af1.ip1.v6, &af2.ip1.v6, sizeof(af1.ip1.v6)) == 0 &&
memcmp(&af1.ip2.v6, &af2.ip2.v6, sizeof(af1.ip2.v6)) == 0 &&
af1.port1 == af2.port1 && af1.port2 == af2.port2)
return 1;
if (memcmp(&af1.ip1.v6, &af2.ip2.v6, sizeof(af1.ip1.v6)) == 0 &&
memcmp(&af1.ip2.v6, &af2.ip1.v6, sizeof(af1.ip2.v6)) == 0 &&
af1.port1 == af2.port2 && af1.port2 == af2.port1)
return 1;
break;
}

return 0;
Expand Down
62 changes: 61 additions & 1 deletion pkt2flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
#include <getopt.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <pcap/pcap.h>
Expand Down Expand Up @@ -241,6 +243,60 @@ static int pcap_handle_ipv4(struct af_6tuple *af_6tuple, const u_char *bytes,
return pcap_handle_layer4(af_6tuple, bytes, len, iphdr->ip_p);
}

static int pcap_handle_ipv6(struct af_6tuple *af_6tuple, const u_char *bytes,
size_t len)
{
struct ip6_hdr *iphdr;
struct ip6_opt *opthdr;
int curheader = 255;
uint8_t nexthdr;

while (1) {
switch (curheader) {
case 255:
if (len < sizeof(*iphdr))
return -1;
iphdr = (struct ip6_hdr *)bytes;
bytes += sizeof(*iphdr);
len -= sizeof(*iphdr);
nexthdr = iphdr->ip6_ctlun.ip6_un1.ip6_un1_nxt;

af_6tuple->af_family = AF_INET6;
af_6tuple->ip1.v6 = iphdr->ip6_src;
af_6tuple->ip2.v6 = iphdr->ip6_dst;
break;
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_DSTOPTS:
if (len < sizeof(*opthdr))
return -1;
nexthdr = bytes[0];

opthdr = (struct ip6_opt *)bytes;
if (len < ((1u + opthdr->ip6o_len) * 8u))
return -1;
bytes += (1u + opthdr->ip6o_len) * 8u;
len -= (1u + opthdr->ip6o_len) * 8u;
break;
case IPPROTO_FRAGMENT:
if (len < 1)
return -1;
nexthdr = bytes[0];
if (len < 8)
return -1;
bytes += 8;
len -= 8;
break;
case IPPROTO_NONE:
return -1;
default:
return pcap_handle_layer4(af_6tuple, bytes, len,
nexthdr);
};
curheader = nexthdr;
}
}

static int pcap_handle_ip(struct af_6tuple *af_6tuple, const u_char *bytes,
size_t len)
{
Expand All @@ -251,6 +307,9 @@ static int pcap_handle_ip(struct af_6tuple *af_6tuple, const u_char *bytes,
if ((bytes[0] >> 4) == 4)
return pcap_handle_ipv4(af_6tuple, bytes, len);

if ((bytes[0] >> 4) == 6)
return pcap_handle_ipv6(af_6tuple, bytes, len);

return -1;
}

Expand All @@ -269,7 +328,8 @@ static int pcap_handle_ethernet(struct af_6tuple *af_6tuple,
len -= sizeof(*ethhdr);
bytes += sizeof(*ethhdr);

if (ntohs(ethhdr->ether_type) != ETHERTYPE_IP)
if (ntohs(ethhdr->ether_type) != ETHERTYPE_IP &&
ntohs(ethhdr->ether_type) != ETHERTYPE_IPV6)
return -1;

return pcap_handle_ip(af_6tuple, bytes, len);
Expand Down
2 changes: 2 additions & 0 deletions pkt2flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#include <stdint.h>
#include <netinet/in.h>
#include <netinet/ip6.h>

#define __SOURCE_VERSION__ "1.2"
#define __AUTHOR__ "X. Chen ([email protected])"
Expand Down Expand Up @@ -68,6 +69,7 @@ struct pkt_dump_file {

union ip_address {
struct in_addr v4;
struct in6_addr v6;
};

struct af_6tuple {
Expand Down
8 changes: 6 additions & 2 deletions utilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,19 @@
char *new_file_name(struct af_6tuple af_6tuple, unsigned long timestamp)
{
char *fname;
char src_ip_str[INET_ADDRSTRLEN];
char dst_ip_str[INET_ADDRSTRLEN];
char src_ip_str[INET6_ADDRSTRLEN];
char dst_ip_str[INET6_ADDRSTRLEN];
int ret;

switch (af_6tuple.af_family) {
case AF_INET:
inet_ntop(AF_INET, &af_6tuple.ip1.v4, src_ip_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &af_6tuple.ip2.v4, dst_ip_str, INET_ADDRSTRLEN);
break;
case AF_INET6:
inet_ntop(AF_INET6, &af_6tuple.ip1.v6, src_ip_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &af_6tuple.ip2.v6, dst_ip_str, INET6_ADDRSTRLEN);
break;
}

ret = asprintf(&fname, "%s_%"PRIu16"_%s_%"PRIu16"_%lu.pcap",
Expand Down

0 comments on commit 10e96c4

Please sign in to comment.