On Thu, 2021-06-17 at 08:06 +0200, Martijn van Duren wrote:
> dlg@ asked me for an example output, so here it is:
> 07:52:52.326084 fe80::fce1:baff:fed2:8886.dhcpv6-client > 
> ff02::1:2.dhcpv6-server: [udp sum ok] DHCPv6 Solicit xid 0xdc0732
>         OPTION_CLIENTID: 00:01:00:01:28:5c:b7:1e:e8:6a:64:e8:d5:3f
>         OPTION_ELAPSED_TIME: 0.00s
>         OPTION_IA_PD: 000000000000000034e3ca60 [hlim 1] (len 52)
> 07:52:52.326916 fe80::fce1:bbff:fed1:8a39.15622 > 
> fe80::fce1:baff:fed2:8886.dhcpv6-client: [udp sum ok] DHCPv6 Advertise xid 
> 0xdc0732
>         OPTION_CLIENTID: 00:01:00:01:28:5c:b7:1e:e8:6a:64:e8:d5:3f
>         OPTION_SERVERID: 00:01:00:01:28:5c:b6:f1:fe:e1:bb:d1:8a:39
>         OPTION_IA_PD: 
> ffffffffffffffff001a0019ffffffffffffffff3020010db811110000000000000000000000000000
>  (len 93, hlim 64)
> 07:52:53.335961 fe80::fce1:baff:fed2:8886.dhcpv6-client > 
> ff02::1:2.dhcpv6-server: [udp sum ok] DHCPv6 Request xid 0xa1d03f
>         OPTION_CLIENTID: 00:01:00:01:28:5c:b7:1e:e8:6a:64:e8:d5:3f
>         OPTION_SERVERID: 00:01:00:01:28:5c:b6:f1:fe:e1:bb:d1:8a:39
>         OPTION_ELAPSED_TIME: 0.00s
>         OPTION_IA_PD: 
> 0000000000000000001a0019ffffffffffffffff3020010db8111100000000000000000000c135e3ca
>  [hlim 1] (len 99)
> 07:52:53.336899 fe80::fce1:bbff:fed1:8a39.15622 > 
> fe80::fce1:baff:fed2:8886.dhcpv6-client: [udp sum ok] DHCPv6 Reply xid 
> 0xa1d03f
>         OPTION_CLIENTID: 00:01:00:01:28:5c:b7:1e:e8:6a:64:e8:d5:3f
>         OPTION_SERVERID: 00:01:00:01:28:5c:b6:f1:fe:e1:bb:d1:8a:39
>         OPTION_IA_PD: 
> ffffffffffffffff001a0019ffffffffffffffff3020010db811110000000000000000000000000000
>  (len 93, hlim 64)
> 
> This contains both the pretty values as described below as well as the
> old format to which IA_PD falls back to. Also worth mentioning is that I
> choose this output for the duid, because it's simpler, it's what
> wide-dhcpv6 uses in it's configs and knowing how a UID is build up
> doesn't give us any useful information imho.
> 
> On Wed, 2021-06-16 at 17:03 +0200, Martijn van Duren wrote:
> > According to the last commit message to print-dhcp6.c by dlg:
> > if someone is interested in making this easier to read, it would
> > be a straightforward and  well contained project to better handle
> > option printing.
> > 
> > I'm playing around a little with dhcp6 and I heeded the call.
> > 
> > This diff does a few things:
> > - Extract the 24 bits as specified by the spec instead of stripping them
> >   inside the printf
> > - Add the defines of all the options inside RFC8415.  This one can be
> >   expanded by iana's official list[0], but that's too much for this
> >   diff.
> > - Print the human readable name of options, or print the numeric value
> >   if unknown.
> >   I also opted for the OPTION_* syntax, instead of the full name,
> >   because "Identity Association for Non-temporary Addresses" seemed a
> >   bit much and it keeps the code simpler.
> > - Pretty print the clientid, serverid, and elapsed_time options. In my
> >   minimal test setup these were the first ones to come by. Values of
> >   other options continue to be printed as they were and might follow if
> >   people are interested in this diff.
> > 
> > OK?
> > 
> > martijn@
> > 
> > [0] 
> > https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml
> > 
Found a type-O. Missing leading 0 when printing the xid.

martijn@

Index: print-dhcp6.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-dhcp6.c,v
retrieving revision 1.12
diff -u -p -r1.12 print-dhcp6.c
--- print-dhcp6.c       2 Dec 2019 22:07:20 -0000       1.12
+++ print-dhcp6.c       20 Jun 2021 08:07:06 -0000
@@ -49,10 +49,44 @@ struct rtentry;
 #define DH6_RELAY_FORW         12
 #define DH6_RELAY_REPL         13
 
