PERFORCE change 100067 for review
Clément Lecigne
clem1 at FreeBSD.org
Mon Jun 26 17:10:25 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=100067
Change 100067 by clem1 at 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:
More information about the p4-projects
mailing list