Date: Mon, 26 Jun 2006 15:58:50 GMT From: Clément Lecigne <clem1@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 100067 for review Message-ID: <200606261558.k5QFwoEp083925@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100067 Change 100067 by clem1@clem1_ipv6vulns on 2006/06/26 15:58:03 Almost full icmp6 support to libnet. Affected files ... .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-functions.h#4 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-headers.h#3 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-structures.h#3 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_build_icmpv6.c#2 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_pblock.c#3 edit Differences ... ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-functions.h#4 (text+ko) ==== @@ -877,6 +877,110 @@ /** * Builds an IP version 6 RFC 2463 Internet Control Message Protocol (ICMP) + * node information header + * @param type type of ICMP packet (should be ICMP6_NIQUERY or ICMP6_NIREPLY) + * @param code code of ICMP packet (should be ICMP6_NIQUERY_IPV6, ICMP6_NIQUERY_IPV4, ICMP6_NIQUERY_FQDN, ICMP6_NIREPLY_SUCCESS, ICMP6_NIREPLY_REFUSED or ICMP6_NIREPLY_UNKNOWN) + * @param sum checksum (0 for libnet to autofill) + * @param qtype + * @param flags + * @param nonce + * @param payload optional payload or NULL + * @param payload_s payload length or 0 + * @param l pointer to a libnet context + * @param ptag protocol tag to modify an existing header, 0 to build a new one + * @return protocol tag value on success, -1 on error + */ +libnet_ptag_t +libnet_build_icmpv6_ni(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int16_t qtype, u_int16_t flags, u_int8_t * nonce, u_int8_t *payload, +u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2463 Internet Control Message Protocol (ICMP) + * router advertissement header + * @param type type of ICMP packet (should be ICMP6_ROUTERADV) + * @param code code of ICMP packet (should be 0) + * @param sum checksum (0 for libnet to autofill) + * @param chl (current hop limit) + * @param m (manager address) + * @param o (other stateful config flag) + * @param rlf (router lifetime) + * @param rct (recheable time) + * @param rtt (retrans time) + * @param payload optional payload or NULL + * @param payload_s payload length or 0 + * @param l pointer to a libnet context + * @param ptag protocol tag to modify an existing header, 0 to build a new one + * @return protocol tag value on success, -1 on error + */ +libnet_ptag_t +libnet_build_icmpv6_ra(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int8_t chl, u_int8_t m, u_int8_t o, u_int16_t rlf, u_int32_t rct, +u_int16_t rtt, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, +libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2463 Internet Control Message Protocol (ICMP) + * router solicitation header + * @param type type of ICMP packet (should be ICMP6_ROUTERSO) + * @param code code of ICMP packet (should be 0) + * @param sum checksum (0 for libnet to autofill) + * @param unused + * @param payload optional payload or NULL + * @param payload_s payload length or 0 + * @param l pointer to a libnet context + * @param ptag protocol tag to modify an existing header, 0 to build a new one + * @return protocol tag value on success, -1 on error + */ +libnet_ptag_t +libnet_build_icmpv6_rs(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int32_t unused, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, +libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2463 Internet Control Message Protocol (ICMP) + * neighbor solicitation header + * @param type type of ICMP packet (should be ICMP6_NEIGHBORSO) + * @param code code of ICMP packet (should be 0) + * @param sum checksum (0 for libnet to autofill) + * @param reserved + * @param target + * @param payload optional payload or NULL + * @param payload_s payload length or 0 + * @param l pointer to a libnet context + * @param ptag protocol tag to modify an existing header, 0 to build a new one + * @return protocol tag value on success, -1 on error + */ +libnet_ptag_t +libnet_build_icmpv6_ns(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int32_t reserved, struct libnet_in6_addr target, u_int8_t *payload, +u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2463 Internet Control Message Protocol (ICMP) + * neighbor advertissement header + * @param type type of ICMP packet (should be ICMP6_NEIGHBORADV) + * @param code code of ICMP packet (should be 0) + * @param sum checksum (0 for libnet to autofill) + * @param router flag + * @param solicited flag + * @param override flag + * @param target address + * @param payload optional payload or NULL + * @param payload_s payload length or 0 + * @param l pointer to a libnet context + * @param ptag protocol tag to modify an existing header, 0 to build a new one + * @return protocol tag value on success, -1 on error + */ +libnet_ptag_t +libnet_build_icmpv6_na(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int8_t router, u_int8_t solicited, u_int8_t override, +struct libnet_in6_addr target, u_int8_t *payload, +u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); + + +/** + * Builds an IP version 6 RFC 2463 Internet Control Message Protocol (ICMP) * redirect message header * @param type type of ICMP packet (should be ICMP6_REDIRECT) * @param code code of ICMP packet (should be 0) ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-headers.h#3 (text+ko) ==== @@ -69,7 +69,12 @@ #define LIBNET_ICMPV6_PARAMPB_H 0x08 /**< ICMPV6_PARAMPB header: 8 bytes */ #define LIBNET_ICMPV6_UNREACH_H 0x08 /**< ICMPV6_UNREACH header: 8 bytes */ #define LIBNET_ICMPV6_TOOBIG_H 0x08 /**< ICMPV6_TOOBIG header: 8 bytes */ +#define LIBNET_ICMPV6_RS_H 0x08 /**< ICMPV6_RS header: 8 bytes */ #define LIBNET_ICMPV6_REDIRECT_H 0x28 /**< ICMPV6_REDIRECT header: 40 bytes */ +#define LIBNET_ICMPV6_NI_H 0x10 /**< ICMPV6_NI header: 16 bytes */ +#define LIBNET_ICMPV6_RA_H 0x10 /**< ICMPV6_RA header: 16 bytes */ +#define LIBNET_ICMPV6_NS_H 0x18 /**< ICMPV6_NS header: 24 bytes */ +#define LIBNET_ICMPV6_NA_H 0x18 /**< ICMPV6_NA header: 24 bytes */ #define LIBNET_IGMP_H 0x08 /**< IGMP header: 8 bytes */ #define LIBNET_IPV4_H 0x14 /**< IPv4 header: 20 bytes */ #define LIBNET_IPV6_H 0x28 /**< IPv6 header: 40 bytes */ @@ -859,11 +864,11 @@ #ifndef ICMP6_ROUTERADV #define ICMP6_ROUTERADV 134 #endif -#ifndef ICMP6_WRUQUERY -#define ICMP6_WRUQUERY 139 +#ifndef ICMP6_NIQUERY +#define ICMP6_NIQUERY 139 #endif -#ifndef ICMP6_WRUREPLY -#define ICMP6_WRUREPLY 140 +#ifndef ICMP6_NIREPLY +#define ICMP6_NIREPLY 140 #endif #ifndef ICMP6_REDIRECT #define ICMP6_REDIRECT 137 @@ -899,23 +904,23 @@ #ifndef ICMP6_PARAMPROB_OPTION #define ICMP6_PARAMPROB_OPTION 2 #endif -#ifndef ICMP6_WRUQUERY_IPV6 -#define ICMP6_WRUQUERY_IPV6 0 +#ifndef ICMP6_NIQUERY_IPV6 +#define ICMP6_NIQUERY_IPV6 0 #endif -#ifndef ICMP6_WRUQUERY_FQDN -#define ICMP6_WRUQUERY_FQDN 1 +#ifndef ICMP6_NIQUERY_FQDN +#define ICMP6_NIQUERY_FQDN 1 #endif -#ifndef ICMP6_WRUQUERY_IPV4 -#define ICMP6_WRUQUERY_IPV4 2 +#ifndef ICMP6_NIQUERY_IPV4 +#define ICMP6_NIQUERY_IPV4 2 #endif -#ifndef ICMP6_WRUREPLY_SUCCESS -#define ICMP6_WRUREPLY_SUCCESS 0 +#ifndef ICMP6_NIREPLY_SUCCESS +#define ICMP6_NIREPLY_SUCCESS 0 #endif -#ifndef ICMP6_WRUREPLY_REFUSED -#define ICMP6_WRUREPLY_REFUSED 1 +#ifndef ICMP6_NIREPLY_REFUSED +#define ICMP6_NIREPLY_REFUSED 1 #endif -#ifndef ICMP6_WRUREPLY_UNKNOWN -#define ICMP6_WRUREPLY_UNKNOWN 2 +#ifndef ICMP6_NIREPLY_UNKNOWN +#define ICMP6_NIREPLY_UNKNOWN 2 #endif #ifndef ICMP6_REDIRECT_ONLINK #define ICMP6_REDIRECT_ONLINK 0 @@ -933,25 +938,81 @@ #undef icmp_seq #define icmp_id hun.echo.id #define icmp_seq hun.echo.seq + struct { + u_int16_t qtype; + u_int16_t flags; + }ni; +#undef icmp_qtype +#undef icmp_flags +#define icmp_qtype hun.ni.qtype +#define icmp_flags hun.ni.flags + struct { + u_int8_t chl; /* current_hop_limit */ + u_int8_t mo; /* m and o bits and 6 bytes reserved */ + u_int16_t rlf; /* router lifetime */ + } ra; +#undef icmp_chl +#undef icmp_mo +#undef icmp_rlf +#define icmp_chl hun.ra.chl +#define icmp_mo hun.ra.mo +#define icmp_rlf hun.ra.rlf + u_int32_t rso; /* router, solicited, override bits in ND_ADVERT */ +#undef icmp_rso +#define icmp_rso hun.rso + struct { + u_int16_t maxdelay; /* ICMP maxdelay used by MLD */ + u_int16_t reserved2; /* ICMP reserved 2 bytes */ + } mld; +#undef icmp_maxdelay +#undef icmp_reserved2 +#define icmp_maxdelay hun.mld.maxdelay +#define icmp_reserved hun.mld.reserved2 u_int32_t pointer; /* ICMP pointer */ #undef icmp_pointer #define icmp_pointer hun.pointer u_int32_t unused; /* ICMP unused bytes in TIMEEXCEED, DEST UNREACH and REDIRECT */ #undef icmp_unused #define icmp_unused hun.unused + u_int32_t reserved4; /* ICMP reserved 4 bytes in ND_NEIGHBOR_ADVERT and SOLIC */ +#undef icmp_reserved4 +#define icmp_reserved4 hun.reserved4 u_int32_t mtu; /* ICMP mtu (TOOBIG) */ #undef icmp_mtu #define icmp_mtu hun.mtu }hun; union{ + int8_t nonce[8]; /* nonce used by node information msg */ + int8_t target1[8]; /* first part of target address in REDIRECT msg */ +#undef icmp_nonce +#define icmp_nonce dun.nonce +#undef icmp_target1 +#define icmp_target1 dun.target1 + int8_t mcast1[8]; /* fist part of the multicast address used by MLD msg */ +#undef icmp_mcast1 +#define icmp_mcast1 dun.mcast1 struct { - struct libnet_in6_addr target, dst; - } redir; -#undef icmp_target -#define icmp_target dun.redir.target + u_int32_t rct; /* reachaable time (ROUTER ADVERT) */ + u_int32_t rtt; /* retransmission time (ROUTER ADVERT) */ + }ra; +#undef icmp_rct +#undef icmp_rtt +#define icmp_rct dun.ra.rct +#define icmp_rtt dun.ra.rtt + }dun; + union{ + int8_t target2[8]; /* second part of target address in REDIRECT msg */ +#undef icmp_target2 +#define icmp_target2 tun.target2 + int8_t mcast2[8]; /* second part of multicast address used by MLD msg */ +#undef icmp_mcast2 +#define icmp_mcast2 tun.mcast2 + }tun; + union{ + struct libnet_in6_addr dst; /* dst address used by REDIRECT msg */ #undef icmp_dst -#define icmp_dst dun.redir.dst - }dun; +#define icmp_dst qun.dst + }qun; }; ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-structures.h#3 (text+ko) ==== @@ -157,7 +157,7 @@ #define LIBNET_PBLOCK_ICMPV6_NEIGHBORADV_H 0x48 /* ICMP6 neighbor advertisement header */ #define LIBNET_PBLOCK_ICMPV6_REDIRECT_H 0x49 /* ICMP6 redirect message header */ #define LIBNET_PBLOCK_ICMPV6_MULTICAST_H 0x4a /* ICMP6 multicast group management header */ -#define LIBNET_PBLOCK_ICMPV6_WRU_H 0x4b /* ICMP6 Who Are You name lookup header */ +#define LIBNET_PBLOCK_ICMPV6_NI_H 0x4b /* ICMP6 node information header */ #define LIBNET_PBLOCK_ICMPV6_UNREACH_H 0x4c /* ICMP6 destination unreach packet */ u_int8_t flags; /* control flags */ #define LIBNET_PBLOCK_DO_CHECKSUM 0x01 /* needs a checksum */ ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_build_icmpv6.c#2 (text+ko) ==== @@ -401,7 +401,7 @@ u_int32_t unused, struct libnet_in6_addr target, struct libnet_in6_addr dst, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { - u_int32_t n, h; + u_int32_t n, h, i; libnet_pblock_t *p; struct libnet_icmpv6_hdr icmp_hdr; @@ -428,7 +428,14 @@ icmp_hdr.icmp_code = code; /* packet code */ icmp_hdr.icmp_sum = (sum ? htons(sum) : 0); /* checksum */ icmp_hdr.icmp_unused = htonl(unused); /* pointer */ - icmp_hdr.icmp_target = target; /* target */ + for (i = 0; i < 8; i++) + { + icmp_hdr.icmp_target1[i] = target.libnet_s6_addr[i]; /* target1 */ + } + for (n = 0; n < 8; n++) + { + icmp_hdr.icmp_target2[n] = target.libnet_s6_addr[i++]; /* target2 */ + } icmp_hdr.icmp_dst = dst; /* dst */ n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV6_REDIRECT_H); @@ -470,3 +477,386 @@ return (-1); } + +libnet_ptag_t +libnet_build_icmpv6_ni(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int16_t qtype, u_int16_t flags, u_int8_t *nonce, u_int8_t *payload, +u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) +{ + u_int32_t n, h, i; + libnet_pblock_t *p; + struct libnet_icmpv6_hdr icmp_hdr; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_NI_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_NI_H + payload_s; /* hl for checksum */ + + /* + * Find the existing protocol block if a ptag is specified, or create + * a new one. + */ + p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV6_NI_H); + if(p == NULL) + { + return (-1); + } + + memset(&icmp_hdr, 0, sizeof(icmp_hdr)); + icmp_hdr.icmp_type = type; /* packet type */ + icmp_hdr.icmp_code = code; /* packet code */ + icmp_hdr.icmp_sum = (sum ? htons(sum) : 0); /* checksum */ + icmp_hdr.icmp_qtype = htonl(qtype); /* qtype */ + icmp_hdr.icmp_flags = htonl(flags); /* flags */ + for (i = 0; i < 8; i++) + { + icmp_hdr.icmp_nonce[i] = nonce[i]; /* nonce */ + } + + n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV6_NI_H); + if (n == -1) + { + goto bad; + } + + if ((payload && !payload_s) || (!payload && payload_s)) + { + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, + "%s(): payload inconsistency\n", __func__); + goto bad; + } + + if (payload && payload_s) + { + n = libnet_pblock_append(l, p, payload, payload_s); + if (n == -1) + { + goto bad; + } + } + + if (sum == 0) + { + /* + * If checksum is zero, by default libnet will compute a checksum + * for the user. The programmer can override this by calling + * libnet_toggle_checksum(l, ptag, 1); + */ + libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); + } + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_NI_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + +libnet_ptag_t +libnet_build_icmpv6_ra(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int8_t chl, u_int8_t m, u_int8_t o, u_int16_t rlf, u_int32_t rct, +u_int16_t rtt, u_int8_t *payload, +u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) +{ + u_int32_t n, h; + libnet_pblock_t *p; + struct libnet_icmpv6_hdr icmp_hdr; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_RA_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_RA_H + payload_s; /* hl for checksum */ + /* + * Find the existing protocol block if a ptag is specified, or create + * a new one. + */ + p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV6_ROUTERADV_H); + if(p == NULL) + { + return (-1); + } + + memset(&icmp_hdr, 0, sizeof(icmp_hdr)); + icmp_hdr.icmp_type = type; /* packet type */ + icmp_hdr.icmp_code = code; /* packet code */ + icmp_hdr.icmp_sum = (sum ? htons(sum) : 0); /* checksum */ + icmp_hdr.icmp_chl = htons(chl); /* current hop limit */ + icmp_hdr.icmp_mo = (m << 7) + (o << 6); /* managed & other bits */ + icmp_hdr.icmp_rlf = htons(rlf); /* router lifetime */ + icmp_hdr.icmp_rct = htonl(rct); /* recheable time */ + icmp_hdr.icmp_rtt = htonl(rtt); /* retrans time */ + + n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV6_RA_H); + if (n == -1) + { + goto bad; + } + + if ((payload && !payload_s) || (!payload && payload_s)) + { + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, + "%s(): payload inconsistency\n", __func__); + goto bad; + } + + if (payload && payload_s) + { + n = libnet_pblock_append(l, p, payload, payload_s); + if (n == -1) + { + goto bad; + } + } + + if (sum == 0) + { + /* + * If checksum is zero, by default libnet will compute a checksum + * for the user. The programmer can override this by calling + * libnet_toggle_checksum(l, ptag, 1); + */ + libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); + } + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_ROUTERADV_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + + +libnet_ptag_t +libnet_build_icmpv6_rs(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int32_t unused, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, +libnet_ptag_t ptag) +{ + u_int32_t n, h; + libnet_pblock_t *p; + struct libnet_icmpv6_hdr icmp_hdr; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_RS_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_RS_H + payload_s; /* hl for checksum */ + + /* + * Find the existing protocol block if a ptag is specified, or create + * a new one. + */ + p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV6_ROUTERSO_H); + if(p == NULL) + { + return (-1); + } + + memset(&icmp_hdr, 0, sizeof(icmp_hdr)); + icmp_hdr.icmp_type = type; /* packet type */ + icmp_hdr.icmp_code = code; /* packet code */ + icmp_hdr.icmp_sum = (sum ? htons(sum) : 0); /* checksum */ + icmp_hdr.icmp_unused = htonl(unused); /* unused field */ + + n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV6_RS_H); + if (n == -1) + { + goto bad; + } + + if ((payload && !payload_s) || (!payload && payload_s)) + { + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, + "%s(): payload inconsistency\n", __func__); + goto bad; + } + + if (payload && payload_s) + { + n = libnet_pblock_append(l, p, payload, payload_s); + if (n == -1) + { + goto bad; + } + } + + if (sum == 0) + { + /* + * If checksum is zero, by default libnet will compute a checksum + * for the user. The programmer can override this by calling + * libnet_toggle_checksum(l, ptag, 1); + */ + libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); + } + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_ROUTERSO_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + +libnet_ptag_t +libnet_build_icmpv6_ns(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int32_t reserved, struct libnet_in6_addr target, u_int8_t *payload, +u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) +{ + u_int32_t n, h, i; + libnet_pblock_t *p; + struct libnet_icmpv6_hdr icmp_hdr; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_NS_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_NS_H + payload_s; /* hl for checksum */ + + /* + * Find the existing protocol block if a ptag is specified, or create + * a new one. + */ + p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV6_NEIGHBORSO_H); + if(p == NULL) + { + return (-1); + } + + memset(&icmp_hdr, 0, sizeof(icmp_hdr)); + icmp_hdr.icmp_type = type; /* packet type */ + icmp_hdr.icmp_code = code; /* packet code */ + icmp_hdr.icmp_sum = (sum ? htons(sum) : 0); /* checksum */ + icmp_hdr.icmp_reserved4 = htonl(reserved); /* unused field */ + for (i = 0; i < 8; i++) + { + icmp_hdr.icmp_target1[i] = target.libnet_s6_addr[i]; /* target1 */ + } + for (n = 0; n < 8; n++) + { + icmp_hdr.icmp_target2[n] = target.libnet_s6_addr[i++]; /* target2 */ + } + + n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV6_NS_H); + if (n == -1) + { + goto bad; + } + + if ((payload && !payload_s) || (!payload && payload_s)) + { + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, + "%s(): payload inconsistency\n", __func__); + goto bad; + } + + if (payload && payload_s) + { + n = libnet_pblock_append(l, p, payload, payload_s); + if (n == -1) + { + goto bad; + } + } + + if (sum == 0) + { + /* + * If checksum is zero, by default libnet will compute a checksum + * for the user. The programmer can override this by calling + * libnet_toggle_checksum(l, ptag, 1); + */ + libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); + } + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_NEIGHBORSO_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + +libnet_ptag_t +libnet_build_icmpv6_na(u_int8_t type, u_int8_t code, u_int16_t sum, +u_int8_t router, u_int8_t solicited, u_int8_t override, +struct libnet_in6_addr target, u_int8_t *payload, +u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) +{ + u_int32_t n, h, i; + libnet_pblock_t *p; + struct libnet_icmpv6_hdr icmp_hdr; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_NA_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_NA_H + payload_s; /* hl for checksum */ + + /* + * Find the existing protocol block if a ptag is specified, or create + * a new one. + */ + p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV6_NEIGHBORADV_H); + if(p == NULL) + { + return (-1); + } + + memset(&icmp_hdr, 0, sizeof(icmp_hdr)); + icmp_hdr.icmp_type = type; /* packet type */ + icmp_hdr.icmp_code = code; /* packet code */ + icmp_hdr.icmp_sum = (sum ? htons(sum) : 0); /* checksum */ + icmp_hdr.icmp_rso = htonl((router << 31) + (solicited << 30) + (override << 29)); /* router, solicited and override bits */ + for (i = 0; i < 8; i++) + { + icmp_hdr.icmp_target1[i] = target.libnet_s6_addr[i]; /* target1 */ + } + for (n = 0; n < 8; n++) + { + icmp_hdr.icmp_target2[n] = target.libnet_s6_addr[i++]; /* target2 */ + } + + n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV6_NA_H); + if (n == -1) + { + goto bad; + } + + if ((payload && !payload_s) || (!payload && payload_s)) + { + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, + "%s(): payload inconsistency\n", __func__); + goto bad; + } + + if (payload && payload_s) + { + n = libnet_pblock_append(l, p, payload, payload_s); + if (n == -1) + { + goto bad; + } + } + + if (sum == 0) + { + /* + * If checksum is zero, by default libnet will compute a checksum + * for the user. The programmer can override this by calling + * libnet_toggle_checksum(l, ptag, 1); + */ + libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); + } + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_NEIGHBORADV_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_pblock.c#3 (text+ko) ==== @@ -508,7 +508,7 @@ case LIBNET_PBLOCK_ICMPV6_TIMXCEED_H: case LIBNET_PBLOCK_ICMPV6_TOOBIG_H: case LIBNET_PBLOCK_ICMPV6_UNREACH_H: - case LIBNET_PBLOCK_ICMPV6_WRU_H: + case LIBNET_PBLOCK_ICMPV6_NI_H: case LIBNET_PBLOCK_ICMPV6_MULTICAST_H: case LIBNET_PBLOCK_ICMPV6_REDIRECT_H: case LIBNET_PBLOCK_ICMPV6_NEIGHBORADV_H:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606261558.k5QFwoEp083925>