+#define XIDLENGTH              3
+
+#define OPTION_CLIENTID                1
+#define OPTION_SERVERID                2
+#define OPTION_IA_NA           3
+#define OPTION_IA_TA           4
+#define OPTION_IAADDR          5
+#define OPTION_ORO             6
+#define OPTION_PREFERENCE      7
+#define OPTION_ELAPSED_TIME    8
+#define OPTION_RELAY_MSG       9
+#define OPTION_AUTH            11
+#define OPTION_UNICAST         12
+#define OPTION_STATUS_CODE     13
+#define OPTION_RAPID_COMMIT    14
+#define OPTION_USER_CLASS      15
+#define OPTION_VENDOR_CLASS    16
+#define OPTION_VENDOR_OPTS     17
+#define OPTION_INTERFACE_ID    18
+#define OPTION_RECONF_MSG      19
+#define OPTION_RECONF_ACCEPT   20
+#define OPTION_IA_PD           25
+#define OPTION_IAPREFIX                26
+#define OPTION_INFORMATION_REFRESH_TIME        32
+#define OPTION_SOL_MAX_RT      82
+#define OPTION_INF_MAX_RT      83
+
+#define CASEEXPAND(var, OPTION) \
+case OPTION:                   \
+       var = #OPTION;          \
+       break;
+
 static void
 dhcp6opt_print(const u_char *cp, u_int length)
 {
        uint16_t code, len;
+       const char *codename;
+       char codenameunknown[sizeof("OPTION (65535)")];
        u_int i;
        int l = snapend - cp;
 
@@ -77,22 +111,96 @@ dhcp6opt_print(const u_char *cp, u_int l
                length -= sizeof(len);
                l -= sizeof(len);
 
-               printf("\n\toption %u len %u", code, len);
+               switch (code) {
+               CASEEXPAND(codename, OPTION_CLIENTID)
+               CASEEXPAND(codename, OPTION_SERVERID)
+               CASEEXPAND(codename, OPTION_IA_NA)
+               CASEEXPAND(codename, OPTION_IA_TA)
+               CASEEXPAND(codename, OPTION_IAADDR)
+               CASEEXPAND(codename, OPTION_ORO)
+               CASEEXPAND(codename, OPTION_PREFERENCE)
+               CASEEXPAND(codename, OPTION_ELAPSED_TIME)
+               CASEEXPAND(codename, OPTION_RELAY_MSG)
+               CASEEXPAND(codename, OPTION_AUTH)
+               CASEEXPAND(codename, OPTION_UNICAST)
+               CASEEXPAND(codename, OPTION_STATUS_CODE)
+               CASEEXPAND(codename, OPTION_RAPID_COMMIT)
+               CASEEXPAND(codename, OPTION_USER_CLASS)
+               CASEEXPAND(codename, OPTION_VENDOR_CLASS)
+               CASEEXPAND(codename, OPTION_VENDOR_OPTS)
+               CASEEXPAND(codename, OPTION_INTERFACE_ID)
+               CASEEXPAND(codename, OPTION_RECONF_MSG)
+               CASEEXPAND(codename, OPTION_RECONF_ACCEPT)
+               CASEEXPAND(codename, OPTION_IA_PD)
+               CASEEXPAND(codename, OPTION_IAPREFIX)
+               CASEEXPAND(codename, OPTION_INFORMATION_REFRESH_TIME)
+               CASEEXPAND(codename, OPTION_SOL_MAX_RT)
+               CASEEXPAND(codename, OPTION_INF_MAX_RT)
+               default:
+                       snprintf(codenameunknown, sizeof(codenameunknown),
+                           "OPTION (%hd)", code);
+                       codename = codenameunknown;
+                       break;
+               }
 
-               if (len > 0) {
-                       if (l < len)
-                               goto trunc;
-                       if (length < len)
-                               goto iptrunc;
-
-                       printf(" ");
-                       for (i = 0; i < len; i++)
-                               printf("%02x", cp[4 + i] & 0xff);
-
-                       cp += len;
-                       length -= len;
-                       l -= len;
+               printf("\n\t%s", codename);
+
+               switch (code) {
+               case OPTION_CLIENTID:
+               case OPTION_SERVERID: {
+                       size_t i;
+
+                       for (i = 0; i < len; i++) {
+                               if (l == 0)
+                                       goto trunc;
+                               if (length == 0)
+                                       goto iptrunc;
+                               printf("%s%02hhx", i == 0 ? ": " : ":", cp[0]);
+                               cp++;
+                               l--;
+                               length--;
+                       }
+                       }
+                       break;
+               case OPTION_ELAPSED_TIME: {
+                       uint16_t time;
+
+                       if (len != 2) {
+                               printf(": Invalid value");
+                               goto badvalue;
+                       } else {
+                               if (l == 0)
+                                       goto trunc;
+                               if (length == 0)
+                                       goto iptrunc;
+                               time = EXTRACT_16BITS(cp);
+                               cp += 2;
+                               l -= 2;
+                               length -= 2;
+
+                               printf(": %d.%02ds", time/100, time % 100);
+                       }
+                       }
+                       break;
+               default:
+ badvalue:
+                       if (len > 0) {
+                               if (l < len)
+                                       goto trunc;
+                               if (length < len)
+                                       goto iptrunc;
+
+                               printf(": ");
+                               for (i = 0; i < len; i++)
+                                       printf("%02x", cp[4 + i] & 0xff);
+
+                               cp += len;
+                               length -= len;
+                               l -= len;
+                       }
+                       break;
                }
+
        }
        return;
 
@@ -127,7 +235,7 @@ void
 dhcp6_print(const u_char *cp, u_int length)
 {
        uint8_t msgtype;
-       uint32_t hdr;
+       uint32_t xid;
        int l = snapend - cp;
        const char *msgname;
 
@@ -184,18 +292,21 @@ dhcp6_print(const u_char *cp, u_int leng
        }
 
        printf(" %s", msgname);
+       cp++;
+       length--;
+       l--;
 
-       if (l < sizeof(hdr))
+       if (l < XIDLENGTH)
                goto trunc;
-       if (length < sizeof(hdr))
+       if (length < XIDLENGTH)
                goto iptrunc;
 
-       hdr = EXTRACT_32BITS(cp);
-       printf(" xid %x", hdr & 0xffffff);
+       xid = EXTRACT_24BITS(cp);
+       printf(" xid 0x%06x", xid);
 
        if (vflag) {
-               cp += sizeof(hdr);
-               length -= sizeof(hdr);
+               cp += XIDLENGTH;
+               length -= XIDLENGTH;
 
                dhcp6opt_print(cp, length);
        }


Reply via email to