summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSebastian Benoit <benno@cvs.openbsd.org>2014-07-11 12:20:27 +0000
committerSebastian Benoit <benno@cvs.openbsd.org>2014-07-11 12:20:27 +0000
commitfdfbd2bd6a3dda0fa55c891b8a19aa1c0a61f6bf (patch)
tree29d5ca91c77b909eb1890ee2d68f1d887d1f4a12 /sys
parentbf060e1a4e91f23e5e8e397236027df12406c154 (diff)
Remove rfc 4620 Node Information Query support (from the kernel).
ok henning@ stu@, Yay! weerd@
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/icmp6.h6
-rw-r--r--sys/netinet6/icmp6.c799
-rw-r--r--sys/netinet6/in6_proto.c3
3 files changed, 6 insertions, 802 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h
index c1af65e9bf6..68c82666ad9 100644
--- a/sys/netinet/icmp6.h
+++ b/sys/netinet/icmp6.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: icmp6.h,v 1.39 2014/05/07 08:14:59 mpi Exp $ */
+/* $OpenBSD: icmp6.h,v 1.40 2014/07/11 12:20:26 benno Exp $ */
/* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */
/*
@@ -553,7 +553,7 @@ struct icmp6stat {
{ "nd6_mmaxtries", CTLTYPE_INT }, \
{ 0, 0 }, \
{ 0, 0 }, \
- { "nodeinfo", CTLTYPE_INT }, \
+ { 0, 0 }, \
{ "errppslimit", CTLTYPE_INT }, \
{ "nd6_maxnudhint", CTLTYPE_INT }, \
{ "mtudisc_hiwat", CTLTYPE_INT }, \
@@ -577,7 +577,7 @@ struct icmp6stat {
&nd6_mmaxtries, \
NULL, \
NULL, \
- &icmp6_nodeinfo, \
+ NULL, \
&icmp6errppslim, \
&nd6_maxnudhint, \
&icmp6_mtudisc_hiwat, \
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index fba04a8e448..517271c6401 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: icmp6.c,v 1.145 2014/07/08 17:19:26 deraadt Exp $ */
+/* $OpenBSD: icmp6.c,v 1.146 2014/07/11 12:20:26 benno Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
@@ -109,7 +109,6 @@ extern struct inpcbtable rawin6pcbtable;
extern int icmp6errppslim;
static int icmp6errpps_count = 0;
static struct timeval icmp6errppslim_last;
-extern int icmp6_nodeinfo;
/*
* List of callbacks to notify when Path MTU changes are made.
@@ -141,13 +140,6 @@ int icmp6_rip6_input(struct mbuf **, int);
int icmp6_ratelimit(const struct in6_addr *, const int, const int);
const char *icmp6_redirect_diag(struct in6_addr *, struct in6_addr *,
struct in6_addr *);
-struct mbuf *ni6_input(struct mbuf *, int);
-struct mbuf *ni6_nametodns(const char *, int, int);
-int ni6_dnsmatch(const char *, int, const char *, int);
-int ni6_addrs(struct icmp6_nodeinfo *, struct mbuf *, struct ifnet **,
- char *);
-int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *,
- struct ifnet *, int);
int icmp6_notify_error(struct mbuf *, int, int, int);
struct rtentry *icmp6_mtudisc_clone(struct sockaddr *, u_int);
void icmp6_mtudisc_timeout(struct rtentry *, struct rttimer *);
@@ -654,88 +646,9 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
break; /* just pass it to applications */
case ICMP6_WRUREQUEST: /* ICMP6_FQDN_QUERY */
- {
- enum { WRU, FQDN } mode;
-
- if (!icmp6_nodeinfo)
- break;
-
- if (icmp6len == sizeof(struct icmp6_hdr) + 4)
- mode = WRU;
- else if (icmp6len >= sizeof(struct icmp6_nodeinfo))
- mode = FQDN;
- else
- goto badlen;
-
- if (mode == FQDN) {
- n = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (n)
- n = ni6_input(n, off);
- /* XXX meaningless if n == NULL */
- noff = sizeof(struct ip6_hdr);
- } else {
- u_char *p;
- int maxlen, maxhlen;
-
- if ((icmp6_nodeinfo & 1) == 0)
- break;
-
- if (code != 0)
- goto badcode;
- maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4;
- if (maxlen >= MCLBYTES) {
- /* Give up remote */
- break;
- }
- MGETHDR(n, M_DONTWAIT, m->m_type);
- if (n && maxlen > MHLEN) {
- MCLGET(n, M_DONTWAIT);
- if ((n->m_flags & M_EXT) == 0) {
- m_free(n);
- n = NULL;
- }
- }
- if (n == NULL) {
- /* Give up remote */
- break;
- }
- n->m_pkthdr.rcvif = NULL;
- n->m_len = 0;
- maxhlen = M_TRAILINGSPACE(n) - maxlen;
- if (maxhlen > hostnamelen)
- maxhlen = hostnamelen;
- /*
- * Copy IPv6 and ICMPv6 only.
- */
- nip6 = mtod(n, struct ip6_hdr *);
- bcopy(ip6, nip6, sizeof(struct ip6_hdr));
- nicmp6 = (struct icmp6_hdr *)(nip6 + 1);
- bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
- p = (u_char *)(nicmp6 + 1);
- bzero(p, 4);
- bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */
- noff = sizeof(struct ip6_hdr);
- if (m_dup_pkthdr(n, m, M_DONTWAIT)) { /* for rcvif */
- m_freem(n);
- break;
- }
- n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
- sizeof(struct icmp6_hdr) + 4 + maxhlen;
- nicmp6->icmp6_type = ICMP6_WRUREPLY;
- nicmp6->icmp6_code = 0;
- }
-#undef hostnamelen
- if (n) {
- icmp6stat.icp6s_reflect++;
- icmp6stat.icp6s_outhist[ICMP6_WRUREPLY]++;
- icmp6_reflect(n, noff);
- }
+ /* IPv6 Node Information Queries are not supported */
break;
- }
-
case ICMP6_WRUREPLY:
- if (code != 0)
- goto badcode;
break;
case ND_ROUTER_SOLICIT:
@@ -1148,714 +1061,6 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated)
}
/*
- * Process a Node Information Query packet, based on
- * draft-ietf-ipngwg-icmp-name-lookups-07.
- *
- * Spec incompatibilities:
- * - IPv6 Subject address handling
- * - IPv4 Subject address handling support missing
- * - Proxy reply (answer even if it's not for me)
- * - joins NI group address at in6_ifattach() time only, does not cope
- * with hostname changes by sethostname(3)
- */
-struct mbuf *
-ni6_input(struct mbuf *m, int off)
-{
- struct icmp6_nodeinfo *ni6, *nni6;
- struct mbuf *n = NULL;
- u_int16_t qtype;
- int subjlen;
- int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
- struct ni_reply_fqdn *fqdn;
- int addrs; /* for NI_QTYPE_NODEADDR */
- struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */
- struct sockaddr_in6 sin6; /* double meaning; ip6_dst and subjectaddr */
- struct ip6_hdr *ip6;
- int oldfqdn = 0; /* if 1, return pascal string (03 draft) */
- char *subj = NULL;
-
- ip6 = mtod(m, struct ip6_hdr *);
- IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6));
- if (ni6 == NULL) {
- /* m is already reclaimed */
- return NULL;
- }
-
- /*
- * Validate IPv6 destination address.
- *
- * The Responder must discard the Query without further processing
- * unless it is one of the Responder's unicast or anycast addresses, or
- * a link-local scope multicast address which the Responder has joined.
- * [icmp-name-lookups-07, Section 4.]
- */
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- bcopy(&ip6->ip6_dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
- /* XXX scopeid */
- if (ifa_ifwithaddr(sin6tosa(&sin6), m->m_pkthdr.ph_rtableid))
- ; /* unicast/anycast, fine */
- else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr))
- ; /* link-local multicast, fine */
- else
- goto bad;
-
- /* validate query Subject field. */
- qtype = ntohs(ni6->ni_qtype);
- subjlen = m->m_pkthdr.len - off - sizeof(struct icmp6_nodeinfo);
- switch (qtype) {
- case NI_QTYPE_NOOP:
- case NI_QTYPE_SUPTYPES:
- /* 07 draft */
- if (ni6->ni_code == ICMP6_NI_SUBJ_FQDN && subjlen == 0)
- break;
- /* FALLTHROUGH */
- case NI_QTYPE_FQDN:
- case NI_QTYPE_NODEADDR:
- switch (ni6->ni_code) {
- case ICMP6_NI_SUBJ_IPV6:
-#if ICMP6_NI_SUBJ_IPV6 != 0
- case 0:
-#endif
- /*
- * backward compatibility - try to accept 03 draft
- * format, where no Subject is present.
- */
- if (qtype == NI_QTYPE_FQDN && ni6->ni_code == 0 &&
- subjlen == 0) {
- oldfqdn++;
- break;
- }
-#if ICMP6_NI_SUBJ_IPV6 != 0
- if (ni6->ni_code != ICMP6_NI_SUBJ_IPV6)
- goto bad;
-#endif
-
- if (subjlen != sizeof(sin6.sin6_addr))
- goto bad;
-
- /*
- * Validate Subject address.
- *
- * Not sure what exactly "address belongs to the node"
- * means in the spec, is it just unicast, or what?
- *
- * At this moment we consider Subject address as
- * "belong to the node" if the Subject address equals
- * to the IPv6 destination address; validation for
- * IPv6 destination address should have done enough
- * check for us.
- *
- * We do not do proxy at this moment.
- */
- /* m_pulldown instead of copy? */
- m_copydata(m, off + sizeof(struct icmp6_nodeinfo),
- subjlen, (caddr_t)&sin6.sin6_addr);
- /* XXX kame scope hack */
- if (IN6_IS_SCOPE_EMBED(&sin6.sin6_addr)) {
- if ((m->m_flags & M_PKTHDR) != 0 &&
- m->m_pkthdr.rcvif) {
- sin6.sin6_addr.s6_addr16[1] =
- htons(m->m_pkthdr.rcvif->if_index);
- }
- }
- subj = (char *)&sin6;
- if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &sin6.sin6_addr))
- break;
-
- /*
- * XXX if we are to allow other cases, we should really
- * be careful about scope here.
- * basically, we should disallow queries toward IPv6
- * destination X with subject Y, if scope(X) > scope(Y).
- * if we allow scope(X) > scope(Y), it will result in
- * information leakage across scope boundary.
- */
- goto bad;
-
- case ICMP6_NI_SUBJ_FQDN:
- /*
- * Validate Subject name with gethostname(3).
- *
- * The behavior may need some debate, since:
- * - we are not sure if the node has FQDN as
- * hostname (returned by gethostname(3)).
- * - the code does wildcard match for truncated names.
- * however, we are not sure if we want to perform
- * wildcard match, if gethostname(3) side has
- * truncated hostname.
- */
- n = ni6_nametodns(hostname, hostnamelen, 0);
- if (!n || n->m_next || n->m_len == 0)
- goto bad;
- IP6_EXTHDR_GET(subj, char *, m,
- off + sizeof(struct icmp6_nodeinfo), subjlen);
- if (subj == NULL)
- goto bad;
- if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *),
- n->m_len)) {
- goto bad;
- }
- m_freem(n);
- n = NULL;
- break;
-
- case ICMP6_NI_SUBJ_IPV4: /* XXX: to be implemented? */
- default:
- goto bad;
- }
- break;
- }
-
- /* refuse based on configuration. XXX ICMP6_NI_REFUSED? */
- switch (qtype) {
- case NI_QTYPE_FQDN:
- if ((icmp6_nodeinfo & 1) == 0)
- goto bad;
- break;
- case NI_QTYPE_NODEADDR:
- if ((icmp6_nodeinfo & 2) == 0)
- goto bad;
- break;
- }
-
- /* guess reply length */
- switch (qtype) {
- case NI_QTYPE_NOOP:
- break; /* no reply data */
- case NI_QTYPE_SUPTYPES:
- replylen += sizeof(u_int32_t);
- break;
- case NI_QTYPE_FQDN:
- /* XXX will append an mbuf */
- replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen);
- break;
- case NI_QTYPE_NODEADDR:
- addrs = ni6_addrs(ni6, m, &ifp, subj);
- if ((replylen += addrs * (sizeof(struct in6_addr) +
- sizeof(u_int32_t))) > MCLBYTES)
- replylen = MCLBYTES; /* XXX: will truncate pkt later */
- break;
- default:
- /*
- * XXX: We must return a reply with the ICMP6 code
- * `unknown Qtype' in this case. However we regard the case
- * as an FQDN query for backward compatibility.
- * Older versions set a random value to this field,
- * so it rarely varies in the defined qtypes.
- * But the mechanism is not reliable...
- * maybe we should obsolete older versions.
- */
- qtype = NI_QTYPE_FQDN;
- /* XXX will append an mbuf */
- replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen);
- oldfqdn++;
- break;
- }
-
- /* allocate an mbuf to reply. */
- MGETHDR(n, M_DONTWAIT, m->m_type);
- if (n == NULL) {
- m_freem(m);
- return (NULL);
- }
-
- if (m_dup_pkthdr(n, m, M_DONTWAIT)) /* just for rcvif */
- goto bad;
-
- if (replylen > MHLEN) {
- if (replylen > MCLBYTES) {
- /*
- * XXX: should we try to allocate more? But MCLBYTES
- * is probably much larger than IPV6_MMTU...
- */
- goto bad;
- }
- MCLGET(n, M_DONTWAIT);
- if ((n->m_flags & M_EXT) == 0) {
- goto bad;
- }
- }
- n->m_pkthdr.len = n->m_len = replylen;
-
- /* copy mbuf header and IPv6 + Node Information base headers */
- bcopy(mtod(m, caddr_t), mtod(n, caddr_t), sizeof(struct ip6_hdr));
- nni6 = (struct icmp6_nodeinfo *)(mtod(n, struct ip6_hdr *) + 1);
- bcopy((caddr_t)ni6, (caddr_t)nni6, sizeof(struct icmp6_nodeinfo));
-
- /* qtype dependent procedure */
- switch (qtype) {
- case NI_QTYPE_NOOP:
- nni6->ni_code = ICMP6_NI_SUCCESS;
- nni6->ni_flags = 0;
- break;
- case NI_QTYPE_SUPTYPES:
- {
- u_int32_t v;
- nni6->ni_code = ICMP6_NI_SUCCESS;
- nni6->ni_flags = htons(0x0000); /* raw bitmap */
- /* supports NOOP, SUPTYPES, FQDN, and NODEADDR */
- v = (u_int32_t)htonl(0x0000000f);
- bcopy(&v, nni6 + 1, sizeof(u_int32_t));
- break;
- }
- case NI_QTYPE_FQDN:
- nni6->ni_code = ICMP6_NI_SUCCESS;
- fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) +
- sizeof(struct ip6_hdr) +
- sizeof(struct icmp6_nodeinfo));
- nni6->ni_flags = 0; /* XXX: meaningless TTL */
- fqdn->ni_fqdn_ttl = 0; /* ditto. */
- /*
- * XXX do we really have FQDN in variable "hostname"?
- */
- n->m_next = ni6_nametodns(hostname, hostnamelen, oldfqdn);
- if (n->m_next == NULL)
- goto bad;
- /* XXX we assume that n->m_next is not a chain */
- if (n->m_next->m_next != NULL)
- goto bad;
- n->m_pkthdr.len += n->m_next->m_len;
- break;
- case NI_QTYPE_NODEADDR:
- {
- int lenlim, copied;
-
- nni6->ni_code = ICMP6_NI_SUCCESS;
- n->m_pkthdr.len = n->m_len =
- sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
- lenlim = M_TRAILINGSPACE(n);
- copied = ni6_store_addrs(ni6, nni6, ifp, lenlim);
- /* XXX: reset mbuf length */
- n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
- sizeof(struct icmp6_nodeinfo) + copied;
- break;
- }
- default:
- break; /* XXX impossible! */
- }
-
- nni6->ni_type = ICMP6_NI_REPLY;
- m_freem(m);
- return (n);
-
- bad:
- m_freem(m);
- if (n)
- m_freem(n);
- return (NULL);
-}
-#undef hostnamelen
-
-#define isupper(x) ('A' <= (x) && (x) <= 'Z')
-#define isalpha(x) (('A' <= (x) && (x) <= 'Z') || ('a' <= (x) && (x) <= 'z'))
-#define isalnum(x) (isalpha(x) || ('0' <= (x) && (x) <= '9'))
-#define tolower(x) (isupper(x) ? (x) + 'a' - 'A' : (x))
-
-/*
- * make a mbuf with DNS-encoded string. no compression support.
- *
- * XXX names with less than 2 dots (like "foo" or "foo.section") will be
- * treated as truncated name (two \0 at the end). this is a wild guess.
- *
- * old - return pascal string if non-zero
- */
-struct mbuf *
-ni6_nametodns(const char *name, int namelen, int old)
-{
- struct mbuf *m;
- char *cp, *ep;
- const char *p, *q;
- int i, len, nterm;
-
- if (old)
- len = namelen + 1;
- else
- len = MCLBYTES;
-
- /* because MAXHOSTNAMELEN is usually 256, we use cluster mbuf */
- MGET(m, M_DONTWAIT, MT_DATA);
- if (m && len > MLEN) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0)
- goto fail;
- }
- if (!m)
- goto fail;
- m->m_next = NULL;
-
- if (old) {
- m->m_len = len;
- *mtod(m, char *) = namelen;
- bcopy(name, mtod(m, char *) + 1, namelen);
- return m;
- } else {
- m->m_len = 0;
- cp = mtod(m, char *);
- ep = mtod(m, char *) + M_TRAILINGSPACE(m);
-
- /* if not certain about my name, return empty buffer */
- if (namelen == 0)
- return m;
-
- /*
- * guess if it looks like shortened hostname, or FQDN.
- * shortened hostname needs two trailing "\0".
- */
- i = 0;
- for (p = name; p < name + namelen; p++) {
- if (*p && *p == '.')
- i++;
- }
- if (i < 2)
- nterm = 2;
- else
- nterm = 1;
-
- p = name;
- while (cp < ep && p < name + namelen) {
- i = 0;
- for (q = p; q < name + namelen && *q && *q != '.'; q++)
- i++;
- /* result does not fit into mbuf */
- if (cp + i + 1 >= ep)
- goto fail;
- /*
- * DNS label length restriction, RFC1035 page 8.
- * "i == 0" case is included here to avoid returning
- * 0-length label on "foo..bar".
- */
- if (i <= 0 || i >= 64)
- goto fail;
- *cp++ = i;
- if (!isalnum(p[0]) || !isalnum(p[i - 1]))
- goto fail;
- while (i > 0) {
- if (!isalnum(*p) && *p != '-')
- goto fail;
- if (isupper(*p)) {
- *cp++ = tolower(*p);
- p++;
- } else
- *cp++ = *p++;
- i--;
- }
- p = q;
- if (p < name + namelen && *p == '.')
- p++;
- }
- /* termination */
- if (cp + nterm >= ep)
- goto fail;
- while (nterm-- > 0)
- *cp++ = '\0';
- m->m_len = cp - mtod(m, char *);
- return m;
- }
-
- panic("should not reach here");
- /* NOTREACHED */
-
- fail:
- if (m)
- m_freem(m);
- return NULL;
-}
-
-/*
- * check if two DNS-encoded string matches. takes care of truncated
- * form (with \0\0 at the end). no compression support.
- * XXX upper/lowercase match (see RFC2065)
- */
-int
-ni6_dnsmatch(const char *a, int alen, const char *b, int blen)
-{
- const char *a0, *b0;
- int l;
-
- /* simplest case - need validation? */
- if (alen == blen && bcmp(a, b, alen) == 0)
- return 1;
-
- a0 = a;
- b0 = b;
-
- /* termination is mandatory */
- if (alen < 2 || blen < 2)
- return 0;
- if (a0[alen - 1] != '\0' || b0[blen - 1] != '\0')
- return 0;
- alen--;
- blen--;
-
- while (a - a0 < alen && b - b0 < blen) {
- if (a - a0 + 1 > alen || b - b0 + 1 > blen)
- return 0;
-
- if ((signed char)a[0] < 0 || (signed char)b[0] < 0)
- return 0;
- /* we don't support compression yet */
- if (a[0] >= 64 || b[0] >= 64)
- return 0;
-
- /* truncated case */
- if (a[0] == 0 && a - a0 == alen - 1)
- return 1;
- if (b[0] == 0 && b - b0 == blen - 1)
- return 1;
- if (a[0] == 0 || b[0] == 0)
- return 0;
-
- if (a[0] != b[0])
- return 0;
- l = a[0];
- if (a - a0 + 1 + l > alen || b - b0 + 1 + l > blen)
- return 0;
- if (bcmp(a + 1, b + 1, l) != 0)
- return 0;
-
- a += 1 + l;
- b += 1 + l;
- }
-
- if (a - a0 == alen && b - b0 == blen)
- return 1;
- else
- return 0;
-}
-
-/*
- * calculate the number of addresses to be returned in the node info reply.
- */
-int
-ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp,
- char *subj)
-{
- struct ifnet *ifp;
- struct in6_ifaddr *ia6;
- struct ifaddr *ifa;
- struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */
- int addrs = 0, addrsofif, iffound = 0;
- int niflags = ni6->ni_flags;
-
- if ((niflags & NI_NODEADDR_FLAG_ALL) == 0) {
- switch (ni6->ni_code) {
- case ICMP6_NI_SUBJ_IPV6:
- if (subj == NULL) /* must be impossible... */
- return (0);
- subj_ip6 = (struct sockaddr_in6 *)subj;
- break;
- default:
- /*
- * XXX: we only support IPv6 subject address for
- * this Qtype.
- */
- return (0);
- }
- }
-
- TAILQ_FOREACH(ifp, &ifnet, if_list) {
- addrsofif = 0;
- TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
- if (ifa->ifa_addr->sa_family != AF_INET6)
- continue;
- ia6 = ifatoia6(ifa);
-
- if ((niflags & NI_NODEADDR_FLAG_ALL) == 0 &&
- IN6_ARE_ADDR_EQUAL(&subj_ip6->sin6_addr,
- &ia6->ia_addr.sin6_addr))
- iffound = 1;
-
- /*
- * IPv4-mapped addresses can only be returned by a
- * Node Information proxy, since they represent
- * addresses of IPv4-only nodes, which perforce do
- * not implement this protocol.
- * [icmp-name-lookups-07, Section 5.4]
- * So we don't support NI_NODEADDR_FLAG_COMPAT in
- * this function at this moment.
- */
-
- /* What do we have to do about ::1? */
- switch (in6_addrscope(&ia6->ia_addr.sin6_addr)) {
- case __IPV6_ADDR_SCOPE_LINKLOCAL:
- if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0)
- continue;
- break;
- case __IPV6_ADDR_SCOPE_SITELOCAL:
- if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0)
- continue;
- break;
- case __IPV6_ADDR_SCOPE_GLOBAL:
- if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0)
- continue;
- break;
- default:
- continue;
- }
-
- /*
- * check if anycast is okay.
- * XXX: just experimental. not in the spec.
- */
- if ((ia6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
- (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0)
- continue; /* we need only unicast addresses */
-
- addrsofif++; /* count the address */
- }
- if (iffound) {
- *ifpp = ifp;
- return (addrsofif);
- }
-
- addrs += addrsofif;
- }
-
- return (addrs);
-}
-
-int
-ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6,
- struct ifnet *ifp0, int resid)
-{
- struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet);
- struct in6_ifaddr *ia6;
- struct ifaddr *ifa;
- struct ifnet *ifp_dep = NULL;
- int copied = 0, allow_deprecated = 0;
- u_char *cp = (u_char *)(nni6 + 1);
- int niflags = ni6->ni_flags;
- u_int32_t ltime;
-
- if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL))
- return (0); /* needless to copy */
-
- again:
-
- for (; ifp != NULL; ifp = TAILQ_NEXT(ifp, if_list)) {
- TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
- if (ifa->ifa_addr->sa_family != AF_INET6)
- continue;
- ia6 = ifatoia6(ifa);
-
- if ((ia6->ia6_flags & IN6_IFF_DEPRECATED) != 0 &&
- allow_deprecated == 0) {
- /*
- * preferred address should be put before
- * deprecated addresses.
- */
-
- /* record the interface for later search */
- if (ifp_dep == NULL)
- ifp_dep = ifp;
-
- continue;
- }
- else if ((ia6->ia6_flags & IN6_IFF_DEPRECATED) == 0 &&
- allow_deprecated != 0)
- continue; /* we now collect deprecated addrs */
-
- /* What do we have to do about ::1? */
- switch (in6_addrscope(&ia6->ia_addr.sin6_addr)) {
- case __IPV6_ADDR_SCOPE_LINKLOCAL:
- if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0)
- continue;
- break;
- case __IPV6_ADDR_SCOPE_SITELOCAL:
- if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0)
- continue;
- break;
- case __IPV6_ADDR_SCOPE_GLOBAL:
- if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0)
- continue;
- break;
- default:
- continue;
- }
-
- /*
- * check if anycast is okay.
- * XXX: just experimental. not in the spec.
- */
- if ((ia6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
- (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0)
- continue;
-
- /* now we can copy the address */
- if (resid < sizeof(struct in6_addr) +
- sizeof(u_int32_t)) {
- /*
- * We give up much more copy.
- * Set the truncate flag and return.
- */
- nni6->ni_flags |=
- NI_NODEADDR_FLAG_TRUNCATE;
- return (copied);
- }
-
- /*
- * Set the TTL of the address.
- * The TTL value should be one of the following
- * according to the specification:
- *
- * 1. The remaining lifetime of a DHCP lease on the
- * address, or
- * 2. The remaining Valid Lifetime of a prefix from
- * which the address was derived through Stateless
- * Autoconfiguration.
- *
- * Note that we currently do not support stateful
- * address configuration by DHCPv6, so the former
- * case can't happen.
- *
- * TTL must be 2^31 > TTL >= 0.
- */
- if (ia6->ia6_lifetime.ia6t_expire == 0)
- ltime = ND6_INFINITE_LIFETIME;
- else {
- time_t diff = ia6->ia6_lifetime.ia6t_expire -
- time_second;
-
- if (diff <= 0)
- ltime = 0;
- else if (diff >= ND6_INFINITE_LIFETIME)
- ltime = ND6_INFINITE_LIFETIME;
- else
- ltime = htonl((u_int32_t)diff);
- }
-
- bcopy(&ltime, cp, sizeof(u_int32_t));
- cp += sizeof(u_int32_t);
-
- /* copy the address itself */
- bcopy(&ia6->ia_addr.sin6_addr, cp,
- sizeof(struct in6_addr));
- /* XXX: KAME link-local hack; remove ifindex */
- if (IN6_IS_ADDR_LINKLOCAL(&ia6->ia_addr.sin6_addr))
- ((struct in6_addr *)cp)->s6_addr16[1] = 0;
- cp += sizeof(struct in6_addr);
-
- resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t));
- copied += (sizeof(struct in6_addr) +
- sizeof(u_int32_t));
- }
- if (ifp0) /* we need search only on the specified IF */
- break;
- }
-
- if (allow_deprecated == 0 && ifp_dep != NULL) {
- ifp = ifp_dep;
- allow_deprecated = 1;
-
- goto again;
- }
-
- return (copied);
-}
-
-/*
* XXX almost dup'ed code with rip6_input.
*/
int
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index 6ab7ce65777..19094d77733 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_proto.c,v 1.70 2014/07/09 08:07:53 benno Exp $ */
+/* $OpenBSD: in6_proto.c,v 1.71 2014/07/11 12:20:26 benno Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/*
@@ -308,5 +308,4 @@ u_long rip6_recvspace = RIPV6RCVQ;
int icmp6_rediraccept = 0; /* don't process redirects by default */
int icmp6_redirtimeout = 10 * 60; /* 10 minutes */
int icmp6errppslim = 100; /* 100pps */
-int icmp6_nodeinfo = 0; /* enable/disable NI response */
int ip6_mtudisc_timeout = IPMTUDISCTIMEOUT;