This diff adds support for some more ND options to tcpdump: printing
v6 nameserver addresses from RDNSS options, and basic support to print
the option name (rather than just "unknown opt_type=XX") for DNSSL
and RFC4191 route information (no full printer for these yet - for
DNSSL the domain names are sent with DNS-encoding so it could do with
ns_nprint() being exposed).

Any comments/OKs?

sample rtadvd.conf to include some data that will be handled by this:

default:\
        :rdnss="2001:4860:4860::8888,2001:4860:4860::8844":\
        :dnssl="openbsd.org"
vlan2:tc=default
vlan3:tc=default


Index: print-icmp6.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-icmp6.c,v
retrieving revision 1.15
diff -u -p -r1.15 print-icmp6.c
--- print-icmp6.c       16 Jan 2015 06:40:21 -0000      1.15
+++ print-icmp6.c       2 Nov 2015 16:53:44 -0000
@@ -511,8 +511,9 @@ icmp6_opt_print(register const u_char *b
        register const struct nd_opt_prefix_info *opp;
        register const struct icmp6_opts_redirect *opr;
        register const struct nd_opt_mtu *opm;
+       register const struct nd_opt_rdnss *oprd;
        register const u_char *ep;
-       int     opts_len;
+       int     i, opts_len;
 #if 0
        register const struct ip6_hdr *ip;
        register const char *str;
@@ -623,6 +624,34 @@ icmp6_opt_print(register const u_char *b
                if (opm->nd_opt_mtu_len != 1)
                        printf("!");
                printf(")");
+               icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3),
+                               resid - (op->nd_opt_len << 3));
+               break;
+       case ND_OPT_ROUTE_INFO:
+               printf("(route-info: opt_len=%d)", op->nd_opt_len);
+               icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3),
+                               resid - (op->nd_opt_len << 3));
+               break;
+       case ND_OPT_RDNSS:
+               oprd = (const struct nd_opt_rdnss *)op;
+               printf("(rdnss: ");
+               TCHECK(oprd->nd_opt_rdnss_lifetime);
+               printf("lifetime=%us",
+                   (u_int32_t)ntohl(oprd->nd_opt_rdnss_lifetime));
+               if (oprd->nd_opt_rdnss_len < 3) {
+                       printf("!");
+               } else for (i = 0; i < ((oprd->nd_opt_rdnss_len - 1) / 2); i++) 
{
+                       struct in6_addr *addr = (struct in6_addr *)(oprd + 1) + 
i;
+                       TCHECK2(*addr, sizeof(struct in6_addr));
+                       printf(", addr=%s", ip6addr_string(addr));
+               }
+               printf(")");
+               icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3),
+                               resid - (op->nd_opt_len << 3));
+               break;
+       case ND_OPT_DNSSL:
+               printf("(dnssl: opt_len=%d)", op->nd_opt_len);
+               /* XXX */
                icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3),
                                resid - (op->nd_opt_len << 3));
                break;

Reply via email to