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


Reply via email to