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:
parent
91498ffec5
commit
149aafe6ad
@ -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;
|
||||
|
@ -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(<ime, 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,
|
||||
|
Loading…
Reference in New Issue
Block a user