]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-bootp.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print-bootp.c
index e06943cba913291aaf3545364a349611b71f558b..0e47ef508f61c8f304056c415cea8ef8f078235e 100644 (file)
@@ -21,9 +21,7 @@
 
 /* \summary: BOOTP and IPv4 DHCP printer */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include "netdissect-stdinc.h"
 
@@ -181,10 +179,12 @@ struct bootp {
 /* RFC 2485 */
 #define        TAG_OPEN_GROUP_UAP      ((uint8_t)  98)
 /* RFC 2563 */
-#define        TAG_DISABLE_AUTOCONF    ((uint8_t) 116)
+#define        TAG_AUTO_CONFIGURE      ((uint8_t) 116)
 /* RFC 2610 */
 #define        TAG_SLP_DA              ((uint8_t)  78)
 #define        TAG_SLP_SCOPE           ((uint8_t)  79)
+/* RFC 8925 */
+#define TAG_IPV6_ONLY_PREFERRED        ((uint8_t) 108)
 /* RFC 2937 */
 #define        TAG_NS_SEARCH           ((uint8_t) 117)
 /* RFC 3004 - The User Class Option for DHCP */
@@ -403,9 +403,9 @@ invalid:
  * The first character specifies the format to print:
  *     i - ip address (32 bits)
  *     p - ip address pairs (32 bits + 32 bits)
- *     l - long (32 bits)
- *     L - unsigned long (32 bits)
- *     s - short (16 bits)
+ *     l - unsigned longs (32 bits)
+ *     L - longs (32 bits)
+ *     s - unsigned shorts (16 bits)
  *     b - period-separated decimal bytes (variable length)
  *     x - colon-separated hex bytes (variable length)
  *     a - ASCII string (variable length)
@@ -495,7 +495,7 @@ static const struct tok tag2str[] = {
 /* RFC 2485 */
        { TAG_OPEN_GROUP_UAP,   "aUAP" },
 /* RFC 2563 */
-       { TAG_DISABLE_AUTOCONF, "BNOAUTO" },
+       { TAG_AUTO_CONFIGURE,   "BAuto-Configure" },
 /* RFC 2610 */
        { TAG_SLP_DA,           "bSLP-DA" },    /*"b" is a little wrong */
        { TAG_SLP_SCOPE,        "bSLP-SCOPE" }, /*"b" is a little wrong */
@@ -520,7 +520,7 @@ static const struct tok tag2str[] = {
        { TAG_TZ_STRING,        "aTZSTR" },
        { TAG_FQDN_OPTION,      "bFQDNS" },     /* XXX 'b' */
        { TAG_AUTH,             "bAUTH" },      /* XXX 'b' */
-       { TAG_CLIENT_LAST_TRANSACTION_TIME, "LLast-Transaction-Time" },
+       { TAG_CLIENT_LAST_TRANSACTION_TIME, "lLast-Transaction-Time" },
        { TAG_ASSOCIATED_IP,    "iAssociated-IP" },
        { TAG_CLIENT_ARCH,      "sARCH" },
        { TAG_CLIENT_NDI,       "bNDI" },       /* XXX 'b' */
@@ -532,6 +532,7 @@ static const struct tok tag2str[] = {
        { TAG_NETINFO_PARENT_TAG, "aNITAG" },
        { TAG_URL,              "aURL" },
        { TAG_MUDURL,           "aMUD-URL" },
+       { TAG_IPV6_ONLY_PREFERRED, "$IPv6-Only-Preferred" },
        { 0, NULL }
 };
 
@@ -709,6 +710,14 @@ rfc1048_print(netdissect_options *ndo,
 
                case 'p':
                        /* IP address pairs */
+                       /* this option should be N x 8 bytes long */
+                       if (len < 8 || len % 8 != 0) {
+                               ND_PRINT("%s[length != N x 8 bytes]",
+                                        len == 0 ? " " : "");
+                               bp += len;
+                               len = 0;
+                               break;
+                       }
                        while (len >= 2*4) {
                                if (!first)
                                        ND_PRINT(",");
@@ -723,7 +732,7 @@ rfc1048_print(netdissect_options *ndo,
                        break;
 
                case 's':
-                       /* shorts */
+                       /* unsigned shorts */
                        while (len >= 2) {
                                if (!first)
                                        ND_PRINT(",");
@@ -736,27 +745,33 @@ rfc1048_print(netdissect_options *ndo,
 
                case 'B':
                        /* boolean */
-                       while (len != 0) {
-                               uint8_t bool_value;
-                               if (!first)
-                                       ND_PRINT(",");
-                               bool_value = GET_U_1(bp);
-                               switch (bool_value) {
-                               case 0:
-                                       ND_PRINT("N");
-                                       break;
-                               case 1:
-                                       ND_PRINT("Y");
-                                       break;
-                               default:
-                                       ND_PRINT("%u?", bool_value);
-                                       break;
-                               }
-                               ++bp;
-                               --len;
-                               first = 0;
+                   {
+                       /* this option should be 1 byte long */
+                       if (len != 1) {
+                               ND_PRINT("[length != 1 byte]");
+                               nd_print_invalid(ndo);
+                               bp += len;
+                               len = 0;
+                               break;
                        }
+
+                       uint8_t bool_value;
+                       bool_value = GET_U_1(bp);
+                       switch (bool_value) {
+                       case 0:
+                               ND_PRINT("N");
+                               break;
+                       case 1:
+                               ND_PRINT("Y");
+                               break;
+                       default:
+                               ND_PRINT("%u?", bool_value);
+                               break;
+                       }
+                       ++bp;
+                       --len;
                        break;
+                   }
 
                case 'b':
                case 'x':
@@ -784,7 +799,8 @@ rfc1048_print(netdissect_options *ndo,
                        case TAG_NETBIOS_NODE:
                                /* this option should be at least 1 byte long */
                                if (len < 1) {
-                                       ND_PRINT("[ERROR: length < 1 bytes]");
+                                       ND_PRINT("[length < 1 byte]");
+                                       nd_print_invalid(ndo);
                                        break;
                                }
                                tag = GET_U_1(bp);
@@ -796,7 +812,8 @@ rfc1048_print(netdissect_options *ndo,
                        case TAG_OPT_OVERLOAD:
                                /* this option should be at least 1 byte long */
                                if (len < 1) {
-                                       ND_PRINT("[ERROR: length < 1 bytes]");
+                                       ND_PRINT("[length < 1 byte]");
+                                       nd_print_invalid(ndo);
                                        break;
                                }
                                tag = GET_U_1(bp);
@@ -808,14 +825,16 @@ rfc1048_print(netdissect_options *ndo,
                        case TAG_CLIENT_FQDN:
                                /* this option should be at least 3 bytes long */
                                if (len < 3) {
-                                       ND_PRINT("[ERROR: length < 3 bytes]");
+                                       ND_PRINT("[length < 3 bytes]");
+                                       nd_print_invalid(ndo);
                                        bp += len;
                                        len = 0;
                                        break;
                                }
                                if (GET_U_1(bp) & 0xf0) {
-                                       ND_PRINT("[ERROR: MBZ nibble 0x%x != 0] ",
+                                       ND_PRINT("[MBZ nibble 0x%x != 0] ",
                                                 (GET_U_1(bp) & 0xf0) >> 4);
+                                       nd_print_invalid(ndo);
                                }
                                if (GET_U_1(bp) & 0x0f)
                                        ND_PRINT("[%s] ",
@@ -838,7 +857,8 @@ rfc1048_print(netdissect_options *ndo,
 
                                /* this option should be at least 1 byte long */
                                if (len < 1) {
-                                       ND_PRINT("[ERROR: length < 1 bytes]");
+                                       ND_PRINT("[length < 1 byte]");
+                                       nd_print_invalid(ndo);
                                        break;
                                }
                                type = GET_U_1(bp);
@@ -908,7 +928,8 @@ rfc1048_print(netdissect_options *ndo,
 
                                /* this option should be at least 5 bytes long */
                                if (len < 5) {
-                                       ND_PRINT("[ERROR: length < 5 bytes]");
+                                       ND_PRINT("[length < 5 bytes]");
+                                       nd_print_invalid(ndo);
                                        bp += len;
                                        len = 0;
                                        break;
@@ -921,7 +942,8 @@ rfc1048_print(netdissect_options *ndo,
                                        len--;
                                        /* mask_width <= 32 */
                                        if (mask_width > 32) {
-                                               ND_PRINT("[ERROR: Mask width (%u) > 32]", mask_width);
+                                               ND_PRINT("[Mask width (%u) > 32]", mask_width);
+                                               nd_print_invalid(ndo);
                                                bp += len;
                                                len = 0;
                                                break;
@@ -929,7 +951,8 @@ rfc1048_print(netdissect_options *ndo,
                                        significant_octets = (mask_width + 7) / 8;
                                        /* significant octets + router(4) */
                                        if (len < significant_octets + 4) {
-                                               ND_PRINT("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4);
+                                               ND_PRINT("[Remaining length (%u) < %u bytes]", len, significant_octets + 4);
+                                               nd_print_invalid(ndo);
                                                bp += len;
                                                len = 0;
                                                break;
@@ -963,7 +986,8 @@ rfc1048_print(netdissect_options *ndo,
 
                                first = 1;
                                if (len < 2) {
-                                       ND_PRINT("[ERROR: length < 2 bytes]");
+                                       ND_PRINT("[length < 2 bytes]");
+                                       nd_print_invalid(ndo);
                                        bp += len;
                                        len = 0;
                                        break;
@@ -975,13 +999,16 @@ rfc1048_print(netdissect_options *ndo,
                                        ND_PRINT("\n\t      ");
                                        ND_PRINT("instance#%u: ", suboptnumber);
                                        if (suboptlen == 0) {
-                                               ND_PRINT("[ERROR: suboption length must be non-zero]");
+                                               ND_PRINT("[suboption length == 0]");
+                                               nd_print_invalid(ndo);
                                                bp += len;
                                                len = 0;
                                                break;
                                        }
                                        if (len < suboptlen) {
-                                               ND_PRINT("[ERROR: invalid option]");
+                                               ND_PRINT("[length %u < suboption length %u",
+                                                        len, suboptlen);
+                                               nd_print_invalid(ndo);
                                                bp += len;
                                                len = 0;
                                                break;
@@ -1008,26 +1035,42 @@ rfc1048_print(netdissect_options *ndo,
                                 * URI: URI of the SZTP bootstrap server.
                                 */
                                while (len >= 2) {
-                                       suboptlen = GET_BE_U_2(bp);
+                                       uint16_t suboptlen2;
+
+                                       suboptlen2 = GET_BE_U_2(bp);
                                        bp += 2;
                                        len -= 2;
                                        ND_PRINT("\n\t      ");
-                                       ND_PRINT("length %u: ", suboptlen);
-                                       if (len < suboptlen) {
+                                       ND_PRINT("length %u: ", suboptlen2);
+                                       if (len < suboptlen2) {
                                                ND_PRINT("length goes past end of option");
                                                bp += len;
                                                len = 0;
                                                break;
                                        }
                                        ND_PRINT("\"");
-                                       nd_printjn(ndo, bp, suboptlen);
+                                       nd_printjn(ndo, bp, suboptlen2);
                                        ND_PRINT("\"");
-                                       len -= suboptlen;
-                                       bp += suboptlen;
+                                       len -= suboptlen2;
+                                       bp += suboptlen2;
                                }
                                if (len != 0) {
-                                       ND_PRINT("[ERROR: length < 2 bytes]");
+                                       ND_PRINT("[length < 2 bytes]");
+                                       nd_print_invalid(ndo);
+                               }
+                               break;
+
+                       case TAG_IPV6_ONLY_PREFERRED:
+                               /* this option should be 4 bytes long */
+                               if (len != 4) {
+                                       ND_PRINT("[length != 4 bytes]");
+                                       nd_print_invalid(ndo);
+                                       bp += len;
+                                       len = 0;
                                }
+                               ND_PRINT("%u", GET_BE_U_4(bp));
+                               bp += 4;
+                               len -= 4;
                                break;
 
                        default: