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
>
> 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 16 Jun 2021 14:55:42 -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%6x", xid);
>
> if (vflag) {
> - cp += sizeof(hdr);
> - length -= sizeof(hdr);
> + cp += XIDLENGTH;
> + length -= XIDLENGTH;
>
> dhcp6opt_print(cp, length);
> }
>
>