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