Fri Oct 3 10:43:48 2008 UTC ()
Pull up revisions:
  src/sys/netinet6/in6.c	1.141 via patch
  src/sys/netinet6/in6_var.h	1.59 via patch
  src/sys/netinet6/nd6_nbr.c	1.89-1.90 via patch
(requested by adrianp in ticket #1967).

If a neighbor solictation isn't from the unspecified address, make sure
that the source address matches one of the interfaces address prefixes.

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


(jdc)
diff -r1.91 -r1.91.4.1 src/sys/netinet6/in6.c
diff -r1.38 -r1.38.4.1 src/sys/netinet6/in6_var.h
diff -r1.56 -r1.56.2.1 src/sys/netinet6/nd6_nbr.c

cvs diff -r1.91 -r1.91.4.1 src/sys/netinet6/in6.c (expand / switch to unified diff)

--- src/sys/netinet6/in6.c 2005/02/01 15:29:23 1.91
+++ src/sys/netinet6/in6.c 2008/10/03 10:43:48 1.91.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: in6.c,v 1.91 2005/02/01 15:29:23 drochner Exp $ */ 1/* $NetBSD: in6.c,v 1.91.4.1 2008/10/03 10:43:48 jdc Exp $ */
2/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */ 2/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -52,27 +52,27 @@ @@ -52,27 +52,27 @@
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)in.c 8.2 (Berkeley) 11/15/93 61 * @(#)in.c 8.2 (Berkeley) 11/15/93
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.91 2005/02/01 15:29:23 drochner Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.91.4.1 2008/10/03 10:43:48 jdc Exp $");
66 66
67#include "opt_inet.h" 67#include "opt_inet.h"
68#include "opt_pfil_hooks.h" 68#include "opt_pfil_hooks.h"
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/ioctl.h> 71#include <sys/ioctl.h>
72#include <sys/errno.h> 72#include <sys/errno.h>
73#include <sys/malloc.h> 73#include <sys/malloc.h>
74#include <sys/socket.h> 74#include <sys/socket.h>
75#include <sys/socketvar.h> 75#include <sys/socketvar.h>
76#include <sys/sockio.h> 76#include <sys/sockio.h>
77#include <sys/systm.h> 77#include <sys/systm.h>
78#include <sys/proc.h> 78#include <sys/proc.h>
@@ -2015,26 +2015,51 @@ in6ifa_ifpwithaddr(ifp, addr) @@ -2015,26 +2015,51 @@ in6ifa_ifpwithaddr(ifp, addr)
2015 { 2015 {
2016 if (ifa->ifa_addr == NULL) 2016 if (ifa->ifa_addr == NULL)
2017 continue; /* just for safety */ 2017 continue; /* just for safety */
2018 if (ifa->ifa_addr->sa_family != AF_INET6) 2018 if (ifa->ifa_addr->sa_family != AF_INET6)
2019 continue; 2019 continue;
2020 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa))) 2020 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
2021 break; 2021 break;
2022 } 2022 }
2023 2023
2024 return ((struct in6_ifaddr *)ifa); 2024 return ((struct in6_ifaddr *)ifa);
2025} 2025}
2026 2026
2027/* 2027/*
 2028 * find the internet address on a given interface corresponding to a neighbor's
 2029 * address.
 2030 */
 2031struct in6_ifaddr *
 2032in6ifa_ifplocaladdr(const struct ifnet *ifp, const struct in6_addr *addr)
 2033{
 2034 struct ifaddr *ifa;
 2035 struct in6_ifaddr *ia;
 2036
 2037 IFADDR_FOREACH(ifa, ifp) {
 2038 if (ifa->ifa_addr == NULL)
 2039 continue; /* just for safety */
 2040 if (ifa->ifa_addr->sa_family != AF_INET6)
 2041 continue;
 2042 ia = (struct in6_ifaddr *)ifa;
 2043 if (IN6_ARE_MASKED_ADDR_EQUAL(addr,
 2044 &ia->ia_addr.sin6_addr,
 2045 &ia->ia_prefixmask.sin6_addr))
 2046 return ia;
 2047 }
 2048
 2049 return NULL;
 2050}
 2051
 2052/*
2028 * Convert IP6 address to printable (loggable) representation. 2053 * Convert IP6 address to printable (loggable) representation.
2029 */ 2054 */
2030static char digits[] = "0123456789abcdef"; 2055static char digits[] = "0123456789abcdef";
2031static int ip6round = 0; 2056static int ip6round = 0;
2032char * 2057char *
2033ip6_sprintf(addr) 2058ip6_sprintf(addr)
2034 const struct in6_addr *addr; 2059 const struct in6_addr *addr;
2035{ 2060{
2036 static char ip6buf[8][48]; 2061 static char ip6buf[8][48];
2037 int i; 2062 int i;
2038 char *cp; 2063 char *cp;
2039 const u_int16_t *a = (const u_int16_t *)addr; 2064 const u_int16_t *a = (const u_int16_t *)addr;
2040 const u_int8_t *d; 2065 const u_int8_t *d;

cvs diff -r1.38 -r1.38.4.1 src/sys/netinet6/in6_var.h (expand / switch to unified diff)

--- src/sys/netinet6/in6_var.h 2005/02/01 15:29:23 1.38
+++ src/sys/netinet6/in6_var.h 2008/10/03 10:43:48 1.38.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: in6_var.h,v 1.38 2005/02/01 15:29:23 drochner Exp $ */ 1/* $NetBSD: in6_var.h,v 1.38.4.1 2008/10/03 10:43:48 jdc Exp $ */
2/* $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $ */ 2/* $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -582,26 +582,28 @@ int in6_control __P((struct socket *, u_ @@ -582,26 +582,28 @@ int in6_control __P((struct socket *, u_
582int in6_update_ifa __P((struct ifnet *, struct in6_aliasreq *, 582int in6_update_ifa __P((struct ifnet *, struct in6_aliasreq *,
583 struct in6_ifaddr *)); 583 struct in6_ifaddr *));
584void in6_purgeaddr __P((struct ifaddr *)); 584void in6_purgeaddr __P((struct ifaddr *));
585int in6if_do_dad __P((struct ifnet *)); 585int in6if_do_dad __P((struct ifnet *));
586void in6_purgeif __P((struct ifnet *)); 586void in6_purgeif __P((struct ifnet *));
587void in6_savemkludge __P((struct in6_ifaddr *)); 587void in6_savemkludge __P((struct in6_ifaddr *));
588void in6_setmaxmtu __P((void)); 588void in6_setmaxmtu __P((void));
589void *in6_domifattach __P((struct ifnet *)); 589void *in6_domifattach __P((struct ifnet *));
590void in6_domifdetach __P((struct ifnet *, void *)); 590void in6_domifdetach __P((struct ifnet *, void *));
591void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *)); 591void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
592void in6_createmkludge __P((struct ifnet *)); 592void in6_createmkludge __P((struct ifnet *));
593void in6_purgemkludge __P((struct ifnet *)); 593void in6_purgemkludge __P((struct ifnet *));
594struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int)); 594struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int));
 595struct in6_ifaddr *in6ifa_ifplocaladdr __P((const struct ifnet *,
 596 const struct in6_addr *));
595struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *)); 597struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *));
596char *ip6_sprintf __P((const struct in6_addr *)); 598char *ip6_sprintf __P((const struct in6_addr *));
597int in6_addr2scopeid __P((struct ifnet *, struct in6_addr *)); 599int in6_addr2scopeid __P((struct ifnet *, struct in6_addr *));
598int in6_matchlen __P((struct in6_addr *, struct in6_addr *)); 600int in6_matchlen __P((struct in6_addr *, struct in6_addr *));
599int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int)); 601int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int));
600void in6_prefixlen2mask __P((struct in6_addr *, int)); 602void in6_prefixlen2mask __P((struct in6_addr *, int));
601void in6_purgeprefix __P((struct ifnet *)); 603void in6_purgeprefix __P((struct ifnet *));
602 604
603int in6_is_addr_deprecated __P((struct sockaddr_in6 *)); 605int in6_is_addr_deprecated __P((struct sockaddr_in6 *));
604struct in6pcb; 606struct in6pcb;
605int in6_embedscope __P((struct in6_addr *, const struct sockaddr_in6 *, 607int in6_embedscope __P((struct in6_addr *, const struct sockaddr_in6 *,
606 struct in6pcb *, struct ifnet **)); 608 struct in6pcb *, struct ifnet **));
607int in6_recoverscope __P((struct sockaddr_in6 *, const struct in6_addr *, 609int in6_recoverscope __P((struct sockaddr_in6 *, const struct in6_addr *,

cvs diff -r1.56 -r1.56.2.1 src/sys/netinet6/nd6_nbr.c (expand / switch to unified diff)

--- src/sys/netinet6/nd6_nbr.c 2005/02/26 22:45:13 1.56
+++ src/sys/netinet6/nd6_nbr.c 2008/10/03 10:43:48 1.56.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nd6_nbr.c,v 1.56 2005/02/26 22:45:13 perry Exp $ */ 1/* $NetBSD: nd6_nbr.c,v 1.56.2.1 2008/10/03 10:43:48 jdc Exp $ */
2/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ 2/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.56 2005/02/26 22:45:13 perry Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.56.2.1 2008/10/03 10:43:48 jdc Exp $");
35 35
36#include "opt_inet.h" 36#include "opt_inet.h"
37#include "opt_ipsec.h" 37#include "opt_ipsec.h"
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/malloc.h> 41#include <sys/malloc.h>
42#include <sys/mbuf.h> 42#include <sys/mbuf.h>
43#include <sys/socket.h> 43#include <sys/socket.h>
44#include <sys/sockio.h> 44#include <sys/sockio.h>
45#include <sys/time.h> 45#include <sys/time.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
47#include <sys/errno.h> 47#include <sys/errno.h>
@@ -129,28 +129,38 @@ nd6_ns_input(m, off, icmp6len) @@ -129,28 +129,38 @@ nd6_ns_input(m, off, icmp6len)
129 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { 129 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
130 /* dst has to be solicited node multicast address. */ 130 /* dst has to be solicited node multicast address. */
131 /* don't check ifindex portion */ 131 /* don't check ifindex portion */
132 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL && 132 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
133 daddr6.s6_addr32[1] == 0 && 133 daddr6.s6_addr32[1] == 0 &&
134 daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE && 134 daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
135 daddr6.s6_addr8[12] == 0xff) { 135 daddr6.s6_addr8[12] == 0xff) {
136 ; /* good */ 136 ; /* good */
137 } else { 137 } else {
138 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 138 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
139 "(wrong ip6 dst)\n")); 139 "(wrong ip6 dst)\n"));
140 goto bad; 140 goto bad;
141 } 141 }
 142 } else {
 143 /*
 144 * Make sure the source address is from a neighbor's address.
 145 */
 146 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
 147 nd6log((LOG_INFO, "nd6_ns_input: "
 148 "NS packet from non-neighbor\n"));
 149 goto bad;
 150 }
