diff options
author | 2001-02-07 11:43:48 +0000 | |
---|---|---|
committer | 2001-02-07 11:43:48 +0000 | |
commit | b79da24ae0993317100166e8276b69d6fc8aad35 (patch) | |
tree | 774dfb490ff1cc8c34de453168737a6f17dae82b | |
parent | pretty up significantly (diff) | |
download | wireguard-openbsd-b79da24ae0993317100166e8276b69d6fc8aad35.tar.xz wireguard-openbsd-b79da24ae0993317100166e8276b69d6fc8aad35.zip |
by default, don't bark on inbound ND messages, as outsider may be able to
fill up /var with bogus packets.
setting net.inet6.icmp6.nd6_debug will re-enable kernel messages on invalid
ND packet and other occasions.
improve icmp6 stats.
-rw-r--r-- | lib/libc/gen/sysctl.3 | 8 | ||||
-rw-r--r-- | sbin/sysctl/sysctl.8 | 3 | ||||
-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 | ||||
-rw-r--r-- | usr.bin/netstat/inet6.c | 319 |
11 files changed, 497 insertions, 373 deletions
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3 index c8f70f8cf0a..8a0fba419b8 100644 --- a/lib/libc/gen/sysctl.3 +++ b/lib/libc/gen/sysctl.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sysctl.3,v 1.61 2001/01/04 07:53:43 angelos Exp $ +.\" $OpenBSD: sysctl.3,v 1.62 2001/02/07 11:43:48 itojun Exp $ .\" .\" Copyright (c) 1993 .\" The Regents of the University of California. All rights reserved. @@ -886,6 +886,7 @@ The currently defined protocols and names are: .It icmp6 nd6_maxnudhint integer yes .It icmp6 mtudisc_hiwat integer yes .It icmp6 mtudisc_lowat integer yes +.It icmp6 nd6_debug integer yes .El .Pp The variables are as follows: @@ -1022,6 +1023,11 @@ is used when we have verified ICMPv6 too big messages. .Li icmp6.mtudisc_lowat is used when we have unverified ICMPv6 too big messages. Verification is performed by using address/port pairs kept in connected pcbs. +.It Li icmp6.nd6_debug +If set to non-zero, kernel IPv6 neighbor discovery code will generate +debugging messages. +The debug outputs are useful to diagnose IPv6 interoperability issues. +The flag must be set to 0 for normal operation. .El .Pp We reuse diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 index 52885b7186f..e826e27da46 100644 --- a/sbin/sysctl/sysctl.8 +++ b/sbin/sysctl/sysctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sysctl.8,v 1.60 2001/01/05 04:27:23 marc Exp $ +.\" $OpenBSD: sysctl.8,v 1.61 2001/02/07 11:43:49 itojun Exp $ .\" $NetBSD: sysctl.8,v 1.4 1995/09/30 07:12:49 thorpej Exp $ .\" .\" Copyright (c) 1993 @@ -227,6 +227,7 @@ privilege can change the value. .It net.inet6.icmp6.nd6_maxnudhint integer yes .It net.inet6.icmp6.mtudisc_hiwat integer yes .It net.inet6.icmp6.mtudisc_lowat integer yes +.It net.inet6.icmp6.nd6_debug integer yes .It net.ipx.ipx.checksum integer yes .It net.ipx.ipx.forwarding integer yes .It net.ipx.ipx.netbios integer yes 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")); + } } } diff --git a/usr.bin/netstat/inet6.c b/usr.bin/netstat/inet6.c index 34d425484f0..596632d1276 100644 --- a/usr.bin/netstat/inet6.c +++ b/usr.bin/netstat/inet6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inet6.c,v 1.13 2000/12/11 17:53:29 itojun Exp $ */ +/* $OpenBSD: inet6.c,v 1.14 2001/02/07 11:43:50 itojun Exp $ */ /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ /* * Copyright (c) 1983, 1988, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)inet.c 8.4 (Berkeley) 4/20/94"; #else -/*__RCSID("$OpenBSD: inet6.c,v 1.13 2000/12/11 17:53:29 itojun Exp $");*/ +/*__RCSID("$OpenBSD: inet6.c,v 1.14 2001/02/07 11:43:50 itojun Exp $");*/ /*__RCSID("KAME Id: inet6.c,v 1.10 2000/02/09 10:49:31 itojun Exp");*/ #endif #endif /* not lint */ @@ -351,6 +351,8 @@ ip6_stats(off, name) { struct ip6stat ip6stat; int first, i; + struct protoent *ep; + const char *n; if (off == 0) return; @@ -359,44 +361,55 @@ ip6_stats(off, name) printf("%s:\n", name); #define p(f, m) if (ip6stat.f || sflag <= 1) \ - printf(m, ip6stat.f, plural(ip6stat.f)) + printf(m, (unsigned long long)ip6stat.f, plural(ip6stat.f)) #define p1(f, m) if (ip6stat.f || sflag <= 1) \ - printf(m, ip6stat.f) + printf(m, (unsigned long long)ip6stat.f) - p(ip6s_total, "\t%qu total packet%s received\n"); - p1(ip6s_toosmall, "\t%qu with size smaller than minimum\n"); - p1(ip6s_tooshort, "\t%qu with data size < data length\n"); - p1(ip6s_badoptions, "\t%qu with bad options\n"); - p1(ip6s_badvers, "\t%qu with incorrect version number\n"); - p(ip6s_fragments, "\t%qu fragment%s received\n"); - p(ip6s_fragdropped, "\t%qu fragment%s dropped (dup or out of space)\n"); - p(ip6s_fragtimeout, "\t%qu fragment%s dropped after timeout\n"); - p(ip6s_fragoverflow, "\t%qu fragment%s that exceeded limit\n"); - p(ip6s_reassembled, "\t%qu packet%s reassembled ok\n"); - p(ip6s_delivered, "\t%qu packet%s for this host\n"); - p(ip6s_forward, "\t%qu packet%s forwarded\n"); - p(ip6s_cantforward, "\t%qu packet%s not forwardable\n"); - p(ip6s_redirectsent, "\t%qu redirect%s sent\n"); - p(ip6s_localout, "\t%qu packet%s sent from this host\n"); - p(ip6s_rawout, "\t%qu packet%s sent with fabricated ip header\n"); - p(ip6s_odropped, "\t%qu output packet%s dropped due to no bufs, etc.\n"); - p(ip6s_noroute, "\t%qu output packet%s discarded due to no route\n"); - p(ip6s_fragmented, "\t%qu output datagram%s fragmented\n"); - p(ip6s_ofragments, "\t%qu fragment%s created\n"); - p(ip6s_cantfrag, "\t%qu datagram%s that can't be fragmented\n"); - p(ip6s_badscope, "\t%qu packet%s that violated scope rules\n"); - p(ip6s_notmember, "\t%qu multicast packet%s which we don't join\n"); + p(ip6s_total, "\t%llu total packet%s received\n"); + p1(ip6s_toosmall, "\t%llu with size smaller than minimum\n"); + p1(ip6s_tooshort, "\t%llu with data size < data length\n"); + p1(ip6s_badoptions, "\t%llu with bad options\n"); + p1(ip6s_badvers, "\t%llu with incorrect version number\n"); + p(ip6s_fragments, "\t%llu fragment%s received\n"); + p(ip6s_fragdropped, + "\t%llu fragment%s dropped (dup or out of space)\n"); + p(ip6s_fragtimeout, "\t%llu fragment%s dropped after timeout\n"); + p(ip6s_fragoverflow, "\t%llu fragment%s that exceeded limit\n"); + p(ip6s_reassembled, "\t%llu packet%s reassembled ok\n"); + p(ip6s_delivered, "\t%llu packet%s for this host\n"); + p(ip6s_forward, "\t%llu packet%s forwarded\n"); + p(ip6s_cantforward, "\t%llu packet%s not forwardable\n"); + p(ip6s_redirectsent, "\t%llu redirect%s sent\n"); + p(ip6s_localout, "\t%llu packet%s sent from this host\n"); + p(ip6s_rawout, "\t%llu packet%s sent with fabricated ip header\n"); + p(ip6s_odropped, + "\t%llu output packet%s dropped due to no bufs, etc.\n"); + p(ip6s_noroute, "\t%llu output packet%s discarded due to no route\n"); + p(ip6s_fragmented, "\t%llu output datagram%s fragmented\n"); + p(ip6s_ofragments, "\t%llu fragment%s created\n"); + p(ip6s_cantfrag, "\t%llu datagram%s that can't be fragmented\n"); + p(ip6s_badscope, "\t%llu packet%s that violated scope rules\n"); + p(ip6s_notmember, "\t%llu multicast packet%s which we don't join\n"); for (first = 1, i = 0; i < 256; i++) if (ip6stat.ip6s_nxthist[i] != 0) { if (first) { printf("\tInput packet histogram:\n"); first = 0; } - printf("\t\t%s: %qu\n", ip6nh[i], - ip6stat.ip6s_nxthist[i]); + n = NULL; + if (ip6nh[i]) + n = ip6nh[i]; + else if ((ep = getprotobynumber(i)) != NULL) + n = ep->p_name; + if (n) + printf("\t\t%s: %llu\n", n, + (unsigned long long)ip6stat.ip6s_nxthist[i]); + else + printf("\t\t#%d: %llu\n", i, + (unsigned long long)ip6stat.ip6s_nxthist[i]); } printf("\tMbuf statistics:\n"); - p(ip6s_m1, "\t\t%qu one mbuf%s\n"); + p(ip6s_m1, "\t\t%llu one mbuf%s\n"); for (first = 1, i = 0; i < 32; i++) { char ifbuf[IFNAMSIZ]; if (ip6stat.ip6s_m2m[i] != 0) { @@ -404,40 +417,42 @@ ip6_stats(off, name) printf("\t\ttwo or more mbuf:\n"); first = 0; } - printf("\t\t\t%s = %qu\n", + printf("\t\t\t%s = %llu\n", if_indextoname(i, ifbuf), - ip6stat.ip6s_m2m[i]); + (unsigned long long)ip6stat.ip6s_m2m[i]); } } - p(ip6s_mext1, "\t\t%qu one ext mbuf%s\n"); - p(ip6s_mext2m, "\t\t%qu two or more ext mbuf%s\n"); - p(ip6s_exthdrtoolong, "\t%qu packet%s whose headers are not continuous\n"); - p(ip6s_nogif, "\t%qu tunneling packet%s that can't find gif\n"); - p(ip6s_toomanyhdr, "\t%qu packet%s discarded due to too many headers\n"); + p(ip6s_mext1, "\t\t%llu one ext mbuf%s\n"); + p(ip6s_mext2m, "\t\t%llu two or more ext mbuf%s\n"); + p(ip6s_exthdrtoolong, + "\t%llu packet%s whose headers are not continuous\n"); + p(ip6s_nogif, "\t%llu tunneling packet%s that can't find gif\n"); + p(ip6s_toomanyhdr, + "\t%llu packet%s discarded due to too many headers\n"); /* for debugging source address selection */ #define PRINT_SCOPESTAT(s,i) do {\ switch(i) { /* XXX hardcoding in each case */\ case 1:\ - p(s, "\t\t%qu node-local%s\n");\ + p(s, "\t\t%llu node-local%s\n");\ break;\ case 2:\ - p(s,"\t\t%qu link-local%s\n");\ + p(s, "\t\t%llu link-local%s\n");\ break;\ case 5:\ - p(s,"\t\t%qu site-local%s\n");\ + p(s, "\t\t%llu site-local%s\n");\ break;\ case 14:\ - p(s,"\t\t%qu global%s\n");\ + p(s, "\t\t%llu global%s\n");\ break;\ default:\ - printf("\t\t%qu addresses scope=%x\n",\ - ip6stat.s, i);\ + printf("\t\t%llu addresses scope=%x\n",\ + (unsigned long long)ip6stat.s, i);\ }\ } while(0); p(ip6s_sources_none, - "\t%qu failure%s of source address selection\n"); + "\t%llu failure%s of source address selection\n"); for (first = 1, i = 0; i < 16; i++) { if (ip6stat.ip6s_sources_sameif[i]) { if (first) { @@ -500,9 +515,10 @@ ip6_ifstats(ifname) struct in6_ifreq ifr; int s; #define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ - printf(m, ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f)) + printf(m, (unsigned long long)ifr.ifr_ifru.ifru_stat.f, \ + plural(ifr.ifr_ifru.ifru_stat.f)) #define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ - printf(m, ip6stat.f) + printf(m, (unsigned long long)ip6stat.f) if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("Warning: socket(AF_INET6)"); @@ -517,27 +533,28 @@ ip6_ifstats(ifname) goto end; } - p(ifs6_in_receive, "\t%qu total input datagram%s\n"); - p(ifs6_in_hdrerr, "\t%qu datagram%s with invalid header received\n"); - p(ifs6_in_toobig, "\t%qu datagram%s exceeded MTU received\n"); - p(ifs6_in_noroute, "\t%qu datagram%s with no route received\n"); - p(ifs6_in_addrerr, "\t%qu datagram%s with invalid dst received\n"); - p(ifs6_in_protounknown, "\t%qu datagram%s with unknown proto received\n"); - p(ifs6_in_discard, "\t%qu input datagram%s discarded\n"); + p(ifs6_in_receive, "\t%llu total input datagram%s\n"); + p(ifs6_in_hdrerr, "\t%llu datagram%s with invalid header received\n"); + p(ifs6_in_toobig, "\t%llu datagram%s exceeded MTU received\n"); + p(ifs6_in_noroute, "\t%llu datagram%s with no route received\n"); + p(ifs6_in_addrerr, "\t%llu datagram%s with invalid dst received\n"); + p(ifs6_in_truncated, "\t%llu truncated datagram%s received\n"); + p(ifs6_in_protounknown, "\t%llu datagram%s with unknown proto received\n"); + p(ifs6_in_discard, "\t%llu input datagram%s discarded\n"); p(ifs6_in_deliver, - "\t%qu datagram%s delivered to an upper layer protocol\n"); - p(ifs6_out_forward, "\t%qu datagram%s forwarded to this interface\n"); + "\t%llu datagram%s delivered to an upper layer protocol\n"); + p(ifs6_out_forward, "\t%llu datagram%s forwarded to this interface\n"); p(ifs6_out_request, - "\t%qu datagram%s sent from an upper layer protocol\n"); - p(ifs6_out_discard, "\t%qu total discarded output datagram%s\n"); - p(ifs6_out_fragok, "\t%qu output datagram%s fragmented\n"); - p(ifs6_out_fragfail, "\t%qu output datagram%s failed on fragment\n"); - p(ifs6_out_fragcreat, "\t%qu output datagram%s succeeded on fragment\n"); - p(ifs6_reass_reqd, "\t%qu incoming datagram%s fragmented\n"); - p(ifs6_reass_ok, "\t%qu datagram%s reassembled\n"); - p(ifs6_reass_fail, "\t%qu datagram%s failed on reassembling\n"); - p(ifs6_in_mcast, "\t%qu multicast datagram%s received\n"); - p(ifs6_out_mcast, "\t%qu multicast datagram%s sent\n"); + "\t%llu datagram%s sent from an upper layer protocol\n"); + p(ifs6_out_discard, "\t%llu total discarded output datagram%s\n"); + p(ifs6_out_fragok, "\t%llu output datagram%s fragmented\n"); + p(ifs6_out_fragfail, "\t%llu output datagram%s failed on fragment\n"); + p(ifs6_out_fragcreat, "\t%llu output datagram%s succeeded on fragment\n"); + p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n"); + p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n"); + p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n"); + p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n"); + p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n"); end: close(s); @@ -822,57 +839,63 @@ icmp6_stats(off, name) printf("%s:\n", name); #define p(f, m) if (icmp6stat.f || sflag <= 1) \ - printf(m, icmp6stat.f, plural(icmp6stat.f)) + printf(m, (unsigned long long)icmp6stat.f, plural(icmp6stat.f)) #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ - printf(m, icmp6stat.f) + printf(m, (unsigned long long)icmp6stat.f) - p(icp6s_error, "\t%qu call%s to icmp6_error\n"); + p(icp6s_error, "\t%llu call%s to icmp6_error\n"); p(icp6s_canterror, - "\t%qu error%s not generated because old message was icmp6 or so\n"); + "\t%llu error%s not generated because old message was icmp6 or so\n"); p(icp6s_toofreq, - "\t%qu error%s not generated because of rate limitation\n"); + "\t%llu error%s not generated because of rate limitation\n"); for (first = 1, i = 0; i < 256; i++) if (icmp6stat.icp6s_outhist[i] != 0) { if (first) { printf("\tOutput packet histogram:\n"); first = 0; } - printf("\t\t%s: %qu\n", icmp6names[i], - icmp6stat.icp6s_outhist[i]); + printf("\t\t%s: %llu\n", icmp6names[i], + (unsigned long long)icmp6stat.icp6s_outhist[i]); } - p(icp6s_badcode, "\t%qu message%s with bad code fields\n"); - p(icp6s_tooshort, "\t%qu message%s < minimum length\n"); - p(icp6s_checksum, "\t%qu bad checksum%s\n"); - p(icp6s_badlen, "\t%qu message%s with bad length\n"); + p(icp6s_badcode, "\t%llu message%s with bad code fields\n"); + p(icp6s_tooshort, "\t%llu message%s < minimum length\n"); + p(icp6s_checksum, "\t%llu bad checksum%s\n"); + p(icp6s_badlen, "\t%llu message%s with bad length\n"); for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++) if (icmp6stat.icp6s_inhist[i] != 0) { if (first) { printf("\tInput packet histogram:\n"); first = 0; } - printf("\t\t%s: %qu\n", icmp6names[i], - icmp6stat.icp6s_inhist[i]); + printf("\t\t%s: %llu\n", icmp6names[i], + (unsigned long long)icmp6stat.icp6s_inhist[i]); } printf("\tHistogram of error messages to be generated:\n"); - p_5(icp6s_odst_unreach_noroute, "\t\t%qu no route\n"); - p_5(icp6s_odst_unreach_admin, "\t\t%qu administratively prohibited\n"); - p_5(icp6s_odst_unreach_beyondscope, "\t\t%qu beyond scope\n"); - p_5(icp6s_odst_unreach_addr, "\t\t%qu address unreachable\n"); - p_5(icp6s_odst_unreach_noport, "\t\t%qu port unreachable\n"); - p_5(icp6s_opacket_too_big, "\t\t%qu packet too big\n"); - p_5(icp6s_otime_exceed_transit, "\t\t%qu time exceed transit\n"); - p_5(icp6s_otime_exceed_reassembly, "\t\t%qu time exceed reassembly\n"); - p_5(icp6s_oparamprob_header, "\t\t%qu erroneous header field\n"); - p_5(icp6s_oparamprob_nextheader, "\t\t%qu unrecognized next header\n"); - p_5(icp6s_oparamprob_option, "\t\t%qu unrecognized option\n"); - p_5(icp6s_oredirect, "\t\t%qu redirect\n"); - p_5(icp6s_ounknown, "\t\t%qu unknown\n"); + p_5(icp6s_odst_unreach_noroute, "\t\t%llu no route\n"); + p_5(icp6s_odst_unreach_admin, "\t\t%llu administratively prohibited\n"); + p_5(icp6s_odst_unreach_beyondscope, "\t\t%llu beyond scope\n"); + p_5(icp6s_odst_unreach_addr, "\t\t%llu address unreachable\n"); + p_5(icp6s_odst_unreach_noport, "\t\t%llu port unreachable\n"); + p_5(icp6s_opacket_too_big, "\t\t%llu packet too big\n"); + p_5(icp6s_otime_exceed_transit, "\t\t%llu time exceed transit\n"); + p_5(icp6s_otime_exceed_reassembly, "\t\t%llu time exceed reassembly\n"); + p_5(icp6s_oparamprob_header, "\t\t%llu erroneous header field\n"); + p_5(icp6s_oparamprob_nextheader, "\t\t%llu unrecognized next header\n"); + p_5(icp6s_oparamprob_option, "\t\t%llu unrecognized option\n"); + p_5(icp6s_oredirect, "\t\t%llu redirect\n"); + p_5(icp6s_ounknown, "\t\t%llu unknown\n"); - p(icp6s_reflect, "\t%qu message response%s generated\n"); - p(icp6s_nd_toomanyopt, "\t%qu message%s with too many ND options\n"); + p(icp6s_reflect, "\t%llu message response%s generated\n"); + p(icp6s_nd_toomanyopt, "\t%llu message%s with too many ND options\n"); + p(icp6s_nd_badopt, "\t%llu message%s with bad ND options\n"); + p(icp6s_badns, "\t%llu bad neighbor solicitation message%s\n"); + p(icp6s_badna, "\t%llu bad neighbor advertisement message%s\n"); + p(icp6s_badrs, "\t%llu bad router solicitation message%s\n"); + p(icp6s_badra, "\t%llu bad router advertisement message%s\n"); + p(icp6s_badredirect, "\t%llu bad redirect message%s\n"); p(icp6s_pmtuchg, "\t%llu path MTU change%s\n"); -#undef p_5 #undef p +#undef p_5 } /* @@ -885,7 +908,8 @@ icmp6_ifstats(ifname) struct in6_ifreq ifr; int s; #define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ - printf(m, (u_quad_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f)) + printf(m, (unsigned long long)ifr.ifr_ifru.ifru_icmp6stat.f, \ + plural(ifr.ifr_ifru.ifru_icmp6stat.f)) if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("Warning: socket(AF_INET6)"); @@ -900,41 +924,41 @@ icmp6_ifstats(ifname) goto end; } - p(ifs6_in_msg, "\t%qu total input message%s\n"); - p(ifs6_in_error, "\t%qu total input error message%s\n"); - p(ifs6_in_dstunreach, "\t%qu input destination unreachable error%s\n"); - p(ifs6_in_adminprohib, "\t%qu input administratively prohibited error%s\n"); - p(ifs6_in_timeexceed, "\t%qu input time exceeded error%s\n"); - p(ifs6_in_paramprob, "\t%qu input parameter problem error%s\n"); - p(ifs6_in_pkttoobig, "\t%qu input packet too big error%s\n"); - p(ifs6_in_echo, "\t%qu input echo request%s\n"); - p(ifs6_in_echoreply, "\t%qu input echo reply%s\n"); - p(ifs6_in_routersolicit, "\t%qu input router solicitation%s\n"); - p(ifs6_in_routeradvert, "\t%qu input router advertisement%s\n"); - p(ifs6_in_neighborsolicit, "\t%qu input neighbor solicitation%s\n"); - p(ifs6_in_neighboradvert, "\t%qu input neighbor advertisement%s\n"); - p(ifs6_in_redirect, "\t%qu input redirect%s\n"); - p(ifs6_in_mldquery, "\t%qu input MLD query%s\n"); - p(ifs6_in_mldreport, "\t%qu input MLD report%s\n"); - p(ifs6_in_mlddone, "\t%qu input MLD done%s\n"); + p(ifs6_in_msg, "\t%llu total input message%s\n"); + p(ifs6_in_error, "\t%llu total input error message%s\n"); + p(ifs6_in_dstunreach, "\t%llu input destination unreachable error%s\n"); + p(ifs6_in_adminprohib, "\t%llu input administratively prohibited error%s\n"); + p(ifs6_in_timeexceed, "\t%llu input time exceeded error%s\n"); + p(ifs6_in_paramprob, "\t%llu input parameter problem error%s\n"); + p(ifs6_in_pkttoobig, "\t%llu input packet too big error%s\n"); + p(ifs6_in_echo, "\t%llu input echo request%s\n"); + p(ifs6_in_echoreply, "\t%llu input echo reply%s\n"); + p(ifs6_in_routersolicit, "\t%llu input router solicitation%s\n"); + p(ifs6_in_routeradvert, "\t%llu input router advertisement%s\n"); + p(ifs6_in_neighborsolicit, "\t%llu input neighbor solicitation%s\n"); + p(ifs6_in_neighboradvert, "\t%llu input neighbor advertisement%s\n"); + p(ifs6_in_redirect, "\t%llu input redirect%s\n"); + p(ifs6_in_mldquery, "\t%llu input MLD query%s\n"); + p(ifs6_in_mldreport, "\t%llu input MLD report%s\n"); + p(ifs6_in_mlddone, "\t%llu input MLD done%s\n"); - p(ifs6_out_msg, "\t%qu total output message%s\n"); - p(ifs6_out_error, "\t%qu total output error message%s\n"); - p(ifs6_out_dstunreach, "\t%qu output destination unreachable error%s\n"); - p(ifs6_out_adminprohib, "\t%qu output administratively prohibited error%s\n"); - p(ifs6_out_timeexceed, "\t%qu output time exceeded error%s\n"); - p(ifs6_out_paramprob, "\t%qu output parameter problem error%s\n"); - p(ifs6_out_pkttoobig, "\t%qu output packet too big error%s\n"); - p(ifs6_out_echo, "\t%qu output echo request%s\n"); - p(ifs6_out_echoreply, "\t%qu output echo reply%s\n"); - p(ifs6_out_routersolicit, "\t%qu output router solicitation%s\n"); - p(ifs6_out_routeradvert, "\t%qu output router advertisement%s\n"); - p(ifs6_out_neighborsolicit, "\t%qu output neighbor solicitation%s\n"); - p(ifs6_out_neighboradvert, "\t%qu output neighbor advertisement%s\n"); - p(ifs6_out_redirect, "\t%qu output redirect%s\n"); - p(ifs6_out_mldquery, "\t%qu output MLD query%s\n"); - p(ifs6_out_mldreport, "\t%qu output MLD report%s\n"); - p(ifs6_out_mlddone, "\t%qu output MLD done%s\n"); + p(ifs6_out_msg, "\t%llu total output message%s\n"); + p(ifs6_out_error, "\t%llu total output error message%s\n"); + p(ifs6_out_dstunreach, "\t%llu output destination unreachable error%s\n"); + p(ifs6_out_adminprohib, "\t%llu output administratively prohibited error%s\n"); + p(ifs6_out_timeexceed, "\t%llu output time exceeded error%s\n"); + p(ifs6_out_paramprob, "\t%llu output parameter problem error%s\n"); + p(ifs6_out_pkttoobig, "\t%llu output packet too big error%s\n"); + p(ifs6_out_echo, "\t%llu output echo request%s\n"); + p(ifs6_out_echoreply, "\t%llu output echo reply%s\n"); + p(ifs6_out_routersolicit, "\t%llu output router solicitation%s\n"); + p(ifs6_out_routeradvert, "\t%llu output router advertisement%s\n"); + p(ifs6_out_neighborsolicit, "\t%llu output neighbor solicitation%s\n"); + p(ifs6_out_neighboradvert, "\t%llu output neighbor advertisement%s\n"); + p(ifs6_out_redirect, "\t%llu output redirect%s\n"); + p(ifs6_out_mldquery, "\t%llu output MLD query%s\n"); + p(ifs6_out_mldreport, "\t%llu output MLD report%s\n"); + p(ifs6_out_mlddone, "\t%llu output MLD done%s\n"); end: close(s); @@ -957,14 +981,14 @@ pim6_stats(off, name) printf("%s:\n", name); #define p(f, m) if (pim6stat.f || sflag <= 1) \ - printf(m, pim6stat.f, plural(pim6stat.f)) - p(pim6s_rcv_total, "\t%qu message%s received\n"); - p(pim6s_rcv_tooshort, "\t%qu message%s received with too few bytes\n"); - p(pim6s_rcv_badsum, "\t%qu message%s received with bad checksum\n"); - p(pim6s_rcv_badversion, "\t%qu message%s received with bad version\n"); - p(pim6s_rcv_registers, "\t%qu register%s received\n"); - p(pim6s_rcv_badregisters, "\t%qu bad register%s received\n"); - p(pim6s_snd_registers, "\t%qu register%s sent\n"); + printf(m, (unsigned long long)pim6stat.f, plural(pim6stat.f)) + p(pim6s_rcv_total, "\t%llu message%s received\n"); + p(pim6s_rcv_tooshort, "\t%llu message%s received with too few bytes\n"); + p(pim6s_rcv_badsum, "\t%llu message%s received with bad checksum\n"); + p(pim6s_rcv_badversion, "\t%llu message%s received with bad version\n"); + p(pim6s_rcv_registers, "\t%llu register%s received\n"); + p(pim6s_rcv_badregisters, "\t%llu bad register%s received\n"); + p(pim6s_snd_registers, "\t%llu register%s sent\n"); #undef p } @@ -980,19 +1004,22 @@ inet6print(in6, port, proto) char *proto; { #define GETSERVBYPORT6(port, proto, ret)\ -{\ +do {\ if (strcmp((proto), "tcp6") == 0)\ (ret) = getservbyport((int)(port), "tcp");\ else if (strcmp((proto), "udp6") == 0)\ (ret) = getservbyport((int)(port), "udp");\ else\ (ret) = getservbyport((int)(port), (proto));\ -}; +} while (0) struct servent *sp = 0; char line[80], *cp; int width; - sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inet6name(in6)); + width = Aflag ? 12 : 16; + if (vflag && width < strlen(inet6name(in6))) + width = strlen(inet6name(in6)); + sprintf(line, "%.*s.", width, inet6name(in6)); cp = index(line, '\0'); if (!nflag && port) GETSERVBYPORT6(port, proto, sp); @@ -1001,6 +1028,8 @@ inet6print(in6, port, proto) else sprintf(cp, "%d", ntohs((u_short)port)); width = Aflag ? 18 : 22; + if (vflag && width < strlen(line)) + width = strlen(line); printf(" %-*.*s", width, width, line); } @@ -1015,11 +1044,11 @@ inet6name(in6p) struct in6_addr *in6p; { register char *cp; - static char line[50]; + static char line[NI_MAXHOST]; struct hostent *hp; static char domain[MAXHOSTNAMELEN + 1]; static int first = 1; - static char hbuf[NI_MAXHOST]; + char hbuf[NI_MAXHOST]; struct sockaddr_in6 sin6; #ifdef NI_WITHSCOPEID const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID; @@ -1046,9 +1075,9 @@ inet6name(in6p) } } if (IN6_IS_ADDR_UNSPECIFIED(in6p)) - strcpy(line, "*"); + strlcpy(line, "*", sizeof(line)); else if (cp) - strcpy(line, cp); + strlcpy(line, cp, sizeof(line)); else { memset(&sin6, 0, sizeof(sin6)); sin6.sin6_len = sizeof(sin6); @@ -1065,7 +1094,7 @@ inet6name(in6p) if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, hbuf, sizeof(hbuf), NULL, 0, niflag) != 0) strcpy(hbuf, "?"); - strncpy(line, hbuf, sizeof(line)); + strlcpy(line, hbuf, sizeof(line)); } return (line); } |