From 140bde424c1381353f37ebc3395305f2acfcf546 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 7 Jun 2013 21:34:35 +0200 Subject: cthelper: add IPv6 support Signed-off-by: Pablo Neira Ayuso --- src/cthelper.c | 70 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 24 deletions(-) (limited to 'src/cthelper.c') diff --git a/src/cthelper.c b/src/cthelper.c index 307be96..f333625 100644 --- a/src/cthelper.c +++ b/src/cthelper.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -77,6 +78,8 @@ nfq_hdr_put(char *buf, int type, uint32_t queue_num) static int pkt_get(void *pkt, uint32_t pktlen, uint16_t proto, uint32_t *protoff) { + uint8_t protocol; + switch(proto) { case ETHERTYPE_IP: { struct iphdr *ip = (struct iphdr *) pkt; @@ -94,41 +97,60 @@ pkt_get(void *pkt, uint32_t pktlen, uint16_t proto, uint32_t *protoff) } *protoff = 4 * ip->ihl; + protocol = ip->protocol; + break; + } + case ETHERTYPE_IPV6: { + struct iphdr *ip = (struct iphdr *) pkt; + struct ip6_hdr *ip6 = (struct ip6_hdr *) pkt; - switch (ip->protocol) { - case IPPROTO_TCP: { - struct tcphdr *tcph = - (struct tcphdr *) ((char *)pkt + *protoff); - - /* No room for IPv4 header plus TCP header. */ - if (pktlen < *protoff + sizeof(struct tcphdr) - || pktlen < *protoff + tcph->doff * 4) { - dlog(LOG_ERR, "no room for IPv4 + TCP header, skip"); - return -1; - } - return 0; + /* No room for IPv6 header. */ + if (pktlen < sizeof(struct ip6_hdr)) { + dlog(LOG_ERR, "no room for IPv6 header"); + return -1; } - case IPPROTO_UDP: - /* No room for IPv4 header plus UDP header. */ - if (pktlen < *protoff + sizeof(struct udphdr)) { - dlog(LOG_ERR, "no room for IPv4 + UDP header, skip"); - return -1; - } - return 0; - default: - dlog(LOG_ERR, "not TCP/UDP, skipping"); + + /* this is not IPv6, skip. */ + if (ip->version != 6) { + dlog(LOG_ERR, "not IPv6, skipping"); return -1; } + + *protoff = sizeof(struct ip6_hdr); + protocol = ip6->ip6_nxt; break; } - case ETHERTYPE_IPV6: - dlog(LOG_ERR, "no IPv6 support sorry"); - return 0; default: /* Unknown layer 3 protocol. */ dlog(LOG_ERR, "unknown layer 3 protocol (%d), skipping", proto); return -1; } + + switch (protocol) { + case IPPROTO_TCP: { + struct tcphdr *tcph = + (struct tcphdr *) ((char *)pkt + *protoff); + + /* No room for IPv4 header plus TCP header. */ + if (pktlen < *protoff + sizeof(struct tcphdr) || + pktlen < *protoff + tcph->doff * 4) { + dlog(LOG_ERR, "no room for IPv4 + TCP header, skip"); + return -1; + } + return 0; + } + case IPPROTO_UDP: + /* No room for IPv4 header plus UDP header. */ + if (pktlen < *protoff + sizeof(struct udphdr)) { + dlog(LOG_ERR, "no room for IPv4 + UDP header, skip"); + return -1; + } + return 0; + default: + dlog(LOG_ERR, "not TCP/UDP, skipping"); + return -1; + } + return 0; } -- cgit v1.2.3