142 } 151 }
143 152
 153
144 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 154 if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
145 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n")); 155 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"));
146 goto bad; 156 goto bad;
147 } 157 }
148 158
149 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6)) 159 if (IN6_IS_SCOPE_LINKLOCAL(&taddr6))
150 taddr6.s6_addr16[1] = htons(ifp->if_index); 160 taddr6.s6_addr16[1] = htons(ifp->if_index);
151 161
152 icmp6len -= sizeof(*nd_ns); 162 icmp6len -= sizeof(*nd_ns);
153 nd6_option_init(nd_ns + 1, icmp6len, &ndopts); 163 nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
154 if (nd6_options(&ndopts) < 0) { 164 if (nd6_options(&ndopts) < 0) {
155 nd6log((LOG_INFO, 165 nd6log((LOG_INFO,
156 "nd6_ns_input: invalid ND option, ignored\n")); 166 "nd6_ns_input: invalid ND option, ignored\n"));
@@ -530,29 +540,27 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, d @@ -530,29 +540,27 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, d
530 * 540 *
531 * the following items are not implemented yet: 541 * the following items are not implemented yet:
532 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD) 542 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
533 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD) 543 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
534 */ 544 */
535void 545void
536nd6_na_input(m, off, icmp6len) 546nd6_na_input(m, off, icmp6len)
537 struct mbuf *m; 547 struct mbuf *m;
538 int off, icmp6len; 548 int off, icmp6len;
539{ 549{
540 struct ifnet *ifp = m->m_pkthdr.rcvif; 550 struct ifnet *ifp = m->m_pkthdr.rcvif;
541 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 551 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
542 struct nd_neighbor_advert *nd_na; 552 struct nd_neighbor_advert *nd_na;
543#if 0 
544 struct in6_addr saddr6 = ip6->ip6_src; 553 struct in6_addr saddr6 = ip6->ip6_src;
545#endif 
546 struct in6_addr daddr6 = ip6->ip6_dst; 554 struct in6_addr daddr6 = ip6->ip6_dst;
547 struct in6_addr taddr6; 555 struct in6_addr taddr6;
548 int flags; 556 int flags;
549 int is_router; 557 int is_router;
550 int is_solicited; 558 int is_solicited;
551 int is_override; 559 int is_override;
552 char *lladdr = NULL; 560 char *lladdr = NULL;
553 int lladdrlen = 0; 561 int lladdrlen = 0;
554 struct ifaddr *ifa; 562 struct ifaddr *ifa;
555 struct llinfo_nd6 *ln; 563 struct llinfo_nd6 *ln;
556 struct rtentry *rt; 564 struct rtentry *rt;
557 struct sockaddr_dl *sdl; 565 struct sockaddr_dl *sdl;
558 union nd_opts ndopts; 566 union nd_opts ndopts;
@@ -619,26 +627,34 @@ nd6_na_input(m, off, icmp6len) @@ -619,26 +627,34 @@ nd6_na_input(m, off, icmp6len)
619 if (ifa 627 if (ifa
620 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) { 628 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) {
621 nd6_dad_na_input(ifa); 629 nd6_dad_na_input(ifa);
622 goto freeit; 630 goto freeit;
623 } 631 }
624 632
625 /* Just for safety, maybe unnecessary. */ 633 /* Just for safety, maybe unnecessary. */
626 if (ifa) { 634 if (ifa) {
627 log(LOG_ERR, 635 log(LOG_ERR,
628 "nd6_na_input: duplicate IP6 address %s\n", 636 "nd6_na_input: duplicate IP6 address %s\n",
629 ip6_sprintf(&taddr6)); 637 ip6_sprintf(&taddr6));
630 goto freeit; 638 goto freeit;
631 } 639 }
 640 /*
 641 * Make sure the source address is from a neighbor's address.
 642 */
 643 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
 644 nd6log((LOG_INFO, "nd6_ns_input: "
 645 "ND packet from non-neighbor\n"));
 646 goto bad;
 647 }
632 648
633 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 649 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
634 nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s " 650 nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "
635 "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6), 651 "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6),
636 ifp->if_addrlen, lladdrlen - 2)); 652 ifp->if_addrlen, lladdrlen - 2));
637 goto bad; 653 goto bad;
638 } 654 }
639 655
640 /* 656 /*
641 * If no neighbor cache entry is found, NA SHOULD silently be 657 * If no neighbor cache entry is found, NA SHOULD silently be
642 * discarded. 658 * discarded.
643 */ 659 */
644 rt = nd6_lookup(&taddr6, 0, ifp); 660 rt = nd6_lookup(&taddr6, 0, ifp);