diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/icmp6.h | 14 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 158 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 55 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 8 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 17 | ||||
-rw-r--r-- | sys/netinet6/nd6.h | 8 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 212 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 68 |
8 files changed, 314 insertions, 226 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index 5a62d382e9a..effaf0f04e0 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -1,5 +1,5 @@ -/* $OpenBSD: icmp6.h,v 1.14 2001/01/22 04:31:21 itojun Exp $ */ -/* $KAME: icmp6.h,v 1.32 2001/01/22 02:26:00 itojun Exp $ */ +/* $OpenBSD: icmp6.h,v 1.15 2001/02/07 11:43:52 itojun Exp $ */ +/* $KAME: icmp6.h,v 1.39 2001/02/06 03:48:06 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -537,6 +537,12 @@ struct icmp6stat { #define icp6s_oredirect icp6s_outerrhist.icp6errs_redirect #define icp6s_ounknown icp6s_outerrhist.icp6errs_unknown u_quad_t icp6s_pmtuchg; /* path MTU changes */ + u_quad_t icp6s_nd_badopt; /* bad ND options */ + u_quad_t icp6s_badns; /* bad neighbor solicitation */ + u_quad_t icp6s_badna; /* bad neighbor advertisement */ + u_quad_t icp6s_badrs; /* bad router advertisement */ + u_quad_t icp6s_badra; /* bad router advertisement */ + u_quad_t icp6s_badredirect; /* bad redirect message */ }; /* @@ -559,7 +565,8 @@ struct icmp6stat { #define ICMPV6CTL_ND6_MAXNUDHINT 15 #define ICMPV6CTL_MTUDISC_HIWAT 16 #define ICMPV6CTL_MTUDISC_LOWAT 17 -#define ICMPV6CTL_MAXID 18 +#define ICMPV6CTL_ND6_DEBUG 18 +#define ICMPV6CTL_MAXID 19 #define ICMPV6CTL_NAMES { \ { 0, 0 }, \ @@ -580,6 +587,7 @@ struct icmp6stat { { "nd6_maxnudhint", CTLTYPE_INT }, \ { "mtudisc_hiwat", CTLTYPE_INT }, \ { "mtudisc_lowat", CTLTYPE_INT }, \ + { "nd6_debug", CTLTYPE_INT }, \ } #define RTF_PROBEMTU RTF_PROTO1 diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index d28fd1bea84..68554f5eed1 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,5 +1,5 @@ -/* $OpenBSD: icmp6.c,v 1.29 2001/01/16 06:16:34 itojun Exp $ */ -/* $KAME: icmp6.c,v 1.172 2000/12/11 19:27:06 itojun Exp $ */ +/* $OpenBSD: icmp6.c,v 1.30 2001/02/07 11:43:52 itojun Exp $ */ +/* $KAME: icmp6.c,v 1.191 2001/02/07 08:07:38 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -340,7 +340,7 @@ icmp6_error(m, type, code, param) if (m && m->m_len < preplen) m = m_pullup(m, preplen); if (m == NULL) { - printf("ENOBUFS in icmp6_error %d\n", __LINE__); + nd6log((LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__)); return; } @@ -417,11 +417,9 @@ icmp6_input(mp, offp, proto) code = icmp6->icmp6_code; if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { -#ifdef ND6_DEBUG - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 checksum error(%d|%x) %s\n", - icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src)); -#endif + icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src))); icmp6stat.icp6s_checksum++; goto freeit; } @@ -552,9 +550,6 @@ icmp6_input(mp, offp, proto) * always copy the length we specified. */ if (maxlen >= MCLBYTES) { -#ifdef DIAGNOSTIC - printf("MCLBYTES too small\n"); -#endif /* Give up remote */ m_freem(n0); break; @@ -673,9 +668,6 @@ icmp6_input(mp, offp, proto) goto badcode; maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4; if (maxlen >= MCLBYTES) { -#ifdef DIAGNOSTIC - printf("MCLBYTES too small\n"); -#endif /* Give up remote */ break; } @@ -815,10 +807,11 @@ icmp6_input(mp, offp, proto) break; default: - printf("icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n", - icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src), - ip6_sprintf(&ip6->ip6_dst), - m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0); + nd6log((LOG_DEBUG, + "icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n", + icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src), + ip6_sprintf(&ip6->ip6_dst), + m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0)); if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) { /* ICMPv6 error: MUST deliver it by spec... */ code = PRC_NCMDS; @@ -987,7 +980,7 @@ icmp6_input(mp, offp, proto) goto notify; } } - notify: + notify: #ifndef PULLDOWN_TEST icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off); #else @@ -1199,8 +1192,8 @@ ni6_input(m, off) /* * Validate Subject address. * - * Not sure what exactly does "address belongs to the - * node" mean in the spec, is it just unicast, or what? + * Not sure what exactly "address belongs to the node" + * means in the spec, is it just unicast, or what? * * At this moment we consider Subject address as * "belong to the node" if the Subject address equals @@ -1319,10 +1312,10 @@ ni6_input(m, off) M_COPY_PKTHDR(n, m); /* just for recvif */ if (replylen > MHLEN) { if (replylen > MCLBYTES) { - /* - * XXX: should we try to allocate more? But MCLBYTES - * is probably much larger than IPV6_MMTU... - */ + /* + * XXX: should we try to allocate more? But MCLBYTES + * is probably much larger than IPV6_MMTU... + */ goto bad; } MCLGET(n, M_DONTWAIT); @@ -1574,9 +1567,9 @@ ni6_addrs(ni6, m, ifpp, subj) struct ifnet **ifpp; char *subj; { - register struct ifnet *ifp; - register struct in6_ifaddr *ifa6; - register struct ifaddr *ifa; + struct ifnet *ifp; + struct in6_ifaddr *ifa6; + struct ifaddr *ifa; struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */ int addrs = 0, addrsofif, iffound = 0; int niflags = ni6->ni_flags; @@ -1625,18 +1618,15 @@ ni6_addrs(ni6, m, ifpp, subj) /* What do we have to do about ::1? */ switch(in6_addrscope(&ifa6->ia_addr.sin6_addr)) { case IPV6_ADDR_SCOPE_LINKLOCAL: - if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) - == 0) + if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) continue; break; case IPV6_ADDR_SCOPE_SITELOCAL: - if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) - == 0) + if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) continue; break; case IPV6_ADDR_SCOPE_GLOBAL: - if ((niflags & NI_NODEADDR_FLAG_GLOBAL) - == 0) + if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) continue; break; default: @@ -1670,9 +1660,9 @@ ni6_store_addrs(ni6, nni6, ifp0, resid) struct ifnet *ifp0; int resid; { - register struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet); - register struct in6_ifaddr *ifa6; - register struct ifaddr *ifa; + struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet); + struct in6_ifaddr *ifa6; + struct ifaddr *ifa; struct ifnet *ifp_dep = NULL; int copied = 0, allow_deprecated = 0; u_char *cp = (u_char *)(nni6 + 1); @@ -1714,18 +1704,15 @@ ni6_store_addrs(ni6, nni6, ifp0, resid) /* What do we have to do about ::1? */ switch(in6_addrscope(&ifa6->ia_addr.sin6_addr)) { case IPV6_ADDR_SCOPE_LINKLOCAL: - if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) - == 0) + if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) continue; break; case IPV6_ADDR_SCOPE_SITELOCAL: - if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) - == 0) + if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) continue; break; case IPV6_ADDR_SCOPE_GLOBAL: - if ((niflags & NI_NODEADDR_FLAG_GLOBAL) - == 0) + if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) continue; break; default: @@ -1829,9 +1816,10 @@ icmp6_reflect(m, off) /* too short to reflect */ if (off < sizeof(struct ip6_hdr)) { - printf("sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n", - (u_long)off, (u_long)sizeof(struct ip6_hdr), - __FILE__, __LINE__); + nd6log((LOG_DEBUG, + "sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n", + (u_long)off, (u_long)sizeof(struct ip6_hdr), + __FILE__, __LINE__)); goto bad; } @@ -2012,7 +2000,7 @@ icmp6_redirect_diag(src6, dst6, tgt6) void icmp6_redirect_input(m, off) - register struct mbuf *m; + struct mbuf *m; int off; { struct ifnet *ifp = m->m_pkthdr.rcvif; @@ -2060,17 +2048,17 @@ icmp6_redirect_input(m, off) /* validation */ if (!IN6_IS_ADDR_LINKLOCAL(&src6)) { - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 redirect sent from %s rejected; " - "must be from linklocal\n", ip6_sprintf(&src6)); - goto freeit; + "must be from linklocal\n", ip6_sprintf(&src6))); + goto bad; } if (ip6->ip6_hlim != 255) { - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 redirect sent from %s rejected; " "hlim=%d (must be 255)\n", - ip6_sprintf(&src6), ip6->ip6_hlim); - goto freeit; + ip6_sprintf(&src6), ip6->ip6_hlim)); + goto bad; } { /* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */ @@ -2085,41 +2073,41 @@ icmp6_redirect_input(m, off) if (rt) { if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) { - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 redirect rejected; no route " "with inet6 gateway found for redirect dst: %s\n", - icmp6_redirect_diag(&src6, &reddst6, &redtgt6)); + icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); RTFREE(rt); - goto freeit; + goto bad; } gw6 = &(((struct sockaddr_in6 *)rt->rt_gateway)->sin6_addr); if (bcmp(&src6, gw6, sizeof(struct in6_addr)) != 0) { - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 redirect rejected; " "not equal to gw-for-src=%s (must be same): " "%s\n", ip6_sprintf(gw6), - icmp6_redirect_diag(&src6, &reddst6, &redtgt6)); + icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); RTFREE(rt); - goto freeit; + goto bad; } } else { - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 redirect rejected; " "no route found for redirect dst: %s\n", - icmp6_redirect_diag(&src6, &reddst6, &redtgt6)); - goto freeit; + icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); + goto bad; } RTFREE(rt); rt = NULL; } if (IN6_IS_ADDR_MULTICAST(&reddst6)) { - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 redirect rejected; " "redirect dst must be unicast: %s\n", - icmp6_redirect_diag(&src6, &reddst6, &redtgt6)); - goto freeit; + icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); + goto bad; } is_router = is_onlink = 0; @@ -2128,20 +2116,21 @@ icmp6_redirect_input(m, off) if (bcmp(&redtgt6, &reddst6, sizeof(redtgt6)) == 0) is_onlink = 1; /* on-link destination case */ if (!is_router && !is_onlink) { - log(LOG_ERR, + nd6log((LOG_ERR, "ICMP6 redirect rejected; " "neither router case nor onlink case: %s\n", - icmp6_redirect_diag(&src6, &reddst6, &redtgt6)); - goto freeit; + icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); + goto bad; } /* validation passed */ icmp6len -= sizeof(*nd_rd); nd6_option_init(nd_rd + 1, icmp6len, &ndopts); if (nd6_options(&ndopts) < 0) { - log(LOG_INFO, "icmp6_redirect_input: " + nd6log((LOG_INFO, "icmp6_redirect_input: " "invalid ND option, rejected: %s\n", - icmp6_redirect_diag(&src6, &reddst6, &redtgt6)); + icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); + /* nd6_options have incremented stats */ goto freeit; } @@ -2156,11 +2145,12 @@ icmp6_redirect_input(m, off) } if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { - log(LOG_INFO, + nd6log((LOG_INFO, "icmp6_redirect_input: lladdrlen mismatch for %s " "(if %d, icmp6 packet %d): %s\n", ip6_sprintf(&redtgt6), ifp->if_addrlen, lladdrlen - 2, - icmp6_redirect_diag(&src6, &reddst6, &redtgt6)); + icmp6_redirect_diag(&src6, &reddst6, &redtgt6))); + goto bad; } /* RFC 2461 8.3 */ @@ -2191,31 +2181,12 @@ icmp6_redirect_input(m, off) /* finally update cached route in each socket via pfctlinput */ { struct sockaddr_in6 sdst; -#if 1 -#else - struct ip6protosw *pr; -#endif bzero(&sdst, sizeof(sdst)); sdst.sin6_family = AF_INET6; sdst.sin6_len = sizeof(struct sockaddr_in6); bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr)); -#if 1 pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&sdst); -#else - /* - * do not use pfctlinput() here, we have different prototype for - * xx_ctlinput() in ip6proto. - */ - for (pr = (struct ip6protosw *)inet6domain.dom_protosw; - pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; - pr++) { - if (pr->pr_ctlinput) { - (*pr->pr_ctlinput)(PRC_REDIRECT_HOST, - (struct sockaddr *)&sdst, NULL, NULL, 0); - } - } -#endif #ifdef IPSEC key_sa_routechange((struct sockaddr *)&sdst); #endif @@ -2223,6 +2194,11 @@ icmp6_redirect_input(m, off) freeit: m_freem(m); + return; + + bad: + icmp6stat.icp6s_badredirect++; + m_freem(m); } void @@ -2641,6 +2617,8 @@ icmp6_sysctl(name, namelen, oldp, oldlenp, newp, newlen) case ICMPV6CTL_MTUDISC_LOWAT: return sysctl_int(oldp, oldlenp, newp, newlen, &icmp6_mtudisc_lowat); + case ICMPV6CTL_ND6_DEBUG: + return sysctl_int(oldp, oldlenp, newp, newlen, &nd6_debug); default: return ENOPROTOOPT; } diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 09e48542cf4..a5fd6d5028d 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -1,5 +1,5 @@ -/* $OpenBSD: in6_ifattach.c,v 1.14 2001/01/18 06:48:25 itojun Exp $ */ -/* $KAME: in6_ifattach.c,v 1.68 2000/10/18 18:44:24 itojun Exp $ */ +/* $OpenBSD: in6_ifattach.c,v 1.15 2001/02/07 11:43:53 itojun Exp $ */ +/* $KAME: in6_ifattach.c,v 1.102 2001/02/07 11:01:29 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -36,6 +36,7 @@ #include <sys/socket.h> #include <sys/sockio.h> #include <sys/kernel.h> +#include <sys/syslog.h> #include <sys/md5k.h> #include <net/if.h> @@ -214,7 +215,7 @@ found: case IFT_STF: #endif /* - * mech-06 says: "SHOULD use IPv4 address as ifid source". + * RFC2893 says: "SHOULD use IPv4 address as ifid source". * however, IPv4 address is not very suitable as unique * identifier source (can be renumbered). * we don't do this. @@ -259,19 +260,15 @@ get_ifid(ifp0, altifp, in6) /* first, try to get it from the interface itself */ if (get_hw_ifid(ifp0, in6) == 0) { -#ifdef ND6_DEBUG - printf("%s: got interface identifier from itself\n", - if_name(ifp0)); -#endif + nd6log((LOG_DEBUG, "%s: got interface identifier from itself\n", + if_name(ifp0))); goto success; } /* try secondary EUI64 source. this basically is for ATM PVC */ if (altifp && get_hw_ifid(altifp, in6) == 0) { -#ifdef ND6_DEBUG - printf("%s: got interface identifier from %s\n", - if_name(ifp0), if_name(altifp)); -#endif + nd6log((LOG_DEBUG, "%s: got interface identifier from %s\n", + if_name(ifp0), if_name(altifp))); goto success; } @@ -288,21 +285,18 @@ get_ifid(ifp0, altifp, in6) * globally unique */ if (IFID_UNIVERSAL(in6)) { - -#ifdef ND6_DEBUG - printf("%s: borrow interface identifier from %s\n", - if_name(ifp0), if_name(ifp)); -#endif + nd6log((LOG_DEBUG, + "%s: borrow interface identifier from %s\n", + if_name(ifp0), if_name(ifp))); goto success; } } /* last resort: get from random number source */ if (get_rand_ifid(ifp, in6) == 0) { -#ifdef ND6_DEBUG - printf("%s: interface identifier generated by random number\n", - if_name(ifp0)); -#endif + nd6log((LOG_DEBUG, + "%s: interface identifier generated by random number\n", + if_name(ifp0))); goto success; } @@ -310,15 +304,13 @@ get_ifid(ifp0, altifp, in6) return -1; success: -#ifdef ND6_DEBUG - printf("%s: ifid: " + nd6log((LOG_INFO, "%s: ifid: " "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", if_name(ifp0), in6->s6_addr[8], in6->s6_addr[9], in6->s6_addr[10], in6->s6_addr[11], in6->s6_addr[12], in6->s6_addr[13], - in6->s6_addr[14], in6->s6_addr[15]); -#endif + in6->s6_addr[14], in6->s6_addr[15])); return 0; } @@ -500,9 +492,8 @@ in6_ifattach_linklocal(ifp, altifp) ia->ia_addr.sin6_addr.s6_addr32[3] = htonl(1); } else { if (get_ifid(ifp, altifp, &ia->ia_addr.sin6_addr) != 0) { -#ifdef ND6_DEBUG - printf("%s: no ifid available\n", if_name(ifp)); -#endif + nd6log((LOG_ERR, + "%s: no ifid available\n", if_name(ifp))); free(ia, M_IFADDR); return -1; } @@ -867,11 +858,11 @@ in6_ifdetach(ifp) ia = ia->ia_next; if (ia->ia_next) ia->ia_next = oia->ia_next; -#ifdef ND6_DEBUG - else - printf("%s: didn't unlink in6ifaddr from " - "list\n", if_name(ifp)); -#endif + else { + nd6log((LOG_ERR, + "%s: didn't unlink in6ifaddr from " + "list\n", if_name(ifp))); + } } IFAFREE(&oia->ia_ifa); diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 4cc9d3424bd..67de254f5c1 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ip6_input.c,v 1.20 2001/02/06 00:22:23 mickey Exp $ */ -/* $KAME: ip6_input.c,v 1.121 2000/08/31 06:07:29 itojun Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.21 2001/02/07 11:43:53 itojun Exp $ */ +/* $KAME: ip6_input.c,v 1.170 2001/02/07 07:50:02 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -484,10 +484,10 @@ ip6_input(m) goto hbhcheck; } else { /* address is not ready, so discard the packet. */ - log(LOG_INFO, + nd6log((LOG_INFO, "ip6_input: packet to an unready address %s->%s\n", ip6_sprintf(&ip6->ip6_src), - ip6_sprintf(&ip6->ip6_dst)); + ip6_sprintf(&ip6->ip6_dst))); goto bad; } diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 230902af6ab..c7abb5797c0 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,5 +1,5 @@ -/* $OpenBSD: nd6.c,v 1.21 2001/02/06 00:22:23 mickey Exp $ */ -/* $KAME: nd6.c,v 1.75 2000/10/15 15:23:11 itojun Exp $ */ +/* $OpenBSD: nd6.c,v 1.22 2001/02/07 11:43:54 itojun Exp $ */ +/* $KAME: nd6.c,v 1.110 2001/02/06 09:14:38 jinmei Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -89,6 +89,12 @@ int nd6_maxndopt = 10; /* max # of ND options allowed */ int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */ +#ifdef ND6_DEBUG +int nd6_debug = 1; +#else +int nd6_debug = 0; +#endif + /* for debugging? */ static int nd6_inuse, nd6_allocated; @@ -307,6 +313,7 @@ nd6_options(ndopts) * Message validation requires that all included * options have a length that is greater than zero. */ + icmp6stat.icp6s_nd_badopt++; bzero(ndopts, sizeof(*ndopts)); return -1; } @@ -341,16 +348,16 @@ nd6_options(ndopts) * Unknown options must be silently ignored, * to accomodate future extension to the protocol. */ - log(LOG_DEBUG, + nd6log((LOG_DEBUG, "nd6_options: unsupported option %d - " - "option ignored\n", nd_opt->nd_opt_type); + "option ignored\n", nd_opt->nd_opt_type)); } skip1: i++; if (i > nd6_maxndopt) { icmp6stat.icp6s_nd_toomanyopt++; - printf("too many loop in nd opt\n"); + nd6log((LOG_INFO, "too many loop in nd opt\n")); break; } diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 3e44d94db02..62851f3ac48 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -1,5 +1,5 @@ -/* $OpenBSD: nd6.h,v 1.9 2001/01/19 06:37:38 itojun Exp $ */ -/* $KAME: nd6.h,v 1.23 2000/06/04 12:54:57 itojun Exp $ */ +/* $OpenBSD: nd6.h,v 1.10 2001/02/07 11:43:54 itojun Exp $ */ +/* $KAME: nd6.h,v 1.42 2001/02/06 09:14:39 jinmei Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -236,6 +236,9 @@ extern struct llinfo_nd6 llinfo_nd6; extern struct nd_ifinfo *nd_ifinfo; extern struct nd_drhead nd_defrouter; extern struct nd_prhead nd_prefix; +extern int nd6_debug; + +#define nd6log(x) do { if (nd6_debug) log x; } while (0) /* nd6_rtr.c */ extern struct ifnet *nd6_defifp; /* XXXYYY */ @@ -302,6 +305,7 @@ void nd6_ns_output __P((struct ifnet *, struct in6_addr *, struct in6_addr *, struct llinfo_nd6 *, int)); caddr_t nd6_ifptomac __P((struct ifnet *)); void nd6_dad_start __P((struct ifaddr *, int *)); +void nd6_dad_stop __P((struct ifaddr *)); void nd6_dad_duplicated __P((struct ifaddr *)); /* nd6_rtr.c */ diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 24a41a4d30e..f55551520a6 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1,5 +1,5 @@ -/* $OpenBSD: nd6_nbr.c,v 1.11 2001/01/18 04:57:05 itojun Exp $ */ -/* $KAME: nd6_nbr.c,v 1.36 2000/05/17 12:35:59 jinmei Exp $ */ +/* $OpenBSD: nd6_nbr.c,v 1.12 2001/02/07 11:43:54 itojun Exp $ */ +/* $KAME: nd6_nbr.c,v 1.57 2001/02/07 08:18:21 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -64,6 +64,8 @@ struct dadq; static struct dadq *nd6_dad_find __P((struct ifaddr *)); +static void nd6_dad_starttimer __P((struct dadq *, int)); +static void nd6_dad_stoptimer __P((struct dadq *)); static void nd6_dad_timer __P((struct ifaddr *)); static void nd6_dad_ns_output __P((struct dadq *, struct ifaddr *)); static void nd6_dad_ns_input __P((struct ifaddr *)); @@ -98,12 +100,25 @@ nd6_ns_input(m, off, icmp6len) union nd_opts ndopts; struct sockaddr_dl *proxydl = NULL; - if (ip6->ip6_hlim != 255) { -#ifdef ND6_DEBUG - log(LOG_ERR, - "nd6_ns_input: invalid hlim %d\n", ip6->ip6_hlim); +#ifndef PULLDOWN_TEST + IP6_EXTHDR_CHECK(m, off, icmp6len,); + nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off); +#else + IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len); + if (nd_ns == NULL) { + icmp6stat.icp6s_tooshort++; + return; + } #endif - goto freeit; + ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */ + taddr6 = nd_ns->nd_ns_target; + + if (ip6->ip6_hlim != 255) { + nd6log((LOG_ERR, + "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n", + ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), + ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); + goto bad; } if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { @@ -115,26 +130,14 @@ nd6_ns_input(m, off, icmp6len) && daddr6.s6_addr8[12] == 0xff) { ; /*good*/ } else { - log(LOG_INFO, "nd6_ns_input: bad DAD packet " - "(wrong ip6 dst)\n"); + nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " + "(wrong ip6 dst)\n")); goto bad; } } -#ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, icmp6len,); - nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off); -#else - IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len); - if (nd_ns == NULL) { - icmp6stat.icp6s_tooshort++; - return; - } -#endif - taddr6 = nd_ns->nd_ns_target; - if (IN6_IS_ADDR_MULTICAST(&taddr6)) { - log(LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"); + nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n")); goto bad; } @@ -144,8 +147,10 @@ nd6_ns_input(m, off, icmp6len) icmp6len -= sizeof(*nd_ns); nd6_option_init(nd_ns + 1, icmp6len, &ndopts); if (nd6_options(&ndopts) < 0) { - log(LOG_INFO, "nd6_ns_input: invalid ND option, ignored\n"); - goto bad; + nd6log((LOG_INFO, + "nd6_ns_input: invalid ND option, ignored\n")); + /* nd6_options have incremented stats */ + goto freeit; } if (ndopts.nd_opts_src_lladdr) { @@ -154,8 +159,8 @@ nd6_ns_input(m, off, icmp6len) } if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) { - log(LOG_INFO, "nd6_ns_input: bad DAD packet " - "(link-layer address option)\n"); + nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " + "(link-layer address option)\n")); goto bad; } @@ -217,7 +222,7 @@ nd6_ns_input(m, off, icmp6len) } if (!ifa) { /* - * We've got a NS packet, and we don't have that adddress + * We've got an NS packet, and we don't have that adddress * assigned for us. We MUST silently ignore it. * See RFC2461 7.2.3. */ @@ -230,10 +235,11 @@ nd6_ns_input(m, off, icmp6len) goto freeit; if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { - log(LOG_INFO, + nd6log((LOG_INFO, "nd6_ns_input: lladdrlen mismatch for %s " "(if %d, NS packet %d)\n", - ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2); + ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2)); + goto bad; } if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) { @@ -300,9 +306,10 @@ nd6_ns_input(m, off, icmp6len) return; bad: - log(LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6)); - log(LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6)); - log(LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6)); + nd6log((LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6))); + nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6))); + nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6))); + icmp6stat.icp6s_badns++; m_freem(m); } @@ -531,11 +538,11 @@ nd6_na_input(m, off, icmp6len) union nd_opts ndopts; if (ip6->ip6_hlim != 255) { -#ifdef ND6_DEBUG - log(LOG_ERR, - "nd6_na_input: invalid hlim %d\n", ip6->ip6_hlim); -#endif - goto freeit; + nd6log((LOG_ERR, + "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n", + ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), + ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); + goto bad; } #ifndef PULLDOWN_TEST @@ -558,22 +565,24 @@ nd6_na_input(m, off, icmp6len) taddr6.s6_addr16[1] = htons(ifp->if_index); if (IN6_IS_ADDR_MULTICAST(&taddr6)) { - log(LOG_ERR, + nd6log((LOG_ERR, "nd6_na_input: invalid target address %s\n", - ip6_sprintf(&taddr6)); - goto freeit; + ip6_sprintf(&taddr6))); + goto bad; } if (IN6_IS_ADDR_MULTICAST(&daddr6)) if (is_solicited) { - log(LOG_ERR, - "nd6_na_input: a solicited adv is multicasted\n"); - goto freeit; + nd6log((LOG_ERR, + "nd6_na_input: a solicited adv is multicasted\n")); + goto bad; } icmp6len -= sizeof(*nd_na); nd6_option_init(nd_na + 1, icmp6len, &ndopts); if (nd6_options(&ndopts) < 0) { - log(LOG_INFO, "nd6_na_input: invalid ND option, ignored\n"); + nd6log((LOG_INFO, + "nd6_na_input: invalid ND option, ignored\n")); + /* nd6_options have incremented stats */ goto freeit; } @@ -608,10 +617,11 @@ nd6_na_input(m, off, icmp6len) } if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { - log(LOG_INFO, + nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s " "(if %d, NA packet %d)\n", - ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2); + ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2)); + goto bad; } /* @@ -766,6 +776,11 @@ nd6_na_input(m, off, icmp6len) freeit: m_freem(m); + return; + + bad: + icmp6stat.icp6s_badna++; + m_freem(m); } /* @@ -942,6 +957,7 @@ struct dadq { }; static struct dadq_head dadq; +static int dad_init = 0; static struct dadq * nd6_dad_find(ifa) @@ -956,6 +972,40 @@ nd6_dad_find(ifa) return NULL; } +static void +nd6_dad_starttimer(dp, ticks) + struct dadq *dp; + int ticks; +{ + +#ifdef __NetBSD__ + callout_reset(&dp->dad_timer_ch, ticks, + (void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa); +#else +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 + dp->dad_timer = +#endif + timeout((void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa, + ticks); +#endif +} + +static void +nd6_dad_stoptimer(dp) + struct dadq *dp; +{ + +#ifdef __NetBSD__ + callout_stop(&dp->dad_timer_ch); +#else + untimeout((void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 + , dp->dad_timer +#endif + ); +#endif +} + /* * Start Duplicated Address Detection (DAD) for specified interface address. */ @@ -966,7 +1016,6 @@ nd6_dad_start(ifa, tick) { struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; struct dadq *dp; - static int dad_init = 0; if (!dad_init) { TAILQ_INIT(&dadq); @@ -1015,10 +1064,8 @@ nd6_dad_start(ifa, tick) bzero(dp, sizeof(*dp)); TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); -#ifdef DEBUG - log(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), - ip6_sprintf(&ia->ia_addr.sin6_addr)); -#endif + nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), + ip6_sprintf(&ia->ia_addr.sin6_addr))); /* * Send NS packet for DAD, ip6_dad_count times. @@ -1033,19 +1080,49 @@ nd6_dad_start(ifa, tick) dp->dad_ns_ocount = dp->dad_ns_tcount = 0; if (!tick) { nd6_dad_ns_output(dp, ifa); - timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa, - nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); + nd6_dad_starttimer(dp, + nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); } else { int ntick; +#ifdef __OpenBSD__ +#define random arc4random +#endif if (*tick == 0) - ntick = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz); + ntick = random() % (MAX_RTR_SOLICITATION_DELAY * hz); else - ntick = *tick + arc4random() % (hz / 2); + ntick = *tick + random() % (hz / 2); +#ifdef __OpenBSD__ +#undef random +#endif *tick = ntick; - timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa, - ntick); + nd6_dad_starttimer(dp, ntick); + } +} + +/* + * terminate DAD unconditionally. used for address removals. + */ +void +nd6_dad_stop(ifa) + struct ifaddr *ifa; +{ + struct dadq *dp; + + if (!dad_init) + return; + dp = nd6_dad_find(ifa); + if (!dp) { + /* DAD wasn't started yet */ + return; } + + nd6_dad_stoptimer(dp); + + TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); + free(dp, M_IP6NDP); + dp = NULL; + IFAFREE(ifa); } static void @@ -1085,8 +1162,8 @@ nd6_dad_timer(ifa) /* timeouted with IFF_{RUNNING,UP} check */ if (dp->dad_ns_tcount > dad_maxtry) { - log(LOG_ERR, "%s: could not run DAD, driver problem?\n", - if_name(ifa->ifa_ifp)); + nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", + if_name(ifa->ifa_ifp))); TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); free(dp, M_IP6NDP); @@ -1101,8 +1178,8 @@ nd6_dad_timer(ifa) * We have more NS to go. Send NS packet for DAD. */ nd6_dad_ns_output(dp, ifa); - timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa, - nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); + nd6_dad_starttimer(dp, + nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); } else { /* * We have transmitted sufficient number of DAD packets. @@ -1161,12 +1238,10 @@ nd6_dad_timer(ifa) */ ia->ia6_flags &= ~IN6_IFF_TENTATIVE; -#ifdef DEBUG - log(LOG_INFO, + nd6log((LOG_DEBUG, "%s: DAD complete for %s - no duplicates found\n", if_name(ifa->ifa_ifp), - ip6_sprintf(&ia->ia_addr.sin6_addr)); -#endif + ip6_sprintf(&ia->ia_addr.sin6_addr))); TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); free(dp, M_IP6NDP); @@ -1201,7 +1276,7 @@ nd6_dad_duplicated(ifa) ia->ia6_flags |= IN6_IFF_DUPLICATED; /* We are done with DAD, with duplicated address found. (failure) */ - untimeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa); + nd6_dad_stoptimer(dp); log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n", if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr)); @@ -1267,9 +1342,10 @@ nd6_dad_ns_input(ifa) /* Quickhack - completely ignore DAD NS packets */ if (dad_ignore_ns) { - log(LOG_INFO, "nd6_dad_ns_input: ignoring DAD NS packet for " + nd6log((LOG_INFO, + "nd6_dad_ns_input: ignoring DAD NS packet for " "address %s(%s)\n", ip6_sprintf(taddr6), - if_name(ifa->ifa_ifp)); + if_name(ifa->ifa_ifp))); return; } diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 735b15b2bb8..d3018656c7e 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,5 +1,5 @@ -/* $OpenBSD: nd6_rtr.c,v 1.7 2000/06/13 04:12:40 itojun Exp $ */ -/* $KAME: nd6_rtr.c,v 1.40 2000/06/13 03:02:29 jinmei Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.8 2001/02/07 11:43:55 itojun Exp $ */ +/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -120,9 +120,11 @@ nd6_rs_input(m, off, icmp6len) /* Sanity checks */ if (ip6->ip6_hlim != 255) { - log(LOG_ERR, - "nd6_rs_input: invalid hlim %d\n", ip6->ip6_hlim); - goto freeit; + nd6log((LOG_ERR, + "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n", + ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), + ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); + goto bad; } /* @@ -146,7 +148,9 @@ nd6_rs_input(m, off, icmp6len) icmp6len -= sizeof(*nd_rs); nd6_option_init(nd_rs + 1, icmp6len, &ndopts); if (nd6_options(&ndopts) < 0) { - log(LOG_INFO, "nd6_rs_input: invalid ND option, ignored\n"); + nd6log((LOG_INFO, + "nd6_rs_input: invalid ND option, ignored\n")); + /* nd6_options have incremented stats */ goto freeit; } @@ -156,16 +160,22 @@ nd6_rs_input(m, off, icmp6len) } if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { - log(LOG_INFO, + nd6log((LOG_INFO, "nd6_rs_input: lladdrlen mismatch for %s " "(if %d, RS packet %d)\n", - ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2); + ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2)); + goto bad; } nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0); freeit: m_freem(m); + return; + + bad: + icmp6stat.icp6s_badrs++; + m_freem(m); } /* @@ -198,16 +208,18 @@ nd6_ra_input(m, off, icmp6len) goto freeit; if (ip6->ip6_hlim != 255) { - log(LOG_ERR, - "nd6_ra_input: invalid hlim %d\n", ip6->ip6_hlim); - goto freeit; + nd6log((LOG_ERR, + "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n", + ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), + ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); + goto bad; } if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) { - log(LOG_ERR, + nd6log((LOG_ERR, "nd6_ra_input: src %s is not link-local\n", - ip6_sprintf(&saddr6)); - goto freeit; + ip6_sprintf(&saddr6))); + goto bad; } #ifndef PULLDOWN_TEST @@ -224,7 +236,9 @@ nd6_ra_input(m, off, icmp6len) icmp6len -= sizeof(*nd_ra); nd6_option_init(nd_ra + 1, icmp6len, &ndopts); if (nd6_options(&ndopts) < 0) { - log(LOG_INFO, "nd6_ra_input: invalid ND option, ignored\n"); + nd6log((LOG_INFO, + "nd6_ra_input: invalid ND option, ignored\n")); + /* nd6_options have incremented stats */ goto freeit; } @@ -377,10 +391,11 @@ nd6_ra_input(m, off, icmp6len) } if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { - log(LOG_INFO, + nd6log((LOG_INFO, "nd6_ra_input: lladdrlen mismatch for %s " "(if %d, RA packet %d)\n", - ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2); + ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2)); + goto bad; } nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_ADVERT, 0); @@ -393,7 +408,12 @@ nd6_ra_input(m, off, icmp6len) pfxlist_onlink_check(); } -freeit: + freeit: + m_freem(m); + return; + + bad: + icmp6stat.icp6s_badra++; m_freem(m); } @@ -611,13 +631,17 @@ defrouter_select() /* * Install a route to the default interface * as default route. + * XXX: we enable this for host only, because + * this may override a default route installed + * a user process (e.g. routing daemon) in a + * router case. */ defrouter_addifreq(nd6_defifp); - } - else /* noisy log? */ - log(LOG_INFO, "defrouter_select: " + } else { + nd6log((LOG_INFO, "defrouter_select: " "there's no default router and no default" - " interface\n"); + " interface\n")); + } } } |