From c8498c6b7f34385ec8ecfd268ca8b59bd7b296e4 Mon Sep 17 00:00:00 2001 From: ae Date: Wed, 10 Sep 2014 14:32:07 +0000 Subject: [PATCH] Add additional checks for IPV6_PKTINFO handling (RFC 3542): * Return ENETDOWN when interface specified by ipi6_ifindex is not enabled for IPv6 use. * Return EADDRNOTAVAIL when ipi6_ifindex specifies an interface, but the address ipi6_addr is not available for use on that interface. * Return EINVAL when ipi6_addr is multicast address. Obtained from: Yandex LLC Sponsored by: Yandex LLC --- sys/netinet6/ip6_output.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 4fae81792032..c3e9501abd05 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -2559,7 +2559,8 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, sticky && !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) { return (EINVAL); } - + if (IN6_IS_ADDR_MULTICAST(&pktinfo->ipi6_addr)) + return (EINVAL); /* validate the interface index if specified. */ if (pktinfo->ipi6_ifindex > V_if_index) return (ENXIO); @@ -2568,7 +2569,19 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, if (ifp == NULL) return (ENXIO); } + if (ifp != NULL && ( + ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) + return (ENETDOWN); + if (ifp != NULL && + !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) { + struct in6_ifaddr *ia; + + ia = in6ifa_ifpwithaddr(ifp, &pktinfo->ipi6_addr); + if (ia == NULL) + return (EADDRNOTAVAIL); + ifa_free(&ia->ia_ifa); + } /* * We store the address anyway, and let in6_selectsrc() * validate the specified address. This is because ipi6_addr