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); }