Date: Mon, 3 Jul 2006 21:11:00 GMT From: Clément Lecigne <clem1@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 100526 for review Message-ID: <200607032111.k63LB07p044086@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100526 Change 100526 by clem1@clem1_ipv6vulns on 2006/07/03 21:10:22 ICMPv6 option support in libnet. Affected files ... .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-functions.h#6 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-headers.h#5 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-structures.h#4 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_build_icmpv6.c#3 edit Differences ... ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-functions.h#6 (text+ko) ==== @@ -999,6 +999,100 @@ u_int32_t unused, struct libnet_in6_addr, struct libnet_in6_addr, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); +/** + * Builds an IP version 6 RFC 2461 Internet Control Message Protocol (ICMP) + * target link layer option header + * @param type of ICMP option packet (should be ICMP6_OPT_TLLA) + * @param code of ICMP option packet (should be 0) + * @param target mac 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_opt_tlla(u_int8_t type, u_int8_t length, + u_int8_t *target, u_int8_t *payload, u_int32_t payload_s, + libnet_t *l, libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2461 Internet Control Message Protocol (ICMP) + * source link layer option header + * @param type of ICMP option packet (should be ICMP6_OPT_SLLA) + * @param len of ICMP option packet + * @param source mac 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_opt_slla(u_int8_t type, u_int8_t length, + u_int8_t *source, u_int8_t *payload, u_int32_t payload_s, + libnet_t *l, libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2461 Internet Control Message Protocol (ICMP) + * prefix information option header + * @param type of ICMP option packet (should be ICMP6_OPT_PI) + * @param len of ICMP option packet + * @param prefix len + * @param on link flag + * @param autonomous addr configuration flag + * @param valid lifetime + * @param preferred lifetime + * @param reserved + * @param ip6 prefix + * @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_opt_pi(u_int8_t type, u_int8_t length, u_int8_t prefixlen, + u_int8_t ol, u_int8_t a, u_int32_t validlt, u_int32_t preferredlt, + u_int32_t reserved, struct libnet_in6_addr prefix, + u_int32_t payload_s, u_int8_t *payload, libnet_t *l, + libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2461 Internet Control Message Protocol (ICMP) + * redirected option header + * @param type of ICMP option packet (should be ICMP6_OPT_RH) + * @param len of ICMP option packet + * @param reserved + * @param reserved + * @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_opt_rh(u_int8_t type, u_int8_t length, u_int16_t r1, + u_int32_t r2, u_int32_t payload_s, u_int8_t *payload, libnet_t *l, + libnet_ptag_t ptag); + +/** + * Builds an IP version 6 RFC 2461 Internet Control Message Protocol (ICMP) + * MTU option header + * @param type of ICMP option packet (should be ICMP6_OPT_RH) + * @param len of ICMP option packet + * @param reserved + * @param MTU + * @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_opt_mtu(u_int8_t type, u_int8_t length, u_int16_t r, + u_int32_t mtu, u_int32_t payload_s, u_int8_t *payload, libnet_t *l, + libnet_ptag_t ptag); /** * Builds an RFC 1112 Internet Group Memebership Protocol (IGMP) header. ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-headers.h#5 (text+ko) ==== @@ -75,6 +75,11 @@ #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_ICMPV6_OPT_SLLA_H 0x08 /**< ICMPV6_LLLA header: 8 bytes */ +#define LIBNET_ICMPV6_OPT_TLLA_H 0x08 /**< ICMPV6_TLLA header: 8 bytes */ +#define LIBNET_ICMPV6_OPT_PI_H 0x20 /**< ICMPV6_PI header: 32 bytes */ +#define LIBNET_ICMPV6_OPT_MTU_H 0x08 /**< ICMPV6_MTU header: 8 bytes */ +#define LIBNET_ICMPV6_OPT_RH_H 0x08 /**< ICMPV6_RH header: 8 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 */ @@ -967,7 +972,7 @@ #undef icmp_maxdelay #undef icmp_reserved2 #define icmp_maxdelay hun.mld.maxdelay -#define icmp_reserved hun.mld.reserved2 +#define icmp_reserved2 hun.mld.reserved2 u_int32_t pointer; /* ICMP pointer */ #undef icmp_pointer #define icmp_pointer hun.pointer @@ -1015,8 +1020,74 @@ }qun; }; +/* + * ICMPV6 link-layer address option header + * Base header size: 8 bytes + */ +struct libnet_icmpv6_opt_lla_hdr +{ + u_int8_t type; /* ICMP opt type */ +#ifndef ICMP6_OPT_SLLA +#define ICMP6_OPT_SLLA 1 +#endif +#ifndef ICMP6_OPT_TLLA +#define ICMP6_OPT_TLLA 2 +#endif + u_int8_t len; /* ICMP opt header len */ + int8_t addr[6]; +}; /* + * ICMPV6 prefix information option header + * Header size: 32 bytes + */ +struct libnet_icmpv6_opt_pi_hdr +{ + u_int8_t type; /* ICMP opt type */ +#ifndef ICMP6_OPT_PI +#define ICMP6_OPT_PI 3 +#endif + u_int8_t len; + u_int8_t prefixlen; + u_int8_t la; + u_int32_t validlt; + u_int32_t preferredlt; + u_int32_t reserved; + struct libnet_in6_addr prefix; +}; + +/* + * ICMPV6 redirect option header + * Header size: 8 bytes + */ +struct libnet_icmpv6_opt_rh_hdr +{ + u_int8_t type; +#ifndef ICMP6_OPT_RH +#define ICMP6_OPT_RH 4 +#endif + u_int8_t len; + u_int16_t reserved1; + u_int32_t reserved2; +}; + +/* + * ICMPV6 MTU option header + * Header size: 8 bytes + */ +struct libnet_icmpv6_opt_mtu_hdr +{ + u_int8_t type; +#ifndef ICMP6_OPT_MTU +#define ICMP6_OPT_MTU 5 +#endif + u_int8_t len; + u_int16_t reserved; + u_int32_t mtu; +}; + + +/* * ICMP header * Internet Control Message Protocol * Base header size: 4 bytes ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-structures.h#4 (text+ko) ==== @@ -159,6 +159,11 @@ #define LIBNET_PBLOCK_ICMPV6_MULTICAST_H 0x4a /* ICMP6 multicast group management header */ #define LIBNET_PBLOCK_ICMPV6_NI_H 0x4b /* ICMP6 node information header */ #define LIBNET_PBLOCK_ICMPV6_UNREACH_H 0x4c /* ICMP6 destination unreach packet */ +#define LIBNET_PBLOCK_ICMPV6_OPT_TLLA_H 0x4d /* ICMP6 option target link layer header */ +#define LIBNET_PBLOCK_ICMPV6_OPT_SLLA_H 0x4e /* ICMP6 option source link layer header */ +#define LIBNET_PBLOCK_ICMPV6_OPT_PI_H 0x4f /* ICMP6 option prefix information header */ +#define LIBNET_PBLOCK_ICMPV6_OPT_RH_H 0x50 /* ICMP6 option redirect header */ +#define LIBNET_PBLOCK_ICMPV6_OPT_MTU_H 0x51 /* ICMP6 option MTU header */ u_int8_t flags; /* control flags */ #define LIBNET_PBLOCK_DO_CHECKSUM 0x01 /* needs a checksum */ libnet_ptag_t ptag; /* protocol block tag */ ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_build_icmpv6.c#3 (text+ko) ==== @@ -461,6 +461,31 @@ } } + /* + * Some shits around icmpv6 option and related to checksumming + */ + if (p->prev && sum == 0) + { + switch(p->prev->type) + { + case LIBNET_PBLOCK_ICMPV6_OPT_SLLA_H: + case LIBNET_PBLOCK_ICMPV6_OPT_TLLA_H: + h += LIBNET_ICMPV6_OPT_TLLA_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_PI_H: + h += LIBNET_ICMPV6_OPT_PI_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_RH_H: + h += LIBNET_ICMPV6_OPT_RH_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_MTU_H: + h += LIBNET_ICMPV6_OPT_MTU_H; + break; + default: + break; + } + } + if (sum == 0) { /* @@ -613,6 +638,31 @@ } } + /* + * Some shits around icmpv6 option and related to checksumming + */ + if (p->prev && sum == 0) + { + switch(p->prev->type) + { + case LIBNET_PBLOCK_ICMPV6_OPT_SLLA_H: + case LIBNET_PBLOCK_ICMPV6_OPT_TLLA_H: + h += LIBNET_ICMPV6_OPT_TLLA_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_PI_H: + h += LIBNET_ICMPV6_OPT_PI_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_RH_H: + h += LIBNET_ICMPV6_OPT_RH_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_MTU_H: + h += LIBNET_ICMPV6_OPT_MTU_H; + break; + default: + break; + } + } + if (sum == 0) { /* @@ -685,6 +735,31 @@ } } + /* + * Some shits around icmpv6 option and related to checksumming + */ + if (p->prev && sum == 0) + { + switch(p->prev->type) + { + case LIBNET_PBLOCK_ICMPV6_OPT_SLLA_H: + case LIBNET_PBLOCK_ICMPV6_OPT_TLLA_H: + h += LIBNET_ICMPV6_OPT_TLLA_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_PI_H: + h += LIBNET_ICMPV6_OPT_PI_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_RH_H: + h += LIBNET_ICMPV6_OPT_RH_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_MTU_H: + h += LIBNET_ICMPV6_OPT_MTU_H; + break; + default: + break; + } + } + if (sum == 0) { /* @@ -764,6 +839,31 @@ } } + /* + * Some shits around icmpv6 option and related to checksumming + */ + if (p->prev && sum == 0) + { + switch(p->prev->type) + { + case LIBNET_PBLOCK_ICMPV6_OPT_SLLA_H: + case LIBNET_PBLOCK_ICMPV6_OPT_TLLA_H: + h += LIBNET_ICMPV6_OPT_TLLA_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_PI_H: + h += LIBNET_ICMPV6_OPT_PI_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_RH_H: + h += LIBNET_ICMPV6_OPT_RH_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_MTU_H: + h += LIBNET_ICMPV6_OPT_MTU_H; + break; + default: + break; + } + } + if (sum == 0) { /* @@ -844,6 +944,31 @@ } } + /* + * Some shits around icmpv6 option and related to checksumming + */ + if (p->prev && sum == 0) + { + switch(p->prev->type) + { + case LIBNET_PBLOCK_ICMPV6_OPT_SLLA_H: + case LIBNET_PBLOCK_ICMPV6_OPT_TLLA_H: + h += LIBNET_ICMPV6_OPT_TLLA_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_PI_H: + h += LIBNET_ICMPV6_OPT_PI_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_RH_H: + h += LIBNET_ICMPV6_OPT_RH_H; + break; + case LIBNET_PBLOCK_ICMPV6_OPT_MTU_H: + h += LIBNET_ICMPV6_OPT_MTU_H; + break; + default: + break; + } + } + if (sum == 0) { /* @@ -860,3 +985,322 @@ return (-1); } +libnet_ptag_t +libnet_build_icmpv6_opt_tlla(u_int8_t type, u_int8_t length, + u_int8_t *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_opt_lla_hdr opt; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_OPT_TLLA_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_OPT_TLLA_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_OPT_TLLA_H); + if(p == NULL) + { + return (-1); + } + + memset(&opt, 0, sizeof(opt)); + opt.type = type; /* option type */ + opt.len = length; /* header len */ + for (i = 0; i < 8; i++) + { + opt.addr[i] = target[i]; /* target */ + } + + n = libnet_pblock_append(l, p, (u_int8_t *)&opt, LIBNET_ICMPV6_OPT_TLLA_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; + } + } + + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_OPT_TLLA_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + +libnet_ptag_t +libnet_build_icmpv6_opt_slla(u_int8_t type, u_int8_t length, + u_int8_t *source, 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_opt_lla_hdr opt; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_OPT_SLLA_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_OPT_SLLA_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_OPT_SLLA_H); + if(p == NULL) + { + return (-1); + } + + memset(&opt, 0, sizeof(opt)); + opt.type = type; /* option type */ + opt.len = length; /* packet code */ + for (i = 0; i < 8; i++) + { + opt.addr[i] = source[i]; /* target */ + } + + n = libnet_pblock_append(l, p, (u_int8_t *)&opt, LIBNET_ICMPV6_OPT_SLLA_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; + } + } + + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_OPT_SLLA_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + +libnet_ptag_t +libnet_build_icmpv6_opt_pi(u_int8_t type, u_int8_t length, u_int8_t prefixlen, + u_int8_t ol, u_int8_t a, u_int32_t validlt, u_int32_t preferredlt, + u_int32_t reserved, struct libnet_in6_addr prefix, + u_int32_t payload_s, u_int8_t *payload, libnet_t *l, + libnet_ptag_t ptag) +{ + u_int32_t n, h; + libnet_pblock_t *p; + struct libnet_icmpv6_opt_pi_hdr opt; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_OPT_PI_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_OPT_PI_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_OPT_PI_H); + if(p == NULL) + { + return (-1); + } + + memset(&opt, 0, sizeof(opt)); + opt.type = type; /* option type */ + opt.len = length; /* packet header len */ + opt.prefixlen = prefixlen; + opt.la = (ol << 7) + (a << 6); + opt.validlt = validlt; + opt.preferredlt = preferredlt; + opt.reserved = reserved; + opt.prefix = prefix; + + n = libnet_pblock_append(l, p, (u_int8_t *)&opt, LIBNET_ICMPV6_OPT_PI_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; + } + } + + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_OPT_PI_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + +libnet_ptag_t +libnet_build_icmpv6_opt_rh(u_int8_t type, u_int8_t length, u_int16_t r1, + u_int32_t r2, u_int32_t payload_s, u_int8_t *payload, libnet_t *l, + libnet_ptag_t ptag) +{ + u_int32_t n, h; + libnet_pblock_t *p; + struct libnet_icmpv6_opt_rh_hdr opt; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_OPT_RH_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_OPT_RH_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_OPT_RH_H); + if(p == NULL) + { + return (-1); + } + + memset(&opt, 0, sizeof(opt)); + opt.type = type; /* option type */ + opt.len = length; /* packet header len */ + opt.reserved1 = r1; + opt.reserved2 = r2; + + n = libnet_pblock_append(l, p, (u_int8_t *)&opt, LIBNET_ICMPV6_OPT_RH_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; + } + } + + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_OPT_RH_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +} + +libnet_ptag_t +libnet_build_icmpv6_opt_mtu(u_int8_t type, u_int8_t length, u_int16_t r, + u_int32_t mtu, u_int32_t payload_s, u_int8_t *payload, + libnet_t *l, libnet_ptag_t ptag) +{ + u_int32_t n, h; + libnet_pblock_t *p; + struct libnet_icmpv6_opt_mtu_hdr opt; + + if(l == NULL) + { + return (-1); + } + + n = LIBNET_ICMPV6_OPT_MTU_H + payload_s; /* size of memory block */ + h = LIBNET_ICMPV6_OPT_MTU_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_OPT_MTU_H); + if(p == NULL) + { + return (-1); + } + + memset(&opt, 0, sizeof(opt)); + opt.type = type; /* option type */ + opt.len = length; /* packet header len */ + opt.reserved = r; + opt.mtu = mtu; + + n = libnet_pblock_append(l, p, (u_int8_t *)&opt, LIBNET_ICMPV6_OPT_MTU_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; + } + } + + return (ptag ? ptag : libnet_pblock_update(l, p, h, + LIBNET_PBLOCK_ICMPV6_OPT_MTU_H)); +bad: + libnet_pblock_delete(l, p); + return (-1); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607032111.k63LB07p044086>