From owner-p4-projects@FreeBSD.ORG Wed Jun 10 17:09:22 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 45126106579F; Wed, 10 Jun 2009 17:09:22 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DD6A71065784 for ; Wed, 10 Jun 2009 17:09:21 +0000 (UTC) (envelope-from pgj@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id C709A8FC1F for ; Wed, 10 Jun 2009 17:09:21 +0000 (UTC) (envelope-from pgj@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5AH9LhW011748 for ; Wed, 10 Jun 2009 17:09:21 GMT (envelope-from pgj@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5AH9Lma011746 for perforce@freebsd.org; Wed, 10 Jun 2009 17:09:21 GMT (envelope-from pgj@FreeBSD.org) Date: Wed, 10 Jun 2009 17:09:21 GMT Message-Id: <200906101709.n5AH9Lma011746@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to pgj@FreeBSD.org using -f From: Gabor Pali To: Perforce Change Reviews Cc: Subject: PERFORCE change 164018 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2009 17:09:23 -0000 http://perforce.freebsd.org/chv.cgi?CH=164018 Change 164018 by pgj@petymeg-current on 2009/06/10 17:09:21 - Move sotoxsocket(), sbtoxsockbuf() from netstat to libnetstat - Remove protopr() from netstat finally Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#19 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#14 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#16 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#3 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#11 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#6 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#19 (text+ko) ==== @@ -249,7 +249,10 @@ } } KREAD(unp->unp_socket, &so, sizeof(so)); - sotoxsocket(&so, &xu.xu_socket); + if (sotoxsocket(kvm, &so, &xu.xu_socket) != 0) { + list->stl_error = NETSTAT_ERROR_UNDEFINED; + return (-1); + } stp = _netstat_st_allocate(list, PF_LOCAL, type, socktype[type]); extract_xunpcb_data(&xu, stp); ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#14 (text+ko) ==== @@ -96,5 +96,5 @@ const char *name); void _netstat_st_reset_stats(struct socket_type *list); -void sotoxsocket(struct socket *so, struct xsocket *xso); +int sotoxsocket(kvm_t * kvm, struct socket *so, struct xsocket *xso); #endif /* !_NETSTAT_INTERNAL_H_ */ ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#16 (text+ko) ==== @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include #include @@ -42,6 +44,56 @@ return (0); } +/* + * Copied directly from uip_socket2.c. We leave out some fields that are in + * nested structures that aren't used to avoid extra work. + */ +static void +sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb) +{ + xsb->sb_cc = sb->sb_cc; + xsb->sb_hiwat = sb->sb_hiwat; + xsb->sb_mbcnt = sb->sb_mbcnt; + xsb->sb_mcnt = sb->sb_mcnt; + xsb->sb_ccnt = sb->sb_ccnt; + xsb->sb_mbmax = sb->sb_mbmax; + xsb->sb_lowat = sb->sb_lowat; + xsb->sb_flags = sb->sb_flags; + xsb->sb_timeo = sb->sb_timeo; +} + +int +sotoxsocket(kvm_t *kvm, struct socket *so, struct xsocket *xso) +{ + struct protosw proto; + struct domain domain; + + bzero(xso, sizeof *xso); + xso->xso_len = sizeof *xso; + xso->xso_so = so; + xso->so_type = so->so_type; + xso->so_options = so->so_options; + xso->so_linger = so->so_linger; + xso->so_state = so->so_state; + xso->so_pcb = so->so_pcb; + if (kread(kvm, (uintptr_t)so->so_proto, &proto, sizeof(proto)) != 0) + return (-1); + xso->xso_protocol = proto.pr_protocol; + if (kread(kvm, (uintptr_t)proto.pr_domain, &domain, + sizeof(domain)) != 0) + return (-1); + xso->xso_family = domain.dom_family; + xso->so_qlen = so->so_qlen; + xso->so_incqlen = so->so_incqlen; + xso->so_qlimit = so->so_qlimit; + xso->so_timeo = so->so_timeo; + xso->so_error = so->so_error; + xso->so_oobmark = so->so_oobmark; + sbtoxsockbuf(&so->so_snd, &xso->so_snd); + sbtoxsockbuf(&so->so_rcv, &xso->so_rcv); + return (0); +} + const char * netstat_strerror(int error) { ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#3 (text+ko) ==== @@ -68,7 +68,6 @@ const char *pluralies(uintmax_t); int sotoxsocket(struct socket *, struct xsocket *); -void protopr(u_long, const char *, int, int); void inetpr(void *, int); void tcp_stats(u_long, const char *, int, int); void udp_stats(u_long, const char *, int, int); ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#11 (text+ko) ==== @@ -97,470 +97,13 @@ #endif /* INET6 */ static void inetppr(struct socket_type *); -static int -pcblist_sysctl(int proto, char **bufp, int istcp) -{ - const char *mibvar; - char *buf; - size_t len; - - switch (proto) { - case IPPROTO_TCP: - mibvar = "net.inet.tcp.pcblist"; - break; - case IPPROTO_UDP: - mibvar = "net.inet.udp.pcblist"; - break; - case IPPROTO_DIVERT: - mibvar = "net.inet.divert.pcblist"; - break; - default: - mibvar = "net.inet.raw.pcblist"; - break; - } - - len = 0; - if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { - if (errno != ENOENT) - warn("sysctl: %s", mibvar); - return (0); - } - if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); - return (0); - } - if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { - warn("sysctl: %s", mibvar); - free(buf); - return (0); - } - *bufp = buf; - return (1); -} - /* - * Copied directly from uipc_socket2.c. We leave out some fields that are in - * nested structures that aren't used to avoid extra work. - */ -static void -sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb) -{ - xsb->sb_cc = sb->sb_cc; - xsb->sb_hiwat = sb->sb_hiwat; - xsb->sb_mbcnt = sb->sb_mbcnt; - xsb->sb_mcnt = sb->sb_mcnt; - xsb->sb_ccnt = sb->sb_ccnt; - xsb->sb_mbmax = sb->sb_mbmax; - xsb->sb_lowat = sb->sb_lowat; - xsb->sb_flags = sb->sb_flags; - xsb->sb_timeo = sb->sb_timeo; -} - -int -sotoxsocket(struct socket *so, struct xsocket *xso) -{ - struct protosw proto; - struct domain domain; - - bzero(xso, sizeof *xso); - xso->xso_len = sizeof *xso; - xso->xso_so = so; - xso->so_type = so->so_type; - xso->so_options = so->so_options; - xso->so_linger = so->so_linger; - xso->so_state = so->so_state; - xso->so_pcb = so->so_pcb; - if (kread((uintptr_t)so->so_proto, &proto, sizeof(proto)) != 0) - return (-1); - xso->xso_protocol = proto.pr_protocol; - if (kread((uintptr_t)proto.pr_domain, &domain, sizeof(domain)) != 0) - return (-1); - xso->xso_family = domain.dom_family; - xso->so_qlen = so->so_qlen; - xso->so_incqlen = so->so_incqlen; - xso->so_qlimit = so->so_qlimit; - xso->so_timeo = so->so_timeo; - xso->so_error = so->so_error; - xso->so_oobmark = so->so_oobmark; - sbtoxsockbuf(&so->so_snd, &xso->so_snd); - sbtoxsockbuf(&so->so_rcv, &xso->so_rcv); - return (0); -} - -static int -pcblist_kvm(u_long off, char **bufp, int istcp) -{ - struct inpcbinfo pcbinfo; - struct inpcbhead listhead; - struct inpcb *inp; - struct xinpcb xi; - struct xinpgen xig; - struct xtcpcb xt; - struct socket so; - struct xsocket *xso; - char *buf, *p; - size_t len; - - if (off == 0) - return (0); - kread(off, &pcbinfo, sizeof(pcbinfo)); - if (istcp) - len = 2 * sizeof(xig) + - (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) * - sizeof(struct xtcpcb); - else - len = 2 * sizeof(xig) + - (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) * - sizeof(struct xinpcb); - if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); - return (0); - } - p = buf; - -#define COPYOUT(obj, size) do { \ - if (len < (size)) { \ - warnx("buffer size exceeded"); \ - goto fail; \ - } \ - bcopy((obj), p, (size)); \ - len -= (size); \ - p += (size); \ -} while (0) - -#define KREAD(off, buf, len) do { \ - if (kread((uintptr_t)(off), (buf), (len)) != 0) \ - goto fail; \ -} while (0) - - /* Write out header. */ - xig.xig_len = sizeof xig; - xig.xig_count = pcbinfo.ipi_count; - xig.xig_gen = pcbinfo.ipi_gencnt; - xig.xig_sogen = 0; - COPYOUT(&xig, sizeof xig); - - /* Walk the PCB list. */ - xt.xt_len = sizeof xt; - xi.xi_len = sizeof xi; - if (istcp) - xso = &xt.xt_socket; - else - xso = &xi.xi_socket; - KREAD(pcbinfo.ipi_listhead, &listhead, sizeof(listhead)); - LIST_FOREACH(inp, &listhead, inp_list) { - if (istcp) { - KREAD(inp, &xt.xt_inp, sizeof(*inp)); - inp = &xt.xt_inp; - } else { - KREAD(inp, &xi.xi_inp, sizeof(*inp)); - inp = &xi.xi_inp; - } - - if (inp->inp_gencnt > pcbinfo.ipi_gencnt) - continue; - - if (istcp) { - if (inp->inp_ppcb == NULL) - bzero(&xt.xt_tp, sizeof xt.xt_tp); - else if (inp->inp_flags & INP_TIMEWAIT) { - bzero(&xt.xt_tp, sizeof xt.xt_tp); - xt.xt_tp.t_state = TCPS_TIME_WAIT; - } else - KREAD(inp->inp_ppcb, &xt.xt_tp, - sizeof xt.xt_tp); - } - if (inp->inp_socket) { - KREAD(inp->inp_socket, &so, sizeof(so)); - if (sotoxsocket(&so, xso) != 0) - goto fail; - } else { - bzero(xso, sizeof(*xso)); - if (istcp) - xso->xso_protocol = IPPROTO_TCP; - } - if (istcp) - COPYOUT(&xt, sizeof xt); - else - COPYOUT(&xi, sizeof xi); - } - - /* Reread the pcbinfo and write out the footer. */ - kread(off, &pcbinfo, sizeof(pcbinfo)); - xig.xig_count = pcbinfo.ipi_count; - xig.xig_gen = pcbinfo.ipi_gencnt; - COPYOUT(&xig, sizeof xig); - - *bufp = buf; - return (1); - -fail: - free(buf); - return (0); -#undef COPYOUT -#undef KREAD -} - -/* * Print a summary of connections related to an Internet * protocol. For TCP, also give state of connection. * Listening processes (aflag) are suppressed unless the * -a (all) flag is specified. */ void -protopr(u_long off, const char *name, int af1, int proto) -{ - int istcp; - static int first = 1; - char *buf; - const char *vchar; - struct tcpcb *tp = NULL; - struct inpcb *inp; - struct xinpgen *xig, *oxig; - struct xsocket *so; - - istcp = 0; - switch (proto) { - case IPPROTO_TCP: -#ifdef INET6 - if (tcp_done != 0) - return; - else - tcp_done = 1; -#endif - istcp = 1; - break; - case IPPROTO_UDP: -#ifdef INET6 - if (udp_done != 0) - return; - else - udp_done = 1; -#endif - break; - } - if (live) { - if (!pcblist_sysctl(proto, &buf, istcp)) - return; - } else { - if (!pcblist_kvm(off, &buf, istcp)) - return; - } - - oxig = xig = (struct xinpgen *)buf; - for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); - xig->xig_len > sizeof(struct xinpgen); - xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { - if (istcp) { - tp = &((struct xtcpcb *)xig)->xt_tp; - inp = &((struct xtcpcb *)xig)->xt_inp; - so = &((struct xtcpcb *)xig)->xt_socket; - } else { - inp = &((struct xinpcb *)xig)->xi_inp; - so = &((struct xinpcb *)xig)->xi_socket; - } - - /* Ignore sockets for protocols other than the desired one. */ - if (so->xso_protocol != proto) - continue; - - /* Ignore PCBs which were freed during copyout. */ - if (inp->inp_gencnt > oxig->xig_gen) - continue; - - if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0) -#ifdef INET6 - || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0) -#endif /* INET6 */ - || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0 -#ifdef INET6 - && (inp->inp_vflag & INP_IPV6) == 0 -#endif /* INET6 */ - )) - ) - continue; - if (!aflag && - ( - (istcp && tp->t_state == TCPS_LISTEN) - || (af1 == AF_INET && - inet_lnaof(inp->inp_laddr) == INADDR_ANY) -#ifdef INET6 - || (af1 == AF_INET6 && - IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) -#endif /* INET6 */ - || (af1 == AF_UNSPEC && - (((inp->inp_vflag & INP_IPV4) != 0 && - inet_lnaof(inp->inp_laddr) == INADDR_ANY) -#ifdef INET6 - || ((inp->inp_vflag & INP_IPV6) != 0 && - IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) -#endif - )) - )) - continue; - - if (first) { - if (!Lflag) { - printf("Active Internet connections"); - if (aflag) - printf(" (including servers)"); - } else - printf( - "Current listen queue sizes (qlen/incqlen/maxqlen)"); - putchar('\n'); - if (Aflag) - printf("%-8.8s ", "Tcpcb"); - if (Lflag) - printf("%-5.5s %-14.14s %-22.22s\n", - "Proto", "Listen", "Local Address"); - else { - printf((Aflag && !Wflag) ? - "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s" : - "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s", - "Proto", "Recv-Q", "Send-Q", - "Local Address", "Foreign Address"); - if (xflag) - printf("%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %s\n", - "R-MBUF", "S-MBUF", "R-CLUS", - "S-CLUS", "R-HIWA", "S-HIWA", - "R-LOWA", "S-LOWA", "R-BCNT", - "S-BCNT", "R-BMAX", "S-BMAX", - "(state)"); - else - printf("(state)\n"); - } - first = 0; - } - if (Lflag && so->so_qlimit == 0) - continue; - if (Aflag) { - if (istcp) - printf("%8lx ", (u_long)inp->inp_ppcb); - else - printf("%8lx ", (u_long)so->so_pcb); - } -#ifdef INET6 - if ((inp->inp_vflag & INP_IPV6) != 0) - vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? - "46" : "6 "; - else -#endif - vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? - "4 " : " "; - printf("%-3.3s%-2.2s ", name, vchar); - if (Lflag) { - char buf1[15]; - - snprintf(buf1, 15, "%d/%d/%d", so->so_qlen, - so->so_incqlen, so->so_qlimit); - printf("%-14.14s ", buf1); - } else { - printf("%6u %6u ", so->so_rcv.sb_cc, so->so_snd.sb_cc); - } - if (numeric_port) { - if (inp->inp_vflag & INP_IPV4) { - inetprint(&inp->inp_laddr, (int)inp->inp_lport, - name, 1); - if (!Lflag) - inetprint(&inp->inp_faddr, - (int)inp->inp_fport, name, 1); - } -#ifdef INET6 - else if (inp->inp_vflag & INP_IPV6) { - inet6print(&inp->in6p_laddr, - (int)inp->inp_lport, name, 1); - if (!Lflag) - inet6print(&inp->in6p_faddr, - (int)inp->inp_fport, name, 1); - } /* else nothing printed now */ -#endif /* INET6 */ - } else if (inp->inp_flags & INP_ANONPORT) { - if (inp->inp_vflag & INP_IPV4) { - inetprint(&inp->inp_laddr, (int)inp->inp_lport, - name, 1); - if (!Lflag) - inetprint(&inp->inp_faddr, - (int)inp->inp_fport, name, 0); - } -#ifdef INET6 - else if (inp->inp_vflag & INP_IPV6) { - inet6print(&inp->in6p_laddr, - (int)inp->inp_lport, name, 1); - if (!Lflag) - inet6print(&inp->in6p_faddr, - (int)inp->inp_fport, name, 0); - } /* else nothing printed now */ -#endif /* INET6 */ - } else { - if (inp->inp_vflag & INP_IPV4) { - inetprint(&inp->inp_laddr, (int)inp->inp_lport, - name, 0); - if (!Lflag) - inetprint(&inp->inp_faddr, - (int)inp->inp_fport, name, - inp->inp_lport != inp->inp_fport); - } -#ifdef INET6 - else if (inp->inp_vflag & INP_IPV6) { - inet6print(&inp->in6p_laddr, - (int)inp->inp_lport, name, 0); - if (!Lflag) - inet6print(&inp->in6p_faddr, - (int)inp->inp_fport, name, - inp->inp_lport != inp->inp_fport); - } /* else nothing printed now */ -#endif /* INET6 */ - } - if (xflag) { - if (Lflag) - printf("%21s %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u ", - " ", - so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt, - so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt, - so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat, - so->so_rcv.sb_lowat, so->so_snd.sb_lowat, - so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt, - so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax); - else - printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u ", - so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt, - so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt, - so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat, - so->so_rcv.sb_lowat, so->so_snd.sb_lowat, - so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt, - so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax); - } - if (istcp && !Lflag) { - if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) - printf("%d", tp->t_state); - else { - printf("%s", tcpstates[tp->t_state]); -#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN) - /* Show T/TCP `hidden state' */ - if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) - putchar('*'); -#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ - } - } - putchar('\n'); - } - if (xig != oxig && xig->xig_gen != oxig->xig_gen) { - if (oxig->xig_count > xig->xig_count) { - printf("Some %s sockets may have been deleted.\n", - name); - } else if (oxig->xig_count < xig->xig_count) { - printf("Some %s sockets may have been created.\n", - name); - } else { - printf( - "Some %s sockets may have been created or deleted.\n", - name); - } - } - free(buf); -} - -void inetpr(void *kvmd, int proto) { struct socket_type_list *stlp; ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#6 (text+ko) ==== @@ -192,21 +192,21 @@ int pr_usesysctl; /* non-zero if we use sysctl, not kvm */ int pr_protocol; } protox[] = { - { N_TCBINFO, N_TCPSTAT, 1, protopr, + { N_TCBINFO, N_TCPSTAT, 1, NULL, tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, - { N_UDBINFO, N_UDPSTAT, 1, protopr, + { N_UDBINFO, N_UDPSTAT, 1, NULL, udp_stats, NULL, "udp", 1, IPPROTO_UDP }, #ifdef SCTP { -1, N_SCTPSTAT, 1, sctp_protopr, sctp_stats, NULL, "sctp", 1, IPPROTO_SCTP }, #endif - { N_DIVCBINFO, -1, 1, protopr, + { N_DIVCBINFO, -1, 1, NULL, NULL, NULL, "divert", 1, IPPROTO_DIVERT }, - { N_RIPCBINFO, N_IPSTAT, 1, protopr, + { N_RIPCBINFO, N_IPSTAT, 1, NULL, ip_stats, NULL, "ip", 1, IPPROTO_RAW }, - { N_RIPCBINFO, N_ICMPSTAT, 1, protopr, + { N_RIPCBINFO, N_ICMPSTAT, 1, NULL, icmp_stats, NULL, "icmp", 1, IPPROTO_ICMP }, - { N_RIPCBINFO, N_IGMPSTAT, 1, protopr, + { N_RIPCBINFO, N_IGMPSTAT, 1, NULL, igmp_stats, NULL, "igmp", 1, IPPROTO_IGMP }, #ifdef IPSEC { -1, N_IPSECSTAT, 1, NULL, /* keep as compat */ @@ -218,7 +218,7 @@ { -1, N_IPCOMPSTAT, 1, NULL, ipcomp_stats, NULL, "ipcomp", 0, 0}, #endif - { N_RIPCBINFO, N_PIMSTAT, 1, protopr, + { N_RIPCBINFO, N_PIMSTAT, 1, NULL, pim_stats, NULL, "pim", 1, IPPROTO_PIM }, { -1, N_CARPSTAT, 1, NULL, carp_stats, NULL, "carp", 1, 0 }, @@ -230,13 +230,13 @@ #ifdef INET6 struct protox ip6protox[] = { - { N_TCBINFO, N_TCPSTAT, 1, protopr, + { N_TCBINFO, N_TCPSTAT, 1, NULL, tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, - { N_UDBINFO, N_UDPSTAT, 1, protopr, + { N_UDBINFO, N_UDPSTAT, 1, NULL, udp_stats, NULL, "udp", 1, IPPROTO_UDP }, - { N_RIPCBINFO, N_IP6STAT, 1, protopr, + { N_RIPCBINFO, N_IP6STAT, 1, NULL, ip6_stats, ip6_ifstats, "ip6", 1, IPPROTO_RAW }, - { N_RIPCBINFO, N_ICMP6STAT, 1, protopr, + { N_RIPCBINFO, N_ICMP6STAT, 1, NULL, icmp6_stats, icmp6_ifstats, "icmp6", 1, IPPROTO_ICMPV6 }, #ifdef IPSEC { -1, N_IPSEC6STAT, 1, NULL, @@ -635,11 +635,6 @@ } } else { pr = tp->pr_cblocks; - if (!pr) { - if (pflag) - printf("%s: no PCB routine\n", tp->pr_name); - return; - } if (tp->pr_usesysctl && live) off = 0; else if (tp->pr_index < 0) { @@ -651,13 +646,27 @@ } else off = nl[tp->pr_index].n_value; } - if (pr != NULL && (off || (live && tp->pr_usesysctl) || + if ((off || (live && tp->pr_usesysctl) || af != AF_UNSPEC)) { /* XXX: temp. hack */ - if (tp->pr_index == N_TCBINFO) - inetpr(kvmd, IPPROTO_TCP); - else - (*pr)(off, name, af, tp->pr_protocol); + switch (tp->pr_protocol) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_DIVERT: + case IPPROTO_RAW: + case IPPROTO_ICMP: + case IPPROTO_IGMP: + case IPPROTO_PIM: + case IPPROTO_ICMPV6: + inetpr(kvmd, tp->pr_protocol); + break; + default: + if (pr != NULL) + (*pr)(off, name, af, tp->pr_protocol); + else if (pflag) + printf("%s: no PCB routine\n", tp->pr_name); + break; + } } }