From c91be816ed58d40d8d3f88b6388a21de320bcdb0 Mon Sep 17 00:00:00 2001 From: repolho Date: Wed, 9 Nov 2011 17:40:45 -0200 Subject: Implemented libnet_autobuild_ipv6() --- libnet/include/libnet/libnet-functions.h | 9 ++++- libnet/src/libnet_build_ip.c | 62 ++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/libnet/include/libnet/libnet-functions.h b/libnet/include/libnet/libnet-functions.h index 6f98ab0..9de11ef 100644 --- a/libnet/include/libnet/libnet-functions.h +++ b/libnet/include/libnet/libnet-functions.h @@ -1036,7 +1036,14 @@ libnet_build_ipv6_hbhopts(uint8_t nh, uint8_t len, const uint8_t* payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag); /** - * This function is not yet implement and is a NOOP. + * Autobuilds a version 6 RFC 2460 Internet Protocol (IP) header. The function + * is useful to build an IP header quickly when you do not need a granular + * level of control. The function takes the same len, nh, and dst arguments + * as libnet_build_ipv4(). The function does not accept a ptag argument, but it + * does return a ptag. In other words, you can use it to build a new IP header + * but not to modify an existing one. + * This function requires libnet_get_ipaddr6(), which is not yet implemented + * for Win32 platforms. * @param len length * @param nh next header * @param dst destination IPv6 address diff --git a/libnet/src/libnet_build_ip.c b/libnet/src/libnet_build_ip.c index 340ab7e..1ecbc76 100644 --- a/libnet/src/libnet_build_ip.c +++ b/libnet/src/libnet_build_ip.c @@ -749,10 +749,66 @@ libnet_ptag_t libnet_autobuild_ipv6(uint16_t len, uint8_t nh, struct libnet_in6_addr dst, libnet_t *l, libnet_ptag_t ptag) { + int libnet_in6_addr_cmp(struct libnet_in6_addr addr1, struct libnet_in6_addr addr2) { + /* Returns != 0 if addresses are equal, 0 otherwise. */ + uint32_t *p1 = (uint32_t*)&addr1.__u6_addr, *p2 = (uint32_t*)&addr2.__u6_addr; + return ((p1[0] == p2[0]) && (p1[1] == p2[1]) && (p1[2] == p2[2]) && + (p1[3] == p2[3])); + } + + uint32_t n; + libnet_pblock_t *p; + struct libnet_ipv6_hdr ip_hdr; + struct libnet_in6_addr src; + + if (l == NULL) + { + return (-1); + } + + n = LIBNET_IPV6_H; /* size of memory block */ + /* + * Find the existing protocol block if a ptag is specified, or create + * a new one. + */ + p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_IPV6_H); + if (p == NULL) + { + return (-1); + } + + src = libnet_get_ipaddr6(l); + if (libnet_in6_addr_cmp(src, in6addr_error)) + { + /* err msg set in libnet_get_ipaddr6() */ + return (-1); + } + + memset(&ip_hdr, 0, sizeof(ip_hdr)); + ip_hdr.ip_flags[0] = 0x06 << 4; /* ip version */ + ip_hdr.ip_flags[1] = 0; + ip_hdr.ip_flags[2] = 0; + ip_hdr.ip_flags[3] = 0; + ip_hdr.ip_len = htons(len); + ip_hdr.ip_nh = nh; + ip_hdr.ip_hl = 64; + ip_hdr.ip_src = src; + ip_hdr.ip_dst = dst; + + n = libnet_pblock_append(l, p, (uint8_t *)&ip_hdr, LIBNET_IPV6_H); + if (n == -1) + { + goto bad; + } - /* NYI */ - snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, - "%s(): not yet implemented\n", __func__); + /* no checksum for IPv6 */ + ptag = ptag ? ptag : libnet_pblock_update(l, p, LIBNET_IPV6_H, + LIBNET_PBLOCK_IPV6_H); + + return ptag; + +bad: + libnet_pblock_delete(l, p); return (-1); } -- cgit v1.2.1