summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-08-19 09:17:37 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-08-19 09:17:37 +0000
commitcd03ae963fe71d81ff1d2673e48c0045a003aa2e (patch)
tree9a8d7d83a1b6a2958a007351db5db4224090a1b0 /sys/netinet6
parent0acbf7431e011faee2384cab2d22ceeebe0df377 (diff)
- upgrade icmp6 node information query support to 06 draft.
- pedant: possible alignment issue in ALIGN > 8 arch (should be okay for now) (sync with kame)
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/icmp6.c76
-rw-r--r--sys/netinet6/ip6_output.c48
2 files changed, 71 insertions, 53 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index cc0067d8afb..c0b6bf0f892 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: icmp6.c,v 1.20 2000/08/03 14:39:23 itojun Exp $ */
-/* $KAME: icmp6.c,v 1.130 2000/08/03 14:22:10 itojun Exp $ */
+/* $OpenBSD: icmp6.c,v 1.21 2000/08/19 09:17:36 itojun Exp $ */
+/* $KAME: icmp6.c,v 1.134 2000/08/19 02:01:46 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -1034,14 +1034,13 @@ icmp6_mtudisc_update(dst, icmp6, m)
}
/*
- * Process a Node Information Query packet, (roughly) based on
- * draft-ietf-ipngwg-icmp-name-lookups-05.
+ * Process a Node Information Query packet, based on
+ * draft-ietf-ipngwg-icmp-name-lookups-06.
*
* Spec incompatibilities:
* - IPv6 Subject address handling
* - IPv4 Subject address handling support missing
* - Proxy reply (answer even if it's not for me)
- * - "Supported Qtypes" support missing
* - joins NI group address at in6_ifattach() time only, does not cope
* with hostname changes by sethostname(3)
*/
@@ -1081,24 +1080,8 @@ ni6_input(m, off)
* Validate IPv6 destination address.
*
* We accept packets with the following IPv6 destination address:
- * - Responder's unicast/anycast address,
- * - link-local multicast address
- * This is a violation to last paragraph in icmp-name-lookups-05
- * page 4, which restricts IPv6 destination address of a query to:
- * - Responder's unicast/anycast address,
- * - NI group address for a name belongs to the Responder, or
- * - NI group address for a name for which the Responder is providing
- * proxy service.
- * (note: NI group address is a link-local multicast address)
- *
- * We allow any link-local multicast address, since "ping6 -w ff02::1"
- * has been really useful for us debugging our network. Also this is
- * still questionable if the restriction in spec buy us security at all,
- * since RFC2463 permits echo packet to multicast destination.
- * Even if we forbid NI query to ff02::1, we can effectively get the
- * same result as "ping6 -w ff02::1" by the following steps:
- * - run "ping6 ff02::1", then
- * - run "ping6 -w" for all addresses replied.
+ * - Responder's unicast/anycast address, and
+ * - link-local multicast address (including NI group address)
*/
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = AF_INET6;
@@ -1118,7 +1101,7 @@ ni6_input(m, off)
case NI_QTYPE_NOOP:
break; /* no reply data */
case NI_QTYPE_SUPTYPES:
- goto bad; /* xxx: to be implemented */
+ replylen += sizeof(u_int32_t);
break;
case NI_QTYPE_FQDN:
/* XXX will append a mbuf */
@@ -1151,10 +1134,10 @@ ni6_input(m, off)
switch (qtype) {
case NI_QTYPE_NOOP:
case NI_QTYPE_SUPTYPES:
- if (subjlen != 0)
- goto bad;
- break;
-
+ /* 06 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) {
@@ -1166,10 +1149,15 @@ ni6_input(m, off)
* backward compatibility - try to accept 03 draft
* format, where no Subject is present.
*/
- if (subjlen == 0) {
+ 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;
@@ -1250,10 +1238,6 @@ ni6_input(m, off)
goto bad;
}
break;
-
- default:
- /* should never be here due to "switch (qtype)" above */
- goto bad;
}
/* allocate a mbuf to reply. */
@@ -1286,12 +1270,21 @@ ni6_input(m, off)
/* qtype dependent procedure */
switch (qtype) {
case NI_QTYPE_NOOP:
+ nni6->ni_code = ICMP6_NI_SUCCESS;
nni6->ni_flags = 0;
break;
case NI_QTYPE_SUPTYPES:
- goto bad; /* xxx: to be implemented */
+ {
+ 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));
@@ -1312,12 +1305,10 @@ ni6_input(m, off)
{
int lenlim, copied;
- if (n->m_flags & M_EXT)
- lenlim = MCLBYTES - sizeof(struct ip6_hdr) -
- sizeof(struct icmp6_nodeinfo);
- else
- lenlim = MHLEN - sizeof(struct ip6_hdr) -
- sizeof(struct icmp6_nodeinfo);
+ 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) +
@@ -1329,7 +1320,6 @@ ni6_input(m, off)
}
nni6->ni_type = ICMP6_NI_REPLY;
- nni6->ni_code = ICMP6_NI_SUCCESS;
m_freem(m);
return(n);
@@ -1441,6 +1431,7 @@ ni6_nametodns(name, namelen, old)
/*
* 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)
*/
static int
ni6_dnsmatch(a, alen, b, blen)
@@ -2139,7 +2130,8 @@ icmp6_redirect_output(m0, rt)
MCLGET(m, M_DONTWAIT);
if (!m)
goto fail;
- maxlen = (m->m_flags & M_EXT) ? MCLBYTES : MHLEN;
+ m->m_len = 0;
+ maxlen = M_TRAILINGSPACE(m);
maxlen = min(IPV6_MMTU, maxlen);
/* just for safety */
if (maxlen < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) +
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 9adc9785508..e9471c1b574 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ip6_output.c,v 1.13 2000/06/20 20:51:26 itojun Exp $ */
-/* $KAME: ip6_output.c,v 1.112 2000/06/18 01:50:39 itojun Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.14 2000/08/19 09:17:36 itojun Exp $ */
+/* $KAME: ip6_output.c,v 1.122 2000/08/19 02:12:02 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -1150,6 +1150,7 @@ ip6_insert_jumboopt(exthdrs, plen)
{
struct mbuf *mopt;
u_char *optbuf;
+ u_int32_t v;
#define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */
@@ -1172,18 +1173,42 @@ ip6_insert_jumboopt(exthdrs, plen)
mopt = exthdrs->ip6e_hbh;
if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
- caddr_t oldoptp = mtod(mopt, caddr_t);
+ /*
+ * XXX assumption:
+ * - exthdrs->ip6e_hbh is not referenced from places
+ * other than exthdrs.
+ * - exthdrs->ip6e_hbh is not an mbuf chain.
+ */
int oldoptlen = mopt->m_len;
+ struct mbuf *n;
- if (mopt->m_flags & M_EXT)
- return(ENOBUFS); /* XXX */
- MCLGET(mopt, M_DONTWAIT);
- if ((mopt->m_flags & M_EXT) == 0)
+ /*
+ * XXX: give up if the whole (new) hbh header does
+ * not fit even in an mbuf cluster.
+ */
+ if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
return(ENOBUFS);
- bcopy(oldoptp, mtod(mopt, caddr_t), oldoptlen);
- optbuf = mtod(mopt, caddr_t) + oldoptlen;
- mopt->m_len = oldoptlen + JUMBOOPTLEN;
+ /*
+ * As a consequence, we must always prepare a cluster
+ * at this point.
+ */
+ MGET(n, M_DONTWAIT, MT_DATA);
+ if (n) {
+ MCLGET(n, M_DONTWAIT);
+ if ((n->m_flags & M_EXT) == 0) {
+ m_freem(n);
+ n = NULL;
+ }
+ }
+ if (!n)
+ return(ENOBUFS);
+ n->m_len = oldoptlen + JUMBOOPTLEN;
+ bcopy(mtod(mopt, caddr_t), mtod(n, caddr_t),
+ oldoptlen);
+ optbuf = mtod(n, caddr_t) + oldoptlen;
+ m_freem(mopt);
+ exthdrs->ip6e_hbh = n;
} else {
optbuf = mtod(mopt, u_char *) + mopt->m_len;
mopt->m_len += JUMBOOPTLEN;
@@ -1202,7 +1227,8 @@ ip6_insert_jumboopt(exthdrs, plen)
/* fill in the option. */
optbuf[2] = IP6OPT_JUMBO;
optbuf[3] = 4;
- *(u_int32_t *)&optbuf[4] = htonl(plen + JUMBOOPTLEN);
+ v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
+ bcopy(&v, &optbuf[4], sizeof(u_int32_t));
/* finally, adjust the packet header length */
exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;