Index: projects/sendfile/usr.bin/bluetooth/btsockstat/btsockstat.c =================================================================== --- projects/sendfile/usr.bin/bluetooth/btsockstat/btsockstat.c (revision 263419) +++ projects/sendfile/usr.bin/bluetooth/btsockstat/btsockstat.c (revision 263420) @@ -1,645 +1,645 @@ /* * btsockstat.c * * Copyright (c) 2001-2002 Maksim Yevmenkin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: btsockstat.c,v 1.8 2003/05/21 22:40:25 max Exp $ * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void hcirawpr (kvm_t *kvmd, u_long addr); static void l2caprawpr (kvm_t *kvmd, u_long addr); static void l2cappr (kvm_t *kvmd, u_long addr); static void l2caprtpr (kvm_t *kvmd, u_long addr); static void rfcommpr (kvm_t *kvmd, u_long addr); static void rfcommpr_s (kvm_t *kvmd, u_long addr); static char * bdaddrpr (bdaddr_p const ba, char *str, int len); static kvm_t * kopen (char const *memf); static int kread (kvm_t *kvmd, u_long addr, char *buffer, int size); static void usage (void); /* * List of symbols */ static struct nlist nl[] = { #define N_HCI_RAW 0 { "_ng_btsocket_hci_raw_sockets" }, #define N_L2CAP_RAW 1 { "_ng_btsocket_l2cap_raw_sockets" }, #define N_L2CAP 2 { "_ng_btsocket_l2cap_sockets" }, #define N_L2CAP_RAW_RT 3 { "_ng_btsocket_l2cap_raw_rt" }, #define N_L2CAP_RT 4 { "_ng_btsocket_l2cap_rt" }, #define N_RFCOMM 5 { "_ng_btsocket_rfcomm_sockets" }, #define N_RFCOMM_S 6 { "_ng_btsocket_rfcomm_sessions" }, { "" }, }; #define state2str(x) \ (((x) >= sizeof(states)/sizeof(states[0]))? "UNKNOWN" : states[(x)]) /* * Main */ static int numeric_bdaddr = 0; int main(int argc, char *argv[]) { int opt, proto = -1, route = 0; kvm_t *kvmd = NULL; char *memf = NULL; while ((opt = getopt(argc, argv, "hnM:p:r")) != -1) { switch (opt) { case 'n': numeric_bdaddr = 1; break; case 'M': memf = optarg; break; case 'p': if (strcasecmp(optarg, "hci_raw") == 0) proto = N_HCI_RAW; else if (strcasecmp(optarg, "l2cap_raw") == 0) proto = N_L2CAP_RAW; else if (strcasecmp(optarg, "l2cap") == 0) proto = N_L2CAP; else if (strcasecmp(optarg, "rfcomm") == 0) proto = N_RFCOMM; else if (strcasecmp(optarg, "rfcomm_s") == 0) proto = N_RFCOMM_S; else usage(); /* NOT REACHED */ break; case 'r': route = 1; break; case 'h': default: usage(); /* NOT REACHED */ } } if ((proto == N_HCI_RAW || proto == N_RFCOMM || proto == N_RFCOMM_S) && route) usage(); /* NOT REACHED */ /* * Discard setgid privileges if not the running kernel so that * bad guys can't print interesting stuff from kernel memory. */ if (memf != NULL) setgid(getgid()); kvmd = kopen(memf); if (kvmd == NULL) return (1); switch (proto) { case N_HCI_RAW: hcirawpr(kvmd, nl[N_HCI_RAW].n_value); break; case N_L2CAP_RAW: if (route) l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value); else l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value); break; case N_L2CAP: if (route) l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value); else l2cappr(kvmd, nl[N_L2CAP].n_value); break; case N_RFCOMM: rfcommpr(kvmd, nl[N_RFCOMM].n_value); break; case N_RFCOMM_S: rfcommpr_s(kvmd, nl[N_RFCOMM_S].n_value); break; default: if (route) { l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value); l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value); } else { hcirawpr(kvmd, nl[N_HCI_RAW].n_value); l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value); l2cappr(kvmd, nl[N_L2CAP].n_value); rfcommpr_s(kvmd, nl[N_RFCOMM_S].n_value); rfcommpr(kvmd, nl[N_RFCOMM].n_value); } break; } return (kvm_close(kvmd)); } /* main */ /* * Print raw HCI sockets */ static void hcirawpr(kvm_t *kvmd, u_long addr) { ng_btsocket_hci_raw_pcb_p this = NULL, next = NULL; ng_btsocket_hci_raw_pcb_t pcb; struct socket so; int first = 1; if (addr == 0) return; if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) return; for ( ; this != NULL; this = next) { if (kread(kvmd, (u_long) this, (char *) &pcb, sizeof(pcb)) < 0) return; if (kread(kvmd, (u_long) pcb.so, (char *) &so, sizeof(so)) < 0) return; next = LIST_NEXT(&pcb, next); if (first) { first = 0; fprintf(stdout, "Active raw HCI sockets\n" \ "%-8.8s %-8.8s %-6.6s %-6.6s %-6.6s %-16.16s\n", "Socket", "PCB", "Flags", "Recv-Q", "Send-Q", "Local address"); } if (pcb.addr.hci_node[0] == 0) { pcb.addr.hci_node[0] = '*'; pcb.addr.hci_node[1] = 0; } fprintf(stdout, "%-8lx %-8lx %-6.6x %6d %6d %-16.16s\n", (unsigned long) pcb.so, (unsigned long) this, pcb.flags, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, pcb.addr.hci_node); } } /* hcirawpr */ /* * Print raw L2CAP sockets */ static void l2caprawpr(kvm_t *kvmd, u_long addr) { ng_btsocket_l2cap_raw_pcb_p this = NULL, next = NULL; ng_btsocket_l2cap_raw_pcb_t pcb; struct socket so; int first = 1; if (addr == 0) return; if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) return; for ( ; this != NULL; this = next) { if (kread(kvmd, (u_long) this, (char *) &pcb, sizeof(pcb)) < 0) return; if (kread(kvmd, (u_long) pcb.so, (char *) &so, sizeof(so)) < 0) return; next = LIST_NEXT(&pcb, next); if (first) { first = 0; fprintf(stdout, "Active raw L2CAP sockets\n" \ "%-8.8s %-8.8s %-6.6s %-6.6s %-17.17s\n", "Socket", "PCB", "Recv-Q", "Send-Q", "Local address"); } fprintf(stdout, "%-8lx %-8lx %6d %6d %-17.17s\n", (unsigned long) pcb.so, (unsigned long) this, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, bdaddrpr(&pcb.src, NULL, 0)); } } /* l2caprawpr */ /* * Print L2CAP sockets */ static void l2cappr(kvm_t *kvmd, u_long addr) { static char const * const states[] = { /* NG_BTSOCKET_L2CAP_CLOSED */ "CLOSED", /* NG_BTSOCKET_L2CAP_CONNECTING */ "CON", /* NG_BTSOCKET_L2CAP_CONFIGURING */ "CONFIG", /* NG_BTSOCKET_L2CAP_OPEN */ "OPEN", /* NG_BTSOCKET_L2CAP_DISCONNECTING */ "DISCON" }; ng_btsocket_l2cap_pcb_p this = NULL, next = NULL; ng_btsocket_l2cap_pcb_t pcb; struct socket so; int first = 1; char local[24], remote[24]; if (addr == 0) return; if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) return; for ( ; this != NULL; this = next) { if (kread(kvmd, (u_long) this, (char *) &pcb, sizeof(pcb)) < 0) return; if (kread(kvmd, (u_long) pcb.so, (char *) &so, sizeof(so)) < 0) return; next = LIST_NEXT(&pcb, next); if (first) { first = 0; fprintf(stdout, "Active L2CAP sockets\n" \ "%-8.8s %-6.6s %-6.6s %-23.23s %-17.17s %-5.5s %s\n", "PCB", "Recv-Q", "Send-Q", "Local address/PSM", "Foreign address", "CID", "State"); } fprintf(stdout, "%-8lx %6d %6d %-17.17s/%-5d %-17.17s %-5d %s\n", (unsigned long) this, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, bdaddrpr(&pcb.src, local, sizeof(local)), pcb.psm, bdaddrpr(&pcb.dst, remote, sizeof(remote)), pcb.cid, (so.so_options & SO_ACCEPTCONN)? "LISTEN" : state2str(pcb.state)); } } /* l2cappr */ /* * Print L2CAP routing table */ static void l2caprtpr(kvm_t *kvmd, u_long addr) { ng_btsocket_l2cap_rtentry_p this = NULL, next = NULL; ng_btsocket_l2cap_rtentry_t rt; int first = 1; if (addr == 0) return; if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) return; for ( ; this != NULL; this = next) { if (kread(kvmd, (u_long) this, (char *) &rt, sizeof(rt)) < 0) return; next = LIST_NEXT(&rt, next); if (first) { first = 0; fprintf(stdout, "Known %sL2CAP routes\n", (addr == nl[N_L2CAP_RAW_RT].n_value)? "raw " : ""); fprintf(stdout, "%-8.8s %-8.8s %-17.17s\n", "RTentry", "Hook", "BD_ADDR"); } fprintf(stdout, "%-8lx %-8lx %-17.17s\n", (unsigned long) this, (unsigned long) rt.hook, bdaddrpr(&rt.src, NULL, 0)); } } /* l2caprtpr */ /* * Print RFCOMM sockets */ static void rfcommpr(kvm_t *kvmd, u_long addr) { static char const * const states[] = { /* NG_BTSOCKET_RFCOMM_DLC_CLOSED */ "CLOSED", /* NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT */ "W4CON", /* NG_BTSOCKET_RFCOMM_DLC_CONFIGURING */ "CONFIG", /* NG_BTSOCKET_RFCOMM_DLC_CONNECTING */ "CONN", /* NG_BTSOCKET_RFCOMM_DLC_CONNECTED */ "OPEN", /* NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING */ "DISCON" }; ng_btsocket_rfcomm_pcb_p this = NULL, next = NULL; ng_btsocket_rfcomm_pcb_t pcb; struct socket so; int first = 1; char local[24], remote[24]; if (addr == 0) return; if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) return; for ( ; this != NULL; this = next) { if (kread(kvmd, (u_long) this, (char *) &pcb, sizeof(pcb)) < 0) return; if (kread(kvmd, (u_long) pcb.so, (char *) &so, sizeof(so)) < 0) return; next = LIST_NEXT(&pcb, next); if (first) { first = 0; fprintf(stdout, "Active RFCOMM sockets\n" \ "%-8.8s %-6.6s %-6.6s %-17.17s %-17.17s %-4.4s %-4.4s %s\n", "PCB", "Recv-Q", "Send-Q", "Local address", "Foreign address", "Chan", "DLCI", "State"); } fprintf(stdout, "%-8lx %6d %6d %-17.17s %-17.17s %-4d %-4d %s\n", (unsigned long) this, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, bdaddrpr(&pcb.src, local, sizeof(local)), bdaddrpr(&pcb.dst, remote, sizeof(remote)), pcb.channel, pcb.dlci, (so.so_options & SO_ACCEPTCONN)? "LISTEN" : state2str(pcb.state)); } } /* rfcommpr */ /* * Print RFCOMM sessions */ static void rfcommpr_s(kvm_t *kvmd, u_long addr) { static char const * const states[] = { /* NG_BTSOCKET_RFCOMM_SESSION_CLOSED */ "CLOSED", /* NG_BTSOCKET_RFCOMM_SESSION_LISTENING */ "LISTEN", /* NG_BTSOCKET_RFCOMM_SESSION_CONNECTING */ "CONNECTING", /* NG_BTSOCKET_RFCOMM_SESSION_CONNECTED */ "CONNECTED", /* NG_BTSOCKET_RFCOMM_SESSION_OPEN */ "OPEN", /* NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING */ "DISCONNECTING" }; ng_btsocket_rfcomm_session_p this = NULL, next = NULL; ng_btsocket_rfcomm_session_t s; struct socket so; int first = 1; if (addr == 0) return; if (kread(kvmd, addr, (char *) &this, sizeof(this)) < 0) return; for ( ; this != NULL; this = next) { if (kread(kvmd, (u_long) this, (char *) &s, sizeof(s)) < 0) return; if (kread(kvmd, (u_long) s.l2so, (char *) &so, sizeof(so)) < 0) return; next = LIST_NEXT(&s, next); if (first) { first = 0; fprintf(stdout, "Active RFCOMM sessions\n" \ "%-8.8s %-8.8s %-4.4s %-5.5s %-5.5s %-4.4s %s\n", "L2PCB", "PCB", "Flags", "MTU", "Out-Q", "DLCs", "State"); } fprintf(stdout, "%-8lx %-8lx %-4x %-5d %-5d %-4s %s\n", (unsigned long) so.so_pcb, (unsigned long) this, s.flags, s.mtu, s.outq.len, LIST_EMPTY(&s.dlcs)? "No" : "Yes", state2str(s.state)); } } /* rfcommpr_s */ /* * Return BD_ADDR as string */ static char * bdaddrpr(bdaddr_p const ba, char *str, int len) { static char buffer[MAXHOSTNAMELEN]; struct hostent *he = NULL; if (str == NULL) { str = buffer; len = sizeof(buffer); } if (memcmp(ba, NG_HCI_BDADDR_ANY, sizeof(*ba)) == 0) { str[0] = '*'; str[1] = 0; return (str); } if (!numeric_bdaddr && (he = bt_gethostbyaddr((char *)ba, sizeof(*ba), AF_BLUETOOTH)) != NULL) { strlcpy(str, he->h_name, len); return (str); } bt_ntoa(ba, str); return (str); } /* bdaddrpr */ /* * Open kvm */ static kvm_t * kopen(char const *memf) { kvm_t *kvmd = NULL; char errbuf[_POSIX2_LINE_MAX]; /* * Discard setgid privileges if not the running kernel so that * bad guys can't print interesting stuff from kernel memory. */ if (memf != NULL) setgid(getgid()); kvmd = kvm_openfiles(NULL, memf, NULL, O_RDONLY, errbuf); if (kvmd == NULL) { warnx("kvm_openfiles: %s", errbuf); return (NULL); } if (kvm_nlist(kvmd, nl) < 0) { warnx("kvm_nlist: %s", kvm_geterr(kvmd)); goto fail; } if (nl[0].n_type == 0) { warnx("kvm_nlist: no namelist"); goto fail; } return (kvmd); fail: kvm_close(kvmd); return (NULL); } /* kopen */ /* * Read kvm */ static int kread(kvm_t *kvmd, u_long addr, char *buffer, int size) { if (kvmd == NULL || buffer == NULL) return (-1); if (kvm_read(kvmd, addr, buffer, size) != size) { warnx("kvm_read: %s", kvm_geterr(kvmd)); return (-1); } return (0); } /* kread */ /* * Print usage and exit */ static void usage(void) { fprintf(stdout, "Usage: btsockstat [-M core ] [-n] [-p proto] [-r]\n"); exit(255); } /* usage */ Index: projects/sendfile/usr.bin/netstat/inet.c =================================================================== --- projects/sendfile/usr.bin/netstat/inet.c (revision 263419) +++ projects/sendfile/usr.bin/netstat/inet.c (revision 263420) @@ -1,1326 +1,1327 @@ /*- * Copyright (c) 1983, 1988, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #endif /* INET6 */ #include #include #include #include #include #include #include #include #include #define TCPSTATES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "netstat.h" char *inetname(struct in_addr *); void inetprint(struct in_addr *, int, const char *, int); #ifdef INET6 static int udp_done, tcp_done, sdp_done; #endif /* INET6 */ static int pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused) { 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; } if (strncmp(name, "sdp", 3) == 0) mibvar = "net.inet.sdp.pcblist"; 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_cc = sb->sb_ccc; 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; struct xtcp_timer *timer; istcp = 0; switch (proto) { case IPPROTO_TCP: #ifdef INET6 if (strncmp(name, "sdp", 3) != 0) { if (tcp_done != 0) return; else tcp_done = 1; } else { if (sdp_done != 0) return; else sdp_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, name, &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) { timer = &((struct xtcpcb *)xig)->xt_timer; 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; timer = NULL; } /* 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("%-*s ", 2 * (int)sizeof(void *), "Tcpcb"); if (Lflag) printf((Aflag && !Wflag) ? "%-5.5s %-14.14s %-18.18s" : "%-5.5s %-14.14s %-22.22s", "Proto", "Listen", "Local Address"); else if (Tflag) printf((Aflag && !Wflag) ? "%-5.5s %-6.6s %-6.6s %-6.6s %-18.18s %s" : "%-5.5s %-6.6s %-6.6s %-6.6s %-22.22s %s", "Proto", "Rexmit", "OOORcv", "0-win", "Local Address", "Foreign 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(" (state)"); } 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", "R-MBUF", "S-MBUF", "R-CLUS", "S-CLUS", "R-HIWA", "S-HIWA", "R-LOWA", "S-LOWA", "R-BCNT", "S-BCNT", "R-BMAX", "S-BMAX"); printf(" %7.7s %7.7s %7.7s %7.7s %7.7s %7.7s", "rexmt", "persist", "keep", "2msl", "delack", "rcvtime"); } putchar('\n'); first = 0; } if (Lflag && so->so_qlimit == 0) continue; if (Aflag) { if (istcp) printf("%*lx ", 2 * (int)sizeof(void *), (u_long)inp->inp_ppcb); else printf("%*lx ", 2 * (int)sizeof(void *), (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 " : " "; if (istcp && (tp->t_flags & TF_TOE) != 0) printf("%-3.3s%-2.2s ", "toe", vchar); else 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 if (Tflag) { if (istcp) printf("%6u %6u %6u ", tp->t_sndrexmitpack, tp->t_rcvoopack, tp->t_sndzerowin); } else { - printf("%6u %6u ", so->so_rcv.sb_cc, so->so_snd.sb_cc); + 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) { 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 (timer != NULL) printf(" %4d.%02d %4d.%02d %4d.%02d %4d.%02d %4d.%02d %4d.%02d", timer->tt_rexmt / 1000, (timer->tt_rexmt % 1000) / 10, timer->tt_persist / 1000, (timer->tt_persist % 1000) / 10, timer->tt_keep / 1000, (timer->tt_keep % 1000) / 10, timer->tt_2msl / 1000, (timer->tt_2msl % 1000) / 10, timer->tt_delack / 1000, (timer->tt_delack % 1000) / 10, timer->t_rcvtime / 1000, (timer->t_rcvtime % 1000) / 10); } if (istcp && !Lflag && !xflag && !Tflag) { 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); } /* * Dump TCP statistics structure. */ void tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct tcpstat tcpstat, zerostat; size_t len = sizeof tcpstat; #ifdef INET6 if (tcp_done != 0) return; else tcp_done = 1; #endif if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { warn("sysctl: net.inet.tcp.stats"); return; } } else kread_counters(off, &tcpstat, len); printf ("%s:\n", name); #define p(f, m) if (tcpstat.f || sflag <= 1) \ printf(m, (uintmax_t )tcpstat.f, plural(tcpstat.f)) #define p1a(f, m) if (tcpstat.f || sflag <= 1) \ printf(m, (uintmax_t )tcpstat.f) #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ printf(m, (uintmax_t )tcpstat.f1, plural(tcpstat.f1), \ (uintmax_t )tcpstat.f2, plural(tcpstat.f2)) #define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ printf(m, (uintmax_t )tcpstat.f1, plural(tcpstat.f1), \ (uintmax_t )tcpstat.f2) #define p3(f, m) if (tcpstat.f || sflag <= 1) \ printf(m, (uintmax_t )tcpstat.f, pluralies(tcpstat.f)) p(tcps_sndtotal, "\t%ju packet%s sent\n"); p2(tcps_sndpack,tcps_sndbyte, "\t\t%ju data packet%s (%ju byte%s)\n"); p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, "\t\t%ju data packet%s (%ju byte%s) retransmitted\n"); p(tcps_sndrexmitbad, "\t\t%ju data packet%s unnecessarily retransmitted\n"); p(tcps_mturesent, "\t\t%ju resend%s initiated by MTU discovery\n"); p2a(tcps_sndacks, tcps_delack, "\t\t%ju ack-only packet%s (%ju delayed)\n"); p(tcps_sndurg, "\t\t%ju URG only packet%s\n"); p(tcps_sndprobe, "\t\t%ju window probe packet%s\n"); p(tcps_sndwinup, "\t\t%ju window update packet%s\n"); p(tcps_sndctrl, "\t\t%ju control packet%s\n"); p(tcps_rcvtotal, "\t%ju packet%s received\n"); p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%ju ack%s (for %ju byte%s)\n"); p(tcps_rcvdupack, "\t\t%ju duplicate ack%s\n"); p(tcps_rcvacktoomuch, "\t\t%ju ack%s for unsent data\n"); p2(tcps_rcvpack, tcps_rcvbyte, "\t\t%ju packet%s (%ju byte%s) received in-sequence\n"); p2(tcps_rcvduppack, tcps_rcvdupbyte, "\t\t%ju completely duplicate packet%s (%ju byte%s)\n"); p(tcps_pawsdrop, "\t\t%ju old duplicate packet%s\n"); p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, "\t\t%ju packet%s with some dup. data (%ju byte%s duped)\n"); p2(tcps_rcvoopack, tcps_rcvoobyte, "\t\t%ju out-of-order packet%s (%ju byte%s)\n"); p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, "\t\t%ju packet%s (%ju byte%s) of data after window\n"); p(tcps_rcvwinprobe, "\t\t%ju window probe%s\n"); p(tcps_rcvwinupd, "\t\t%ju window update packet%s\n"); p(tcps_rcvafterclose, "\t\t%ju packet%s received after close\n"); p(tcps_rcvbadsum, "\t\t%ju discarded for bad checksum%s\n"); p(tcps_rcvbadoff, "\t\t%ju discarded for bad header offset field%s\n"); p1a(tcps_rcvshort, "\t\t%ju discarded because packet too short\n"); p1a(tcps_rcvmemdrop, "\t\t%ju discarded due to memory problems\n"); p(tcps_connattempt, "\t%ju connection request%s\n"); p(tcps_accepts, "\t%ju connection accept%s\n"); p(tcps_badsyn, "\t%ju bad connection attempt%s\n"); p(tcps_listendrop, "\t%ju listen queue overflow%s\n"); p(tcps_badrst, "\t%ju ignored RSTs in the window%s\n"); p(tcps_connects, "\t%ju connection%s established (including accepts)\n"); p2(tcps_closed, tcps_drops, "\t%ju connection%s closed (including %ju drop%s)\n"); p(tcps_cachedrtt, "\t\t%ju connection%s updated cached RTT on close\n"); p(tcps_cachedrttvar, "\t\t%ju connection%s updated cached RTT variance on close\n"); p(tcps_cachedssthresh, "\t\t%ju connection%s updated cached ssthresh on close\n"); p(tcps_conndrops, "\t%ju embryonic connection%s dropped\n"); p2(tcps_rttupdated, tcps_segstimed, "\t%ju segment%s updated rtt (of %ju attempt%s)\n"); p(tcps_rexmttimeo, "\t%ju retransmit timeout%s\n"); p(tcps_timeoutdrop, "\t\t%ju connection%s dropped by rexmit timeout\n"); p(tcps_persisttimeo, "\t%ju persist timeout%s\n"); p(tcps_persistdrop, "\t\t%ju connection%s dropped by persist timeout\n"); p(tcps_finwait2_drops, "\t%ju Connection%s (fin_wait_2) dropped because of timeout\n"); p(tcps_keeptimeo, "\t%ju keepalive timeout%s\n"); p(tcps_keepprobe, "\t\t%ju keepalive probe%s sent\n"); p(tcps_keepdrops, "\t\t%ju connection%s dropped by keepalive\n"); p(tcps_predack, "\t%ju correct ACK header prediction%s\n"); p(tcps_preddat, "\t%ju correct data packet header prediction%s\n"); p3(tcps_sc_added, "\t%ju syncache entr%s added\n"); p1a(tcps_sc_retransmitted, "\t\t%ju retransmitted\n"); p1a(tcps_sc_dupsyn, "\t\t%ju dupsyn\n"); p1a(tcps_sc_dropped, "\t\t%ju dropped\n"); p1a(tcps_sc_completed, "\t\t%ju completed\n"); p1a(tcps_sc_bucketoverflow, "\t\t%ju bucket overflow\n"); p1a(tcps_sc_cacheoverflow, "\t\t%ju cache overflow\n"); p1a(tcps_sc_reset, "\t\t%ju reset\n"); p1a(tcps_sc_stale, "\t\t%ju stale\n"); p1a(tcps_sc_aborted, "\t\t%ju aborted\n"); p1a(tcps_sc_badack, "\t\t%ju badack\n"); p1a(tcps_sc_unreach, "\t\t%ju unreach\n"); p(tcps_sc_zonefail, "\t\t%ju zone failure%s\n"); p(tcps_sc_sendcookie, "\t%ju cookie%s sent\n"); p(tcps_sc_recvcookie, "\t%ju cookie%s received\n"); p3(tcps_hc_added, "\t%ju hostcache entr%s added\n"); p1a(tcps_hc_bucketoverflow, "\t\t%ju bucket overflow\n"); p(tcps_sack_recovery_episode, "\t%ju SACK recovery episode%s\n"); p(tcps_sack_rexmits, "\t%ju segment rexmit%s in SACK recovery episodes\n"); p(tcps_sack_rexmit_bytes, "\t%ju byte rexmit%s in SACK recovery episodes\n"); p(tcps_sack_rcv_blocks, "\t%ju SACK option%s (SACK blocks) received\n"); p(tcps_sack_send_blocks, "\t%ju SACK option%s (SACK blocks) sent\n"); p1a(tcps_sack_sboverflow, "\t%ju SACK scoreboard overflow\n"); p(tcps_ecn_ce, "\t%ju packet%s with ECN CE bit set\n"); p(tcps_ecn_ect0, "\t%ju packet%s with ECN ECT(0) bit set\n"); p(tcps_ecn_ect1, "\t%ju packet%s with ECN ECT(1) bit set\n"); p(tcps_ecn_shs, "\t%ju successful ECN handshake%s\n"); p(tcps_ecn_rcwnd, "\t%ju time%s ECN reduced the congestion window\n"); p(tcps_sig_rcvgoodsig, "\t%ju packet%s with valid tcp-md5 signature received\n"); p(tcps_sig_rcvbadsig, "\t%ju packet%s with invalid tcp-md5 signature received\n"); p(tcps_sig_err_buildsig, "\t%ju packet%s with tcp-md5 signature mismatch\n"); p(tcps_sig_err_sigopt, "\t%ju packet%s with unexpected tcp-md5 signature received\n"); p(tcps_sig_err_nosigopt, "\t%ju packet%s without expected tcp-md5 signature received\n"); #undef p #undef p1a #undef p2 #undef p2a #undef p3 } /* * Dump UDP statistics structure. */ void udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct udpstat udpstat, zerostat; size_t len = sizeof udpstat; uint64_t delivered; #ifdef INET6 if (udp_done != 0) return; else udp_done = 1; #endif if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { warn("sysctl: net.inet.udp.stats"); return; } } else kread_counters(off, &udpstat, len); printf("%s:\n", name); #define p(f, m) if (udpstat.f || sflag <= 1) \ printf("\t%ju " m, (uintmax_t)udpstat.f, plural(udpstat.f)) #define p1a(f, m) if (udpstat.f || sflag <= 1) \ printf("\t%ju " m, (uintmax_t)udpstat.f) p(udps_ipackets, "datagram%s received\n"); p1a(udps_hdrops, "with incomplete header\n"); p1a(udps_badlen, "with bad data length field\n"); p1a(udps_badsum, "with bad checksum\n"); p1a(udps_nosum, "with no checksum\n"); p1a(udps_noport, "dropped due to no socket\n"); p(udps_noportbcast, "broadcast/multicast datagram%s undelivered\n"); p1a(udps_fullsock, "dropped due to full socket buffers\n"); p1a(udpps_pcbhashmiss, "not for hashed pcb\n"); delivered = udpstat.udps_ipackets - udpstat.udps_hdrops - udpstat.udps_badlen - udpstat.udps_badsum - udpstat.udps_noport - udpstat.udps_noportbcast - udpstat.udps_fullsock; if (delivered || sflag <= 1) printf("\t%ju delivered\n", (uint64_t)delivered); p(udps_opackets, "datagram%s output\n"); /* the next statistic is cumulative in udps_noportbcast */ p(udps_filtermcast, "time%s multicast source filter matched\n"); #undef p #undef p1a } /* * Dump CARP statistics structure. */ void carp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct carpstats carpstat, zerostat; size_t len = sizeof(struct carpstats); if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.carp.stats", &carpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) warn("sysctl: net.inet.carp.stats"); return; } } else { if (off == 0) return; kread_counters(off, &carpstat, len); } printf("%s:\n", name); #define p(f, m) if (carpstat.f || sflag <= 1) \ printf(m, (uintmax_t)carpstat.f, plural(carpstat.f)) #define p2(f, m) if (carpstat.f || sflag <= 1) \ printf(m, (uintmax_t)carpstat.f) p(carps_ipackets, "\t%ju packet%s received (IPv4)\n"); p(carps_ipackets6, "\t%ju packet%s received (IPv6)\n"); p(carps_badttl, "\t\t%ju packet%s discarded for wrong TTL\n"); p(carps_hdrops, "\t\t%ju packet%s shorter than header\n"); p(carps_badsum, "\t\t%ju discarded for bad checksum%s\n"); p(carps_badver, "\t\t%ju discarded packet%s with a bad version\n"); p2(carps_badlen, "\t\t%ju discarded because packet too short\n"); p2(carps_badauth, "\t\t%ju discarded for bad authentication\n"); p2(carps_badvhid, "\t\t%ju discarded for bad vhid\n"); p2(carps_badaddrs, "\t\t%ju discarded because of a bad address list\n"); p(carps_opackets, "\t%ju packet%s sent (IPv4)\n"); p(carps_opackets6, "\t%ju packet%s sent (IPv6)\n"); p2(carps_onomem, "\t\t%ju send failed due to mbuf memory error\n"); #if notyet p(carps_ostates, "\t\t%s state update%s sent\n"); #endif #undef p #undef p2 } /* * Dump IP statistics structure. */ void ip_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct ipstat ipstat, zerostat; size_t len = sizeof ipstat; if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { warn("sysctl: net.inet.ip.stats"); return; } } else kread_counters(off, &ipstat, len); printf("%s:\n", name); #define p(f, m) if (ipstat.f || sflag <= 1) \ printf(m, (uintmax_t )ipstat.f, plural(ipstat.f)) #define p1a(f, m) if (ipstat.f || sflag <= 1) \ printf(m, (uintmax_t )ipstat.f) p(ips_total, "\t%ju total packet%s received\n"); p(ips_badsum, "\t%ju bad header checksum%s\n"); p1a(ips_toosmall, "\t%ju with size smaller than minimum\n"); p1a(ips_tooshort, "\t%ju with data size < data length\n"); p1a(ips_toolong, "\t%ju with ip length > max ip packet size\n"); p1a(ips_badhlen, "\t%ju with header length < data size\n"); p1a(ips_badlen, "\t%ju with data length < header length\n"); p1a(ips_badoptions, "\t%ju with bad options\n"); p1a(ips_badvers, "\t%ju with incorrect version number\n"); p(ips_fragments, "\t%ju fragment%s received\n"); p(ips_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n"); p(ips_fragtimeout, "\t%ju fragment%s dropped after timeout\n"); p(ips_reassembled, "\t%ju packet%s reassembled ok\n"); p(ips_delivered, "\t%ju packet%s for this host\n"); p(ips_noproto, "\t%ju packet%s for unknown/unsupported protocol\n"); p(ips_forward, "\t%ju packet%s forwarded"); p(ips_fastforward, " (%ju packet%s fast forwarded)"); if (ipstat.ips_forward || sflag <= 1) putchar('\n'); p(ips_cantforward, "\t%ju packet%s not forwardable\n"); p(ips_notmember, "\t%ju packet%s received for unknown multicast group\n"); p(ips_redirectsent, "\t%ju redirect%s sent\n"); p(ips_localout, "\t%ju packet%s sent from this host\n"); p(ips_rawout, "\t%ju packet%s sent with fabricated ip header\n"); p(ips_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n"); p(ips_noroute, "\t%ju output packet%s discarded due to no route\n"); p(ips_fragmented, "\t%ju output datagram%s fragmented\n"); p(ips_ofragments, "\t%ju fragment%s created\n"); p(ips_cantfrag, "\t%ju datagram%s that can't be fragmented\n"); p(ips_nogif, "\t%ju tunneling packet%s that can't find gif\n"); p(ips_badaddr, "\t%ju datagram%s with bad address in header\n"); #undef p #undef p1a } /* * Dump ARP statistics structure. */ void arp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct arpstat arpstat, zerostat; size_t len = sizeof(arpstat); if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.link.ether.arp.stats", &arpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { warn("sysctl: net.link.ether.arp.stats"); return; } } else kread_counters(off, &arpstat, len); printf("%s:\n", name); #define p(f, m) if (arpstat.f || sflag <= 1) \ printf("\t%ju " m, (uintmax_t)arpstat.f, plural(arpstat.f)) #define p2(f, m) if (arpstat.f || sflag <= 1) \ printf("\t%ju " m, (uintmax_t)arpstat.f, pluralies(arpstat.f)) p(txrequests, "ARP request%s sent\n"); p2(txreplies, "ARP repl%s sent\n"); p(rxrequests, "ARP request%s received\n"); p2(rxreplies, "ARP repl%s received\n"); p(received, "ARP packet%s received\n"); p(dropped, "total packet%s dropped due to no ARP entry\n"); p(timeouts, "ARP entry%s timed out\n"); p(dupips, "Duplicate IP%s seen\n"); #undef p #undef p2 } static const char *icmpnames[ICMP_MAXTYPE + 1] = { "echo reply", /* RFC 792 */ "#1", "#2", "destination unreachable", /* RFC 792 */ "source quench", /* RFC 792 */ "routing redirect", /* RFC 792 */ "#6", "#7", "echo", /* RFC 792 */ "router advertisement", /* RFC 1256 */ "router solicitation", /* RFC 1256 */ "time exceeded", /* RFC 792 */ "parameter problem", /* RFC 792 */ "time stamp", /* RFC 792 */ "time stamp reply", /* RFC 792 */ "information request", /* RFC 792 */ "information request reply", /* RFC 792 */ "address mask request", /* RFC 950 */ "address mask reply", /* RFC 950 */ "#19", "#20", "#21", "#22", "#23", "#24", "#25", "#26", "#27", "#28", "#29", "icmp traceroute", /* RFC 1393 */ "datagram conversion error", /* RFC 1475 */ "mobile host redirect", "IPv6 where-are-you", "IPv6 i-am-here", "mobile registration req", "mobile registration reply", "domain name request", /* RFC 1788 */ "domain name reply", /* RFC 1788 */ "icmp SKIP", "icmp photuris", /* RFC 2521 */ }; /* * Dump ICMP statistics. */ void icmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct icmpstat icmpstat, zerostat; int i, first; size_t len; len = sizeof icmpstat; if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { warn("sysctl: net.inet.icmp.stats"); return; } } else kread_counters(off, &icmpstat, len); printf("%s:\n", name); #define p(f, m) if (icmpstat.f || sflag <= 1) \ printf(m, icmpstat.f, plural(icmpstat.f)) #define p1a(f, m) if (icmpstat.f || sflag <= 1) \ printf(m, icmpstat.f) #define p2(f, m) if (icmpstat.f || sflag <= 1) \ printf(m, icmpstat.f, plurales(icmpstat.f)) p(icps_error, "\t%lu call%s to icmp_error\n"); p(icps_oldicmp, "\t%lu error%s not generated in response to an icmp message\n"); for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) if (icmpstat.icps_outhist[i] != 0) { if (first) { printf("\tOutput histogram:\n"); first = 0; } if (icmpnames[i] != NULL) printf("\t\t%s: %lu\n", icmpnames[i], icmpstat.icps_outhist[i]); else printf("\t\tunknown ICMP #%d: %lu\n", i, icmpstat.icps_outhist[i]); } p(icps_badcode, "\t%lu message%s with bad code fields\n"); p(icps_tooshort, "\t%lu message%s less than the minimum length\n"); p(icps_checksum, "\t%lu message%s with bad checksum\n"); p(icps_badlen, "\t%lu message%s with bad length\n"); p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n"); p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n"); for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) if (icmpstat.icps_inhist[i] != 0) { if (first) { printf("\tInput histogram:\n"); first = 0; } if (icmpnames[i] != NULL) printf("\t\t%s: %lu\n", icmpnames[i], icmpstat.icps_inhist[i]); else printf("\t\tunknown ICMP #%d: %lu\n", i, icmpstat.icps_inhist[i]); } p(icps_reflect, "\t%lu message response%s generated\n"); p2(icps_badaddr, "\t%lu invalid return address%s\n"); p(icps_noroute, "\t%lu no return route%s\n"); #undef p #undef p1a #undef p2 if (live) { len = sizeof i; if (sysctlbyname("net.inet.icmp.maskrepl", &i, &len, NULL, 0) < 0) return; printf("\tICMP address mask responses are %sabled\n", i ? "en" : "dis"); } } #ifndef BURN_BRIDGES /* * Dump IGMP statistics structure (pre 8.x kernel). */ static void igmp_stats_live_old(const char *name) { struct oigmpstat oigmpstat, zerostat; size_t len = sizeof(oigmpstat); if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.igmp.stats", &oigmpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { warn("sysctl: net.inet.igmp.stats"); return; } printf("%s:\n", name); #define p(f, m) if (oigmpstat.f || sflag <= 1) \ printf(m, oigmpstat.f, plural(oigmpstat.f)) #define py(f, m) if (oigmpstat.f || sflag <= 1) \ printf(m, oigmpstat.f, oigmpstat.f != 1 ? "ies" : "y") p(igps_rcv_total, "\t%u message%s received\n"); p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n"); p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n"); py(igps_rcv_queries, "\t%u membership quer%s received\n"); py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n"); p(igps_rcv_reports, "\t%u membership report%s received\n"); p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n"); p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n"); p(igps_snd_reports, "\t%u membership report%s sent\n"); #undef p #undef py } #endif /* !BURN_BRIDGES */ /* * Dump IGMP statistics structure. */ void igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct igmpstat igmpstat, zerostat; size_t len; #ifndef BURN_BRIDGES if (live) { /* * Detect if we are being run against a pre-IGMPv3 kernel. * We cannot do this for a core file as the legacy * struct igmpstat has no size field, nor does it * export it in any readily-available symbols. */ len = 0; if (sysctlbyname("net.inet.igmp.stats", NULL, &len, NULL, 0) < 0) { warn("sysctl: net.inet.igmp.stats"); return; } if (len < sizeof(igmpstat)) { igmp_stats_live_old(name); return; } } #endif /* !BURN_BRIDGES */ len = sizeof(igmpstat); if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { warn("sysctl: net.inet.igmp.stats"); return; } } else { len = sizeof(igmpstat); kread(off, &igmpstat, len); } if (igmpstat.igps_version != IGPS_VERSION_3) { warnx("%s: version mismatch (%d != %d)", __func__, igmpstat.igps_version, IGPS_VERSION_3); } if (igmpstat.igps_len != IGPS_VERSION3_LEN) { warnx("%s: size mismatch (%d != %d)", __func__, igmpstat.igps_len, IGPS_VERSION3_LEN); } printf("%s:\n", name); #define p64(f, m) if (igmpstat.f || sflag <= 1) \ printf(m, (uintmax_t) igmpstat.f, plural(igmpstat.f)) #define py64(f, m) if (igmpstat.f || sflag <= 1) \ printf(m, (uintmax_t) igmpstat.f, pluralies(igmpstat.f)) p64(igps_rcv_total, "\t%ju message%s received\n"); p64(igps_rcv_tooshort, "\t%ju message%s received with too few bytes\n"); p64(igps_rcv_badttl, "\t%ju message%s received with wrong TTL\n"); p64(igps_rcv_badsum, "\t%ju message%s received with bad checksum\n"); py64(igps_rcv_v1v2_queries, "\t%ju V1/V2 membership quer%s received\n"); py64(igps_rcv_v3_queries, "\t%ju V3 membership quer%s received\n"); py64(igps_rcv_badqueries, "\t%ju membership quer%s received with invalid field(s)\n"); py64(igps_rcv_gen_queries, "\t%ju general quer%s received\n"); py64(igps_rcv_group_queries, "\t%ju group quer%s received\n"); py64(igps_rcv_gsr_queries, "\t%ju group-source quer%s received\n"); py64(igps_drop_gsr_queries, "\t%ju group-source quer%s dropped\n"); p64(igps_rcv_reports, "\t%ju membership report%s received\n"); p64(igps_rcv_badreports, "\t%ju membership report%s received with invalid field(s)\n"); p64(igps_rcv_ourreports, "\t%ju membership report%s received for groups to which we belong\n"); p64(igps_rcv_nora, "\t%ju V3 report%s received without Router Alert\n"); p64(igps_snd_reports, "\t%ju membership report%s sent\n"); #undef p64 #undef py64 } /* * Dump PIM statistics structure. */ void pim_stats(u_long off __unused, const char *name, int af1 __unused, int proto __unused) { struct pimstat pimstat, zerostat; size_t len = sizeof pimstat; if (live) { if (zflag) memset(&zerostat, 0, len); if (sysctlbyname("net.inet.pim.stats", &pimstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) warn("sysctl: net.inet.pim.stats"); return; } } else { if (off == 0) return; kread_counters(off, &pimstat, len); } printf("%s:\n", name); #define p(f, m) if (pimstat.f || sflag <= 1) \ printf(m, (uintmax_t)pimstat.f, plural(pimstat.f)) #define py(f, m) if (pimstat.f || sflag <= 1) \ printf(m, (uintmax_t)pimstat.f, pimstat.f != 1 ? "ies" : "y") p(pims_rcv_total_msgs, "\t%ju message%s received\n"); p(pims_rcv_total_bytes, "\t%ju byte%s received\n"); p(pims_rcv_tooshort, "\t%ju message%s received with too few bytes\n"); p(pims_rcv_badsum, "\t%ju message%s received with bad checksum\n"); p(pims_rcv_badversion, "\t%ju message%s received with bad version\n"); p(pims_rcv_registers_msgs, "\t%ju data register message%s received\n"); p(pims_rcv_registers_bytes, "\t%ju data register byte%s received\n"); p(pims_rcv_registers_wrongiif, "\t%ju data register message%s received on wrong iif\n"); p(pims_rcv_badregisters, "\t%ju bad register%s received\n"); p(pims_snd_registers_msgs, "\t%ju data register message%s sent\n"); p(pims_snd_registers_bytes, "\t%ju data register byte%s sent\n"); #undef p #undef py } /* * Pretty print an Internet address (net address + port). */ void inetprint(struct in_addr *in, int port, const char *proto, int num_port) { struct servent *sp = 0; char line[80], *cp; int width; if (Wflag) sprintf(line, "%s.", inetname(in)); else sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in)); cp = strchr(line, '\0'); if (!num_port && port) sp = getservbyport((int)port, proto); if (sp || port == 0) sprintf(cp, "%.15s ", sp ? sp->s_name : "*"); else sprintf(cp, "%d ", ntohs((u_short)port)); width = (Aflag && !Wflag) ? 18 : 22; if (Wflag) printf("%-*s ", width, line); else printf("%-*.*s ", width, width, line); } /* * Construct an Internet address representation. * If numeric_addr has been supplied, give * numeric value, otherwise try for symbolic name. */ char * inetname(struct in_addr *inp) { char *cp; static char line[MAXHOSTNAMELEN]; struct hostent *hp; struct netent *np; cp = 0; if (!numeric_addr && inp->s_addr != INADDR_ANY) { int net = inet_netof(*inp); int lna = inet_lnaof(*inp); if (lna == INADDR_ANY) { np = getnetbyaddr(net, AF_INET); if (np) cp = np->n_name; } if (cp == 0) { hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); if (hp) { cp = hp->h_name; trimdomain(cp, strlen(cp)); } } } if (inp->s_addr == INADDR_ANY) strcpy(line, "*"); else if (cp) { strlcpy(line, cp, sizeof(line)); } else { inp->s_addr = ntohl(inp->s_addr); #define C(x) ((u_int)((x) & 0xff)) sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); } return (line); } Index: projects/sendfile/usr.bin/netstat/netgraph.c =================================================================== --- projects/sendfile/usr.bin/netstat/netgraph.c (revision 263419) +++ projects/sendfile/usr.bin/netstat/netgraph.c (revision 263420) @@ -1,142 +1,142 @@ /*- * Copyright (c) 1996-1999 Whistle Communications, Inc. * All rights reserved. * * Subject to the following obligations and disclaimer of warranty, use and * redistribution of this software, in source or object code forms, with or * without modifications are expressly permitted by Whistle Communications; * provided, however, that: * 1. Any and all reproductions of the source or object code must include the * copyright notice above and the following disclaimer of warranties; and * 2. No rights are granted, in any manner or form, to use Whistle * Communications, Inc. trademarks, including the mark "WHISTLE * COMMUNICATIONS" on advertising, endorsements, or otherwise except as * such appears in the above copyright notice or in the software. * * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "netstat.h" static int first = 1; static int csock = -1; void netgraphprotopr(u_long off, const char *name, int af1 __unused, int proto __unused) { struct ngpcb *this, *next; struct ngpcb ngpcb; struct socket sockb; int debug = 1; /* If symbol not found, try looking in the KLD module */ if (off == 0) { if (debug) fprintf(stderr, "Error reading symbols from ng_socket.ko"); return; } /* Get pointer to first socket */ kread(off, (char *)&this, sizeof(this)); /* Get my own socket node */ if (csock == -1) NgMkSockNode(NULL, &csock, NULL); for (; this != NULL; this = next) { u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)]; struct ng_mesg *resp = (struct ng_mesg *) rbuf; struct nodeinfo *ni = (struct nodeinfo *) resp->data; char path[64]; /* Read in ngpcb structure */ kread((u_long)this, (char *)&ngpcb, sizeof(ngpcb)); next = LIST_NEXT(&ngpcb, socks); /* Read in socket structure */ kread((u_long)ngpcb.ng_socket, (char *)&sockb, sizeof(sockb)); /* Check type of socket */ if (strcmp(name, "ctrl") == 0 && ngpcb.type != NG_CONTROL) continue; if (strcmp(name, "data") == 0 && ngpcb.type != NG_DATA) continue; /* Do headline */ if (first) { printf("Netgraph sockets\n"); if (Aflag) printf("%-8.8s ", "PCB"); printf("%-5.5s %-6.6s %-6.6s %-14.14s %s\n", "Type", "Recv-Q", "Send-Q", "Node Address", "#Hooks"); first = 0; } /* Show socket */ if (Aflag) printf("%8lx ", (u_long) this); printf("%-5.5s %6u %6u ", - name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); + name, sockb.so_rcv.sb_ccc, sockb.so_snd.sb_ccc); /* Get info on associated node */ if (ngpcb.node_id == 0 || csock == -1) goto finish; snprintf(path, sizeof(path), "[%x]:", ngpcb.node_id); if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) goto finish; if (NgRecvMsg(csock, resp, sizeof(rbuf), NULL) < 0) goto finish; /* Display associated node info */ if (*ni->name != '\0') snprintf(path, sizeof(path), "%s:", ni->name); printf("%-14.14s %4d", path, ni->hooks); finish: putchar('\n'); } } Index: projects/sendfile/usr.bin/netstat/unix.c =================================================================== --- projects/sendfile/usr.bin/netstat/unix.c (revision 263419) +++ projects/sendfile/usr.bin/netstat/unix.c (revision 263420) @@ -1,299 +1,300 @@ /*- * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)unix.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); /* * Display protocol blocks in the unix domain. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "netstat.h" static void unixdomainpr(struct xunpcb *, struct xsocket *); static const char *const socktype[] = { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" }; static int pcblist_sysctl(int type, char **bufp) { char *buf; size_t len; char mibvar[sizeof "net.local.seqpacket.pcblist"]; sprintf(mibvar, "net.local.%s.pcblist", socktype[type]); len = 0; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { if (errno != ENOENT) warn("sysctl: %s", mibvar); return (-1); } if ((buf = malloc(len)) == 0) { warnx("malloc %lu bytes", (u_long)len); return (-2); } if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { warn("sysctl: %s", mibvar); free(buf); return (-2); } *bufp = buf; return (0); } static int pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) { struct unp_head head; struct unpcb *unp, unp_conn; u_char sun_len; struct socket so; struct xunpgen xug; struct xunpcb xu; unp_gen_t unp_gencnt; u_int unp_count; char *buf, *p; size_t len; if (count_off == 0 || gencnt_off == 0) return (-2); if (head_off == 0) return (-1); kread(count_off, &unp_count, sizeof(unp_count)); len = 2 * sizeof(xug) + (unp_count + unp_count / 8) * sizeof(xu); if ((buf = malloc(len)) == 0) { warnx("malloc %lu bytes", (u_long)len); return (-2); } 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. */ kread(gencnt_off, &unp_gencnt, sizeof(unp_gencnt)); xug.xug_len = sizeof xug; xug.xug_count = unp_count; xug.xug_gen = unp_gencnt; xug.xug_sogen = 0; COPYOUT(&xug, sizeof xug); /* Walk the PCB list. */ xu.xu_len = sizeof xu; KREAD(head_off, &head, sizeof(head)); LIST_FOREACH(unp, &head, unp_link) { xu.xu_unpp = unp; KREAD(unp, &xu.xu_unp, sizeof (*unp)); unp = &xu.xu_unp; if (unp->unp_gencnt > unp_gencnt) continue; if (unp->unp_addr != NULL) { KREAD(unp->unp_addr, &sun_len, sizeof(sun_len)); KREAD(unp->unp_addr, &xu.xu_addr, sun_len); } if (unp->unp_conn != NULL) { KREAD(unp->unp_conn, &unp_conn, sizeof(unp_conn)); if (unp_conn.unp_addr != NULL) { KREAD(unp_conn.unp_addr, &sun_len, sizeof(sun_len)); KREAD(unp_conn.unp_addr, &xu.xu_caddr, sun_len); } } KREAD(unp->unp_socket, &so, sizeof(so)); if (sotoxsocket(&so, &xu.xu_socket) != 0) goto fail; COPYOUT(&xu, sizeof(xu)); } /* Reread the counts and write the footer. */ kread(count_off, &unp_count, sizeof(unp_count)); kread(gencnt_off, &unp_gencnt, sizeof(unp_gencnt)); xug.xug_count = unp_count; xug.xug_gen = unp_gencnt; COPYOUT(&xug, sizeof xug); *bufp = buf; return (0); fail: free(buf); return (-1); #undef COPYOUT #undef KREAD } void unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off, u_long sphead_off) { char *buf; int ret, type; struct xsocket *so; struct xunpgen *xug, *oxug; struct xunpcb *xunp; u_long head_off; buf = NULL; for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) { if (live) ret = pcblist_sysctl(type, &buf); else { head_off = 0; switch (type) { case SOCK_STREAM: head_off = shead_off; break; case SOCK_DGRAM: head_off = dhead_off; break; case SOCK_SEQPACKET: head_off = sphead_off; break; } ret = pcblist_kvm(count_off, gencnt_off, head_off, &buf); } if (ret == -1) continue; if (ret < 0) return; oxug = xug = (struct xunpgen *)buf; for (xug = (struct xunpgen *)((char *)xug + xug->xug_len); xug->xug_len > sizeof(struct xunpgen); xug = (struct xunpgen *)((char *)xug + xug->xug_len)) { xunp = (struct xunpcb *)xug; so = &xunp->xu_socket; /* Ignore PCBs which were freed during copyout. */ if (xunp->xu_unp.unp_gencnt > oxug->xug_gen) continue; unixdomainpr(xunp, so); } if (xug != oxug && xug->xug_gen != oxug->xug_gen) { if (oxug->xug_count > xug->xug_count) { printf("Some %s sockets may have been deleted.\n", socktype[type]); } else if (oxug->xug_count < xug->xug_count) { printf("Some %s sockets may have been created.\n", socktype[type]); } else { printf("Some %s sockets may have been created or deleted", socktype[type]); } } free(buf); } } static void unixdomainpr(struct xunpcb *xunp, struct xsocket *so) { struct unpcb *unp; struct sockaddr_un *sa; static int first = 1; char buf1[15]; unp = &xunp->xu_unp; if (unp->unp_addr) sa = &xunp->xu_addr; else sa = (struct sockaddr_un *)0; if (first && !Lflag) { printf("Active UNIX domain sockets\n"); printf( "%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n", "Address", "Type", "Recv-Q", "Send-Q", "Inode", "Conn", "Refs", "Nextref"); first = 0; } if (Lflag && so->so_qlimit == 0) return; if (Lflag) { snprintf(buf1, 15, "%d/%d/%d", so->so_qlen, so->so_incqlen, so->so_qlimit); printf("unix %-14.14s", buf1); } else { printf("%8lx %-6.6s %6u %6u %8lx %8lx %8lx %8lx", (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc, - so->so_snd.sb_cc, (long)unp->unp_vnode, (long)unp->unp_conn, + so->so_snd.sb_cc, (long)unp->unp_vnode, + (long)unp->unp_conn, (long)LIST_FIRST(&unp->unp_refs), (long)LIST_NEXT(unp, unp_reflink)); } if (sa) printf(" %.*s", (int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)), sa->sun_path); putchar('\n'); } Index: projects/sendfile/usr.bin/systat/netstat.c =================================================================== --- projects/sendfile/usr.bin/systat/netstat.c (revision 263419) +++ projects/sendfile/usr.bin/systat/netstat.c (revision 263420) @@ -1,657 +1,657 @@ /*- * Copyright (c) 1980, 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #ifdef lint static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93"; #endif /* * netstat */ #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #endif #include #include #include #include #include #include #include #include #define TCPSTATES #include #include #include #include #include #include #include #include #include #include #include "systat.h" #include "extern.h" static struct netinfo *enter(struct inpcb *, int, const char *); static void enter_kvm(struct inpcb *, struct socket *, int, const char *); static void enter_sysctl(struct inpcb *, struct xsocket *, int, const char *); static void fetchnetstat_kvm(void); static void fetchnetstat_sysctl(void); static char *inetname(struct sockaddr *); static void inetprint(struct sockaddr *, const char *); #define streq(a,b) (strcmp(a,b)==0) #define YMAX(w) ((w)->_maxy-1) WINDOW * opennetstat(void) { sethostent(1); setnetent(1); return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); } struct netinfo { TAILQ_ENTRY(netinfo) chain; short ni_line; /* line on screen */ short ni_seen; /* 0 when not present in list */ short ni_flags; #define NIF_LACHG 0x1 /* local address changed */ #define NIF_FACHG 0x2 /* foreign address changed */ short ni_state; /* tcp state */ const char *ni_proto; /* protocol */ struct sockaddr_storage ni_lsa; /* local address */ struct sockaddr_storage ni_fsa; /* foreign address */ u_int ni_rcvcc; /* rcv buffer character count */ u_int ni_sndcc; /* snd buffer character count */ }; TAILQ_HEAD(netinfohead, netinfo) netcb = TAILQ_HEAD_INITIALIZER(netcb); static int aflag = 0; static int nflag = 0; static int lastrow = 1; void closenetstat(WINDOW *w) { struct netinfo *p; endhostent(); endnetent(); TAILQ_FOREACH(p, &netcb, chain) { if (p->ni_line != -1) lastrow--; p->ni_line = -1; } if (w != NULL) { wclear(w); wrefresh(w); delwin(w); } } static const char *miblist[] = { "net.inet.tcp.pcblist", "net.inet.udp.pcblist" }; static char tcb[] = "tcb", udb[] = "udb"; struct nlist namelist[] = { #define X_TCB 0 { .n_name = tcb }, #define X_UDB 1 { .n_name = udb }, { .n_name = NULL }, }; int initnetstat(void) { protos = TCP|UDP; return(1); } void fetchnetstat(void) { if (use_kvm) fetchnetstat_kvm(); else fetchnetstat_sysctl(); } static void fetchnetstat_kvm(void) { struct inpcb *next; struct netinfo *p; struct inpcbhead head; struct inpcb inpcb; struct socket sockb; struct tcpcb tcpcb; void *off; int istcp; if (namelist[X_TCB].n_value == 0) return; TAILQ_FOREACH(p, &netcb, chain) p->ni_seen = 0; if (protos&TCP) { off = NPTR(X_TCB); istcp = 1; } else if (protos&UDP) { off = NPTR(X_UDB); istcp = 0; } else { error("No protocols to display"); return; } again: KREAD(off, &head, sizeof (struct inpcbhead)); LIST_FOREACH(next, &head, inp_list) { KREAD(next, &inpcb, sizeof (inpcb)); next = &inpcb; if (!aflag) { if (inpcb.inp_vflag & INP_IPV4) { if (inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) continue; } #ifdef INET6 else if (inpcb.inp_vflag & INP_IPV6) { if (memcmp(&inpcb.in6p_laddr, &in6addr_any, sizeof(in6addr_any)) == 0) continue; } #endif } if (nhosts && !checkhost(&inpcb)) continue; if (nports && !checkport(&inpcb)) continue; if (istcp) { if (inpcb.inp_flags & INP_TIMEWAIT) { bzero(&sockb, sizeof(sockb)); enter_kvm(&inpcb, &sockb, TCPS_TIME_WAIT, "tcp"); } else { KREAD(inpcb.inp_socket, &sockb, sizeof (sockb)); KREAD(inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); enter_kvm(&inpcb, &sockb, tcpcb.t_state, "tcp"); } } else enter_kvm(&inpcb, &sockb, 0, "udp"); } if (istcp && (protos&UDP)) { istcp = 0; off = NPTR(X_UDB); goto again; } } static void fetchnetstat_sysctl(void) { struct netinfo *p; int idx; struct xinpgen *inpg; char *cur, *end; struct inpcb *inpcb; struct xinpcb *xip = NULL; struct xtcpcb *xtp = NULL; int plen; size_t lsz; TAILQ_FOREACH(p, &netcb, chain) p->ni_seen = 0; if (protos&TCP) { idx = 0; } else if (protos&UDP) { idx = 1; } else { error("No protocols to display"); return; } for (;idx < 2; idx++) { if (idx == 1 && !(protos&UDP)) break; inpg = (struct xinpgen *)sysctl_dynread(miblist[idx], &lsz); if (inpg == NULL) { error("sysctl(%s...) failed", miblist[idx]); continue; } /* * We currently do no require a consistent pcb list. * Try to be robust in case of struct size changes */ cur = ((char *)inpg) + inpg->xig_len; /* There is also a trailing struct xinpgen */ end = ((char *)inpg) + lsz - inpg->xig_len; if (end <= cur) { free(inpg); continue; } if (idx == 0) { /* TCP */ xtp = (struct xtcpcb *)cur; plen = xtp->xt_len; } else { xip = (struct xinpcb *)cur; plen = xip->xi_len; } while (cur + plen <= end) { if (idx == 0) { /* TCP */ xtp = (struct xtcpcb *)cur; inpcb = &xtp->xt_inp; } else { xip = (struct xinpcb *)cur; inpcb = &xip->xi_inp; } cur += plen; if (!aflag) { if (inpcb->inp_vflag & INP_IPV4) { if (inet_lnaof(inpcb->inp_laddr) == INADDR_ANY) continue; } #ifdef INET6 else if (inpcb->inp_vflag & INP_IPV6) { if (memcmp(&inpcb->in6p_laddr, &in6addr_any, sizeof(in6addr_any)) == 0) continue; } #endif } if (nhosts && !checkhost(inpcb)) continue; if (nports && !checkport(inpcb)) continue; if (idx == 0) /* TCP */ enter_sysctl(inpcb, &xtp->xt_socket, xtp->xt_tp.t_state, "tcp"); else /* UDP */ enter_sysctl(inpcb, &xip->xi_socket, 0, "udp"); } free(inpg); } } static void enter_kvm(struct inpcb *inp, struct socket *so, int state, const char *proto) { struct netinfo *p; if ((p = enter(inp, state, proto)) != NULL) { - p->ni_rcvcc = so->so_rcv.sb_cc; - p->ni_sndcc = so->so_snd.sb_cc; + p->ni_rcvcc = so->so_rcv.sb_ccc; + p->ni_sndcc = so->so_snd.sb_ccc; } } static void enter_sysctl(struct inpcb *inp, struct xsocket *so, int state, const char *proto) { struct netinfo *p; if ((p = enter(inp, state, proto)) != NULL) { p->ni_rcvcc = so->so_rcv.sb_cc; p->ni_sndcc = so->so_snd.sb_cc; } } static struct netinfo * enter(struct inpcb *inp, int state, const char *proto) { struct netinfo *p; struct sockaddr_storage lsa, fsa; struct sockaddr_in *sa4; #ifdef INET6 struct sockaddr_in6 *sa6; #endif memset(&lsa, 0, sizeof(lsa)); memset(&fsa, 0, sizeof(fsa)); if (inp->inp_vflag & INP_IPV4) { sa4 = (struct sockaddr_in *)&lsa; sa4->sin_addr = inp->inp_laddr; sa4->sin_port = inp->inp_lport; sa4->sin_family = AF_INET; sa4->sin_len = sizeof(struct sockaddr_in); sa4 = (struct sockaddr_in *)&fsa; sa4->sin_addr = inp->inp_faddr; sa4->sin_port = inp->inp_fport; sa4->sin_family = AF_INET; sa4->sin_len = sizeof(struct sockaddr_in); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { sa6 = (struct sockaddr_in6 *)&lsa; memcpy(&sa6->sin6_addr, &inp->in6p_laddr, sizeof(struct in6_addr)); sa6->sin6_port = inp->inp_lport; sa6->sin6_family = AF_INET6; sa6->sin6_len = sizeof(struct sockaddr_in6); sa6 = (struct sockaddr_in6 *)&fsa; memcpy(&sa6->sin6_addr, &inp->in6p_faddr, sizeof(struct in6_addr)); sa6->sin6_port = inp->inp_fport; sa6->sin6_family = AF_INET6; sa6->sin6_len = sizeof(struct sockaddr_in6); } #endif else return NULL; /* * Only take exact matches, any sockets with * previously unbound addresses will be deleted * below in the display routine because they * will appear as ``not seen'' in the kernel * data structures. */ TAILQ_FOREACH(p, &netcb, chain) { if (!streq(proto, p->ni_proto)) continue; if (p->ni_lsa.ss_family != lsa.ss_family || memcmp(&p->ni_lsa, &lsa, lsa.ss_len) != 0) continue; if (p->ni_fsa.ss_family == fsa.ss_family && memcmp(&p->ni_fsa, &fsa, fsa.ss_len) == 0) break; } if (p == NULL) { if ((p = malloc(sizeof(*p))) == NULL) { error("Out of memory"); return NULL; } TAILQ_INSERT_HEAD(&netcb, p, chain); p->ni_line = -1; memcpy(&p->ni_lsa, &lsa, lsa.ss_len); memcpy(&p->ni_fsa, &fsa, fsa.ss_len); p->ni_proto = strdup(proto); p->ni_flags = NIF_LACHG|NIF_FACHG; } p->ni_state = state; p->ni_seen = 1; return p; } /* column locations */ #define LADDR 0 #define FADDR LADDR+23 #define PROTO FADDR+23 #define RCVCC PROTO+6 #define SNDCC RCVCC+7 #define STATE SNDCC+7 void labelnetstat(void) { if (use_kvm && namelist[X_TCB].n_type == 0) return; wmove(wnd, 0, 0); wclrtobot(wnd); mvwaddstr(wnd, 0, LADDR, "Local Address"); mvwaddstr(wnd, 0, FADDR, "Foreign Address"); mvwaddstr(wnd, 0, PROTO, "Proto"); mvwaddstr(wnd, 0, RCVCC, "Recv-Q"); mvwaddstr(wnd, 0, SNDCC, "Send-Q"); mvwaddstr(wnd, 0, STATE, "(state)"); } void shownetstat(void) { struct netinfo *p, *q; char proto[6]; const char *family = ""; /* * First, delete any connections that have gone * away and adjust the position of connections * below to reflect the deleted line. */ p = TAILQ_FIRST(&netcb); while (p != NULL) { if (p->ni_line == -1 || p->ni_seen) { p = TAILQ_NEXT(p, chain); continue; } wmove(wnd, p->ni_line, 0); wdeleteln(wnd); TAILQ_FOREACH(q, &netcb, chain) if (q != p && q->ni_line > p->ni_line) { q->ni_line--; /* this shouldn't be necessary */ q->ni_flags |= NIF_LACHG|NIF_FACHG; } lastrow--; q = TAILQ_NEXT(p, chain); TAILQ_REMOVE(&netcb, p, chain); free(p); p = q; } /* * Update existing connections and add new ones. */ TAILQ_FOREACH(p, &netcb, chain) { if (p->ni_line == -1) { /* * Add a new entry if possible. */ if (lastrow > YMAX(wnd)) continue; p->ni_line = lastrow++; p->ni_flags |= NIF_LACHG|NIF_FACHG; } if (p->ni_flags & NIF_LACHG) { wmove(wnd, p->ni_line, LADDR); inetprint((struct sockaddr *)&p->ni_lsa, p->ni_proto); p->ni_flags &= ~NIF_LACHG; } if (p->ni_flags & NIF_FACHG) { wmove(wnd, p->ni_line, FADDR); inetprint((struct sockaddr *)&p->ni_fsa, p->ni_proto); p->ni_flags &= ~NIF_FACHG; } #ifdef INET6 family = (p->ni_lsa.ss_family == AF_INET) ? "4" : "6"; #endif snprintf(proto, sizeof(proto), "%s%s", p->ni_proto, family); mvwaddstr(wnd, p->ni_line, PROTO, proto); mvwprintw(wnd, p->ni_line, RCVCC, "%6u", p->ni_rcvcc); mvwprintw(wnd, p->ni_line, SNDCC, "%6u", p->ni_sndcc); if (streq(p->ni_proto, "tcp")) { if (p->ni_state < 0 || p->ni_state >= TCP_NSTATES) mvwprintw(wnd, p->ni_line, STATE, "%d", p->ni_state); else mvwaddstr(wnd, p->ni_line, STATE, tcpstates[p->ni_state]); } wclrtoeol(wnd); } if (lastrow < YMAX(wnd)) { wmove(wnd, lastrow, 0); wclrtobot(wnd); wmove(wnd, YMAX(wnd), 0); wdeleteln(wnd); /* XXX */ } } /* * Pretty print an Internet address (net address + port). * If the nflag was specified, use numbers instead of names. */ static void inetprint(struct sockaddr *sa, const char *proto) { struct servent *sp = 0; char line[80], *cp; int port; switch (sa->sa_family) { case AF_INET: port = ((struct sockaddr_in *)sa)->sin_port; break; #ifdef INET6 case AF_INET6: port = ((struct sockaddr_in6 *)sa)->sin6_port; break; #endif default: port = 0; break; } snprintf(line, sizeof(line), "%.*s.", 16, inetname(sa)); cp = strchr(line, '\0'); if (!nflag && port) sp = getservbyport(port, proto); if (sp || port == 0) snprintf(cp, sizeof(line) - (cp - line), "%.8s", sp ? sp->s_name : "*"); else snprintf(cp, sizeof(line) - (cp - line), "%d", ntohs((u_short)port)); /* pad to full column to clear any garbage */ cp = strchr(line, '\0'); while (cp - line < 22) *cp++ = ' '; line[22] = '\0'; waddstr(wnd, line); } /* * Construct an Internet address representation. * If the nflag has been supplied, give * numeric value, otherwise try for symbolic name. */ static char * inetname(struct sockaddr *sa) { char *cp = 0; static char line[NI_MAXHOST]; struct hostent *hp; struct netent *np; struct in_addr in; #ifdef INET6 if (sa->sa_family == AF_INET6) { if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) strcpy(line, "*"); else getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0, nflag ? NI_NUMERICHOST : 0); return (line); } #endif in = ((struct sockaddr_in *)sa)->sin_addr; if (!nflag && in.s_addr != INADDR_ANY) { int net = inet_netof(in); int lna = inet_lnaof(in); if (lna == INADDR_ANY) { np = getnetbyaddr(net, AF_INET); if (np) cp = np->n_name; } if (cp == 0) { hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET); if (hp) cp = hp->h_name; } } if (in.s_addr == INADDR_ANY) strcpy(line, "*"); else if (cp) snprintf(line, sizeof(line), "%s", cp); else { in.s_addr = ntohl(in.s_addr); #define C(x) ((x) & 0xff) snprintf(line, sizeof(line), "%u.%u.%u.%u", C(in.s_addr >> 24), C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); } return (line); } int cmdnetstat(const char *cmd, const char *args) { if (prefix(cmd, "all")) { aflag = !aflag; goto fixup; } if (prefix(cmd, "numbers") || prefix(cmd, "names")) { struct netinfo *p; int new; new = prefix(cmd, "numbers"); if (new == nflag) return (1); TAILQ_FOREACH(p, &netcb, chain) { if (p->ni_line == -1) continue; p->ni_flags |= NIF_LACHG|NIF_FACHG; } nflag = new; goto redisplay; } if (!netcmd(cmd, args)) return (0); fixup: fetchnetstat(); redisplay: shownetstat(); refresh(); return (1); }