mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-29 12:03:03 +00:00
Use FF02:0:0:0:0:2:FF00::/104 prefix for IPv6 Node Information Group
Address. Although KAME implementation used FF02:0:0:0:0:2::/96 based on older versions of draft-ietf-ipngwg-icmp-name-lookup, it has been changed in RFC 4620. The kernel always joins the /104-prefixed address, and additionally does /96-prefixed one only when net.inet6.icmp6.nodeinfo_oldmcprefix=1. The default value of the sysctl is 1. ping6(8) -N flag now uses /104-prefixed one. When this flag is specified twice, it uses /96-prefixed one instead. Reviewed by: ume Based on work by: Thomas Scheffler PR: conf/174957 MFC after: 2 weeks
This commit is contained in:
parent
e0906c9a0d
commit
5df1b6b57e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=250251
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 20, 2010
|
||||
.Dd May 5, 2013
|
||||
.Dt PING6 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -215,8 +215,8 @@ unicast and multicast packets.
|
||||
Numeric output only.
|
||||
No attempt will be made to lookup symbolic names from addresses in the reply.
|
||||
.It Fl N
|
||||
Probe node information multicast group
|
||||
.Pq Li ff02::2:xxxx:xxxx .
|
||||
Probe node information multicast group address
|
||||
.Pq Li ff02::2:ffxx:xxxx .
|
||||
.Ar host
|
||||
must be string hostname of the target
|
||||
(must not be a numeric IPv6 address).
|
||||
@ -227,6 +227,15 @@ Since node information multicast group is a link-local multicast group,
|
||||
outgoing interface needs to be specified by
|
||||
.Fl I
|
||||
option.
|
||||
.Pp
|
||||
When specified twice, the address
|
||||
.Pq Li ff02::2:xxxx:xxxx
|
||||
is used instead.
|
||||
The former is in RFC 4620, the latter is in an old Internet Draft
|
||||
draft-ietf-ipngwg-icmp-name-lookup.
|
||||
Note that KAME-derived implementations including
|
||||
.Fx
|
||||
use the latter.
|
||||
.It Fl o
|
||||
Exit successfully after receiving one reply packet.
|
||||
.It Fl p Ar pattern
|
||||
|
@ -287,7 +287,7 @@ void pr_retip(struct ip6_hdr *, u_char *);
|
||||
void summary(void);
|
||||
void tvsub(struct timeval *, struct timeval *);
|
||||
int setpolicy(int, char *);
|
||||
char *nigroup(char *);
|
||||
char *nigroup(char *, int);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
@ -306,6 +306,7 @@ main(int argc, char *argv[])
|
||||
struct addrinfo hints;
|
||||
int cc, i;
|
||||
int ch, hold, packlen, preload, optval, ret_ga;
|
||||
int nig_oldmcprefix = -1;
|
||||
u_char *datap;
|
||||
char *e, *target, *ifname = NULL, *gateway = NULL;
|
||||
int ip6optlen = 0;
|
||||
@ -490,6 +491,7 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
case 'N':
|
||||
options |= F_NIGROUP;
|
||||
nig_oldmcprefix++;
|
||||
break;
|
||||
case 'o':
|
||||
options |= F_ONCE;
|
||||
@ -605,7 +607,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (options & F_NIGROUP) {
|
||||
target = nigroup(argv[argc - 1]);
|
||||
target = nigroup(argv[argc - 1], nig_oldmcprefix);
|
||||
if (target == NULL) {
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
@ -2723,7 +2725,7 @@ setpolicy(int so __unused, char *policy)
|
||||
#endif
|
||||
|
||||
char *
|
||||
nigroup(char *name)
|
||||
nigroup(char *name, int nig_oldmcprefix)
|
||||
{
|
||||
char *p;
|
||||
char *q;
|
||||
@ -2733,6 +2735,7 @@ nigroup(char *name)
|
||||
size_t l;
|
||||
char hbuf[NI_MAXHOST];
|
||||
struct in6_addr in6;
|
||||
int valid;
|
||||
|
||||
p = strchr(name, '.');
|
||||
if (!p)
|
||||
@ -2748,7 +2751,7 @@ nigroup(char *name)
|
||||
*q = tolower(*(unsigned char *)q);
|
||||
}
|
||||
|
||||
/* generate 8 bytes of pseudo-random value. */
|
||||
/* generate 16 bytes of pseudo-random value. */
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
MD5Init(&ctxt);
|
||||
c = l & 0xff;
|
||||
@ -2756,9 +2759,23 @@ nigroup(char *name)
|
||||
MD5Update(&ctxt, (unsigned char *)name, l);
|
||||
MD5Final(digest, &ctxt);
|
||||
|
||||
if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1)
|
||||
if (nig_oldmcprefix) {
|
||||
/* draft-ietf-ipngwg-icmp-name-lookup */
|
||||
valid = inet_pton(AF_INET6, "ff02::2:0000:0000", &in6);
|
||||
} else {
|
||||
/* RFC 4620 */
|
||||
valid = inet_pton(AF_INET6, "ff02::2:ff00:0000", &in6);
|
||||
}
|
||||
if (valid != 1)
|
||||
return NULL; /*XXX*/
|
||||
bcopy(digest, &in6.s6_addr[12], 4);
|
||||
|
||||
if (nig_oldmcprefix) {
|
||||
/* draft-ietf-ipngwg-icmp-name-lookup */
|
||||
bcopy(digest, &in6.s6_addr[12], 4);
|
||||
} else {
|
||||
/* RFC 4620 */
|
||||
bcopy(digest, &in6.s6_addr[13], 3);
|
||||
}
|
||||
|
||||
if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL)
|
||||
return NULL;
|
||||
|
@ -659,7 +659,8 @@ void kmod_icmp6stat_inc(int statnum);
|
||||
#define ICMPV6CTL_MLD_SOMAXSRC 22
|
||||
#define ICMPV6CTL_MLD_VERSION 23
|
||||
#define ICMPV6CTL_ND6_MAXQLEN 24
|
||||
#define ICMPV6CTL_MAXID 25
|
||||
#define ICMPV6CTL_NODEINFO_OLDMCPREFIX 25
|
||||
#define ICMPV6CTL_MAXID 26
|
||||
|
||||
#define RTF_PROBEMTU RTF_PROTO1
|
||||
|
||||
|
@ -106,6 +106,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet6/scope6_var.h>
|
||||
#include <netinet6/in6_pcb.h>
|
||||
|
||||
VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix);
|
||||
#define V_icmp6_nodeinfo_oldmcprefix VNET(icmp6_nodeinfo_oldmcprefix)
|
||||
|
||||
/*
|
||||
* Definitions of some costant IP6 addresses.
|
||||
*/
|
||||
@ -947,6 +950,17 @@ in6_update_ifa_join_mc(struct ifnet *ifp, struct in6_aliasreq *ifra,
|
||||
else
|
||||
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
|
||||
}
|
||||
if (V_icmp6_nodeinfo_oldmcprefix &&
|
||||
in6_nigroup_oldmcprefix(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
|
||||
imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
|
||||
if (imm == NULL)
|
||||
nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
|
||||
"(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
|
||||
&mltaddr.sin6_addr), if_name(ifp), error));
|
||||
/* XXX not very fatal, go on... */
|
||||
else
|
||||
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
|
||||
}
|
||||
|
||||
/*
|
||||
* Join interface-local all-nodes address.
|
||||
|
@ -616,13 +616,16 @@ in6_ifattach_loopback(struct ifnet *ifp)
|
||||
|
||||
/*
|
||||
* compute NI group address, based on the current hostname setting.
|
||||
* see draft-ietf-ipngwg-icmp-name-lookup-* (04 and later).
|
||||
* see RFC 4620.
|
||||
*
|
||||
* when ifp == NULL, the caller is responsible for filling scopeid.
|
||||
*
|
||||
* If oldmcprefix == 1, FF02:0:0:0:0:2::/96 is used for NI group address
|
||||
* while it is FF02:0:0:0:0:2:FF00::/104 in RFC 4620.
|
||||
*/
|
||||
int
|
||||
in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
|
||||
struct in6_addr *in6)
|
||||
static int
|
||||
in6_nigroup0(struct ifnet *ifp, const char *name, int namelen,
|
||||
struct in6_addr *in6, int oldmcprefix)
|
||||
{
|
||||
struct prison *pr;
|
||||
const char *p;
|
||||
@ -667,7 +670,7 @@ in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
|
||||
*q = *q - 'A' + 'a';
|
||||
}
|
||||
|
||||
/* generate 8 bytes of pseudo-random value. */
|
||||
/* generate 16 bytes of pseudo-random value. */
|
||||
bzero(&ctxt, sizeof(ctxt));
|
||||
MD5Init(&ctxt);
|
||||
MD5Update(&ctxt, &l, sizeof(l));
|
||||
@ -677,13 +680,36 @@ in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
|
||||
bzero(in6, sizeof(*in6));
|
||||
in6->s6_addr16[0] = IPV6_ADDR_INT16_MLL;
|
||||
in6->s6_addr8[11] = 2;
|
||||
bcopy(digest, &in6->s6_addr32[3], sizeof(in6->s6_addr32[3]));
|
||||
if (oldmcprefix == 0) {
|
||||
in6->s6_addr8[12] = 0xff;
|
||||
/* Copy the first 24 bits of 128-bit hash into the address. */
|
||||
bcopy(digest, &in6->s6_addr8[13], 3);
|
||||
} else {
|
||||
/* Copy the first 32 bits of 128-bit hash into the address. */
|
||||
bcopy(digest, &in6->s6_addr32[3], sizeof(in6->s6_addr32[3]));
|
||||
}
|
||||
if (in6_setscope(in6, ifp, NULL))
|
||||
return (-1); /* XXX: should not fail */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
|
||||
struct in6_addr *in6)
|
||||
{
|
||||
|
||||
return (in6_nigroup0(ifp, name, namelen, in6, 0));
|
||||
}
|
||||
|
||||
int
|
||||
in6_nigroup_oldmcprefix(struct ifnet *ifp, const char *name, int namelen,
|
||||
struct in6_addr *in6)
|
||||
{
|
||||
|
||||
return (in6_nigroup0(ifp, name, namelen, in6, 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX multiple loopback interface needs more care. for instance,
|
||||
* nodelocal address needs to be configured onto only one of them.
|
||||
|
@ -40,6 +40,7 @@ int in6_get_tmpifid(struct ifnet *, u_int8_t *, const u_int8_t *, int);
|
||||
void in6_tmpaddrtimer(void *);
|
||||
int in6_get_hw_ifid(struct ifnet *, struct in6_addr *);
|
||||
int in6_nigroup(struct ifnet *, const char *, int, struct in6_addr *);
|
||||
int in6_nigroup_oldmcprefix(struct ifnet *, const char *, int, struct in6_addr *);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETINET6_IN6_IFATTACH_H_ */
|
||||
|
@ -438,6 +438,7 @@ VNET_DEFINE(int, icmp6errppslim) = 100; /* 100pps */
|
||||
/* control how to respond to NI queries */
|
||||
VNET_DEFINE(int, icmp6_nodeinfo) =
|
||||
(ICMP6_NODEINFO_FQDNOK|ICMP6_NODEINFO_NODEADDROK);
|
||||
VNET_DEFINE(int, icmp6_nodeinfo_oldmcprefix) = 1;
|
||||
|
||||
/*
|
||||
* sysctl related items.
|
||||
@ -602,6 +603,11 @@ SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_USELOOPBACK, nd6_useloopback,
|
||||
CTLFLAG_RW, &VNET_NAME(nd6_useloopback), 0, "");
|
||||
SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_NODEINFO, nodeinfo, CTLFLAG_RW,
|
||||
&VNET_NAME(icmp6_nodeinfo), 0, "");
|
||||
SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_NODEINFO_OLDMCPREFIX,
|
||||
nodeinfo_oldmcprefix, CTLFLAG_RW,
|
||||
&VNET_NAME(icmp6_nodeinfo_oldmcprefix), 0,
|
||||
"Join old IPv6 NI group address in draft-ietf-ipngwg-icmp-name-lookup"
|
||||
" for compatibility with KAME implememtation.");
|
||||
SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_ERRPPSLIMIT, errppslimit,
|
||||
CTLFLAG_RW, &VNET_NAME(icmp6errppslim), 0, "");
|
||||
SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXNUDHINT, nd6_maxnudhint,
|
||||
|
Loading…
Reference in New Issue
Block a user