diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-08-19 09:17:37 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-08-19 09:17:37 +0000 |
commit | cd03ae963fe71d81ff1d2673e48c0045a003aa2e (patch) | |
tree | 9a8d7d83a1b6a2958a007351db5db4224090a1b0 /sys/netinet6 | |
parent | 0acbf7431e011faee2384cab2d22ceeebe0df377 (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.c | 76 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 48 |
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; |