Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICMPv6: Recognise ND option 38 (PREF64) #1109

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions print-icmp6.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ struct nd_opt_hdr { /* Neighbor discovery option header */
#define ND_OPT_ROUTE_INFO 24 /* RFC4191 */
#define ND_OPT_RDNSS 25
#define ND_OPT_DNSSL 31
#define ND_OPT_PREF64_INFORMATION 38 /* RFC8781 */

struct nd_opt_prefix_info { /* prefix information */
nd_uint8_t nd_opt_pi_type;
Expand Down Expand Up @@ -357,6 +358,13 @@ struct nd_opt_route_info { /* route info */
/* prefix follows */
};

struct nd_opt_pref64 { /* PREF64 option */
nd_uint8_t nd_opt_pref64_type;
nd_uint8_t nd_opt_pref64_len;
nd_uint16_t nd_opt_pref64_slplc; /* 13bit lft + 3bit PLC */
nd_uint32_t nd_opt_pref64_words[3]; /* highest 96 bits of prefix */
};

/*
* icmp6 namelookup
*/
Expand Down Expand Up @@ -475,6 +483,8 @@ struct rr_result { /* router renumbering result message */

static const char *get_rtpref(u_int);
static const char *get_lifetime(uint32_t);
static const char *get_pref64_lifetime(uint16_t);
static const char *get_pref64_len_repr(uint16_t);
static void print_lladdr(netdissect_options *ndo, const u_char *, size_t);
static int icmp6_opt_print(netdissect_options *ndo, const u_char *, int);
static void mld6_print(netdissect_options *ndo, const u_char *);
Expand Down Expand Up @@ -713,6 +723,7 @@ static const struct tok icmp6_opt_values[] = {
{ ND_OPT_ADVINTERVAL, "advertisement interval"},
{ ND_OPT_HOMEAGENT_INFO, "homeagent information"},
{ ND_OPT_ROUTE_INFO, "route info"},
{ ND_OPT_PREF64_INFORMATION, "pref64 info"},
{ 0, NULL }
};

Expand Down Expand Up @@ -753,6 +764,30 @@ get_lifetime(uint32_t v)
}
}

static const char *
get_pref64_lifetime(uint16_t v)
{
static char buf[12];

snprintf(buf, sizeof(buf), "%us", v & 0xfff8);
return buf;
}

static const char *
get_pref64_len_repr(uint16_t v)
{
const char *prefixlen_strunk = "??";
static const char *prefixlen_str[] = {
"96", "64", "56", "48", "40", "32"
};

v = v & 0x0007;
if (v < 6)
return prefixlen_str[v];
else
return prefixlen_strunk;
}

static void
print_lladdr(netdissect_options *ndo, const uint8_t *p, size_t l)
{
Expand Down Expand Up @@ -1383,10 +1418,12 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid)
const struct nd_opt_advinterval *opa;
const struct nd_opt_homeagent_info *oph;
const struct nd_opt_route_info *opri;
const struct nd_opt_pref64 *op64;
const u_char *cp, *ep, *domp;
nd_ipv6 in6;
size_t l;
u_int i;
uint16_t w;

cp = bp;
/* 'ep' points to the end of available data. */
Expand Down Expand Up @@ -1496,6 +1533,20 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid)
ND_PRINT(", lifetime=%s",
get_lifetime(GET_BE_U_4(opri->nd_opt_rti_lifetime)));
break;
case ND_OPT_PREF64_INFORMATION:
op64 = (const struct nd_opt_pref64 *)op;
if (opt_len != 2)
ND_PRINT("%s", "bad option length! ");
w = GET_BE_U_2(op64->nd_opt_pref64_slplc);
memset(&in6, 0, sizeof(in6));
GET_CPY_BYTES(&in6, op64->nd_opt_pref64_words,
sizeof(op64->nd_opt_pref64_words));
ND_PRINT("%s/%s (plc %u)",
ip6addr_string(ndo, (const u_char *)&in6),
get_pref64_len_repr(w),
w & 7);
ND_PRINT(", lifetime %s", get_pref64_lifetime(w));
break;
default:
if (ndo->ndo_vflag <= 1) {
print_unknown_data(ndo,cp+2,"\n\t ", (opt_len << 3) - 2); /* skip option header */
Expand Down
2 changes: 2 additions & 0 deletions tests/TESTLIST
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ 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-ra-pref64-v1 icmpv6-ra-pref64.pcap icmpv6-ra-pref64-v1.out -v
icmpv6-ra-pref64-v2 icmpv6-ra-pref64.pcap icmpv6-ra-pref64-v2.out -vv

# SPB tests
spb spb.pcap spb.out
Expand Down
20 changes: 20 additions & 0 deletions tests/icmpv6-ra-pref64-v1.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
1 20:18:21.401201 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
prefix info option (3), length 32 (4): 2001:db8:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
pref64 info option (38), length 16 (2): 2001:db8:1:64:ff9b::/96 (plc 0), lifetime 0s
2 20:18:24.401773 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
prefix info option (3), length 32 (4): 2001:db8:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
pref64 info option (38), length 16 (2): 2001:db8:0:64:ff9b::/?? (plc 6), lifetime 1800s
3 20:18:27.402345 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
prefix info option (3), length 32 (4): 2a00:f480:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
pref64 info option (38), length 16 (2): 2001:db8:0:64:ff9b::/96 (plc 0), lifetime 1800s
4 20:18:30.402917 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
prefix info option (3), length 32 (4): 2001:db8:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
pref64 info option (38), length 16 (2): 2001:db8:0:64:ff9b::/96 (plc 0), lifetime 65528s
36 changes: 36 additions & 0 deletions tests/icmpv6-ra-pref64-v2.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
1 20:18:21.401201 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
0x0000: e215 81b4 b945
prefix info option (3), length 32 (4): 2001:db8:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
0x0000: 4080 0000 0e10 0000 0708 0000 0000 2001
0x0010: 0db8 00cc 00dd 0000 0000 0000 0000
pref64 info option (38), length 16 (2): 2001:db8:1:64:ff9b::/96 (plc 0), lifetime 0s
0x0000: 0000 2001 0db8 0001 0064 ff9b 0000
2 20:18:24.401773 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
0x0000: e215 81b4 b945
prefix info option (3), length 32 (4): 2001:db8:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
0x0000: 4080 0000 0e10 0000 0708 0000 0000 2001
0x0010: 0db8 00cc 00dd 0000 0000 0000 0000
pref64 info option (38), length 16 (2): 2001:db8:0:64:ff9b::/?? (plc 6), lifetime 1800s
0x0000: 070e 2001 0db8 0000 0064 ff9b 0000
3 20:18:27.402345 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
0x0000: e215 81b4 b945
prefix info option (3), length 32 (4): 2a00:f480:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
0x0000: 4080 0000 0e10 0000 0708 0000 0000 2a00
0x0010: f480 00cc 00dd 0000 0000 0000 0000
pref64 info option (38), length 16 (2): 2001:db8:0:64:ff9b::/96 (plc 0), lifetime 1800s
0x0000: 0708 2001 0db8 0000 0064 ff9b 0000
4 20:18:30.402917 IP6 (flowlabel 0x9fc72, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::e015:81ff:feb4:b945 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 80, Flags [other stateful], pref medium, router lifetime 500s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): e2:15:81:b4:b9:45
0x0000: e215 81b4 b945
prefix info option (3), length 32 (4): 2001:db8:cc:dd::/64, Flags [onlink], valid time 3600s, pref. time 1800s
0x0000: 4080 0000 0e10 0000 0708 0000 0000 2001
0x0010: 0db8 00cc 00dd 0000 0000 0000 0000
pref64 info option (38), length 16 (2): 2001:db8:0:64:ff9b::/96 (plc 0), lifetime 65528s
0x0000: fff8 2001 0db8 0000 0064 ff9b 0000
Binary file added tests/icmpv6-ra-pref64.pcap
Binary file not shown.