sync with kame.

net.inet6.icmp6.nodeinfo is now a bitmap (2^0 = ping6 -w, 2^1 = ping6 -a).
give up local if there's mbuf alloc failures.
cope with ".." in hostname.
sync comments/whitespaces.
This commit is contained in:
itojun 2001-10-15 11:12:44 +00:00
parent 91498ffec5
commit 149aafe6ad
2 changed files with 116 additions and 48 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: esp_rijndael.c,v 1.5 2001/06/18 11:23:00 wiz Exp $ */
/* $NetBSD: esp_rijndael.c,v 1.6 2001/10/15 11:12:44 itojun Exp $ */
/* $KAME: esp_rijndael.c,v 1.4 2001/03/02 05:53:05 itojun Exp $ */
/*
@ -48,7 +48,7 @@
#include <net/net_osdep.h>
/* as rijndael uses asymmetric scheduled keys, we need to do it twice. */
/* as rijndael uses assymetric scheduled keys, we need to do it twice. */
int
esp_rijndael_schedlen(algo)
const struct esp_algorithm *algo;

View File

@ -1,4 +1,4 @@
/* $NetBSD: icmp6.c,v 1.66 2001/06/22 13:01:49 itojun Exp $ */
/* $NetBSD: icmp6.c,v 1.67 2001/10/15 11:12:44 itojun Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
@ -288,9 +288,15 @@ icmp6_error(m, type, code, param)
oip6 = mtod(m, struct ip6_hdr *);
/*
* Multicast destination check. For unrecognized option errors,
* this check has already done in ip6_unknown_opt(), so we can
* check only for other errors.
* If the destination address of the erroneous packet is a multicast
* address, or the packet was sent using link-layer multicast,
* we should basically suppress sending an error (RFC 2463, Section
* 2.4).
* We have two exceptions (the item e.2 in that section):
* - the Pakcet Too Big message can be sent for path MTU discovery.
* - the Parameter Problem Message that can be allowed an icmp6 error
* in the option type field. This check has been done in
* ip6_unknown_opt(), so we can just check the type and code.
*/
if ((m->m_flags & (M_BCAST|M_MCAST) ||
IN6_IS_ADDR_MULTICAST(&oip6->ip6_dst)) &&
@ -299,7 +305,10 @@ icmp6_error(m, type, code, param)
code != ICMP6_PARAMPROB_OPTION)))
goto freeit;
/* Source address check. XXX: the case of anycast source? */
/*
* RFC 2463, 2.4 (e.5): source address check.
* XXX: the case of anycast source?
*/
if (IN6_IS_ADDR_UNSPECIFIED(&oip6->ip6_src) ||
IN6_IS_ADDR_MULTICAST(&oip6->ip6_src))
goto freeit;
@ -336,7 +345,18 @@ icmp6_error(m, type, code, param)
} else {
/* ICMPv6 informational - send the error */
}
} else {
}
#if 0 /* controversial */
else if (off >= 0 && nxt == IPPROTO_ESP) {
/*
* It could be ICMPv6 error inside ESP. Take a safer side,
* don't respond.
*/
icmp6stat.icp6s_canterror++;
goto freeit;
}
#endif
else {
/* non-ICMPv6 - send the error */
}
@ -388,7 +408,7 @@ icmp6_error(m, type, code, param)
m->m_pkthdr.rcvif = NULL;
icmp6stat.icp6s_outhist[type]++;
icmp6_reflect(m, sizeof(struct ip6_hdr)); /*header order: IPv6 - ICMPv6*/
icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */
return;
@ -416,7 +436,7 @@ icmp6_input(mp, offp, proto)
#ifndef PULLDOWN_TEST
IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE);
/* m might change if M_LOOP. So, call mtod after this */
/* m might change if M_LOOP. So, call mtod after this */
#endif
/*
@ -476,7 +496,6 @@ icmp6_input(mp, offp, proto)
icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_error);
switch (icmp6->icmp6_type) {
case ICMP6_DST_UNREACH:
icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_dstunreach);
switch (code) {
@ -497,7 +516,7 @@ icmp6_input(mp, offp, proto)
#else
case ICMP6_DST_UNREACH_BEYONDSCOPE:
/* I mean "source address was incorrect." */
code = PRC_PARAMPROB;
code = PRC_UNREACH_NET;
break;
#endif
case ICMP6_DST_UNREACH_NOPORT:
@ -527,8 +546,10 @@ icmp6_input(mp, offp, proto)
icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_timeexceed);
switch (code) {
case ICMP6_TIME_EXCEED_TRANSIT:
code = PRC_TIMXCEED_INTRANS;
break;
case ICMP6_TIME_EXCEED_REASSEMBLY:
code += PRC_TIMXCEED_INTRANS;
code = PRC_TIMXCEED_REASS;
break;
default:
goto badcode;
@ -556,17 +577,29 @@ icmp6_input(mp, offp, proto)
icmp6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_echo);
if (code != 0)
goto badcode;
if ((n = m_copy(m, 0, M_COPYALL)) == NULL) {
/* Give up remote */
break;
/*
* Copy mbuf to send to two data paths: userland socket(s),
* and to the querier (echo reply).
* m: a copy for socket, n: a copy for querier
*/
if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
/* Give up local */
n = m;
m = NULL;
goto deliverecho;
}
if ((n->m_flags & M_EXT) != 0
|| n->m_len < off + sizeof(struct icmp6_hdr)) {
/*
* If the first mbuf is shared, or the first mbuf is too short,
* copy the first part of the data into a fresh mbuf.
* Otherwise, we will wrongly overwrite both copies.
*/
if ((n->m_flags & M_EXT) != 0 ||
n->m_len < off + sizeof(struct icmp6_hdr)) {
struct mbuf *n0 = n;
const int maxlen = sizeof(*nip6) + sizeof(*nicmp6);
/*
* Prepare an internal mbuf. m_pullup() doesn't
* Prepare an internal mbuf. m_pullup() doesn't
* always copy the length we specified.
*/
if (maxlen >= MCLBYTES) {
@ -583,9 +616,11 @@ icmp6_input(mp, offp, proto)
}
}
if (n == NULL) {
/* Give up remote */
/* Give up local */
m_freem(n0);
break;
n = m;
m = NULL;
goto deliverecho;
}
M_COPY_PKTHDR(n, n0);
/*
@ -596,17 +631,19 @@ icmp6_input(mp, offp, proto)
nicmp6 = (struct icmp6_hdr *)(nip6 + 1);
bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
noff = sizeof(struct ip6_hdr);
n->m_pkthdr.len = n->m_len =
noff + sizeof(struct icmp6_hdr);
n->m_len = noff + sizeof(struct icmp6_hdr);
/*
* Adjust mbuf. ip6_plen will be adjusted in
* Adjust mbuf. ip6_plen will be adjusted in
* ip6_output().
* n->m_pkthdr.len == n0->m_pkthdr.len at this point.
*/
n->m_pkthdr.len += noff + sizeof(struct icmp6_hdr);
n->m_pkthdr.len -= (off + sizeof(struct icmp6_hdr));
m_adj(n0, off + sizeof(struct icmp6_hdr));
n->m_pkthdr.len += n0->m_pkthdr.len;
n->m_next = n0;
n0->m_flags &= ~M_PKTHDR;
} else {
deliverecho:
nip6 = mtod(n, struct ip6_hdr *);
nicmp6 = (struct icmp6_hdr *)((caddr_t)nip6 + off);
noff = off;
@ -618,6 +655,8 @@ icmp6_input(mp, offp, proto)
icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++;
icmp6_reflect(n, noff);
}
if (!m)
goto freeit;
break;
case ICMP6_ECHO_REPLY:
@ -652,7 +691,7 @@ icmp6_input(mp, offp, proto)
case MLD6_MTRACE_RESP:
case MLD6_MTRACE:
/* XXX: these two are experimental. not officially defind. */
/* XXX: these two are experimental. not officially defind. */
/* XXX: per-interface statistics? */
break; /* just pass it to applications */
@ -675,7 +714,7 @@ icmp6_input(mp, offp, proto)
IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo),
IPPROTO_DONE);
#endif
n = m_copy(m, 0, M_COPYALL);
n = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
if (n)
n = ni6_input(n, off);
/* XXX meaningless if n == NULL */
@ -684,6 +723,9 @@ icmp6_input(mp, offp, proto)
u_char *p;
int maxlen, maxhlen;
if ((icmp6_nodeinfo & 5) != 5)
break;
if (code != 0)
goto badcode;
maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4;
@ -703,6 +745,7 @@ icmp6_input(mp, offp, proto)
/* Give up remote */
break;
}
n->m_pkthdr.rcvif = NULL;
n->m_len = 0;
maxhlen = M_TRAILINGSPACE(n) - maxlen;
if (maxhlen > hostnamelen)
@ -716,7 +759,7 @@ icmp6_input(mp, offp, proto)
bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
p = (u_char *)(nicmp6 + 1);
bzero(p, 4);
bcopy(hostname, p + 4, maxhlen); /*meaningless TTL*/
bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */
noff = sizeof(struct ip6_hdr);
M_COPY_PKTHDR(n, m); /* just for recvif */
n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
@ -909,7 +952,7 @@ icmp6_notify_error(m, off, icmp6len, code)
struct ip6_rthdr0 *rth0;
int rthlen;
while (1) { /* XXX: should avoid inf. loop explicitly? */
while (1) { /* XXX: should avoid infinite loop explicitly? */
struct ip6_ext *eh;
switch (nxt) {
@ -1023,7 +1066,7 @@ icmp6_notify_error(m, off, icmp6len, code)
default:
/*
* This case includes ESP and the No Next
* Header. In such cases going to the notify
* Header. In such cases going to the notify
* label does not have any meaning
* (i.e. ctlfunc will be NULL), but we go
* anyway since we might have to update
@ -1171,8 +1214,9 @@ icmp6_mtudisc_update(ip6cp, validated)
rt->rt_rmx.rmx_mtu = mtu;
}
}
if (rt)
if (rt) { /* XXX: need braces to avoid conflict with else in RTFREE. */
RTFREE(rt);
}
/*
* Notify protocols that the MTU for this destination
@ -1255,7 +1299,7 @@ ni6_input(m, off)
/* 07 draft */
if (ni6->ni_code == ICMP6_NI_SUBJ_FQDN && subjlen == 0)
break;
/*FALLTHROUGH*/
/* FALLTHROUGH */
case NI_QTYPE_FQDN:
case NI_QTYPE_NODEADDR:
switch (ni6->ni_code) {
@ -1353,6 +1397,18 @@ ni6_input(m, off)
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:
@ -1373,7 +1429,7 @@ ni6_input(m, off)
default:
/*
* XXX: We must return a reply with the ICMP6 code
* `unknown Qtype' in this case. However we regard the case
* `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.
@ -1547,8 +1603,12 @@ ni6_nametodns(name, namelen, old)
/* result does not fit into mbuf */
if (cp + i + 1 >= ep)
goto fail;
/* DNS label length restriction, RFC1035 page 8 */
if (i >= 64)
/*
* 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;
bcopy(p, cp, i);
@ -1567,7 +1627,7 @@ ni6_nametodns(name, namelen, old)
}
panic("should not reach here");
/*NOTREACHED*/
/* NOTREACHED */
fail:
if (m)
@ -1719,7 +1779,7 @@ ni6_addrs(ni6, m, ifpp, subj)
/*
* check if anycast is okay.
* XXX: just experimental. not in the spec.
* XXX: just experimental. not in the spec.
*/
if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
(niflags & NI_NODEADDR_FLAG_ANYCAST) == 0)
@ -1805,7 +1865,7 @@ ni6_store_addrs(ni6, nni6, ifp0, resid)
/*
* check if anycast is okay.
* XXX: just experimental. not in the spec.
* XXX: just experimental. not in the spec.
*/
if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0 &&
(niflags & NI_NODEADDR_FLAG_ANYCAST) == 0)
@ -1837,16 +1897,21 @@ ni6_store_addrs(ni6, nni6, ifp0, resid)
* 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 (ifa6->ia6_lifetime.ia6t_expire == 0)
ltime = ND6_INFINITE_LIFETIME;
else {
if (ifa6->ia6_lifetime.ia6t_expire >
time_second)
ltime = htonl(ifa6->ia6_lifetime.ia6t_expire - time_second);
ltime = ifa6->ia6_lifetime.ia6t_expire - time_second;
else
ltime = 0;
}
if (ltime > 0x7fffffff)
ltime = 0x7fffffff;
ltime = htonl(ltime);
bcopy(&ltime, cp, sizeof(u_int32_t));
cp += sizeof(u_int32_t);
@ -2055,7 +2120,9 @@ icmp6_reflect(m, off)
sa6_src.sin6_len = sizeof(sa6_src);
sa6_src.sin6_addr = ip6->ip6_dst;
in6_recoverscope(&sa6_src, &ip6->ip6_dst, m->m_pkthdr.rcvif);
in6_embedscope(&ip6->ip6_dst, &sa6_src, NULL, NULL);
in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL, NULL);
ip6->ip6_dst = sa6_src.sin6_addr;
bzero(&sa6_dst, sizeof(sa6_dst));
sa6_dst.sin6_family = AF_INET6;
sa6_dst.sin6_len = sizeof(sa6_dst);
@ -2064,7 +2131,7 @@ icmp6_reflect(m, off)
in6_embedscope(&t, &sa6_dst, NULL, NULL);
/*
* If the incoming packet was addressed directly to us(i.e. unicast),
* If the incoming packet was addressed directly to us (i.e. unicast),
* use dst as the src for the reply.
* The IN6_IFF_NOTREADY case would be VERY rare, but is possible
* (for example) when we encounter an error while forwarding procedure
@ -2079,7 +2146,7 @@ icmp6_reflect(m, off)
if (ia == NULL && IN6_IS_ADDR_LINKLOCAL(&t) && (m->m_flags & M_LOOP)) {
/*
* This is the case if the dst is our link-local address
* and the sender is also ourseleves.
* and the sender is also ourselves.
*/
src = &t;
}
@ -2090,13 +2157,14 @@ icmp6_reflect(m, off)
/*
* This case matches to multicasts, our anycast, or unicasts
* that we do not own. Select a source address based on the
* that we do not own. Select a source address based on the
* source address of the erroneous packet.
*/
bzero(&ro, sizeof(ro));
src = in6_selectsrc(&sa6_src, NULL, NULL, &ro, NULL, &e);
if (ro.ro_rt)
if (ro.ro_rt) { /* XXX: see comments in icmp6_mtudisc_update */
RTFREE(ro.ro_rt); /* XXX: we could use this */
}
if (src == NULL) {
nd6log((LOG_DEBUG,
"icmp6_reflect: source can't be determined: "
@ -2123,7 +2191,7 @@ icmp6_reflect(m, off)
sizeof(struct ip6_hdr), plen);
/*
* xxx option handling
* XXX option handling
*/
m->m_flags &= ~(M_BCAST|M_MCAST);
@ -2322,7 +2390,7 @@ icmp6_redirect_input(m, off)
nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT,
is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER);
if (!is_onlink) { /* better router case. perform rtredirect. */
if (!is_onlink) { /* better router case. perform rtredirect. */
/* perform rtredirect */
struct sockaddr_in6 sdst;
struct sockaddr_in6 sgw;
@ -2533,7 +2601,7 @@ icmp6_redirect_output(m0, rt)
if (!rt_router)
goto nolladdropt;
len = sizeof(*nd_opt) + ifp->if_addrlen;
len = (len + 7) & ~7; /*round by 8*/
len = (len + 7) & ~7; /* round by 8 */
/* safety check */
if (len + (p - (u_char *)ip6) > maxlen)
goto nolladdropt;
@ -2771,7 +2839,7 @@ icmp6_ratelimit(dst, type, code)
{
int ret;
ret = 0; /*okay to send*/
ret = 0; /* okay to send */
/* PPS limit */
if (!ppsratecheck(&icmp6errppslim_last, &icmp6errpps_count,