]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-dhcp6.c
CHANGES: Add/move change(s) backported to 4.99
[tcpdump] / print-dhcp6.c
index 590b9c50edf5bb021c2406ca64660fdb54d149b0..c196ad7497f3e95d493960bf5b1c1ea4748fb873 100644 (file)
  *  RFC6334: Dual-Stack Lite option,
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include "netdissect-stdinc.h"
 
-#include <stdio.h>
-#include <string.h>
-
 #include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
@@ -124,6 +119,10 @@ struct dhcp6_relay {
 /* options */
 #define DH6OPT_CLIENTID        1
 #define DH6OPT_SERVERID        2
+#  define DUID_LLT  1 /* RFC8415 */
+#  define DUID_EN   2 /* RFC8415 */
+#  define DUID_LL   3 /* RFC8415 */
+#  define DUID_UUID 4 /* RFC6355 */
 #define DH6OPT_IA_NA 3
 #define DH6OPT_IA_TA 4
 #define DH6OPT_IA_ADDR 5
@@ -191,8 +190,10 @@ struct dhcp6_relay {
 #  define DH6OPT_NTP_SUBOPTION_SRV_ADDR 1
 #  define DH6OPT_NTP_SUBOPTION_MC_ADDR 2
 #  define DH6OPT_NTP_SUBOPTION_SRV_FQDN 3
+#define DH6OPT_BOOTFILE_URL 59    /* RFC5970 */
 #define DH6OPT_AFTR_NAME 64
 #define DH6OPT_MUDURL 112
+#define DH6OPT_SZTP_REDIRECT 136  /* RFC8572 */
 
 static const struct tok dh6opt_str[] = {
        { DH6OPT_CLIENTID,           "client-ID"            },
@@ -242,8 +243,10 @@ static const struct tok dh6opt_str[] = {
        { DH6OPT_LQ_RELAY_DATA,      "LQ-relay-data"        },
        { DH6OPT_LQ_CLIENT_LINK,     "LQ-client-link"       },
        { DH6OPT_NTP_SERVER,         "NTP-server"           },
+       { DH6OPT_BOOTFILE_URL,       "Bootfile-URL"         },
        { DH6OPT_AFTR_NAME,          "AFTR-Name"            },
        { DH6OPT_MUDURL,             "MUD-URL"              },
+       { DH6OPT_SZTP_REDIRECT,      "SZTP-redirect"        },
        { 0, NULL }
 };
 
@@ -293,6 +296,8 @@ dhcp6opt_print(netdissect_options *ndo,
        uint16_t subopt_len;
        uint8_t dh6_reconf_type;
        uint8_t dh6_lq_query_type;
+       u_int first_list_value;
+       uint16_t remainder_len;
 
        if (cp == ep)
                return;
@@ -317,7 +322,7 @@ dhcp6opt_print(netdissect_options *ndo,
                        }
                        tp = (const u_char *)(dh6o + 1);
                        switch (GET_BE_U_2(tp)) {
-                       case 1:
+                       case DUID_LLT:
                                if (optlen >= 2 + 6) {
                                        ND_PRINT(" hwaddr/time type %u time %u ",
                                            GET_BE_U_2(tp + 2),
@@ -332,10 +337,10 @@ dhcp6opt_print(netdissect_options *ndo,
                                        ND_PRINT(" ?)");
                                }
                                break;
-                       case 2:
-                               if (optlen >= 2 + 8) {
-                                       ND_PRINT(" vid ");
-                                       for (i = 2; i < 2 + 8; i++)
+                       case DUID_EN:
+                               if (optlen >= 2 + 4) {
+                                       ND_PRINT(" enterprise %u ", GET_BE_U_4(tp + 2));
+                                       for (i = 2 + 4; i < optlen; i++)
                                                ND_PRINT("%02x",
                                                         GET_U_1(tp + i));
                                        /*(*/
@@ -345,7 +350,7 @@ dhcp6opt_print(netdissect_options *ndo,
                                        ND_PRINT(" ?)");
                                }
                                break;
-                       case 3:
+                       case DUID_LL:
                                if (optlen >= 2 + 2) {
                                        ND_PRINT(" hwaddr type %u ",
                                            GET_BE_U_2(tp + 2));
@@ -359,6 +364,19 @@ dhcp6opt_print(netdissect_options *ndo,
                                        ND_PRINT(" ?)");
                                }
                                break;
+                       case DUID_UUID:
+                               ND_PRINT(" uuid ");
+                               if (optlen == 2 + 16) {
+                                       for (i = 2; i < optlen; i++)
+                                               ND_PRINT("%02x",
+                                                        GET_U_1(tp + i));
+                                       /*(*/
+                                       ND_PRINT(")");
+                               } else {
+                                       /*(*/
+                                       ND_PRINT(" ?)");
+                               }
+                               break;
                        default:
                                ND_PRINT(" type %u)", GET_BE_U_2(tp));
                                break;
@@ -371,7 +389,7 @@ dhcp6opt_print(netdissect_options *ndo,
                                break;
                        }
                        tp = (const u_char *)(dh6o + 1);
-                       ND_PRINT(" %s", ip6addr_string(ndo, tp));
+                       ND_PRINT(" %s", GET_IP6ADDR_STRING(tp));
                        ND_PRINT(" pltime:%u vltime:%u",
                            GET_BE_U_4(tp + 16),
                            GET_BE_U_4(tp + 20));
@@ -411,11 +429,26 @@ dhcp6opt_print(netdissect_options *ndo,
                        ND_PRINT(" %u)", GET_BE_U_2(tp));
                        break;
                case DH6OPT_RELAY_MSG:
+                   {
+                       const u_char *snapend_save;
+
                        ND_PRINT(" (");
                        tp = (const u_char *)(dh6o + 1);
+                       /*
+                        * Update the snapend to the end of the option before
+                        * calling recursively dhcp6_print() for the nested
+                        * packet. Other options may be present after the
+                        * nested DHCPv6 packet. This prevents that, in
+                        * dhcp6_print(), for the nested DHCPv6 packet, the
+                        * remaining length < remaining caplen.
+                        */
+                       snapend_save = ndo->ndo_snapend;
+                       ndo->ndo_snapend = ND_MIN(tp + optlen, ndo->ndo_snapend);
                        dhcp6_print(ndo, tp, optlen);
+                       ndo->ndo_snapend = snapend_save;
                        ND_PRINT(")");
                        break;
+                   }
                case DH6OPT_AUTH:
                        if (optlen < 11) {
                                ND_PRINT(" ?)");
@@ -561,7 +594,7 @@ dhcp6opt_print(netdissect_options *ndo,
                        }
                        tp = (const u_char *)(dh6o + 1);
                        for (i = 0; i < optlen; i += 16)
-                               ND_PRINT(" %s", ip6addr_string(ndo, tp + i));
+                               ND_PRINT(" %s", GET_IP6ADDR_STRING(tp + i));
                        ND_PRINT(")");
                        break;
                case DH6OPT_SIP_SERVER_D:
@@ -618,7 +651,7 @@ dhcp6opt_print(netdissect_options *ndo,
                                break;
                        }
                        tp = (const u_char *)(dh6o + 1);
-                       ND_PRINT(" %s/%u", ip6addr_string(ndo, tp + 9),
+                       ND_PRINT(" %s/%u", GET_IP6ADDR_STRING(tp + 9),
                                 GET_U_1(tp + 8));
                        ND_PRINT(" pltime:%u vltime:%u",
                            GET_BE_U_4(tp),
@@ -670,7 +703,7 @@ dhcp6opt_print(netdissect_options *ndo,
                                ND_PRINT(" type_%u", dh6_lq_query_type);
                                break;
                        }
-                       ND_PRINT(" %s", ip6addr_string(ndo, tp + 1));
+                       ND_PRINT(" %s", GET_IP6ADDR_STRING(tp + 1));
                        if (optlen > 17) {
                                /* there are query-options */
                                dhcp6opt_print(ndo, tp + 17, tp + optlen);
@@ -691,7 +724,7 @@ dhcp6opt_print(netdissect_options *ndo,
                                break;
                        }
                        tp = (const u_char *)(dh6o + 1);
-                       ND_PRINT(" %s ", ip6addr_string(ndo, tp));
+                       ND_PRINT(" %s ", GET_IP6ADDR_STRING(tp));
                        /*
                         * Print hex dump first 10 characters.
                         */
@@ -720,7 +753,7 @@ dhcp6opt_print(netdissect_options *ndo,
                                                ND_PRINT(" ?");
                                                break;
                                        }
-                                       ND_PRINT(" %s", ip6addr_string(ndo, tp));
+                                       ND_PRINT(" %s", GET_IP6ADDR_STRING(tp));
                                        break;
                                case DH6OPT_NTP_SUBOPTION_SRV_FQDN:
                                        ND_PRINT(" ");
@@ -748,7 +781,7 @@ dhcp6opt_print(netdissect_options *ndo,
                                label_len = GET_U_1(tp);
                                tp++;
                                if (label_len < remain_len - 1) {
-                                       (void)nd_printn(ndo, tp, label_len, NULL);
+                                       nd_printjnp(ndo, tp, label_len);
                                        tp += label_len;
                                        remain_len -= (label_len + 1);
                                        if(GET_U_1(tp)) ND_PRINT(".");
@@ -767,8 +800,41 @@ dhcp6opt_print(netdissect_options *ndo,
                                break;
                        }
                        tp = (const u_char *)(dh6o + 1);
-                       ND_PRINT("=");
-                       (void)nd_printn(ndo, tp, (u_int)optlen, NULL);
+                       ND_PRINT(" ");
+                       nd_printjnp(ndo, tp, optlen);
+                       ND_PRINT(")");
+                       break;
+
+               case DH6OPT_BOOTFILE_URL:
+                       tp = (const u_char *)(dh6o + 1);
+                       ND_PRINT(" ");
+                       nd_printjn(ndo, tp, optlen);
+                       ND_PRINT(")");
+                       break;
+
+               case DH6OPT_SZTP_REDIRECT:
+               case DH6OPT_USER_CLASS:
+                       ND_PRINT(" ");
+                       tp = (const u_char *)(dh6o + 1);
+                       first_list_value = TRUE;
+                       remainder_len = optlen;
+                       while (remainder_len >= 2) {
+                               if (first_list_value == FALSE) {
+                                       ND_PRINT(",");
+                               }
+                               first_list_value = FALSE;
+                               subopt_len = GET_BE_U_2(tp);
+                               if (subopt_len > remainder_len-2) {
+                                       break;
+                               }
+                               tp += 2;
+                               nd_printjn(ndo, tp, subopt_len);
+                               tp += subopt_len;
+                               remainder_len -= (subopt_len+2);
+                       }
+                       if (remainder_len != 0 ) {
+                               ND_PRINT(" ?");
+                       }
                        ND_PRINT(")");
                        break;
 
@@ -826,11 +892,9 @@ dhcp6_print(netdissect_options *ndo,
                extp = (const u_char *)(dh6 + 1);
                dhcp6opt_print(ndo, extp, ep);
        } else {                /* relay messages */
-               ND_TCHECK_16(dh6relay->dh6relay_peeraddr);
-
-               ND_PRINT("linkaddr=%s", ip6addr_string(ndo, dh6relay->dh6relay_linkaddr));
+               ND_PRINT("linkaddr=%s", GET_IP6ADDR_STRING(dh6relay->dh6relay_linkaddr));
 
-               ND_PRINT(" peeraddr=%s", ip6addr_string(ndo, dh6relay->dh6relay_peeraddr));
+               ND_PRINT(" peeraddr=%s", GET_IP6ADDR_STRING(dh6relay->dh6relay_peeraddr));
 
                dhcp6opt_print(ndo, (const u_char *)(dh6relay + 1), ep);
        }