summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/icmp6.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-10-24 18:26:30 +0000
committerume <ume@FreeBSD.org>2003-10-24 18:26:30 +0000
commit881c4fa39150df7d0de2dae7ae808f6a73cb199a (patch)
tree6ce05cb7459c9a9be90d670c12bfddbbbcb6946d /sys/netinet6/icmp6.c
parent0b2009d038122fd790a91ca95c5d9044ff2715c0 (diff)
downloadFreeBSD-src-881c4fa39150df7d0de2dae7ae808f6a73cb199a.zip
FreeBSD-src-881c4fa39150df7d0de2dae7ae808f6a73cb199a.tar.gz
Switch Advanced Sockets API for IPv6 from RFC2292 to RFC3542
(aka RFC2292bis). Though I believe this commit doesn't break backward compatibility againt existing binaries, it breaks backward compatibility of API. Now, the applications which use Advanced Sockets API such as telnet, ping6, mld6query and traceroute6 use RFC3542 API. Obtained from: KAME
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r--sys/netinet6/icmp6.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index aa96326..30e534f 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -245,9 +245,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)) &&
@@ -256,7 +262,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;
@@ -1100,6 +1109,26 @@ icmp6_mtudisc_update(ip6cp, validated)
struct rtentry *rt = NULL;
struct sockaddr_in6 sin6;
+#if 0
+ /*
+ * RFC2460 section 5, last paragraph.
+ * even though minimum link MTU for IPv6 is IPV6_MMTU,
+ * we may see ICMPv6 too big with mtu < IPV6_MMTU
+ * due to packet translator in the middle.
+ * see ip6_output() and ip6_getpmtu() "alwaysfrag" case for
+ * special handling.
+ */
+ if (mtu < IPV6_MMTU)
+ return;
+#endif
+
+ /*
+ * we reject ICMPv6 too big with abnormally small value.
+ * XXX what is the good definition of "abnormally small"?
+ */
+ if (mtu < sizeof(struct ip6_hdr) + sizeof(struct ip6_frag) + 8)
+ return;
+
if (!validated)
return;
@@ -2122,7 +2151,9 @@ icmp6_reflect(m, off)
ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
ip6->ip6_vfc |= IPV6_VERSION;
ip6->ip6_nxt = IPPROTO_ICMPV6;
- if (m->m_pkthdr.rcvif) {
+ if (outif)
+ ip6->ip6_hlim = ND_IFINFO(outif)->chlim;
+ else if (m->m_pkthdr.rcvif) {
/* XXX: This may not be the outgoing interface */
ip6->ip6_hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim;
} else
OpenPOWER on IntegriCloud