ICMPv6: Recognise ND option 14 (Nonce)

This option has been observed to be included in neighbour solicitations
sent by Linux kernel when `conf/*/enhanced_dad` is enabled on the
relevant network interface. It looks like it appeared in the linked
kernel commit.

In accordance with RFC 7527, a nonce can help distinguish valid DAD NS
messages in the presence of Ethernet loopbacks: after a DAD probe is
sent on the network, if an NS is received with the same nonce it is
considered looped back and ignored.

We implement the printer for this option and add a simple test with 3
different verbosity levels.

Link: adc176c547
Link: https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-5
This commit is contained in:
Arseny Maslennikov 2023-12-04 14:44:55 +03:00
parent f9ea99305f
commit cb9fe0977a
6 changed files with 27 additions and 0 deletions

View File

@ -283,6 +283,7 @@ struct nd_opt_hdr { /* Neighbor discovery option header */
#define ND_OPT_MTU 5
#define ND_OPT_ADVINTERVAL 7
#define ND_OPT_HOMEAGENT_INFO 8
#define ND_OPT_NONCE 14
#define ND_OPT_ROUTE_INFO 24 /* RFC4191 */
#define ND_OPT_RDNSS 25
#define ND_OPT_DNSSL 31
@ -712,6 +713,7 @@ static const struct tok icmp6_opt_values[] = {
{ ND_OPT_DNSSL, "dnssl"},
{ ND_OPT_ADVINTERVAL, "advertisement interval"},
{ ND_OPT_HOMEAGENT_INFO, "homeagent information"},
{ ND_OPT_NONCE, "nonce"},
{ ND_OPT_ROUTE_INFO, "route info"},
{ 0, NULL }
};
@ -753,6 +755,18 @@ get_lifetime(uint32_t v)
}
}
static void
print_opaque_data(netdissect_options *ndo, const uint8_t *p, size_t l)
{
if (l > 0)
ND_PRINT("0x");
while (l > 0) {
ND_PRINT("%02x", GET_U_1(p));
p++;
l--;
}
}
static void
print_lladdr(netdissect_options *ndo, const uint8_t *p, size_t l)
{
@ -1473,6 +1487,10 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid)
GET_BE_U_2(oph->nd_opt_hai_preference),
GET_BE_U_2(oph->nd_opt_hai_lifetime));
break;
case ND_OPT_NONCE:
l = (opt_len << 3) - 2;
print_opaque_data(ndo, cp + 2, l);
break;
case ND_OPT_ROUTE_INFO:
opri = (const struct nd_opt_route_info *)op;
ND_TCHECK_4(opri->nd_opt_rti_lifetime);

View File

@ -230,6 +230,9 @@ icmpv6-rfc7112 icmpv6-rfc7112.pcap icmpv6-rfc7112.out
icmpv6-RFC2894-RR icmpv6-RFC2894-RR.pcap icmpv6-RFC2894-RR.out
icmpv6-RFC2894-RR-v icmpv6-RFC2894-RR.pcap icmpv6-RFC2894-RR-v.out -v
icmpv6-ni-flags icmpv6-ni-flags.pcap icmpv6-ni-flags.out
icmpv6-ns-nonce-v0 icmpv6-ns-nonce.pcap icmpv6-ns-nonce-v0.out
icmpv6-ns-nonce-v1 icmpv6-ns-nonce.pcap icmpv6-ns-nonce-v1.out -v
icmpv6-ns-nonce-v2 icmpv6-ns-nonce.pcap icmpv6-ns-nonce-v2.out -vv
# SPB tests
spb spb.pcap spb.out

View File

@ -0,0 +1 @@
1 11:07:31.663323 IP6 :: > ff02::1:ffe1:f: ICMP6, neighbor solicitation, who has fe80::546f:f7ff:fee1:f, length 32

View File

@ -0,0 +1,2 @@
1 11:07:31.663323 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) :: > ff02::1:ffe1:f: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::546f:f7ff:fee1:f
nonce option (14), length 8 (1): 0x6069604c0aaa

View File

@ -0,0 +1,3 @@
1 11:07:31.663323 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) :: > ff02::1:ffe1:f: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::546f:f7ff:fee1:f
nonce option (14), length 8 (1): 0x6069604c0aaa
0x0000: 6069 604c 0aaa

BIN
tests/icmpv6-ns-nonce.pcap Normal file

Binary file not shown.