Fri Oct 3 10:32:23 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 #1210).

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.119 -r1.119.8.1 src/sys/netinet6/in6.c
diff -r1.47 -r1.47.8.1 src/sys/netinet6/in6_var.h
diff -r1.65 -r1.65.14.1 src/sys/netinet6/nd6_nbr.c

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

--- src/sys/netinet6/in6.c 2006/11/24 19:47:00 1.119
+++ src/sys/netinet6/in6.c 2008/10/03 10:32:22 1.119.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: in6.c,v 1.119 2006/11/24 19:47:00 christos Exp $ */ 1/* $NetBSD: in6.c,v 1.119.8.1 2008/10/03 10:32:22 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.119 2006/11/24 19:47:00 christos Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.119.8.1 2008/10/03 10:32:22 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>
@@ -1788,26 +1788,51 @@ in6ifa_ifpwithaddr(ifp, addr) @@ -1788,26 +1788,51 @@ in6ifa_ifpwithaddr(ifp, addr)
1788 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1788 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1789 if (ifa->ifa_addr == NULL) 1789 if (ifa->ifa_addr == NULL)
1790 continue; /* just for safety */ 1790 continue; /* just for safety */
1791 if (ifa->ifa_addr->sa_family != AF_INET6) 1791 if (ifa->ifa_addr->sa_family != AF_INET6)
1792 continue; 1792 continue;
1793 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa))) 1793 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1794 break; 1794 break;
1795 } 1795 }
1796 1796
1797 return (struct in6_ifaddr *)ifa; 1797 return (struct in6_ifaddr *)ifa;
1798} 1798}
1799 1799
1800/* 1800/*
 1801 * find the internet address on a given interface corresponding to a neighbor's
 1802 * address.
 1803 */
 1804struct in6_ifaddr *
 1805in6ifa_ifplocaladdr(const struct ifnet *ifp, const struct in6_addr *addr)
 1806{
 1807 struct ifaddr *ifa;
 1808 struct in6_ifaddr *ia;
 1809
 1810 IFADDR_FOREACH(ifa, ifp) {
 1811 if (ifa->ifa_addr == NULL)
 1812 continue; /* just for safety */
 1813 if (ifa->ifa_addr->sa_family != AF_INET6)
 1814 continue;
 1815 ia = (struct in6_ifaddr *)ifa;
 1816 if (IN6_ARE_MASKED_ADDR_EQUAL(addr,
 1817 &ia->ia_addr.sin6_addr,
 1818 &ia->ia_prefixmask.sin6_addr))
 1819 return ia;
 1820 }
 1821
 1822 return NULL;
 1823}
 1824
 1825/*
1801 * Convert IP6 address to printable (loggable) representation. 1826 * Convert IP6 address to printable (loggable) representation.
1802 */ 1827 */
1803static int ip6round = 0; 1828static int ip6round = 0;
1804char * 1829char *
1805ip6_sprintf(addr) 1830ip6_sprintf(addr)
1806 const struct in6_addr *addr; 1831 const struct in6_addr *addr;
1807{ 1832{
1808 static char ip6buf[8][48]; 1833 static char ip6buf[8][48];
1809 int i; 1834 int i;
1810 char *cp; 1835 char *cp;
1811 const u_int16_t *a = (const u_int16_t *)addr; 1836 const u_int16_t *a = (const u_int16_t *)addr;
1812 const u_int8_t *d; 1837 const u_int8_t *d;
1813 int dcolon = 0; 1838 int dcolon = 0;

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

--- src/sys/netinet6/in6_var.h 2006/11/20 04:17:57 1.47
+++ src/sys/netinet6/in6_var.h 2008/10/03 10:32:22 1.47.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: in6_var.h,v 1.47 2006/11/20 04:17:57 dyoung Exp $ */ 1/* $NetBSD: in6_var.h,v 1.47.8.1 2008/10/03 10:32:22 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
@@ -633,26 +633,28 @@ void in6_purgeaddr __P((struct ifaddr *) @@ -633,26 +633,28 @@ void in6_purgeaddr __P((struct ifaddr *)
633int in6if_do_dad __P((struct ifnet *)); 633int in6if_do_dad __P((struct ifnet *));
634void in6_purgeif __P((struct ifnet *)); 634void in6_purgeif __P((struct ifnet *));
635void in6_savemkludge __P((struct in6_ifaddr *)); 635void in6_savemkludge __P((struct in6_ifaddr *));
636void in6_setmaxmtu __P((void)); 636void in6_setmaxmtu __P((void));
637int in6_if2idlen __P((struct ifnet *)); 637int in6_if2idlen __P((struct ifnet *));
638void *in6_domifattach __P((struct ifnet *)); 638void *in6_domifattach __P((struct ifnet *));
639void in6_domifdetach __P((struct ifnet *, void *)); 639void in6_domifdetach __P((struct ifnet *, void *));
640void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *)); 640void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
641void in6_ifremloop(struct ifaddr *); 641void in6_ifremloop(struct ifaddr *);
642void in6_ifaddloop(struct ifaddr *); 642void in6_ifaddloop(struct ifaddr *);
643void in6_createmkludge __P((struct ifnet *)); 643void in6_createmkludge __P((struct ifnet *));
644void in6_purgemkludge __P((struct ifnet *)); 644void in6_purgemkludge __P((struct ifnet *));
645struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int)); 645struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *, int));
 646struct in6_ifaddr *in6ifa_ifplocaladdr __P((const struct ifnet *,
 647 const struct in6_addr *));
646struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *)); 648struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *, struct in6_addr *));
647char *ip6_sprintf __P((const struct in6_addr *)); 649char *ip6_sprintf __P((const struct in6_addr *));
648int in6_matchlen __P((struct in6_addr *, struct in6_addr *)); 650int in6_matchlen __P((struct in6_addr *, struct in6_addr *));
649int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int)); 651int in6_are_prefix_equal __P((struct in6_addr *, struct in6_addr *, int));
650void in6_prefixlen2mask __P((struct in6_addr *, int)); 652void in6_prefixlen2mask __P((struct in6_addr *, int));
651void in6_purgeprefix __P((struct ifnet *)); 653void in6_purgeprefix __P((struct ifnet *));
652 654
653int in6_src_ioctl __P((u_long, caddr_t)); 655int in6_src_ioctl __P((u_long, caddr_t));
654int in6_is_addr_deprecated __P((struct sockaddr_in6 *)); 656int in6_is_addr_deprecated __P((struct sockaddr_in6 *));
655struct in6pcb; 657struct in6pcb;
656#endif /* _KERNEL */ 658#endif /* _KERNEL */
657 659
658#endif /* !_NETINET6_IN6_VAR_H_ */ 660#endif /* !_NETINET6_IN6_VAR_H_ */

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

--- src/sys/netinet6/nd6_nbr.c 2006/06/28 16:43:43 1.65
+++ src/sys/netinet6/nd6_nbr.c 2008/10/03 10:32:22 1.65.14.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nd6_nbr.c,v 1.65 2006/06/28 16:43:43 drochner Exp $ */ 1/* $NetBSD: nd6_nbr.c,v 1.65.14.1 2008/10/03 10:32:22 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.65 2006/06/28 16:43:43 drochner Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.65.14.1 2008/10/03 10:32:22 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>
@@ -138,28 +138,38 @@ nd6_ns_input(m, off, icmp6len) @@ -138,28 +138,38 @@ nd6_ns_input(m, off, icmp6len)
138 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { 138 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
139 /* dst has to be a solicited node multicast address. */ 139 /* dst has to be a solicited node multicast address. */
140 /* don't check ifindex portion */ 140 /* don't check ifindex portion */
141 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL && 141 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
142 daddr6.s6_addr32[1] == 0 && 142 daddr6.s6_addr32[1] == 0 &&
143 daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE && 143 daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
144 daddr6.s6_addr8[12] == 0xff) { 144 daddr6.s6_addr8[12] == 0xff) {
145 ; /* good */ 145 ; /* good */
146 } else { 146 } else {
147 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 147 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
148 "(wrong ip6 dst)\n")); 148 "(wrong ip6 dst)\n"));
149 goto bad; 149 goto bad;
150 } 150 }
 151 } else {
 152 /*
 153 * Make sure the source address is from a neighbor's address.
 154 */
 155 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
 156 nd6log((LOG_INFO, "nd6_ns_input: "
 157 "NS packet from non-neighbor\n"));
 158 goto bad;
 159 }
151 } 160 }
152 161
 162
153 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 163 if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
154 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n")); 164 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"));
155 goto bad; 165 goto bad;
156 } 166 }
157 167
158 icmp6len -= sizeof(*nd_ns); 168 icmp6len -= sizeof(*nd_ns);
159 nd6_option_init(nd_ns + 1, icmp6len, &ndopts); 169 nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
160 if (nd6_options(&ndopts) < 0) { 170 if (nd6_options(&ndopts) < 0) {
161 nd6log((LOG_INFO, 171 nd6log((LOG_INFO,
162 "nd6_ns_input: invalid ND option, ignored\n")); 172 "nd6_ns_input: invalid ND option, ignored\n"));
163 /* nd6_options have incremented stats */ 173 /* nd6_options have incremented stats */
164 goto freeit; 174 goto freeit;
165 } 175 }
@@ -548,29 +558,27 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, d @@ -548,29 +558,27 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, d
548 * 558 *
549 * the following items are not implemented yet: 559 * the following items are not implemented yet:
550 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD) 560 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
551 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD) 561 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
552 */ 562 */
553void 563void
554nd6_na_input(m, off, icmp6len) 564nd6_na_input(m, off, icmp6len)
555 struct mbuf *m; 565 struct mbuf *m;
556 int off, icmp6len; 566 int off, icmp6len;
557{ 567{
558 struct ifnet *ifp = m->m_pkthdr.rcvif; 568 struct ifnet *ifp = m->m_pkthdr.rcvif;
559 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 569 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
560 struct nd_neighbor_advert *nd_na; 570 struct nd_neighbor_advert *nd_na;
561#if 0 
562 struct in6_addr saddr6 = ip6->ip6_src; 571 struct in6_addr saddr6 = ip6->ip6_src;
563#endif 
564 struct in6_addr daddr6 = ip6->ip6_dst; 572 struct in6_addr daddr6 = ip6->ip6_dst;
565 struct in6_addr taddr6; 573 struct in6_addr taddr6;
566 int flags; 574 int flags;
567 int is_router; 575 int is_router;
568 int is_solicited; 576 int is_solicited;
569 int is_override; 577 int is_override;
570 char *lladdr = NULL; 578 char *lladdr = NULL;
571 int lladdrlen = 0; 579 int lladdrlen = 0;
572 struct ifaddr *ifa; 580 struct ifaddr *ifa;
573 struct llinfo_nd6 *ln; 581 struct llinfo_nd6 *ln;
574 struct rtentry *rt; 582 struct rtentry *rt;
575 struct sockaddr_dl *sdl; 583 struct sockaddr_dl *sdl;
576 union nd_opts ndopts; 584 union nd_opts ndopts;
@@ -638,26 +646,34 @@ nd6_na_input(m, off, icmp6len) @@ -638,26 +646,34 @@ nd6_na_input(m, off, icmp6len)
638 if (ifa 646 if (ifa
639 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) { 647 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) {
640 nd6_dad_na_input(ifa); 648 nd6_dad_na_input(ifa);
641 goto freeit; 649 goto freeit;
642 } 650 }
643 651
644 /* Just for safety, maybe unnecessary. */ 652 /* Just for safety, maybe unnecessary. */
645 if (ifa) { 653 if (ifa) {
646 log(LOG_ERR, 654 log(LOG_ERR,
647 "nd6_na_input: duplicate IP6 address %s\n", 655 "nd6_na_input: duplicate IP6 address %s\n",
648 ip6_sprintf(&taddr6)); 656 ip6_sprintf(&taddr6));
649 goto freeit; 657 goto freeit;
650 } 658 }
 659 /*
 660 * Make sure the source address is from a neighbor's address.
 661 */
 662 if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
 663 nd6log((LOG_INFO, "nd6_ns_input: "
 664 "ND packet from non-neighbor\n"));
 665 goto bad;
 666 }
651 667
652 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 668 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
653 nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s " 669 nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "
654 "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6), 670 "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6),
655 ifp->if_addrlen, lladdrlen - 2)); 671 ifp->if_addrlen, lladdrlen - 2));
656 goto bad; 672 goto bad;
657 } 673 }
658 674
659 /* 675 /*
660 * If no neighbor cache entry is found, NA SHOULD silently be 676 * If no neighbor cache entry is found, NA SHOULD silently be
661 * discarded. 677 * discarded.
662 */ 678 */
663 rt = nd6_lookup(&taddr6, 0, ifp); 679 rt = nd6_lookup(&taddr6, 0, ifp);