Generalize previous fix so that both NS and NA packets are checked.

This commit is contained in:
matt 2008-07-31 18:24:07 +00:00
parent fc3801b3c9
commit a1469c2d6d
3 changed files with 41 additions and 17 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.c,v 1.140 2008/02/27 19:40:56 matt Exp $ */
/* $NetBSD: in6.c,v 1.141 2008/07/31 18:24:07 matt Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.140 2008/02/27 19:40:56 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.141 2008/07/31 18:24:07 matt Exp $");
#include "opt_inet.h"
#include "opt_pfil_hooks.h"
@ -1788,6 +1788,31 @@ in6ifa_ifpwithaddr(const struct ifnet *ifp, const struct in6_addr *addr)
return (struct in6_ifaddr *)ifa;
}
/*
* find the internet address on a given interface corresponding to a neighbor's
* address.
*/
struct in6_ifaddr *
in6ifa_ifplocaladdr(const struct ifnet *ifp, const struct in6_addr *addr)
{
struct ifaddr *ifa;
struct in6_ifaddr *ia;
IFADDR_FOREACH(ifa, ifp) {
if (ifa->ifa_addr == NULL)
continue; /* just for safety */
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
ia = (struct in6_ifaddr *)ifa;
if (IN6_ARE_MASKED_ADDR_EQUAL(addr,
&ia->ia_addr.sin6_addr,
&ia->ia_prefixmask.sin6_addr))
return ia;
}
return NULL;
}
/*
* Convert IP6 address to printable (loggable) representation.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_var.h,v 1.58 2008/04/15 03:57:04 thorpej Exp $ */
/* $NetBSD: in6_var.h,v 1.59 2008/07/31 18:24:07 matt Exp $ */
/* $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $ */
/*
@ -683,6 +683,8 @@ void in6_ifaddloop(struct ifaddr *);
void in6_createmkludge(struct ifnet *);
void in6_purgemkludge(struct ifnet *);
struct in6_ifaddr *in6ifa_ifpforlinklocal(const struct ifnet *, int);
struct in6_ifaddr *in6ifa_ifplocaladdr(const struct ifnet *,
const struct in6_addr *);
struct in6_ifaddr *in6ifa_ifpwithaddr(const struct ifnet *,
const struct in6_addr *);
char *ip6_sprintf(const struct in6_addr *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nd6_nbr.c,v 1.89 2008/07/31 18:01:36 matt Exp $ */
/* $NetBSD: nd6_nbr.c,v 1.90 2008/07/31 18:24:07 matt Exp $ */
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.89 2008/07/31 18:01:36 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.90 2008/07/31 18:24:07 matt Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -150,16 +150,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
/*
* Make sure the source address is from a neighbor's address.
*/
IFADDR_FOREACH(ifa, ifp) {
struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
if (ia->ia_ifa.ifa_addr != NULL
&& ia->ia_ifa.ifa_addr->sa_family == AF_INET6
&& IN6_ARE_MASKED_ADDR_EQUAL(&saddr6,
&ia->ia_addr.sin6_addr,
&ia->ia_prefixmask.sin6_addr))
break;
}
if (ifa == NULL) {
if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
nd6log((LOG_INFO, "nd6_ns_input: "
"NS packet from non-neighbor\n"));
goto bad;
@ -562,9 +553,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
struct ifnet *ifp = m->m_pkthdr.rcvif;
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct nd_neighbor_advert *nd_na;
#if 0
struct in6_addr saddr6 = ip6->ip6_src;
#endif
struct in6_addr daddr6 = ip6->ip6_dst;
struct in6_addr taddr6;
int flags;
@ -652,6 +641,14 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
ip6_sprintf(&taddr6));
goto freeit;
}
/*
* Make sure the source address is from a neighbor's address.
*/
if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
nd6log((LOG_INFO, "nd6_ns_input: "
"ND packet from non-neighbor\n"));
goto bad;
}
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "