]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Further IPv4-mapped IPv6 address cleanups.
authorGuy Harris <[email protected]>
Sun, 30 Oct 2016 18:15:40 +0000 (11:15 -0700)
committerGuy Harris <[email protected]>
Sun, 30 Oct 2016 18:15:40 +0000 (11:15 -0700)
Have a routine to check for those addresses, and use it in all cases.

Have a #define for the length of the fixed part of those addresses at
the beginning, and use it.

Fix a length check; Coverity noted that the check never failed, because
we were comparing the length of the prefix field in the packet with the
length of the IPv4 prefix, not the length of the IPv4 prefix plus the
fixed part at the beginning.

print-hncp.c

index c4baec0e54f17e78a7210946895de29e3aa193a9..87ee8bbb9232e18d40cdca6efba4750e5bd5d7e2 100644 (file)
@@ -136,6 +136,25 @@ static const struct tok dh6opt_str[] = {
     { 0, NULL }
 };
 
     { 0, NULL }
 };
 
+/*
+ * For IPv4-mapped IPv6 addresses, length of the prefix that precedes
+ * the 4 bytes of IPv4 address at the end of the IPv6 address.
+ */
+#define IPV4_MAPPED_HEADING_LEN    12
+
+/*
+ * Is an IPv6 address an IPv4-mapped address?
+ */
+static inline int
+is_ipv4_mapped_address(const u_char *addr)
+{
+    /* The value of the prefix */
+    static const u_char ipv4_mapped_heading[IPV4_MAPPED_HEADING_LEN] =
+        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF };
+
+    return memcmp(addr, ipv4_mapped_heading, IPV4_MAPPED_HEADING_LEN) == 0;
+}
+
 static const char *
 format_nid(const u_char *data)
 {
 static const char *
 format_nid(const u_char *data)
 {
@@ -175,8 +194,8 @@ format_interval(const uint32_t n)
 static const char *
 format_ip6addr(netdissect_options *ndo, const u_char *cp)
 {
 static const char *
 format_ip6addr(netdissect_options *ndo, const u_char *cp)
 {
-    if (EXTRACT_64BITS(cp) == 0x0 && EXTRACT_32BITS(cp+8) == 0xffff)
-        return ipaddr_string(ndo, cp + 12);
+    if (is_ipv4_mapped_address(cp))
+        return ipaddr_string(ndo, cp + IPV4_MAPPED_HEADING_LEN);
     else
         return ip6addr_string(ndo, cp);
 }
     else
         return ip6addr_string(ndo, cp);
 }
@@ -186,11 +205,9 @@ print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length)
 {
     int plenbytes;
     char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::/128")];
 {
     int plenbytes;
     char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::/128")];
-    /* First 12 bytes of an IPv4-mapped IPv6 address */
-    static const u_char ipv4_mapped_heading[12] =
-        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF };
 
 
-    if (prefix[0] >= 96 && max_length >= 13 && memcmp(prefix+1, ipv4_mapped_heading, 12) == 0) {
+    if (prefix[0] >= 96 && max_length >= IPV4_MAPPED_HEADING_LEN + 1 &&
+        is_ipv4_mapped_address(&prefix[1])) {
         struct in_addr addr;
         u_int plen;
 
         struct in_addr addr;
         u_int plen;
 
@@ -201,15 +218,15 @@ print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length)
 
         memset(&addr, 0, sizeof(addr));
         plenbytes = (plen + 7) / 8;
 
         memset(&addr, 0, sizeof(addr));
         plenbytes = (plen + 7) / 8;
-        if (max_length < (u_int)plenbytes)
+        if (max_length < (u_int)plenbytes + IPV4_MAPPED_HEADING_LEN)
             return -3;
             return -3;
-        memcpy(&addr, &prefix[13], plenbytes);
+        memcpy(&addr, &prefix[1 + IPV4_MAPPED_HEADING_LEN], plenbytes);
         if (plen % 8) {
                ((u_char *)&addr)[plenbytes - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
        snprintf(buf, sizeof(buf), "%s/%d", ipaddr_string(ndo, &addr), plen);
         if (plen % 8) {
                ((u_char *)&addr)[plenbytes - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
        snprintf(buf, sizeof(buf), "%s/%d", ipaddr_string(ndo, &addr), plen);
-        plenbytes += 13;
+        plenbytes += 1 + IPV4_MAPPED_HEADING_LEN;
     } else {
         plenbytes = decode_prefix6(ndo, prefix, max_length, buf, sizeof(buf));
     }
     } else {
         plenbytes = decode_prefix6(ndo, prefix, max_length, buf, sizeof(buf));
     }