Skip site navigation (1)Skip section navigation (2)
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>