diff options
author | sjg <sjg@FreeBSD.org> | 2015-05-27 01:19:58 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2015-05-27 01:19:58 +0000 |
commit | 65145fa4c81da358fcbc3b650156dab705dfa34e (patch) | |
tree | 55c065b6730aaac2afb6c29933ee6ec5fa4c4249 /usr.bin/netstat | |
parent | 60ff4eb0dff94a04d75d0d52a3957aaaf5f8c693 (diff) | |
parent | e6b664c390af88d4a87208bc042ce503da664c3b (diff) | |
download | FreeBSD-src-65145fa4c81da358fcbc3b650156dab705dfa34e.zip FreeBSD-src-65145fa4c81da358fcbc3b650156dab705dfa34e.tar.gz |
Merge sync of head
Diffstat (limited to 'usr.bin/netstat')
-rw-r--r-- | usr.bin/netstat/Makefile | 8 | ||||
-rw-r--r-- | usr.bin/netstat/Makefile.depend | 1 | ||||
-rw-r--r-- | usr.bin/netstat/bpf.c | 57 | ||||
-rw-r--r-- | usr.bin/netstat/flowtable.c | 1 | ||||
-rw-r--r-- | usr.bin/netstat/if.c | 326 | ||||
-rw-r--r-- | usr.bin/netstat/inet.c | 1058 | ||||
-rw-r--r-- | usr.bin/netstat/inet6.c | 648 | ||||
-rw-r--r-- | usr.bin/netstat/ipsec.c | 262 | ||||
-rw-r--r-- | usr.bin/netstat/main.c | 100 | ||||
-rw-r--r-- | usr.bin/netstat/mbuf.c | 106 | ||||
-rw-r--r-- | usr.bin/netstat/mroute.c | 207 | ||||
-rw-r--r-- | usr.bin/netstat/mroute6.c | 203 | ||||
-rw-r--r-- | usr.bin/netstat/netgraph.c | 27 | ||||
-rw-r--r-- | usr.bin/netstat/netisr.c | 190 | ||||
-rw-r--r-- | usr.bin/netstat/netstat.1 | 25 | ||||
-rw-r--r-- | usr.bin/netstat/netstat.h | 4 | ||||
-rw-r--r-- | usr.bin/netstat/pfkey.c | 94 | ||||
-rw-r--r-- | usr.bin/netstat/route.c | 535 | ||||
-rw-r--r-- | usr.bin/netstat/sctp.c | 438 | ||||
-rw-r--r-- | usr.bin/netstat/unix.c | 76 |
20 files changed, 2504 insertions, 1862 deletions
diff --git a/usr.bin/netstat/Makefile b/usr.bin/netstat/Makefile index 2d50a49..9c70eb4 100644 --- a/usr.bin/netstat/Makefile +++ b/usr.bin/netstat/Makefile @@ -33,14 +33,14 @@ CFLAGS+=-DPF BINGRP= kmem BINMODE=2555 -DPADD= ${LIBKVM} ${LIBMEMSTAT} ${LIBUTIL} -LDADD= -lkvm -lmemstat -lutil +LIBADD= kvm memstat util .if ${MK_NETGRAPH_SUPPORT} != "no" SRCS+= netgraph.c -DPADD+= ${LIBNETGRAPH} -LDADD+= -lnetgraph +LIBADD+= netgraph CFLAGS+=-DNETGRAPH .endif +LIBADD+= xo + .include <bsd.prog.mk> diff --git a/usr.bin/netstat/Makefile.depend b/usr.bin/netstat/Makefile.depend index 225f5f8..cf3f475 100644 --- a/usr.bin/netstat/Makefile.depend +++ b/usr.bin/netstat/Makefile.depend @@ -15,6 +15,7 @@ DIRDEPS = \ lib/libmemstat \ lib/libnetgraph \ lib/libutil \ + lib/libxo \ .include <dirdeps.mk> diff --git a/usr.bin/netstat/bpf.c b/usr.bin/netstat/bpf.c index 2ffeacb..60546e3 100644 --- a/usr.bin/netstat/bpf.c +++ b/usr.bin/netstat/bpf.c @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$"); #include <sys/user.h> #include <net/if.h> -#include <net/if_var.h> #include <net/bpf.h> #include <net/bpfdesc.h> #include <arpa/inet.h> @@ -46,8 +45,10 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <unistd.h> +#include <libxo/xo.h> #include "netstat.h" @@ -67,7 +68,7 @@ bpf_pidname(pid_t pid) size = sizeof(newkp); error = sysctl(mib, 4, &newkp, &size, NULL, 0); if (error < 0) { - warn("kern.proc.pid failed"); + xo_warn("kern.proc.pid failed"); return (strdup("??????")); } return (strdup(newkp.ki_comm)); @@ -86,6 +87,21 @@ bpf_flags(struct xbpf_d *bd, char *flagbuf) *flagbuf++ = bd->bd_async ? 'a' : '-'; *flagbuf++ = bd->bd_locked ? 'l' : '-'; *flagbuf++ = '\0'; + + if (bd->bd_promisc) + xo_emit("{e:promiscuous/}"); + if (bd->bd_immediate) + xo_emit("{e:immediate/}"); + if (bd->bd_hdrcmplt) + xo_emit("{e:header-complete/}"); + xo_emit("{e:direction}", (bd->bd_direction == BPF_D_IN) ? "input" : + (bd->bd_direction == BPF_D_OUT) ? "output" : "bidirectional"); + if (bd->bd_feedback) + xo_emit("{e:feedback/}"); + if (bd->bd_async) + xo_emit("{e:async/}"); + if (bd->bd_locked) + xo_emit("{e:locked/}"); } void @@ -99,44 +115,55 @@ bpf_stats(char *ifname) bzero(&zerostat, sizeof(zerostat)); if (sysctlbyname("net.bpf.stats", NULL, NULL, &zerostat, sizeof(zerostat)) < 0) - warn("failed to zero bpf counters"); + xo_warn("failed to zero bpf counters"); return; } if (sysctlbyname("net.bpf.stats", NULL, &size, NULL, 0) < 0) { - warn("net.bpf.stats"); + xo_warn("net.bpf.stats"); return; } if (size == 0) return; bd = malloc(size); if (bd == NULL) { - warn("malloc failed"); + xo_warn("malloc failed"); return; } if (sysctlbyname("net.bpf.stats", bd, &size, NULL, 0) < 0) { - warn("net.bpf.stats"); + xo_warn("net.bpf.stats"); free(bd); return; } - (void) printf("%5s %6s %7s %9s %9s %9s %5s %5s %s\n", - "Pid", "Netif", "Flags", "Recv", "Drop", "Match", "Sblen", - "Hblen", "Command"); + xo_emit("{T:/%5s} {T:/%6s} {T:/%7s} {T:/%9s} {T:/%9s} {T:/%9s} " + "{T:/%5s} {T:/%5s} {T:/%s}\n", + "Pid", "Netif", "Flags", "Recv", "Drop", "Match", + "Sblen", "Hblen", "Command"); + xo_open_container("bpf-statistics"); + xo_open_list("bpf-entry"); for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) { if (d->bd_structsize != sizeof(*d)) { - warnx("bpf_stats_extended: version mismatch"); + xo_warnx("bpf_stats_extended: version mismatch"); return; } if (ifname && strcmp(ifname, d->bd_ifname) != 0) continue; - bpf_flags(d, flagbuf); + xo_open_instance("bpf-entry"); pname = bpf_pidname(d->bd_pid); - (void) printf("%5d %6s %7s %9ju %9ju %9ju %5d %5d %s\n", - d->bd_pid, d->bd_ifname, flagbuf, - d->bd_rcount, d->bd_dcount, d->bd_fcount, - d->bd_slen, d->bd_hlen, pname); + xo_emit("{k:pid/%5d} {k:interface-name/%6s} ", + d->bd_pid, d->bd_ifname); + bpf_flags(d, flagbuf); + xo_emit("{d:flags/%7s} {:received-packets/%9ju} " + "{:dropped-packets/%9ju} {:filter-packets/%9ju} " + "{:store-buffer-length/%5d} {:hold-buffer-length/%5d} " + "{:process/%s}\n", + flagbuf, (uintmax_t)d->bd_rcount, (uintmax_t)d->bd_dcount, + (uintmax_t)d->bd_fcount, d->bd_slen, d->bd_hlen, pname); free(pname); + xo_close_instance("bpf-entry"); } + xo_close_list("bpf-entry"); + xo_close_container("bpf-statistics"); free(bd); } diff --git a/usr.bin/netstat/flowtable.c b/usr.bin/netstat/flowtable.c index a3d5dd5..a232d80 100644 --- a/usr.bin/netstat/flowtable.c +++ b/usr.bin/netstat/flowtable.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <stdint.h> #include <stdio.h> +#include <stdbool.h> #include "netstat.h" /* diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c index a4c86be..109ef2d 100644 --- a/usr.bin/netstat/if.c +++ b/usr.bin/netstat/if.c @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include <sys/time.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <net/if_types.h> #include <net/ethernet.h> @@ -72,6 +71,7 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <sysexits.h> #include <unistd.h> +#include <libxo/xo.h> #include "netstat.h" @@ -98,14 +98,38 @@ static const char* pfsyncacts[] = { /* PFSYNC_ACT_EOF */ "end of frame mark", }; +static const char* pfsyncacts_name[] = { + /* PFSYNC_ACT_CLR */ "clear-all-request", + /* PFSYNC_ACT_INS */ "state-insert", + /* PFSYNC_ACT_INS_ACK */ "state-inserted-ack", + /* PFSYNC_ACT_UPD */ "state-update", + /* PFSYNC_ACT_UPD_C */ "compressed-state-update", + /* PFSYNC_ACT_UPD_REQ */ "uncompressed-state-request", + /* PFSYNC_ACT_DEL */ "state-delete", + /* PFSYNC_ACT_DEL_C */ "compressed-state-delete", + /* PFSYNC_ACT_INS_F */ "fragment-insert", + /* PFSYNC_ACT_DEL_F */ "fragment-delete", + /* PFSYNC_ACT_BUS */ "bulk-update-mark", + /* PFSYNC_ACT_TDB */ "TDB-replay-counter-update", + /* PFSYNC_ACT_EOF */ "end-of-frame-mark", +}; + static void -pfsync_acts_stats(const char *fmt, uint64_t *a) +pfsync_acts_stats(const char *list, const char *desc, uint64_t *a) { int i; - for (i = 0; i < PFSYNC_ACT_MAX; i++, a++) - if (*a || sflag <= 1) - printf(fmt, *a, pfsyncacts[i], plural(*a)); + xo_open_list(list); + for (i = 0; i < PFSYNC_ACT_MAX; i++, a++) { + if (*a || sflag <= 1) { + xo_open_instance(list); + xo_emit("\t\t{e:name}{:count/%ju} {N:/%s%s %s}\n", + pfsyncacts_name[i], (uintmax_t)(*a), + pfsyncacts[i], plural(*a), desc); + xo_close_instance(list); + } + } + xo_close_list(list); } /* @@ -129,32 +153,50 @@ pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused) } else kread(off, &pfsyncstat, len); - printf("%s:\n", name); + xo_emit("{T:/%s}:\n", name); + xo_open_container(name); #define p(f, m) if (pfsyncstat.f || sflag <= 1) \ - printf(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f)) + xo_emit(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f)) - p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n"); - p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n"); - pfsync_acts_stats("\t %ju %s%s received\n", + p(pfsyncs_ipackets, "\t{:received-inet-packets/%ju} " + "{N:/packet%s received (IPv4)}\n"); + p(pfsyncs_ipackets6, "\t{:received-inet6-packets/%ju} " + "{N:/packet%s received (IPv6)}\n"); + pfsync_acts_stats("input-histogram", "received", &pfsyncstat.pfsyncs_iacts[0]); - p(pfsyncs_badif, "\t\t%ju packet%s discarded for bad interface\n"); - p(pfsyncs_badttl, "\t\t%ju packet%s discarded for bad ttl\n"); - p(pfsyncs_hdrops, "\t\t%ju packet%s shorter than header\n"); - p(pfsyncs_badver, "\t\t%ju packet%s discarded for bad version\n"); - p(pfsyncs_badauth, "\t\t%ju packet%s discarded for bad HMAC\n"); - p(pfsyncs_badact,"\t\t%ju packet%s discarded for bad action\n"); - p(pfsyncs_badlen, "\t\t%ju packet%s discarded for short packet\n"); - p(pfsyncs_badval, "\t\t%ju state%s discarded for bad values\n"); - p(pfsyncs_stale, "\t\t%ju stale state%s\n"); - p(pfsyncs_badstate, "\t\t%ju failed state lookup/insert%s\n"); - p(pfsyncs_opackets, "\t%ju packet%s sent (IPv4)\n"); - p(pfsyncs_opackets6, "\t%ju packet%s sent (IPv6)\n"); - pfsync_acts_stats("\t %ju %s%s sent\n", + p(pfsyncs_badif, "\t\t/{:dropped-bad-interface/%ju} " + "{N:/packet%s discarded for bad interface}\n"); + p(pfsyncs_badttl, "\t\t{:dropped-bad-ttl/%ju} " + "{N:/packet%s discarded for bad ttl}\n"); + p(pfsyncs_hdrops, "\t\t{:dropped-short-header/%ju} " + "{N:/packet%s shorter than header}\n"); + p(pfsyncs_badver, "\t\t{:dropped-bad-version/%ju} " + "{N:/packet%s discarded for bad version}\n"); + p(pfsyncs_badauth, "\t\t{:dropped-bad-auth/%ju} " + "{N:/packet%s discarded for bad HMAC}\n"); + p(pfsyncs_badact,"\t\t{:dropped-bad-action/%ju} " + "{N:/packet%s discarded for bad action}\n"); + p(pfsyncs_badlen, "\t\t{:dropped-short/%ju} " + "{N:/packet%s discarded for short packet}\n"); + p(pfsyncs_badval, "\t\t{:dropped-bad-values/%ju} " + "{N:/state%s discarded for bad values}\n"); + p(pfsyncs_stale, "\t\t{:dropped-stale-state/%ju} " + "{N:/stale state%s}\n"); + p(pfsyncs_badstate, "\t\t{:dropped-failed-lookup/%ju} " + "{N:/failed state lookup\\/insert%s}\n"); + p(pfsyncs_opackets, "\t{:sent-inet-packets/%ju} " + "{N:/packet%s sent (IPv4})\n"); + p(pfsyncs_opackets6, "\t{:send-inet6-packets/%ju} " + "{N:/packet%s sent (IPv6})\n"); + pfsync_acts_stats("output-histogram", "sent", &pfsyncstat.pfsyncs_oacts[0]); - p(pfsyncs_onomem, "\t\t%ju failure%s due to mbuf memory error\n"); - p(pfsyncs_oerrors, "\t\t%ju send error%s\n"); + p(pfsyncs_onomem, "\t\t{:discarded-no-memory/%ju} " + "{N:/failure%s due to mbuf memory error}\n"); + p(pfsyncs_oerrors, "\t\t{:send-errors/%ju} " + "{N:/send error%s}\n"); #undef p + xo_close_container(name); } #endif /* PF */ @@ -162,10 +204,11 @@ pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused) * Display a formatted value, or a '-' in the same space. */ static void -show_stat(const char *fmt, int width, u_long value, short showvalue) +show_stat(const char *fmt, int width, const char *name, + u_long value, short showvalue) { const char *lsep, *rsep; - char newfmt[32]; + char newfmt[64]; lsep = ""; if (strncmp(fmt, "LS", 2) == 0) { @@ -179,23 +222,38 @@ show_stat(const char *fmt, int width, u_long value, short showvalue) } if (showvalue == 0) { /* Print just dash. */ - sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep); - printf(newfmt, "-"); + xo_emit("{P:/%s}{D:/%*s}{P:/%s}", lsep, width, "-", rsep); return; } + /* + * XXX: workaround {P:} modifier can't be empty and doesn't seem to + * take args... so we need to conditionally include it in the format. + */ +#define maybe_pad(pad) do { \ + if (strlen(pad)) { \ + snprintf(newfmt, sizeof(newfmt), "{P:%s}", pad); \ + xo_emit(newfmt); \ + } \ +} while (0) + if (hflag) { char buf[5]; /* Format in human readable form. */ humanize_number(buf, sizeof(buf), (int64_t)value, "", HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL); - sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep); - printf(newfmt, buf); + maybe_pad(lsep); + snprintf(newfmt, sizeof(newfmt), "{:%s/%%%ds}", name, width); + xo_emit(newfmt, buf); + maybe_pad(rsep); } else { /* Construct the format string. */ - sprintf(newfmt, "%s%%%d%s%s", lsep, width, fmt, rsep); - printf(newfmt, value); + maybe_pad(lsep); + snprintf(newfmt, sizeof(newfmt), "{:%s/%%%d%s}", + name, width, fmt); + xo_emit(newfmt, value); + maybe_pad(rsep); } } @@ -235,34 +293,37 @@ intpr(int interval, void (*pfunc)(char *), int af) if (aflag && getifmaddrs(&ifmap) != 0) err(EX_OSERR, "getifmaddrs"); + xo_open_list("interface"); if (!pfunc) { if (Wflag) - printf("%-7.7s", "Name"); + xo_emit("{T:/%-7.7s}", "Name"); else - printf("%-5.5s", "Name"); - printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s", + xo_emit("{T:/%-5.5s}", "Name"); + xo_emit(" {T:/%5.5s} {T:/%-13.13s} {T:/%-17.17s} {T:/%8.8s} " + "{T:/%5.5s} {T:/%5.5s}", "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop"); if (bflag) - printf(" %10.10s","Ibytes"); - printf(" %8.8s %5.5s", "Opkts", "Oerrs"); + xo_emit(" {T:/%10.10s}","Ibytes"); + xo_emit(" {T:/%8.8s} {T:/%5.5s}", "Opkts", "Oerrs"); if (bflag) - printf(" %10.10s","Obytes"); - printf(" %5s", "Coll"); + xo_emit(" {T:/%10.10s}","Obytes"); + xo_emit(" {T:/%5s}", "Coll"); if (dflag) - printf(" %s", "Drop"); - putchar('\n'); + xo_emit(" {T:/%s}", "Drop"); + xo_emit("\n"); } for (ifa = ifap; ifa; ifa = ifa->ifa_next) { bool network = false, link = false; + char *name, *xname, buf[IFNAMSIZ+1]; if (interface != NULL && strcmp(ifa->ifa_name, interface) != 0) continue; + name = ifa->ifa_name; + if (pfunc) { - char *name; - name = ifa->ifa_name; (*pfunc)(name); /* @@ -278,19 +339,31 @@ intpr(int interval, void (*pfunc)(char *), int af) if (af != AF_UNSPEC && ifa->ifa_addr->sa_family != af) continue; + xo_open_instance("interface"); + + if ((ifa->ifa_flags & IFF_UP) == 0) { + xname = stpcpy(buf, name); + *xname++ = '*'; + *xname = '\0'; + xname = buf; + } else + xname = name; + if (Wflag) - printf("%-7.7s", ifa->ifa_name); + xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%7.7s}", + name, ifa->ifa_flags, xname); else - printf("%-5.5s", ifa->ifa_name); + xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%5.5s}", + name, ifa->ifa_flags, xname); #define IFA_MTU(ifa) (((struct if_data *)(ifa)->ifa_data)->ifi_mtu) - show_stat("lu", 6, IFA_MTU(ifa), IFA_MTU(ifa)); + show_stat("lu", 6, "mtu", IFA_MTU(ifa), IFA_MTU(ifa)); #undef IFA_MTU switch (ifa->ifa_addr->sa_family) { case AF_UNSPEC: - printf("%-13.13s ", "none"); - printf("%-15.15s ", "none"); + xo_emit("{:network/%-13.13s} ", "none"); + xo_emit("{:address/%-15.15s} ", "none"); break; case AF_INET: { @@ -298,9 +371,10 @@ intpr(int interval, void (*pfunc)(char *), int af) sin = (struct sockaddr_in *)ifa->ifa_addr; mask = (struct sockaddr_in *)ifa->ifa_netmask; - printf("%-13.13s ", netname(sin->sin_addr.s_addr, + xo_emit("{t:network/%-13.13s} ", + netname(sin->sin_addr.s_addr, mask->sin_addr.s_addr)); - printf("%-17.17s ", + xo_emit("{t:address/%-17.17s} ", routename(sin->sin_addr.s_addr)); network = true; @@ -314,67 +388,82 @@ intpr(int interval, void (*pfunc)(char *), int af) sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; mask = (struct sockaddr_in6 *)ifa->ifa_netmask; - printf("%-13.13s ", netname6(sin6, &mask->sin6_addr)); + xo_emit("{t:network/%-13.13s} ", + netname6(sin6, &mask->sin6_addr)); getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, addr_buf, sizeof(addr_buf), 0, 0, NI_NUMERICHOST); - printf("%-17.17s ", addr_buf); + xo_emit("{t:address/%-17.17s} ", addr_buf); network = 1; break; - } + } #endif /* INET6 */ case AF_LINK: { struct sockaddr_dl *sdl; char *cp, linknum[10]; - int n, m; + int len = 32; + char buf[len]; + int n, z; sdl = (struct sockaddr_dl *)ifa->ifa_addr; cp = (char *)LLADDR(sdl); n = sdl->sdl_alen; sprintf(linknum, "<Link#%d>", sdl->sdl_index); - m = printf("%-13.13s ", linknum); - - while ((--n >= 0) && (m < 30)) - m += printf("%02x%c", *cp++ & 0xff, - n > 0 ? ':' : ' '); - m = 32 - m; - while (m-- > 0) - putchar(' '); - + xo_emit("{t:network/%-13.13s} ", linknum); + buf[0] = '\0'; + z = 0; + while ((--n >= 0) && (z < len)) { + snprintf(buf + z, len - z, "%02x%c", + *cp++ & 0xff, n > 0 ? ':' : ' '); + z += 3; + } + if (z > 0) + xo_emit("{:address/%*s}", 32 - z, buf); + else + xo_emit("{P: }"); link = 1; break; } } #define IFA_STAT(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s) - show_stat("lu", 8, IFA_STAT(ipackets), link|network); - show_stat("lu", 5, IFA_STAT(ierrors), link); - show_stat("lu", 5, IFA_STAT(iqdrops), link); + show_stat("lu", 8, "received-packets", IFA_STAT(ipackets), + link|network); + show_stat("lu", 5, "received-errors", IFA_STAT(ierrors), link); + show_stat("lu", 5, "dropped-packets", IFA_STAT(iqdrops), link); if (bflag) - show_stat("lu", 10, IFA_STAT(ibytes), link|network); - show_stat("lu", 8, IFA_STAT(opackets), link|network); - show_stat("lu", 5, IFA_STAT(oerrors), link); + show_stat("lu", 10, "received-bytes", IFA_STAT(ibytes), + link|network); + show_stat("lu", 8, "sent-packets", IFA_STAT(opackets), + link|network); + show_stat("lu", 5, "send-errors", IFA_STAT(oerrors), link); if (bflag) - show_stat("lu", 10, IFA_STAT(obytes), link|network); - show_stat("NRSlu", 5, IFA_STAT(collisions), link); + show_stat("lu", 10, "sent-bytes", IFA_STAT(obytes), + link|network); + show_stat("NRSlu", 5, "collisions", IFA_STAT(collisions), link); if (dflag) - show_stat("LSlu", 5, IFA_STAT(oqdrops), link); - putchar('\n'); + show_stat("LSlu", 5, "dropped-packets", + IFA_STAT(oqdrops), link); + xo_emit("\n"); - if (!aflag) + if (!aflag) { + xo_close_instance("interface"); continue; + } /* * Print family's multicast addresses. */ + xo_open_list("multicast-address"); for (ifma = next_ifma(ifmap, ifa->ifa_name, - ifa->ifa_addr->sa_family); - ifma != NULL; - ifma = next_ifma(ifma, ifa->ifa_name, - ifa->ifa_addr->sa_family)) { + ifa->ifa_addr->sa_family); + ifma != NULL; + ifma = next_ifma(ifma, ifa->ifa_name, + ifa->ifa_addr->sa_family)) { const char *fmt = NULL; + xo_open_instance("multicast-address"); switch (ifma->ifma_addr->sa_family) { case AF_INET: { @@ -391,7 +480,7 @@ intpr(int interval, void (*pfunc)(char *), int af) getnameinfo(ifma->ifma_addr, ifma->ifma_addr->sa_len, addr_buf, sizeof(addr_buf), 0, 0, NI_NUMERICHOST); - printf("%*s %s\n", + xo_emit("{P:/%*s }{t:address/%-19.19s}", Wflag ? 27 : 25, "", addr_buf); break; #endif /* INET6 */ @@ -412,21 +501,24 @@ intpr(int interval, void (*pfunc)(char *), int af) } if (fmt) { - printf("%*s %-17.17s", + xo_emit("{P:/%*s }{t:address/%-17.17s/}", Wflag ? 27 : 25, "", fmt); if (ifma->ifma_addr->sa_family == AF_LINK) { - printf(" %8ju", - (uintmax_t )IFA_STAT(imcasts)); - printf("%*s", bflag ? 17 : 6, ""); - printf(" %8ju", - (uintmax_t )IFA_STAT(omcasts)); - } - putchar('\n'); + xo_emit(" {:received-packets/%8lu}", + IFA_STAT(imcasts)); + xo_emit("{P:/%*s}", bflag? 17 : 6, ""); + xo_emit(" {:sent-packets/%8lu}", + IFA_STAT(omcasts)); + } + xo_emit("\n"); } - + xo_close_instance("multicast-address"); ifma = ifma->ifma_next; } + xo_close_list("multicast-address"); + xo_close_instance("interface"); } + xo_close_list("interface"); freeifaddrs(ifap); if (aflag) @@ -455,7 +547,7 @@ fill_iftot(struct iftot *st) bool found = false; if (getifaddrs(&ifap) != 0) - err(EX_OSERR, "getifaddrs"); + xo_err(EX_OSERR, "getifaddrs"); bzero(st, sizeof(*st)); @@ -481,7 +573,7 @@ fill_iftot(struct iftot *st) } if (interface && found == false) - err(EX_DATAERR, "interface %s not found", interface); + xo_err(EX_DATAERR, "interface %s not found", interface); freeifaddrs(ifap); } @@ -520,23 +612,26 @@ sidewaysintpr(int interval) interval_it.it_interval.tv_usec = 0; interval_it.it_value = interval_it.it_interval; setitimer(ITIMER_REAL, &interval_it, NULL); + xo_open_list("interface-statistics"); banner: - printf("%17s %14s %16s", "input", + xo_emit("{T:/%17s} {T:/%14s} {T:/%16s}\n", "input", interface != NULL ? interface : "(Total)", "output"); - putchar('\n'); - printf("%10s %5s %5s %10s %10s %5s %10s %5s", + xo_emit("{T:/%10s} {T:/%5s} {T:/%5s} {T:/%10s} {T:/%10s} {T:/%5s} " + "{T:/%10s} {T:/%5s}", "packets", "errs", "idrops", "bytes", "packets", "errs", "bytes", "colls"); if (dflag) - printf(" %5.5s", "drops"); - putchar('\n'); - fflush(stdout); + xo_emit(" {T:/%5.5s}", "drops"); + xo_emit("\n"); + xo_flush(); line = 0; loop: - if ((noutputs != 0) && (--noutputs == 0)) - exit(0); + if ((noutputs != 0) && (--noutputs == 0)) { + xo_close_list("interface-statistics"); + return; + } oldmask = sigblock(sigmask(SIGALRM)); while (!signalled) sigpause(0); @@ -546,18 +641,29 @@ loop: fill_iftot(new); - show_stat("lu", 10, new->ift_ip - old->ift_ip, 1); - show_stat("lu", 5, new->ift_ie - old->ift_ie, 1); - show_stat("lu", 5, new->ift_id - old->ift_id, 1); - show_stat("lu", 10, new->ift_ib - old->ift_ib, 1); - show_stat("lu", 10, new->ift_op - old->ift_op, 1); - show_stat("lu", 5, new->ift_oe - old->ift_oe, 1); - show_stat("lu", 10, new->ift_ob - old->ift_ob, 1); - show_stat("NRSlu", 5, new->ift_co - old->ift_co, 1); + xo_open_instance("stats"); + show_stat("lu", 10, "received-packets", + new->ift_ip - old->ift_ip, 1); + show_stat("lu", 5, "received-errors", + new->ift_ie - old->ift_ie, 1); + show_stat("lu", 5, "dropped-packets", + new->ift_id - old->ift_id, 1); + show_stat("lu", 10, "received-bytes", + new->ift_ib - old->ift_ib, 1); + show_stat("lu", 10, "sent-packets", + new->ift_op - old->ift_op, 1); + show_stat("lu", 5, "send-errors", + new->ift_oe - old->ift_oe, 1); + show_stat("lu", 10, "sent-bytes", + new->ift_ob - old->ift_ob, 1); + show_stat("NRSlu", 5, "collisions", + new->ift_co - old->ift_co, 1); if (dflag) - show_stat("LSlu", 5, new->ift_od - old->ift_od, 1); - putchar('\n'); - fflush(stdout); + show_stat("LSlu", 5, "dropped-packets", + new->ift_od - old->ift_od, 1); + xo_close_instance("stats"); + xo_emit("\n"); + xo_flush(); if (new == &ift[0]) { new = &ift[1]; diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index 10d0698..c966bf4 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -78,12 +78,14 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <unistd.h> +#include <libxo/xo.h> #include "netstat.h" char *inetname(struct in_addr *); -void inetprint(struct in_addr *, int, const char *, int); +void inetprint(const char *, struct in_addr *, int, const char *, int); #ifdef INET6 static int udp_done, tcp_done, sdp_done; #endif /* INET6 */ @@ -114,15 +116,15 @@ pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused) len = 0; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { if (errno != ENOENT) - warn("sysctl: %s", mibvar); + xo_warn("sysctl: %s", mibvar); return (0); } if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); + xo_warnx("malloc %lu bytes", (u_long)len); return (0); } if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { - warn("sysctl: %s", mibvar); + xo_warn("sysctl: %s", mibvar); free(buf); return (0); } @@ -137,7 +139,7 @@ pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused) 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; @@ -205,14 +207,14 @@ pcblist_kvm(u_long off, char **bufp, int istcp) (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) * sizeof(struct xinpcb); if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); + xo_warnx("malloc %lu bytes", (u_long)len); return (0); } p = buf; #define COPYOUT(obj, size) do { \ if (len < (size)) { \ - warnx("buffer size exceeded"); \ + xo_warnx("buffer size exceeded"); \ goto fail; \ } \ bcopy((obj), p, (size)); \ @@ -349,8 +351,8 @@ protopr(u_long off, const char *name, int af1, int proto) 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)) { + 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; @@ -403,185 +405,218 @@ protopr(u_long off, const char *name, int af1, int proto) if (first) { if (!Lflag) { - printf("Active Internet connections"); + xo_emit("Active Internet connections"); if (aflag) - printf(" (including servers)"); + xo_emit(" (including servers)"); } else - printf( + xo_emit( "Current listen queue sizes (qlen/incqlen/maxqlen)"); - putchar('\n'); + xo_emit("\n"); if (Aflag) - printf("%-*s ", 2 * (int)sizeof(void *), "Tcpcb"); + xo_emit("{T:/%-*s} ", 2 * (int)sizeof(void *), + "Tcpcb"); if (Lflag) - printf((Aflag && !Wflag) ? - "%-5.5s %-14.14s %-18.18s" : - "%-5.5s %-14.14s %-22.22s", + xo_emit((Aflag && !Wflag) ? + "{T:/%-5.5s} {T:/%-14.14s} {T:/%-18.18s}" : + "{T:/%-5.5s} {T:/%-14.14s} {T:/%-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", + xo_emit((Aflag && !Wflag) ? + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%s}" : + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%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"); + xo_emit((Aflag && !Wflag) ? + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%-18.18s}" : + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%-22.22s}", + "Proto", "Recv-Q", "Send-Q", + "Local Address", "Foreign Address"); if (!xflag && !Rflag) - printf(" (state)"); + xo_emit(" (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"); + xo_emit(" {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} " + "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} " + "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} " + "{T:/%-6.6s} {T:/%-6.6s} {T:/%-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"); + xo_emit(" {T:/%7.7s} {T:/%7.7s} {T:/%7.7s} " + "{T:/%7.7s} {T:/%7.7s} {T:/%7.7s}", + "rexmt", "persist", "keep", "2msl", + "delack", "rcvtime"); } else if (Rflag) { - printf (" %8.8s %5.5s", + xo_emit(" {T:/%8.8s} {T:/%5.5s}", "flowid", "ftype"); } - putchar('\n'); + xo_emit("\n"); first = 0; } if (Lflag && so->so_qlimit == 0) continue; + xo_open_instance("socket"); if (Aflag) { if (istcp) - printf("%*lx ", 2 * (int)sizeof(void *), (u_long)inp->inp_ppcb); + xo_emit("{q:address/%*lx} ", + 2 * (int)sizeof(void *), + (u_long)inp->inp_ppcb); else - printf("%*lx ", 2 * (int)sizeof(void *), (u_long)so->so_pcb); + xo_emit("{q:adddress/%*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 "; + "46" : "6"; else #endif vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? - "4 " : " "; + "4" : ""; if (istcp && (tp->t_flags & TF_TOE) != 0) - printf("%-3.3s%-2.2s ", "toe", vchar); + xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", "toe", vchar); else - printf("%-3.3s%-2.2s ", name, vchar); + xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", 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); + xo_emit("{:listen-queue-sizes/%-14.14s} ", buf1); } else if (Tflag) { if (istcp) - printf("%6u %6u %6u ", tp->t_sndrexmitpack, - tp->t_rcvoopack, tp->t_sndzerowin); + xo_emit("{:sent-retransmit-packets/%6u} " + "{:received-out-of-order-packets/%6u} " + "{:sent-zero-window/%6u} ", + tp->t_sndrexmitpack, tp->t_rcvoopack, + tp->t_sndzerowin); } else { - printf("%6u %6u ", so->so_rcv.sb_cc, so->so_snd.sb_cc); + xo_emit("{:receive-bytes-waiting/%6u} " + "{:send-bytes-waiting/%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); + inetprint("local", &inp->inp_laddr, + (int)inp->inp_lport, name, 1); if (!Lflag) - inetprint(&inp->inp_faddr, + inetprint("remote", &inp->inp_faddr, (int)inp->inp_fport, name, 1); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { - inet6print(&inp->in6p_laddr, + inet6print("local", &inp->in6p_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) - inet6print(&inp->in6p_faddr, + inet6print("remote", &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); + inetprint("local", &inp->inp_laddr, + (int)inp->inp_lport, name, 1); if (!Lflag) - inetprint(&inp->inp_faddr, + inetprint("remote", &inp->inp_faddr, (int)inp->inp_fport, name, 0); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { - inet6print(&inp->in6p_laddr, + inet6print("local", &inp->in6p_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) - inet6print(&inp->in6p_faddr, + inet6print("remote", &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); + inetprint("local", &inp->inp_laddr, + (int)inp->inp_lport, name, 0); if (!Lflag) - inetprint(&inp->inp_faddr, + inetprint("remote", &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, + inet6print("local", &inp->in6p_laddr, (int)inp->inp_lport, name, 0); if (!Lflag) - inet6print(&inp->in6p_faddr, + inet6print("remote", &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); + xo_emit("{:receive-mbufs/%6u} {:send-mbufs/%6u} " + "{:receive-clusters/%6u} {:send-clusters/%6u} " + "{:receive-high-water/%6u} {:send-high-water/%6u} " + "{:receive-low-water/%6u} {:send-low-water/%6u} " + "{:receive-mbuf-bytes/%6u} {:send-mbuf-bytes/%6u} " + "{:receive-mbuf-bytes-max/%6u} " + "{:send-mbuf-bytes-max/%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); + xo_emit(" {:retransmit-timer/%4d.%02d} " + "{:persist-timer/%4d.%02d} " + "{:keepalive-timer/%4d.%02d} " + "{:msl2-timer/%4d.%02d} " + "{:delay-ack-timer/%4d.%02d} " + "{:inactivity-timer/%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 && !Rflag) { if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) - printf("%d", tp->t_state); + xo_emit("{:tcp-state/%d}", tp->t_state); else { - printf("%s", tcpstates[tp->t_state]); + xo_emit("{:tcp-state/%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('*'); + xo_emit("{:need-syn-or-fin/*}"); #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ } } if (Rflag) { - printf(" %08x %5d", + /* XXX: is this right Alfred */ + xo_emit(" {:flow-id/%08x} {:flow-type/%5d}", inp->inp_flowid, inp->inp_flowtype); } - putchar('\n'); + xo_emit("\n"); + xo_close_instance("socket"); } 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); + xo_emit("Some {d:lost/%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); + xo_emit("Some {d:created/%s} sockets may have been " + "created.\n", name); } else { - printf( - "Some %s sockets may have been created or deleted.\n", - name); + xo_emit("Some {d:changed/%s} sockets may have been " + "created or deleted.\n", name); } } free(buf); @@ -608,146 +643,216 @@ tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 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"); + xo_warn("sysctl: net.inet.tcp.stats"); return; } } else kread_counters(off, &tcpstat, len); - printf ("%s:\n", name); + xo_open_container("tcp"); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (tcpstat.f || sflag <= 1) \ - printf(m, (uintmax_t )tcpstat.f, plural(tcpstat.f)) - + xo_emit(m, (uintmax_t )tcpstat.f, plural(tcpstat.f)) #define p1a(f, m) if (tcpstat.f || sflag <= 1) \ - printf(m, (uintmax_t )tcpstat.f) - + xo_emit(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), \ + xo_emit(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), \ + xo_emit(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_rcvreassfull, - "\t\t%ju discarded due to no space in reassembly queue\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 + xo_emit(m, (uintmax_t )tcpstat.f, pluralies(tcpstat.f)) + + p(tcps_sndtotal, "\t{:sent-packets/%ju} {N:/packet%s sent}\n"); + p2(tcps_sndpack,tcps_sndbyte, "\t\t{:sent-data-packets/%ju} " + "{N:/data packet%s} ({:sent-data-bytes/%ju} {N:/byte%s})\n"); + p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, "\t\t" + "{:sent-retransmitted-packets/%ju} {N:/data packet%s} " + "({:sent-retransmitted-bytes/%ju} {N:/byte%s}) " + "{N:retransmitted}\n"); + p(tcps_sndrexmitbad, "\t\t" + "{:sent-unnecessary-retransmitted-packets/%ju} " + "{N:/data packet%s unnecessarily retransmitted}\n"); + p(tcps_mturesent, "\t\t{:sent-resends-by-mtu-discovery/%ju} " + "{N:/resend%s initiated by MTU discovery}\n"); + p2a(tcps_sndacks, tcps_delack, "\t\t{:sent-ack-only-packets/%ju} " + "{N:/ack-only packet%s/} ({:sent-packets-delayed/%ju} " + "{N:delayed})\n"); + p(tcps_sndurg, "\t\t{:sent-urg-only-packets/%ju} " + "{N:/URG only packet%s}\n"); + p(tcps_sndprobe, "\t\t{:sent-window-probe-packets/%ju} " + "{N:/window probe packet%s}\n"); + p(tcps_sndwinup, "\t\t{:sent-window-update-packets/%ju} " + "{N:/window update packet%s}\n"); + p(tcps_sndctrl, "\t\t{:sent-control-packets/%ju} " + "{N:/control packet%s}\n"); + p(tcps_rcvtotal, "\t{:received-packets/%ju} " + "{N:/packet%s received}\n"); + p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t" + "{:received-ack-packets/%ju} {N:/ack%s} " + "{N:(for} {:received-ack-bytes/%ju} {N:/byte%s})\n"); + p(tcps_rcvdupack, "\t\t{:received-duplicate-acks/%ju} " + "{N:/duplicate ack%s}\n"); + p(tcps_rcvacktoomuch, "\t\t{:received-acks-for-unsent-data/%ju} " + "{N:/ack%s for unsent data}\n"); + p2(tcps_rcvpack, tcps_rcvbyte, "\t\t" + "{:received-in-sequence-packets/%ju} {N:/packet%s} " + "({:received-in-sequence-bytes/%ju} {N:/byte%s}) " + "{N:received in-sequence}\n"); + p2(tcps_rcvduppack, tcps_rcvdupbyte, "\t\t" + "{:received-completely-duplicate-packets/%ju} " + "{N:/completely duplicate packet%s} " + "({:received-completely-duplicate-bytes/%ju} {N:/byte%s})\n"); + p(tcps_pawsdrop, "\t\t{:received-old-duplicate-packets/%ju} " + "{N:/old duplicate packet%s}\n"); + p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, "\t\t" + "{:received-some-duplicate-packets/%ju} " + "{N:/packet%s with some dup. data} " + "({:received-some-duplicate-bytes/%ju} {N:/byte%s duped/})\n"); + p2(tcps_rcvoopack, tcps_rcvoobyte, "\t\t{:received-out-of-order/%ju} " + "{N:/out-of-order packet%s} " + "({:received-out-of-order-bytes/%ju} {N:/byte%s})\n"); + p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, "\t\t" + "{:received-after-window-packets/%ju} {N:/packet%s} " + "({:received-after-window-bytes/%ju} {N:/byte%s}) " + "{N:of data after window}\n"); + p(tcps_rcvwinprobe, "\t\t{:received-window-probes/%ju} " + "{N:/window probe%s}\n"); + p(tcps_rcvwinupd, "\t\t{:receive-window-update-packets/%ju} " + "{N:/window update packet%s}\n"); + p(tcps_rcvafterclose, "\t\t{:received-after-close-packets/%ju} " + "{N:/packet%s received after close}\n"); + p(tcps_rcvbadsum, "\t\t{:discard-bad-checksum/%ju} " + "{N:/discarded for bad checksum%s}\n"); + p(tcps_rcvbadoff, "\t\t{:discard-bad-header-offset/%ju} " + "{N:/discarded for bad header offset field%s}\n"); + p1a(tcps_rcvshort, "\t\t{:discard-too-short/%ju} " + "{N:discarded because packet too short}\n"); + p1a(tcps_rcvmemdrop, "\t\t{:discard-memory-problems/%ju} " + "{N:discarded due to memory problems}\n"); + p(tcps_connattempt, "\t{:connection-requests/%ju} " + "{N:/connection request%s}\n"); + p(tcps_accepts, "\t{:connections-accepts/%ju} " + "{N:/connection accept%s}\n"); + p(tcps_badsyn, "\t{:bad-connection-attempts/%ju} " + "{N:/bad connection attempt%s}\n"); + p(tcps_listendrop, "\t{:listen-queue-overflows/%ju} " + "{N:/listen queue overflow%s}\n"); + p(tcps_badrst, "\t{:ignored-in-window-resets/%ju} " + "{N:/ignored RSTs in the window%s}\n"); + p(tcps_connects, "\t{:connections-established/%ju} " + "{N:/connection%s established (including accepts)}\n"); + p2(tcps_closed, tcps_drops, "\t{:connections-closed/%ju} " + "{N:/connection%s closed (including} " + "{:connection-drops/%ju} {N:/drop%s})\n"); + p(tcps_cachedrtt, "\t\t{:connections-updated-rtt-on-close/%ju} " + "{N:/connection%s updated cached RTT on close}\n"); + p(tcps_cachedrttvar, "\t\t" + "{:connections-updated-variance-on-close/%ju} " + "{N:/connection%s updated cached RTT variance on close}\n"); + p(tcps_cachedssthresh, "\t\t" + "{:connections-updated-ssthresh-on-close/%ju} " + "{N:/connection%s updated cached ssthresh on close}\n"); + p(tcps_conndrops, "\t{:embryonic-connections-dropped/%ju} " + "{N:/embryonic connection%s dropped}\n"); + p2(tcps_rttupdated, tcps_segstimed, "\t{:segments-updated-rtt/%ju} " + "{N:/segment%s updated rtt (of} " + "{:segment-update-attempts/%ju} {N:/attempt%s})\n"); + p(tcps_rexmttimeo, "\t{:retransmit-timeouts/%ju} " + "{N:/retransmit timeout%s}\n"); + p(tcps_timeoutdrop, "\t\t" + "{:connections-dropped-by-retransmit-timeout/%ju} " + "{N:/connection%s dropped by rexmit timeout}\n"); + p(tcps_persisttimeo, "\t{:persist-timeout/%ju} " + "{N:/persist timeout%s}\n"); + p(tcps_persistdrop, "\t\t" + "{:connections-dropped-by-persist-timeout/%ju} " + "{N:/connection%s dropped by persist timeout}\n"); + p(tcps_finwait2_drops, "\t" + "{:connections-dropped-by-finwait2-timeout/%ju} " + "{N:/Connection%s (fin_wait_2) dropped because of timeout}\n"); + p(tcps_keeptimeo, "\t{:keepalive-timeout/%ju} " + "{N:/keepalive timeout%s}\n"); + p(tcps_keepprobe, "\t\t{:keepalive-probes/%ju} " + "{N:/keepalive probe%s sent}\n"); + p(tcps_keepdrops, "\t\t{:connections-dropped-by-keepalives/%ju} " + "{N:/connection%s dropped by keepalive}\n"); + p(tcps_predack, "\t{:ack-header-predictions/%ju} " + "{N:/correct ACK header prediction%s}\n"); + p(tcps_preddat, "\t{:data-packet-header-predictions/%ju} " + "{N:/correct data packet header prediction%s}\n"); + + xo_open_container("syncache"); + + p3(tcps_sc_added, "\t{:entries-added/%ju} " + "{N:/syncache entr%s added}\n"); + p1a(tcps_sc_retransmitted, "\t\t{:retransmitted/%ju} " + "{N:/retransmitted}\n"); + p1a(tcps_sc_dupsyn, "\t\t{:duplicates/%ju} {N:/dupsyn}\n"); + p1a(tcps_sc_dropped, "\t\t{:dropped/%ju} {N:/dropped}\n"); + p1a(tcps_sc_completed, "\t\t{:completed/%ju} {N:/completed}\n"); + p1a(tcps_sc_bucketoverflow, "\t\t{:bucket-overflow/%ju} " + "{N:/bucket overflow}\n"); + p1a(tcps_sc_cacheoverflow, "\t\t{:cache-overflow/%ju} " + "{N:/cache overflow}\n"); + p1a(tcps_sc_reset, "\t\t{:reset/%ju} {N:/reset}\n"); + p1a(tcps_sc_stale, "\t\t{:stale/%ju} {N:/stale}\n"); + p1a(tcps_sc_aborted, "\t\t{:aborted/%ju} {N:/aborted}\n"); + p1a(tcps_sc_badack, "\t\t{:bad-ack/%ju} {N:/badack}\n"); + p1a(tcps_sc_unreach, "\t\t{:unreachable/%ju} {N:/unreach}\n"); + p(tcps_sc_zonefail, "\t\t{:zone-failures/%ju} {N:/zone failure%s}\n"); + p(tcps_sc_sendcookie, "\t{:sent-cookies/%ju} {N:/cookie%s sent}\n"); + p(tcps_sc_recvcookie, "\t{:receivd-cookies/%ju} " + "{N:/cookie%s received}\n"); + + xo_close_container("syncache"); + + xo_open_container("hostcache"); + + p3(tcps_hc_added, "\t{:entries-added/%ju} " + "{N:/hostcache entr%s added}\n"); + p1a(tcps_hc_bucketoverflow, "\t\t{:buffer-overflows/%ju} " + "{N:/bucket overflow}\n"); + + xo_close_container("hostcache"); + + xo_open_container("sack"); + + p(tcps_sack_recovery_episode, "\t{:recovery-episodes/%ju} " + "{N:/SACK recovery episode%s}\n"); + p(tcps_sack_rexmits, "\t{:segment-retransmits/%ju} " + "{N:/segment rexmit%s in SACK recovery episodes}\n"); + p(tcps_sack_rexmit_bytes, "\t{:byte-retransmits/%ju} " + "{N:/byte rexmit%s in SACK recovery episodes}\n"); + p(tcps_sack_rcv_blocks, "\t{:received-blocks/%ju} " + "{N:/SACK option%s (SACK blocks) received}\n"); + p(tcps_sack_send_blocks, "\t{:sent-option-blocks/%ju} " + "{N:/SACK option%s (SACK blocks) sent}\n"); + p1a(tcps_sack_sboverflow, "\t{:scoreboard-overflows/%ju} " + "{N:/SACK scoreboard overflow}\n"); + + xo_close_container("sack"); + xo_open_container("ecn"); + + p(tcps_ecn_ce, "\t{:ce-packets/%ju} " + "{N:/packet%s with ECN CE bit set}\n"); + p(tcps_ecn_ect0, "\t{:ect0-packets/%ju} " + "{N:/packet%s with ECN ECT(0) bit set}\n"); + p(tcps_ecn_ect1, "\t{:ect1-packets/%ju} " + "{N:/packet%s with ECN ECT(1) bit set}\n"); + p(tcps_ecn_shs, "\t{:handshakes/%ju} " + "{N:/successful ECN handshake%s}\n"); + p(tcps_ecn_rcwnd, "\t{:congestion-reductions/%ju} " + "{N:/time%s ECN reduced the congestion window}\n"); + #undef p + #undef p1a + #undef p2 + #undef p2a + #undef p3 + xo_close_container("ecn"); + xo_close_container("tcp"); } /* @@ -772,27 +877,38 @@ udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 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"); + xo_warn("sysctl: net.inet.udp.stats"); return; } } else kread_counters(off, &udpstat, len); - printf("%s:\n", name); + xo_open_container("udp"); + xo_emit("{T:/%s}:\n", name); + #define p(f, m) if (udpstat.f || sflag <= 1) \ - printf("\t%ju " m, (uintmax_t)udpstat.f, plural(udpstat.f)) + xo_emit("\t" 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"); + xo_emit("\t" m, (uintmax_t)udpstat.f) + + p(udps_ipackets, "{:received-datagrams/%ju} " + "{N:/datagram%s received}\n"); + p1a(udps_hdrops, "{:dropped-incomplete-headers/%ju} " + "{N:/with incomplete header}\n"); + p1a(udps_badlen, "{:dropped-bad-data-length/%ju} " + "{N:/with bad data length field}\n"); + p1a(udps_badsum, "{:dropped-bad-checksum/%ju} " + "{N:/with bad checksum}\n"); + p1a(udps_nosum, "{:dropped-no-checksum/%ju} " + "{N:/with no checksum}\n"); + p1a(udps_noport, "{:dropped-no-socket/%ju} " + "{N:/dropped due to no socket}\n"); + p(udps_noportbcast, "{:dropped-broadcast-multicast/%ju} " + "{N:/broadcast\\/multicast datagram%s undelivered}\n"); + p1a(udps_fullsock, "{:dropped-full-socket-buffer/%ju} " + "{N:/dropped due to full socket buffers}\n"); + p1a(udpps_pcbhashmiss, "{:not-for-hashed-pcb/%ju} " + "{N:/not for hashed pcb}\n"); delivered = udpstat.udps_ipackets - udpstat.udps_hdrops - udpstat.udps_badlen - @@ -801,13 +917,15 @@ udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 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"); + xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n", + (uint64_t)delivered); + p(udps_opackets, "{:output-packets/%ju} {N:/datagram%s output}\n"); /* the next statistic is cumulative in udps_noportbcast */ - p(udps_filtermcast, - "time%s multicast source filter matched\n"); + p(udps_filtermcast, "{:multicast-source-filter-matches/%ju} " + "{N:/time%s multicast source filter matched}\n"); #undef p #undef p1a + xo_close_container("udp"); } /* @@ -825,7 +943,7 @@ carp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (sysctlbyname("net.inet.carp.stats", &carpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) - warn("sysctl: net.inet.carp.stats"); + xo_warn("sysctl: net.inet.carp.stats"); return; } } else { @@ -834,31 +952,47 @@ carp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) kread_counters(off, &carpstat, len); } - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (carpstat.f || sflag <= 1) \ - printf(m, (uintmax_t)carpstat.f, plural(carpstat.f)) + xo_emit(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"); + xo_emit(m, (uintmax_t)carpstat.f) + + p(carps_ipackets, "\t{:received-inet-packets/%ju} " + "{N:/packet%s received (IPv4)}\n"); + p(carps_ipackets6, "\t{:received-inet6-packets/%ju} " + "{N:/packet%s received (IPv6)}\n"); + p(carps_badttl, "\t\t{:dropped-wrong-ttl/%ju} " + "{N:/packet%s discarded for wrong TTL}\n"); + p(carps_hdrops, "\t\t{:dropped-short-header/%ju} " + "{N:/packet%s shorter than header}\n"); + p(carps_badsum, "\t\t{:dropped-bad-checksum/%ju} " + "{N:/discarded for bad checksum%s}\n"); + p(carps_badver, "\t\t{:dropped-bad-version/%ju} " + "{N:/discarded packet%s with a bad version}\n"); + p2(carps_badlen, "\t\t{:dropped-short-packet/%ju} " + "{N:/discarded because packet too short}\n"); + p2(carps_badauth, "\t\t{:dropped-bad-authentication/%ju} " + "{N:/discarded for bad authentication}\n"); + p2(carps_badvhid, "\t\t{:dropped-bad-vhid/%ju} " + "{N:/discarded for bad vhid}\n"); + p2(carps_badaddrs, "\t\t{:dropped-bad-address-list/%ju} " + "{N:/discarded because of a bad address list}\n"); + p(carps_opackets, "\t{:sent-inet-packets/%ju} " + "{N:/packet%s sent (IPv4)}\n"); + p(carps_opackets6, "\t{:sent-inet6-packets/%ju} " + "{N:/packet%s sent (IPv6)}\n"); + p2(carps_onomem, "\t\t{:send-failed-memory-error/%ju} " + "{N:/send failed due to mbuf memory error}\n"); #if notyet - p(carps_ostates, "\t\t%s state update%s sent\n"); + p(carps_ostates, "\t\t{:send-state-updates/%s} " + "{N:/state update%s sent}\n"); #endif #undef p #undef p2 + xo_close_container(name); } /* @@ -875,54 +1009,83 @@ ip_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 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"); + xo_warn("sysctl: net.inet.ip.stats"); return; } } else kread_counters(off, &ipstat, len); - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (ipstat.f || sflag <= 1) \ - printf(m, (uintmax_t )ipstat.f, plural(ipstat.f)) + xo_emit(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)"); + xo_emit(m, (uintmax_t )ipstat.f) + + p(ips_total, "\t{:received-packets/%ju} " + "{N:/total packet%s received}\n"); + p(ips_badsum, "\t{:dropped-bad-checksum/%ju} " + "{N:/bad header checksum%s}\n"); + p1a(ips_toosmall, "\t{:dropped-below-minimum-size/%ju} " + "{N:/with size smaller than minimum}\n"); + p1a(ips_tooshort, "\t{:dropped-short-packets/%ju} " + "{N:/with data size < data length}\n"); + p1a(ips_toolong, "\t{:dropped-too-long/%ju} " + "{N:/with ip length > max ip packet size}\n"); + p1a(ips_badhlen, "\t{:dropped-short-header-length/%ju} " + "{N:/with header length < data size}\n"); + p1a(ips_badlen, "\t{:dropped-short-data/%ju} " + "{N:/with data length < header length}\n"); + p1a(ips_badoptions, "\t{:dropped-bad-options/%ju} " + "{N:/with bad options}\n"); + p1a(ips_badvers, "\t{:dropped-bad-version/%ju} " + "{N:/with incorrect version number}\n"); + p(ips_fragments, "\t{:received-fragments/%ju} " + "{N:/fragment%s received}\n"); + p(ips_fragdropped, "\t{:dropped-fragments/%ju} " + "{N:/fragment%s dropped (dup or out of space)}\n"); + p(ips_fragtimeout, "\t{:dropped-fragments-after-timeout/%ju} " + "{N:/fragment%s dropped after timeout}\n"); + p(ips_reassembled, "\t{:reassembled-packets/%ju} " + "{N:/packet%s reassembled ok}\n"); + p(ips_delivered, "\t{:received-local-packets/%ju} " + "{N:/packet%s for this host}\n"); + p(ips_noproto, "\t{:dropped-unknown-protocol/%ju} " + "{N:/packet%s for unknown\\/unsupported protocol}\n"); + p(ips_forward, "\t{:forwarded-packets/%ju} " + "{N:/packet%s forwarded}"); + p(ips_fastforward, " ({:fast-forwarded-packets/%ju} " + "{N:/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"); + xo_emit("\n"); + p(ips_cantforward, "\t{:packets-cannot-forward/%ju} " + "{N:/packet%s not forwardable}\n"); + p(ips_notmember, "\t{:received-unknown-multicast-group/%ju} " + "{N:/packet%s received for unknown multicast group}\n"); + p(ips_redirectsent, "\t{:redirects-sent/%ju} " + "{N:/redirect%s sent}\n"); + p(ips_localout, "\t{:sent-packets/%ju} " + "{N:/packet%s sent from this host}\n"); + p(ips_rawout, "\t{:send-packets-fabricated-header/%ju} " + "{N:/packet%s sent with fabricated ip header}\n"); + p(ips_odropped, "\t{:discard-no-mbufs/%ju} " + "{N:/output packet%s dropped due to no bufs, etc.}\n"); + p(ips_noroute, "\t{:discard-no-route/%ju} " + "{N:/output packet%s discarded due to no route}\n"); + p(ips_fragmented, "\t{:sent-fragments/%ju} " + "{N:/output datagram%s fragmented}\n"); + p(ips_ofragments, "\t{:fragments-created/%ju} " + "{N:/fragment%s created}\n"); + p(ips_cantfrag, "\t{:discard-cannot-fragment/%ju} " + "{N:/datagram%s that can't be fragmented}\n"); + p(ips_nogif, "\t{:discard-tunnel-no-gif/%ju} " + "{N:/tunneling packet%s that can't find gif}\n"); + p(ips_badaddr, "\t{:discard-bad-address/%ju} " + "{N:/datagram%s with bad address in header}\n"); #undef p #undef p1a + xo_close_container(name); } /* @@ -939,29 +1102,37 @@ arp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 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"); + xo_warn("sysctl: net.link.ether.arp.stats"); return; } } else kread_counters(off, &arpstat, len); - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (arpstat.f || sflag <= 1) \ - printf("\t%ju " m, (uintmax_t)arpstat.f, plural(arpstat.f)) + xo_emit("\t" 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"); + xo_emit("\t" m, (uintmax_t)arpstat.f, pluralies(arpstat.f)) + + p(txrequests, "{:sent-requests/%ju} {N:/ARP request%s sent}\n"); + p2(txreplies, "{:sent-replies/%ju} {N:/ARP repl%s sent}\n"); + p(rxrequests, "{:received-requests/%ju} " + "{N:/ARP request%s received}\n"); + p2(rxreplies, "{:received-replies/%ju} " + "{N:/ARP repl%s received}\n"); + p(received, "{:received-packers/%ju} " + "{N:/ARP packet%s received}\n"); + p(dropped, "{:dropped-no-entry/%ju} " + "{N:/total packet%s dropped due to no ARP entry}\n"); + p(timeouts, "{:entries-timeout/%ju} " + "{N:/ARP entry%s timed out}\n"); + p(dupips, "{:dropped-duplicate-address/%ju} " + "{N:/Duplicate IP%s seen}\n"); #undef p #undef p2 + xo_close_container(name); } @@ -1026,59 +1197,89 @@ icmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 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"); + xo_warn("sysctl: net.inet.icmp.stats"); return; } } else kread_counters(off, &icmpstat, len); - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (icmpstat.f || sflag <= 1) \ - printf(m, icmpstat.f, plural(icmpstat.f)) + xo_emit(m, icmpstat.f, plural(icmpstat.f)) #define p1a(f, m) if (icmpstat.f || sflag <= 1) \ - printf(m, icmpstat.f) + xo_emit(m, icmpstat.f) #define p2(f, m) if (icmpstat.f || sflag <= 1) \ - printf(m, icmpstat.f, plurales(icmpstat.f)) + xo_emit(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++) + p(icps_error, "\t{:icmp-calls/%lu} " + "{N:/call%s to icmp_error}\n"); + p(icps_oldicmp, "\t{:errors-not-from-message/%lu} " + "{N:/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"); + xo_open_list("output-histogram"); + xo_emit("\tOutput histogram:\n"); first = 0; } + xo_open_instance("output-histogram"); if (icmpnames[i] != NULL) - printf("\t\t%s: %lu\n", icmpnames[i], - icmpstat.icps_outhist[i]); + xo_emit("\t\t{k:name/%s}: {:count/%lu}\n", + icmpnames[i], icmpstat.icps_outhist[i]); else - printf("\t\tunknown ICMP #%d: %lu\n", i, - icmpstat.icps_outhist[i]); + xo_emit("\t\tunknown ICMP #{k:name/%d}: " + "{:count/%lu}\n", + i, icmpstat.icps_outhist[i]); + xo_close_instance("output-histogram"); } - 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 (!first) + xo_close_list("output-histogram"); + + p(icps_badcode, "\t{:dropped-bad-code/%lu} " + "{N:/message%s with bad code fields}\n"); + p(icps_tooshort, "\t{:dropped-too-short/%lu} " + "{N:/message%s less than the minimum length}\n"); + p(icps_checksum, "\t{:dropped-bad-checksum/%lu} " + "{N:/message%s with bad checksum}\n"); + p(icps_badlen, "\t{:dropped-bad-length/%lu} " + "{N:/message%s with bad length}\n"); + p1a(icps_bmcastecho, "\t{:dropped-multicast-echo/%lu} " + "{N:/multicast echo requests ignored}\n"); + p1a(icps_bmcasttstamp, "\t{:dropped-multicast-timestamp/%lu} " + "{N:/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"); + xo_open_list("input-histogram"); + xo_emit("\tInput histogram:\n"); first = 0; } + xo_open_instance("input-histogram"); if (icmpnames[i] != NULL) - printf("\t\t%s: %lu\n", icmpnames[i], - icmpstat.icps_inhist[i]); + xo_emit("\t\t{k:name/%s}: {:count/%lu}\n", + icmpnames[i], + icmpstat.icps_inhist[i]); else - printf("\t\tunknown ICMP #%d: %lu\n", i, - icmpstat.icps_inhist[i]); + xo_emit( + "\t\tunknown ICMP #{k:name/%d}: {:count/%lu}\n", + i, icmpstat.icps_inhist[i]); + xo_close_instance("input-histogram"); } - 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"); + } + if (!first) + xo_close_list("input-histogram"); + + p(icps_reflect, "\t{:sent-packets/%lu} " + "{N:/message response%s generated}\n"); + p2(icps_badaddr, "\t{:discard-invalid-return-address/%lu} " + "{N:/invalid return address%s}\n"); + p(icps_noroute, "\t{:discard-no-route/%lu} " + "{N:/no return route%s}\n"); #undef p #undef p1a #undef p2 @@ -1087,51 +1288,12 @@ icmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (sysctlbyname("net.inet.icmp.maskrepl", &i, &len, NULL, 0) < 0) return; - printf("\tICMP address mask responses are %sabled\n", - i ? "en" : "dis"); + xo_emit("\tICMP address mask responses are " + "{q:icmp-address-responses/%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 + xo_close_container(name); } -#endif /* !BURN_BRIDGES */ /* * Dump IGMP statistics structure. @@ -1142,34 +1304,13 @@ 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"); + xo_warn("sysctl: net.inet.igmp.stats"); return; } } else { @@ -1178,41 +1319,59 @@ igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) } if (igmpstat.igps_version != IGPS_VERSION_3) { - warnx("%s: version mismatch (%d != %d)", __func__, + xo_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__, + xo_warnx("%s: size mismatch (%d != %d)", __func__, igmpstat.igps_len, IGPS_VERSION3_LEN); } - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p64(f, m) if (igmpstat.f || sflag <= 1) \ - printf(m, (uintmax_t) igmpstat.f, plural(igmpstat.f)) + xo_emit(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"); + xo_emit(m, (uintmax_t) igmpstat.f, pluralies(igmpstat.f)) + + p64(igps_rcv_total, "\t{:received-messages/%ju} " + "{N:/message%s received}\n"); + p64(igps_rcv_tooshort, "\t{:dropped-too-short/%ju} " + "{N:/message%s received with too few bytes}\n"); + p64(igps_rcv_badttl, "\t{:dropped-wrong-ttl/%ju} " + "{N:/message%s received with wrong TTL}\n"); + p64(igps_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " + "{N:/message%s received with bad checksum}\n"); + py64(igps_rcv_v1v2_queries, "\t{:received-membership-queries/%ju} " + "{N:/V1\\/V2 membership quer%s received}\n"); + py64(igps_rcv_v3_queries, "\t{:received-v3-membership-queries/%ju} " + "{N:/V3 membership quer%s received}\n"); + py64(igps_rcv_badqueries, "\t{:dropped-membership-queries/%ju} " + "{N:/membership quer%s received with invalid field(s)}\n"); + py64(igps_rcv_gen_queries, "\t{:received-general-queries/%ju} " + "{N:/general quer%s received}\n"); + py64(igps_rcv_group_queries, "\t{:received-group-queries/%ju} " + "{N:/group quer%s received}\n"); + py64(igps_rcv_gsr_queries, "\t{:received-group-source-queries/%ju} " + "{N:/group-source quer%s received}\n"); + py64(igps_drop_gsr_queries, "\t{:dropped-group-source-queries/%ju} " + "{N:/group-source quer%s dropped}\n"); + p64(igps_rcv_reports, "\t{:received-membership-requests/%ju} " + "{N:/membership report%s received}\n"); + p64(igps_rcv_badreports, "\t{:dropped-membership-reports/%ju} " + "{N:/membership report%s received with invalid field(s)}\n"); + p64(igps_rcv_ourreports, "\t" + "{:received-membership-reports-matching/%ju} " + "{N:/membership report%s received for groups to which we belong}" + "\n"); + p64(igps_rcv_nora, "\t{:received-v3-reports-no-router-alert/%ju} " + "{N:/V3 report%s received without Router Alert}\n"); + p64(igps_snd_reports, "\t{:sent-membership-reports/%ju} " + "{N:/membership report%s sent}\n"); #undef p64 #undef py64 + xo_close_container(name); } /* @@ -1231,7 +1390,7 @@ pim_stats(u_long off __unused, const char *name, int af1 __unused, if (sysctlbyname("net.inet.pim.stats", &pimstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) - warn("sysctl: net.inet.pim.stats"); + xo_warn("sysctl: net.inet.pim.stats"); return; } } else { @@ -1240,38 +1399,56 @@ pim_stats(u_long off __unused, const char *name, int af1 __unused, kread_counters(off, &pimstat, len); } - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (pimstat.f || sflag <= 1) \ - printf(m, (uintmax_t)pimstat.f, plural(pimstat.f)) + xo_emit(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"); + xo_emit(m, (uintmax_t)pimstat.f, pimstat.f != 1 ? "ies" : "y") + + p(pims_rcv_total_msgs, "\t{:received-messages/%ju} " + "{N:/message%s received}\n"); + p(pims_rcv_total_bytes, "\t{:received-bytes/%ju} " + "{N:/byte%s received}\n"); + p(pims_rcv_tooshort, "\t{:dropped-too-short/%ju} " + "{N:/message%s received with too few bytes}\n"); + p(pims_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " + "{N:/message%s received with bad checksum}\n"); + p(pims_rcv_badversion, "\t{:dropped-bad-version/%ju} " + "{N:/message%s received with bad version}\n"); + p(pims_rcv_registers_msgs, "\t{:received-data-register-messages/%ju} " + "{N:/data register message%s received}\n"); + p(pims_rcv_registers_bytes, "\t{:received-data-register-bytes/%ju} " + "{N:/data register byte%s received}\n"); + p(pims_rcv_registers_wrongiif, "\t" + "{:received-data-register-wrong-interface/%ju} " + "{N:/data register message%s received on wrong iif}\n"); + p(pims_rcv_badregisters, "\t{:received-bad-registers/%ju} " + "{N:/bad register%s received}\n"); + p(pims_snd_registers_msgs, "\t{:sent-data-register-messages/%ju} " + "{N:/data register message%s sent}\n"); + p(pims_snd_registers_bytes, "\t{:sent-data-register-bytes/%ju} " + "{N:/data register byte%s sent}\n"); #undef p #undef py + xo_close_container(name); } /* * Pretty print an Internet address (net address + port). */ void -inetprint(struct in_addr *in, int port, const char *proto, int num_port) +inetprint(const char *container, struct in_addr *in, int port, + const char *proto, int num_port) { struct servent *sp = 0; char line[80], *cp; int width; + if (container) + xo_open_container(container); + if (Wflag) sprintf(line, "%s.", inetname(in)); else @@ -1285,9 +1462,16 @@ inetprint(struct in_addr *in, int port, const char *proto, int num_port) sprintf(cp, "%d ", ntohs((u_short)port)); width = (Aflag && !Wflag) ? 18 : 22; if (Wflag) - printf("%-*s ", width, line); + xo_emit("{d:target/%-*s} ", width, line); else - printf("%-*.*s ", width, width, line); + xo_emit("{d:target/%-*.*s} ", width, width, line); + + int alen = cp - line - 1, plen = strlen(cp) - 1; + xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen, + plen, cp); + + if (container) + xo_close_container(container); } /* diff --git a/usr.bin/netstat/inet6.c b/usr.bin/netstat/inet6.c index 96fdcaf..3535f45 100644 --- a/usr.bin/netstat/inet6.c +++ b/usr.bin/netstat/inet6.c @@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$"); #include <net/route.h> #include <net/if.h> -#include <net/if_var.h> #include <netinet/in.h> #include <netinet/ip6.h> #include <netinet/icmp6.h> @@ -65,9 +64,11 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <stdint.h> #include <stdio.h> +#include <stdbool.h> #include <errno.h> #include <string.h> #include <unistd.h> +#include <libxo/xo.h> #include "netstat.h" struct socket sockb; @@ -372,153 +373,246 @@ ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) - warn("sysctl: net.inet6.ip6.stats"); + xo_warn("sysctl: net.inet6.ip6.stats"); return; } } else kread_counters(off, &ip6stat, len); - - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (ip6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) + xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f)) #define p1a(f, m) if (ip6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)ip6stat.f) - - p(ip6s_total, "\t%ju total packet%s received\n"); - p1a(ip6s_toosmall, "\t%ju with size smaller than minimum\n"); - p1a(ip6s_tooshort, "\t%ju with data size < data length\n"); - p1a(ip6s_badoptions, "\t%ju with bad options\n"); - p1a(ip6s_badvers, "\t%ju with incorrect version number\n"); - p(ip6s_fragments, "\t%ju fragment%s received\n"); - p(ip6s_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n"); - p(ip6s_fragtimeout, "\t%ju fragment%s dropped after timeout\n"); - p(ip6s_fragoverflow, "\t%ju fragment%s that exceeded limit\n"); - p(ip6s_reassembled, "\t%ju packet%s reassembled ok\n"); - p(ip6s_delivered, "\t%ju packet%s for this host\n"); - p(ip6s_forward, "\t%ju packet%s forwarded\n"); - p(ip6s_cantforward, "\t%ju packet%s not forwardable\n"); - p(ip6s_redirectsent, "\t%ju redirect%s sent\n"); - p(ip6s_localout, "\t%ju packet%s sent from this host\n"); - p(ip6s_rawout, "\t%ju packet%s sent with fabricated ip header\n"); - p(ip6s_odropped, "\t%ju output packet%s dropped due to no bufs, etc.\n"); - p(ip6s_noroute, "\t%ju output packet%s discarded due to no route\n"); - p(ip6s_fragmented, "\t%ju output datagram%s fragmented\n"); - p(ip6s_ofragments, "\t%ju fragment%s created\n"); - p(ip6s_cantfrag, "\t%ju datagram%s that can't be fragmented\n"); - p(ip6s_badscope, "\t%ju packet%s that violated scope rules\n"); - p(ip6s_notmember, "\t%ju multicast packet%s which we don't join\n"); + xo_emit(m, (uintmax_t)ip6stat.f) + + p(ip6s_total, "\t{:received-packets/%ju} " + "{N:/total packet%s received}\n"); + p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} " + "{N:/with size smaller than minimum}\n"); + p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} " + "{N:/with data size < data length}\n"); + p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} " + "{N:/with bad options}\n"); + p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} " + "{N:/with incorrect version number}\n"); + p(ip6s_fragments, "\t{:received-fragments/%ju} " + "{N:/fragment%s received}\n"); + p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} " + "{N:/fragment%s dropped (dup or out of space)}\n"); + p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} " + "{N:/fragment%s dropped after timeout}\n"); + p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} " + "{N:/fragment%s that exceeded limit}\n"); + p(ip6s_reassembled, "\t{:reassembled-packets/%ju} " + "{N:/packet%s reassembled ok}\n"); + p(ip6s_delivered, "\t{:received-local-packets/%ju} " + "{N:/packet%s for this host}\n"); + p(ip6s_forward, "\t{:forwarded-packets/%ju} " + "{N:/packet%s forwarded}\n"); + p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} " + "{N:/packet%s not forwardable}\n"); + p(ip6s_redirectsent, "\t{:sent-redirects/%ju} " + "{N:/redirect%s sent}\n"); + p(ip6s_localout, "\t{:sent-packets/%ju} " + "{N:/packet%s sent from this host}\n"); + p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} " + "{N:/packet%s sent with fabricated ip header}\n"); + p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} " + "{N:/output packet%s dropped due to no bufs, etc.}\n"); + p(ip6s_noroute, "\t{:discard-no-route/%ju} " + "{N:/output packet%s discarded due to no route}\n"); + p(ip6s_fragmented, "\t{:sent-fragments/%ju} " + "{N:/output datagram%s fragmented}\n"); + p(ip6s_ofragments, "\t{:fragments-created/%ju} " + "{N:/fragment%s created}\n"); + p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} " + "{N:/datagram%s that can't be fragmented}\n"); + p(ip6s_badscope, "\t{:discard-scope-violations/%ju} " + "{N:/packet%s that violated scope rules}\n"); + p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} " + "{N:/multicast packet%s which we don't join}\n"); for (first = 1, i = 0; i < IP6S_HDRCNT; i++) if (ip6stat.ip6s_nxthist[i] != 0) { if (first) { - printf("\tInput histogram:\n"); + xo_emit("\t{T:Input histogram}:\n"); + xo_open_list("input-histogram"); first = 0; } - printf("\t\t%s: %ju\n", ip6nh[i], + xo_open_instance("input-histogram"); + xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i], (uintmax_t)ip6stat.ip6s_nxthist[i]); + xo_close_instance("input-histogram"); } - printf("\tMbuf statistics:\n"); - printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1); + if (!first) + xo_close_list("input-histogram"); + + xo_open_container("mbuf-statistics"); + xo_emit("\t{T:Mbuf statistics}:\n"); + xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n", + (uintmax_t)ip6stat.ip6s_m1); for (first = 1, i = 0; i < IP6S_M2MMAX; i++) { char ifbuf[IFNAMSIZ]; if (ip6stat.ip6s_m2m[i] != 0) { if (first) { - printf("\t\ttwo or more mbuf:\n"); + xo_emit("\t\t{N:two or more mbuf}:\n"); + xo_open_list("mbuf-data"); first = 0; } - printf("\t\t\t%s= %ju\n", + xo_open_instance("mbuf-data"); + xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n", if_indextoname(i, ifbuf), (uintmax_t)ip6stat.ip6s_m2m[i]); + xo_close_instance("mbuf-data"); } } - printf("\t\t%ju one ext mbuf\n", + if (!first) + xo_close_list("mbuf-data"); + xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext1); - printf("\t\t%ju two or more ext mbuf\n", - (uintmax_t)ip6stat.ip6s_mext2m); - p(ip6s_exthdrtoolong, - "\t%ju packet%s whose headers are not contiguous\n"); - p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n"); - p(ip6s_toomanyhdr, - "\t%ju packet%s discarded because of too many headers\n"); + xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} " + "{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m); + xo_close_container("mbuf-statistics"); + + p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} " + "{N:/packet%s whose headers are not contiguous}\n"); + p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} " + "{N:/tunneling packet%s that can't find gif}\n"); + p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} " + "{N:/packet%s discarded because of too many headers}\n"); /* for debugging source address selection */ #define PRINT_SCOPESTAT(s,i) do {\ switch(i) { /* XXX hardcoding in each case */\ case 1:\ - p(s, "\t\t%ju interface-local%s\n");\ + p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \ + "{N:/interface-local%s}\n"); \ break;\ case 2:\ - p(s,"\t\t%ju link-local%s\n");\ + p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \ + "{N:/link-local%s}\n"); \ break;\ case 5:\ - p(s,"\t\t%ju site-local%s\n");\ + p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \ + "{N:/site-local%s}\n");\ break;\ case 14:\ - p(s,"\t\t%ju global%s\n");\ + p(s,"\t\t{ke:name/globals}{:count/%ju} " \ + "{N:/global%s}\n");\ break;\ default:\ - printf("\t\t%ju addresses scope=%x\n",\ - (uintmax_t)ip6stat.s, i);\ + xo_emit("\t\t{qke:name/%x}{:count/%ju} " \ + "addresses scope=%x\n",\ + i, (uintmax_t)ip6stat.s, i); \ }\ } while (0); - p(ip6s_sources_none, - "\t%ju failure%s of source address selection\n"); + xo_open_container("source-address-selection"); + p(ip6s_sources_none, "\t{:address-selection-failures/%ju} " + "{N:/failure%s of source address selection}\n"); + for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { if (ip6stat.ip6s_sources_sameif[i]) { if (first) { - printf("\tsource addresses on an outgoing I/F\n"); + xo_open_list("outgoing-interface"); + xo_emit("\tsource addresses on an outgoing " + "I/F\n"); first = 0; } + xo_open_instance("outgoing-interface"); PRINT_SCOPESTAT(ip6s_sources_sameif[i], i); + xo_close_instance("outgoing-interface"); } } + if (!first) + xo_close_list("outgoing-interface"); + for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { if (ip6stat.ip6s_sources_otherif[i]) { if (first) { - printf("\tsource addresses on a non-outgoing I/F\n"); + xo_open_list("non-outgoing-interface"); + xo_emit("\tsource addresses on a non-outgoing " + "I/F\n"); first = 0; } + xo_open_instance("non-outgoing-interface"); PRINT_SCOPESTAT(ip6s_sources_otherif[i], i); + xo_close_instance("non-outgoing-interface"); } } + if (!first) + xo_close_list("non-outgoing-interface"); + for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { if (ip6stat.ip6s_sources_samescope[i]) { if (first) { - printf("\tsource addresses of same scope\n"); + xo_open_list("same-source"); + xo_emit("\tsource addresses of same scope\n"); first = 0; } + xo_open_instance("same-source"); PRINT_SCOPESTAT(ip6s_sources_samescope[i], i); + xo_close_instance("same-source"); } } + if (!first) + xo_close_list("same-source"); + for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { if (ip6stat.ip6s_sources_otherscope[i]) { if (first) { - printf("\tsource addresses of a different scope\n"); + xo_open_list("different-scope"); + xo_emit("\tsource addresses of a different " + "scope\n"); first = 0; } + xo_open_instance("different-scope"); PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i); + xo_close_instance("different-scope"); } } + if (!first) + xo_close_list("different-scope"); + for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) { if (ip6stat.ip6s_sources_deprecated[i]) { if (first) { - printf("\tdeprecated source addresses\n"); + xo_open_list("deprecated-source"); + xo_emit("\tdeprecated source addresses\n"); first = 0; } + xo_open_instance("deprecated-source"); PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i); + xo_close_instance("deprecated-source"); } } + if (!first) + xo_close_list("deprecated-source"); - printf("\tSource addresses selection rule applied:\n"); - for (i = 0; i < IP6S_RULESMAX; i++) { - if (ip6stat.ip6s_sources_rule[i]) - printf("\t\t%ju %s\n", - (uintmax_t)ip6stat.ip6s_sources_rule[i], - srcrule_str[i]); + for (first = 1, i = 0; i < IP6S_RULESMAX; i++) { + if (ip6stat.ip6s_sources_rule[i]) { + if (first) { + xo_open_list("rules-applied"); + xo_emit("\t{T:Source addresses selection " + "rule applied}:\n"); + first = 0; + } + xo_open_instance("rules-applied"); + xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n", + srcrule_str[i], + (uintmax_t)ip6stat.ip6s_sources_rule[i], + srcrule_str[i]); + xo_close_instance("rules-applied"); + } } + if (!first) + xo_close_list("rules-applied"); + + xo_close_container("source-address-selection"); + #undef p #undef p1a + xo_close_container(name); } /* @@ -529,52 +623,74 @@ ip6_ifstats(char *ifname) { struct in6_ifreq ifr; int s; -#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ - printf(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, plural(ifr.ifr_ifru.ifru_stat.f)) -#define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ - printf(m, (uintmax_t)ip6stat.f) + +#define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ + xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_stat.f, \ + plural(ifr.ifr_ifru.ifru_stat.f)) if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - perror("Warning: socket(AF_INET6)"); + xo_warn("Warning: socket(AF_INET6)"); return; } strcpy(ifr.ifr_name, ifname); if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { if (errno != EPFNOSUPPORT) - perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); + xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)"); goto end; } - printf("ip6 on %s:\n", ifr.ifr_name); - p(ifs6_in_receive, "\t%ju total input datagram%s\n"); - p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n"); - p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n"); - p(ifs6_in_noroute, "\t%ju datagram%s with no route received\n"); - p(ifs6_in_addrerr, "\t%ju datagram%s with invalid dst received\n"); - p(ifs6_in_protounknown, "\t%ju datagram%s with unknown proto received\n"); - p(ifs6_in_truncated, "\t%ju truncated datagram%s received\n"); - p(ifs6_in_discard, "\t%ju input datagram%s discarded\n"); - p(ifs6_in_deliver, - "\t%ju datagram%s delivered to an upper layer protocol\n"); - p(ifs6_out_forward, "\t%ju datagram%s forwarded to this interface\n"); - p(ifs6_out_request, - "\t%ju datagram%s sent from an upper layer protocol\n"); - p(ifs6_out_discard, "\t%ju total discarded output datagram%s\n"); - p(ifs6_out_fragok, "\t%ju output datagram%s fragmented\n"); - p(ifs6_out_fragfail, "\t%ju output datagram%s failed on fragment\n"); - p(ifs6_out_fragcreat, "\t%ju output datagram%s succeeded on fragment\n"); - p(ifs6_reass_reqd, "\t%ju incoming datagram%s fragmented\n"); - p(ifs6_reass_ok, "\t%ju datagram%s reassembled\n"); - p(ifs6_reass_fail, "\t%ju datagram%s failed on reassembly\n"); - p(ifs6_in_mcast, "\t%ju multicast datagram%s received\n"); - p(ifs6_out_mcast, "\t%ju multicast datagram%s sent\n"); - - end: - close(s); + xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name); + + xo_open_instance("ip6-interface-statistics"); + xo_emit("{ke:name/%s}", ifr.ifr_name); + + p(ifs6_in_receive, "\t{:received-packets/%ju} " + "{N:/total input datagram%s}\n"); + p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} " + "{N:/datagram%s with invalid header received}\n"); + p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} " + "{N:/datagram%s exceeded MTU received}\n"); + p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} " + "{N:/datagram%s with no route received}\n"); + p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} " + "{N:/datagram%s with invalid dst received}\n"); + p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} " + "{N:/datagram%s with unknown proto received}\n"); + p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} " + "{N:/truncated datagram%s received}\n"); + p(ifs6_in_discard, "\t{:dropped-discarded/%ju} " + "{N:/input datagram%s discarded}\n"); + p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} " + "{N:/datagram%s delivered to an upper layer protocol}\n"); + p(ifs6_out_forward, "\t{:sent-forwarded/%ju} " + "{N:/datagram%s forwarded to this interface}\n"); + p(ifs6_out_request, "\t{:sent-packets/%ju} " + "{N:/datagram%s sent from an upper layer protocol}\n"); + p(ifs6_out_discard, "\t{:discard-packets/%ju} " + "{N:/total discarded output datagram%s}\n"); + p(ifs6_out_fragok, "\t{:discard-fragments/%ju} " + "{N:/output datagram%s fragmented}\n"); + p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} " + "{N:/output datagram%s failed on fragment}\n"); + p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} " + "{N:/output datagram%s succeeded on fragment}\n"); + p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} " + "{N:/incoming datagram%s fragmented}\n"); + p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} " + "{N:/datagram%s reassembled}\n"); + p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} " + "{N:/datagram%s failed on reassembly}\n"); + p(ifs6_in_mcast, "\t{:received-multicast/%ju} " + "{N:/multicast datagram%s received}\n"); + p(ifs6_out_mcast, "\t{:sent-multicast/%ju} " + "{N:/multicast datagram%s sent}\n"); + + end: + xo_close_instance("ip6-interface-statistics"); + close(s); #undef p -#undef p_5 } static const char *icmp6names[] = { @@ -854,76 +970,118 @@ icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) - warn("sysctl: net.inet6.icmp6.stats"); + xo_warn("sysctl: net.inet6.icmp6.stats"); return; } } else kread_counters(off, &icmp6stat, len); - printf("%s:\n", name); + xo_emit("{T:/%s}:\n", name); + xo_open_container(name); #define p(f, m) if (icmp6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) + xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f)) #define p_5(f, m) if (icmp6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)icmp6stat.f) + xo_emit(m, (uintmax_t)icmp6stat.f) - p(icp6s_error, "\t%ju call%s to icmp6_error\n"); - p(icp6s_canterror, - "\t%ju error%s not generated in response to an icmp6 message\n"); - p(icp6s_toofreq, - "\t%ju error%s not generated because of rate limitation\n"); + p(icp6s_error, "\t{:icmp6-calls/%ju} " + "{N:/call%s to icmp6_error}\n"); + p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} " + "{N:/error%s not generated in response to an icmp6 message}\n"); + p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} " + "{N:/error%s not generated because of rate limitation}\n"); #define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0])) for (first = 1, i = 0; i < NELEM; i++) if (icmp6stat.icp6s_outhist[i] != 0) { if (first) { - printf("\tOutput histogram:\n"); + xo_open_list("output-histogram"); + xo_emit("\t{T:Output histogram}:\n"); first = 0; } - printf("\t\t%s: %ju\n", icmp6names[i], + xo_open_instance("output-histogram"); + xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", + icmp6names[i], (uintmax_t)icmp6stat.icp6s_outhist[i]); + xo_close_instance("output-histogram"); } + if (!first) + xo_close_list("output-histogram"); #undef NELEM - p(icp6s_badcode, "\t%ju message%s with bad code fields\n"); - p(icp6s_tooshort, "\t%ju message%s < minimum length\n"); - p(icp6s_checksum, "\t%ju bad checksum%s\n"); - p(icp6s_badlen, "\t%ju message%s with bad length\n"); + + p(icp6s_badcode, "\t{:dropped-bad-code/%ju} " + "{N:/message%s with bad code fields}\n"); + p(icp6s_tooshort, "\t{:dropped-too-short/%ju} " + "{N:/message%s < minimum length}\n"); + p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} " + "{N:/bad checksum%s}\n"); + p(icp6s_badlen, "\t{:dropped-bad-length/%ju} " + "{N:/message%s with bad length}\n"); #define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0])) for (first = 1, i = 0; i < NELEM; i++) if (icmp6stat.icp6s_inhist[i] != 0) { if (first) { - printf("\tInput histogram:\n"); + xo_open_list("input-histogram"); + xo_emit("\t{T:Input histogram}:\n"); first = 0; } - printf("\t\t%s: %ju\n", icmp6names[i], + xo_open_instance("input-histogram"); + xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", + icmp6names[i], (uintmax_t)icmp6stat.icp6s_inhist[i]); + xo_close_instance("input-histogram"); } + if (!first) + xo_close_list("input-histogram"); #undef NELEM - printf("\tHistogram of error messages to be generated:\n"); - p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n"); - p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n"); - p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n"); - p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n"); - p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n"); - p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n"); - p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n"); - p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n"); - p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n"); - p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n"); - p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n"); - p_5(icp6s_oredirect, "\t\t%ju redirect\n"); - p_5(icp6s_ounknown, "\t\t%ju unknown\n"); - - p(icp6s_reflect, "\t%ju message response%s generated\n"); - p(icp6s_nd_toomanyopt, "\t%ju message%s with too many ND options\n"); - p(icp6s_nd_badopt, "\t%ju message%s with bad ND options\n"); - p(icp6s_badns, "\t%ju bad neighbor solicitation message%s\n"); - p(icp6s_badna, "\t%ju bad neighbor advertisement message%s\n"); - p(icp6s_badrs, "\t%ju bad router solicitation message%s\n"); - p(icp6s_badra, "\t%ju bad router advertisement message%s\n"); - p(icp6s_badredirect, "\t%ju bad redirect message%s\n"); - p(icp6s_pmtuchg, "\t%ju path MTU change%s\n"); + xo_emit("\t{T:Histogram of error messages to be generated}:\n"); + xo_open_container("errors"); + p_5(icp6s_odst_unreach_noroute, "\t\t{:no-route/%ju} " + "{N:/no route}\n"); + p_5(icp6s_odst_unreach_admin, "\t\t{:admin-prohibited/%ju} " + "{N:/administratively prohibited}\n"); + p_5(icp6s_odst_unreach_beyondscope, "\t\t{:beyond-scope/%ju} " + "{N:/beyond scope}\n"); + p_5(icp6s_odst_unreach_addr, "\t\t{:address-unreachable/%ju} " + "{N:/address unreachable}\n"); + p_5(icp6s_odst_unreach_noport, "\t\t{:port-unreachable/%ju} " + "{N:/port unreachable}\n"); + p_5(icp6s_opacket_too_big, "\t\t{:packet-too-big/%ju} " + "{N:/packet too big}\n"); + p_5(icp6s_otime_exceed_transit, "\t\t{:time-exceed-transmit/%ju} " + "{N:/time exceed transit}\n"); + p_5(icp6s_otime_exceed_reassembly, "\t\t{:time-exceed-reassembly/%ju} " + "{N:/time exceed reassembly}\n"); + p_5(icp6s_oparamprob_header, "\t\t{:bad-header/%ju} " + "{N:/erroneous header field}\n"); + p_5(icp6s_oparamprob_nextheader, "\t\t{:bad-next-header/%ju} " + "{N:/unrecognized next header}\n"); + p_5(icp6s_oparamprob_option, "\t\t{:bad-option/%ju} " + "{N:/unrecognized option}\n"); + p_5(icp6s_oredirect, "\t\t{:redirects/%ju} " + "{N:/redirect}\n"); + p_5(icp6s_ounknown, "\t\t{:unknown/%ju} {N:unknown}\n"); + + p(icp6s_reflect, "\t{:reflect/%ju} " + "{N:/message response%s generated}\n"); + p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} " + "{N:/message%s with too many ND options}\n"); + p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} " + "{N:/message%s with bad ND options}\n"); + p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} " + "{N:/bad neighbor solicitation message%s}\n"); + p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} " + "{N:/bad neighbor advertisement message%s}\n"); + p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} " + "{N:/bad router solicitation message%s}\n"); + p(icp6s_badra, "\t{:bad-router-advertisement/%ju} " + "{N:/bad router advertisement message%s}\n"); + p(icp6s_badredirect, "\t{:bad-redirect/%ju} " + "{N:/bad redirect message%s}\n"); + xo_close_container("errors"); + p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n"); #undef p #undef p_5 + xo_close_container(name); } /* @@ -934,61 +1092,102 @@ icmp6_ifstats(char *ifname) { struct in6_ifreq ifr; int s; -#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, plural(ifr.ifr_ifru.ifru_icmp6stat.f)) -#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) + +#define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ + xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ + plural(ifr.ifr_ifru.ifru_icmp6stat.f)) +#define p2(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ + xo_emit(m, (uintmax_t)ifr.ifr_ifru.ifru_icmp6stat.f, \ + pluralies(ifr.ifr_ifru.ifru_icmp6stat.f)) if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - perror("Warning: socket(AF_INET6)"); + xo_warn("Warning: socket(AF_INET6)"); return; } strcpy(ifr.ifr_name, ifname); if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { if (errno != EPFNOSUPPORT) - perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); + xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); goto end; } - printf("icmp6 on %s:\n", ifr.ifr_name); - p(ifs6_in_msg, "\t%ju total input message%s\n"); - p(ifs6_in_error, "\t%ju total input error message%s\n"); - p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n"); - p(ifs6_in_adminprohib, "\t%ju input administratively prohibited error%s\n"); - p(ifs6_in_timeexceed, "\t%ju input time exceeded error%s\n"); - p(ifs6_in_paramprob, "\t%ju input parameter problem error%s\n"); - p(ifs6_in_pkttoobig, "\t%ju input packet too big error%s\n"); - p(ifs6_in_echo, "\t%ju input echo request%s\n"); - p2(ifs6_in_echoreply, "\t%ju input echo repl%s\n"); - p(ifs6_in_routersolicit, "\t%ju input router solicitation%s\n"); - p(ifs6_in_routeradvert, "\t%ju input router advertisement%s\n"); - p(ifs6_in_neighborsolicit, "\t%ju input neighbor solicitation%s\n"); - p(ifs6_in_neighboradvert, "\t%ju input neighbor advertisement%s\n"); - p(ifs6_in_redirect, "\t%ju input redirect%s\n"); - p2(ifs6_in_mldquery, "\t%ju input MLD quer%s\n"); - p(ifs6_in_mldreport, "\t%ju input MLD report%s\n"); - p(ifs6_in_mlddone, "\t%ju input MLD done%s\n"); - - p(ifs6_out_msg, "\t%ju total output message%s\n"); - p(ifs6_out_error, "\t%ju total output error message%s\n"); - p(ifs6_out_dstunreach, "\t%ju output destination unreachable error%s\n"); - p(ifs6_out_adminprohib, "\t%ju output administratively prohibited error%s\n"); - p(ifs6_out_timeexceed, "\t%ju output time exceeded error%s\n"); - p(ifs6_out_paramprob, "\t%ju output parameter problem error%s\n"); - p(ifs6_out_pkttoobig, "\t%ju output packet too big error%s\n"); - p(ifs6_out_echo, "\t%ju output echo request%s\n"); - p2(ifs6_out_echoreply, "\t%ju output echo repl%s\n"); - p(ifs6_out_routersolicit, "\t%ju output router solicitation%s\n"); - p(ifs6_out_routeradvert, "\t%ju output router advertisement%s\n"); - p(ifs6_out_neighborsolicit, "\t%ju output neighbor solicitation%s\n"); - p(ifs6_out_neighboradvert, "\t%ju output neighbor advertisement%s\n"); - p(ifs6_out_redirect, "\t%ju output redirect%s\n"); - p2(ifs6_out_mldquery, "\t%ju output MLD quer%s\n"); - p(ifs6_out_mldreport, "\t%ju output MLD report%s\n"); - p(ifs6_out_mlddone, "\t%ju output MLD done%s\n"); - - end: + xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name); + + xo_open_instance("icmp6-interface-statistics"); + xo_emit("{ke:name/%s}", ifr.ifr_name); + p(ifs6_in_msg, "\t{:received-packets/%ju} " + "{N:/total input message%s}\n"); + p(ifs6_in_error, "\t{:received-errors/%ju} " + "{N:/total input error message%s}\n"); + p(ifs6_in_dstunreach, "\t{:received-destination-unreachable/%ju} " + "{N:/input destination unreachable error%s}\n"); + p(ifs6_in_adminprohib, "\t{:received-admin-prohibited/%ju} " + "{N:/input administratively prohibited error%s}\n"); + p(ifs6_in_timeexceed, "\t{:received-time-exceeded/%ju} " + "{N:/input time exceeded error%s}\n"); + p(ifs6_in_paramprob, "\t{:received-bad-parameter/%ju} " + "{N:/input parameter problem error%s}\n"); + p(ifs6_in_pkttoobig, "\t{:received-packet-too-big/%ju} " + "{N:/input packet too big error%s}\n"); + p(ifs6_in_echo, "\t{:received-echo-requests/%ju} " + "{N:/input echo request%s}\n"); + p2(ifs6_in_echoreply, "\t{:received-echo-replies/%ju} " + "{N:/input echo repl%s}\n"); + p(ifs6_in_routersolicit, "\t{:received-router-solicitation/%ju} " + "{N:/input router solicitation%s}\n"); + p(ifs6_in_routeradvert, "\t{:received-router-advertisement/%ju} " + "{N:/input router advertisement%s}\n"); + p(ifs6_in_neighborsolicit, "\t{:received-neighbor-solicitation/%ju} " + "{N:/input neighbor solicitation%s}\n"); + p(ifs6_in_neighboradvert, "\t{:received-neighbor-advertisement/%ju} " + "{N:/input neighbor advertisement%s}\n"); + p(ifs6_in_redirect, "\t{received-redirects/%ju} " + "{N:/input redirect%s}\n"); + p2(ifs6_in_mldquery, "\t{:received-mld-queries/%ju} " + "{N:/input MLD quer%s}\n"); + p(ifs6_in_mldreport, "\t{:received-mld-reports/%ju} " + "{N:/input MLD report%s}\n"); + p(ifs6_in_mlddone, "\t{:received-mld-done/%ju} " + "{N:/input MLD done%s}\n"); + + p(ifs6_out_msg, "\t{:sent-packets/%ju} " + "{N:/total output message%s}\n"); + p(ifs6_out_error, "\t{:sent-errors/%ju} " + "{N:/total output error message%s}\n"); + p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} " + "{N:/output destination unreachable error%s}\n"); + p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} " + "{N:/output administratively prohibited error%s}\n"); + p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} " + "{N:/output time exceeded error%s}\n"); + p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} " + "{N:/output parameter problem error%s}\n"); + p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} " + "{N:/output packet too big error%s}\n"); + p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} " + "{N:/output echo request%s}\n"); + p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} " + "{N:/output echo repl%s}\n"); + p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} " + "{N:/output router solicitation%s}\n"); + p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} " + "{N:/output router advertisement%s}\n"); + p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} " + "{N:/output neighbor solicitation%s}\n"); + p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} " + "{N:/output neighbor advertisement%s}\n"); + p(ifs6_out_redirect, "\t{:sent-redirects/%ju} " + "{N:/output redirect%s}\n"); + p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} " + "{N:/output MLD quer%s}\n"); + p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} " + "{N:/output MLD report%s}\n"); + p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} " + "{N:/output MLD done%s}\n"); + +end: + xo_close_instance("icmp6-interface-statistics"); close(s); #undef p } @@ -1008,7 +1207,7 @@ pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) - warn("sysctl: net.inet6.pim.stats"); + xo_warn("sysctl: net.inet6.pim.stats"); return; } } else { @@ -1017,18 +1216,28 @@ pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) kread(off, &pim6stat, len); } - printf("%s:\n", name); + xo_emit("{T:/%s}:\n", name); + xo_open_container(name); #define p(f, m) if (pim6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) - p(pim6s_rcv_total, "\t%ju message%s received\n"); - p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n"); - p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n"); - p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n"); - p(pim6s_rcv_registers, "\t%ju register%s received\n"); - p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n"); - p(pim6s_snd_registers, "\t%ju register%s sent\n"); + xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f)) + + p(pim6s_rcv_total, "\t{:received-packets/%ju} " + "{N:/message%s received}\n"); + p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} " + "{N:/message%s received with too few bytes}\n"); + p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " + "{N:/message%s received with bad checksum}\n"); + p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} " + "{N:/message%s received with bad version}\n"); + p(pim6s_rcv_registers, "\t{:received-registers/%ju} " + "{N:/register%s received}\n"); + p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} " + "{N:/bad register%s received}\n"); + p(pim6s_snd_registers, "\t{:sent-registers/%ju} " + "{N:/register%s sent}\n"); #undef p + xo_close_container(name); } /* @@ -1048,33 +1257,42 @@ rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) - warn("sysctl: net.inet6.ip6.rip6stats"); + xo_warn("sysctl: net.inet6.ip6.rip6stats"); return; } } else kread_counters(off, &rip6stat, len); - printf("%s:\n", name); + xo_emit("{T:/%s}:\n", name); + xo_open_container(name); #define p(f, m) if (rip6stat.f || sflag <= 1) \ - printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) - p(rip6s_ipackets, "\t%ju message%s received\n"); - p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n"); - p(rip6s_badsum, "\t%ju message%s with bad checksum\n"); - p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n"); - p(rip6s_nosockmcast, - "\t%ju multicast message%s dropped due to no socket\n"); - p(rip6s_fullsock, - "\t%ju message%s dropped due to full socket buffers\n"); + xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f)) + + p(rip6s_ipackets, "\t{:received-packets/%ju} " + "{N:/message%s received}\n"); + p(rip6s_isum, "\t{:input-checksum-computation/%ju} " + "{N:/checksum calculation%s on inbound}\n"); + p(rip6s_badsum, "\t{:received-bad-checksum/%ju} " + "{N:/message%s with bad checksum}\n"); + p(rip6s_nosock, "\t{:dropped-no-socket/%ju} " + "{N:/message%s dropped due to no socket}\n"); + p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} " + "{N:/multicast message%s dropped due to no socket}\n"); + p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} " + "{N:/message%s dropped due to full socket buffers}\n"); delivered = rip6stat.rip6s_ipackets - rip6stat.rip6s_badsum - rip6stat.rip6s_nosock - rip6stat.rip6s_nosockmcast - rip6stat.rip6s_fullsock; if (delivered || sflag <= 1) - printf("\t%ju delivered\n", (uintmax_t)delivered); - p(rip6s_opackets, "\t%ju datagram%s output\n"); + xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n", + (uintmax_t)delivered); + p(rip6s_opackets, "\t{:sent-packets/%ju} " + "{N:/datagram%s output}\n"); #undef p + xo_close_container(name); } /* @@ -1092,14 +1310,18 @@ rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) }; void -inet6print(struct in6_addr *in6, int port, const char *proto, int numeric) +inet6print(const char *container, struct in6_addr *in6, int port, + const char *proto, int numeric) { struct servent *sp = 0; char line[80], *cp; int width; - sprintf(line, "%.*s.", Wflag ? 39 : - (Aflag && !numeric) ? 12 : 16, inet6name(in6)); + if (container) + xo_open_container(container); + + sprintf(line, "%.*s.", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16, + inet6name(in6)); cp = strchr(line, '\0'); if (!numeric && port) GETSERVBYPORT6(port, proto, sp); @@ -1108,7 +1330,15 @@ inet6print(struct in6_addr *in6, int port, const char *proto, int numeric) else sprintf(cp, "%d", ntohs((u_short)port)); width = Wflag ? 45 : Aflag ? 18 : 22; - printf("%-*.*s ", width, width, line); + + xo_emit("{d:target/%-*.*s} ", width, width, line); + + int alen = cp - line - 1, plen = strlen(cp) - 1; + xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen, + plen, cp); + + if (container) + xo_close_container(container); } /* @@ -1142,7 +1372,7 @@ inet6name(struct in6_addr *in6p) memset(&sin6, 0, sizeof(sin6)); memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p)); sin6.sin6_family = AF_INET6; - /* XXX: in6p.s6_addr[2] can contain scopeid. */ + /* XXX: in6p.s6_addr[2] can contain scopeid. */ in6_fillscopeid(&sin6); flags = (numeric_addr) ? NI_NUMERICHOST : 0; error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, diff --git a/usr.bin/netstat/ipsec.c b/usr.bin/netstat/ipsec.c index b4014ad..137a26c 100644 --- a/usr.bin/netstat/ipsec.c +++ b/usr.bin/netstat/ipsec.c @@ -107,8 +107,10 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> +#include <stdbool.h> #include <string.h> #include <unistd.h> +#include <libxo/xo.h> #include "netstat.h" #ifdef IPSEC @@ -171,27 +173,39 @@ static void print_ipsecstats(const struct ipsecstat *ipsecstat); static void print_ipsecstats(const struct ipsecstat *ipsecstat) { + xo_open_container("ipsec-statistics"); + #define p(f, m) if (ipsecstat->f || sflag <= 1) \ - printf(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f)) - p(ips_in_polvio, "\t%ju inbound packet%s violated process " - "security policy\n"); - p(ips_in_nomem, "\t%ju inbound packet%s failed due to " - "insufficient memory\n"); - p(ips_in_inval, "\t%ju invalid inbound packet%s\n"); - p(ips_out_polvio, "\t%ju outbound packet%s violated process " - "security policy\n"); - p(ips_out_nosa, "\t%ju outbound packet%s with no SA available\n"); - p(ips_out_nomem, "\t%ju outbound packet%s failed due to " - "insufficient memory\n"); - p(ips_out_noroute, "\t%ju outbound packet%s with no route " - "available\n"); - p(ips_out_inval, "\t%ju invalid outbound packet%s\n"); - p(ips_out_bundlesa, "\t%ju outbound packet%s with bundled SAs\n"); - p(ips_mbcoalesced, "\t%ju mbuf%s coalesced during clone\n"); - p(ips_clcoalesced, "\t%ju cluster%s coalesced during clone\n"); - p(ips_clcopied, "\t%ju cluster%s copied during clone\n"); - p(ips_mbinserted, "\t%ju mbuf%s inserted during makespace\n"); + xo_emit(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f)) + + p(ips_in_polvio, "\t{:dropped-policy-violation/%ju} " + "{N:/inbound packet%s violated process security policy}\n"); + p(ips_in_nomem, "\t{:dropped-no-memory/%ju} " + "{N:/inbound packet%s failed due to insufficient memory}\n"); + p(ips_in_inval, "\t{:dropped-invalid/%ju} " + "{N:/invalid inbound packet%s}\n"); + p(ips_out_polvio, "\t{:discarded-policy-violation/%ju} " + "{N:/outbound packet%s violated process security policy}\n"); + p(ips_out_nosa, "\t{:discarded-no-sa/%ju} " + "{N:/outbound packet%s with no SA available}\n"); + p(ips_out_nomem, "\t{:discarded-no-memory/%ju} " + "{N:/outbound packet%s failed due to insufficient memory}\n"); + p(ips_out_noroute, "\t{:discarded-no-route/%ju} " + "{N:/outbound packet%s with no route available}\n"); + p(ips_out_inval, "\t{:discarded-invalid/%ju} " + "{N:/invalid outbound packet%s}\n"); + p(ips_out_bundlesa, "\t{:send-bundled-sa/%ju} " + "{N:/outbound packet%s with bundled SAs}\n"); + p(ips_mbcoalesced, "\t{:mbufs-coalesced-during-clone/%ju} " + "{N:/mbuf%s coalesced during clone}\n"); + p(ips_clcoalesced, "\t{:clusters-coalesced-during-clone/%ju} " + "{N:/cluster%s coalesced during clone}\n"); + p(ips_clcopied, "\t{:clusters-copied-during-clone/%ju} " + "{N:/cluster%s copied during clone}\n"); + p(ips_mbinserted, "\t{:mbufs-inserted/%ju} " + "{N:/mbuf%s inserted during makespace}\n"); #undef p + xo_close_container("ipsec-statistics"); } void @@ -201,15 +215,13 @@ ipsec_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (off == 0) return; - printf ("%s:\n", name); + xo_emit("{T:/%s}:\n", name); kread_counters(off, (char *)&ipsecstat, sizeof(ipsecstat)); print_ipsecstats(&ipsecstat); } -static void ipsec_hist_new(const uint64_t *hist, size_t histmax, - const struct val2str *name, const char *title); static void print_ahstats(const struct ahstat *ahstat); static void print_espstats(const struct espstat *espstat); static void print_ipcompstats(const struct ipcompstat *ipcompstat); @@ -219,7 +231,7 @@ static void print_ipcompstats(const struct ipcompstat *ipcompstat); */ static void ipsec_hist_new(const uint64_t *hist, size_t histmax, - const struct val2str *name, const char *title) + const struct val2str *name, const char *title, const char *cname) { int first; size_t proto; @@ -230,54 +242,72 @@ ipsec_hist_new(const uint64_t *hist, size_t histmax, if (hist[proto] <= 0) continue; if (first) { - printf("\t%s histogram:\n", title); + xo_open_list(cname); + xo_emit("\t{T:/%s histogram}:\n", title); first = 0; } + xo_open_instance(cname); for (p = name; p && p->str; p++) { if (p->val == (int)proto) break; } if (p && p->str) { - printf("\t\t%s: %ju\n", p->str, + xo_emit("\t\t{k:name}: {:count/%ju}\n", p->str, (uintmax_t)hist[proto]); } else { - printf("\t\t#%lu: %ju\n", (unsigned long)proto, - (uintmax_t)hist[proto]); + xo_emit("\t\t#{k:name/%lu}: {:count/%ju}\n", + (unsigned long)proto, (uintmax_t)hist[proto]); } + xo_close_instance(cname); } + if (!first) + xo_close_list(cname); } static void print_ahstats(const struct ahstat *ahstat) { -#define p(f, m) if (ahstat->f || sflag <= 1) \ - printf("\t%ju" m, (uintmax_t)ahstat->f, plural(ahstat->f)) -#define hist(f, n, t) \ - ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t)); - - p(ahs_hdrops, " packet%s shorter than header shows\n"); - p(ahs_nopf, " packet%s dropped; protocol family not supported\n"); - p(ahs_notdb, " packet%s dropped; no TDB\n"); - p(ahs_badkcr, " packet%s dropped; bad KCR\n"); - p(ahs_qfull, " packet%s dropped; queue full\n"); - p(ahs_noxform, " packet%s dropped; no transform\n"); - p(ahs_wrap, " replay counter wrap%s\n"); - p(ahs_badauth, " packet%s dropped; bad authentication detected\n"); - p(ahs_badauthl, " packet%s dropped; bad authentication length\n"); - p(ahs_replay, " possible replay packet%s detected\n"); - p(ahs_input, " packet%s in\n"); - p(ahs_output, " packet%s out\n"); - p(ahs_invalid, " packet%s dropped; invalid TDB\n"); - p(ahs_ibytes, " byte%s in\n"); - p(ahs_obytes, " byte%s out\n"); - p(ahs_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); - p(ahs_pdrops, " packet%s blocked due to policy\n"); - p(ahs_crypto, " crypto processing failure%s\n"); - p(ahs_tunnel, " tunnel sanity check failure%s\n"); - hist(ahstat->ahs_hist, ipsec_ahnames, "AH output"); + xo_open_container("ah-statictics"); + +#define p(f, n, m) if (ahstat->f || sflag <= 1) \ + xo_emit("\t{:" n "/%ju} {N:/" m "}\n", \ + (uintmax_t)ahstat->f, plural(ahstat->f)) +#define hist(f, n, t, c) \ + ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t), (c)) + + p(ahs_hdrops, "dropped-short-header", + "packet%s shorter than header shows"); + p(ahs_nopf, "dropped-bad-protocol", + "packet%s dropped; protocol family not supported"); + p(ahs_notdb, "dropped-no-tdb", "packet%s dropped; no TDB"); + p(ahs_badkcr, "dropped-bad-kcr", "packet%s dropped; bad KCR"); + p(ahs_qfull, "dropped-queue-full", "packet%s dropped; queue full"); + p(ahs_noxform, "dropped-no-transform", + "packet%s dropped; no transform"); + p(ahs_wrap, "replay-counter-wraps", "replay counter wrap%s"); + p(ahs_badauth, "dropped-bad-auth", + "packet%s dropped; bad authentication detected"); + p(ahs_badauthl, "dropped-bad-auth-level", + "packet%s dropped; bad authentication length"); + p(ahs_replay, "possile-replay-detected", + "possible replay packet%s detected"); + p(ahs_input, "received-packets", "packet%s in"); + p(ahs_output, "send-packets", "packet%s out"); + p(ahs_invalid, "dropped-bad-tdb", "packet%s dropped; invalid TDB"); + p(ahs_ibytes, "received-bytes", "byte%s in"); + p(ahs_obytes, "send-bytes", "byte%s out"); + p(ahs_toobig, "dropped-too-large", + "packet%s dropped; larger than IP_MAXPACKET"); + p(ahs_pdrops, "dropped-policy-violation", + "packet%s blocked due to policy"); + p(ahs_crypto, "crypto-failures", "crypto processing failure%s"); + p(ahs_tunnel, "tunnel-failures", "tunnel sanity check failure%s"); + hist(ahstat->ahs_hist, ipsec_ahnames, + "AH output", "ah-output-histogram"); #undef p #undef hist + xo_close_container("ah-statictics"); } void @@ -287,7 +317,7 @@ ah_stats(u_long off, const char *name, int family __unused, int proto __unused) if (off == 0) return; - printf ("%s:\n", name); + xo_emit("{T:/%s}:\n", name); kread_counters(off, (char *)&ahstat, sizeof(ahstat)); print_ahstats(&ahstat); @@ -296,35 +326,47 @@ ah_stats(u_long off, const char *name, int family __unused, int proto __unused) static void print_espstats(const struct espstat *espstat) { -#define p(f, m) if (espstat->f || sflag <= 1) \ - printf("\t%ju" m, (uintmax_t)espstat->f, plural(espstat->f)) -#define hist(f, n, t) \ - ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t)); - - p(esps_hdrops, " packet%s shorter than header shows\n"); - p(esps_nopf, " packet%s dropped; protocol family not supported\n"); - p(esps_notdb, " packet%s dropped; no TDB\n"); - p(esps_badkcr, " packet%s dropped; bad KCR\n"); - p(esps_qfull, " packet%s dropped; queue full\n"); - p(esps_noxform, " packet%s dropped; no transform\n"); - p(esps_badilen, " packet%s dropped; bad ilen\n"); - p(esps_wrap, " replay counter wrap%s\n"); - p(esps_badenc, " packet%s dropped; bad encryption detected\n"); - p(esps_badauth, " packet%s dropped; bad authentication detected\n"); - p(esps_replay, " possible replay packet%s detected\n"); - p(esps_input, " packet%s in\n"); - p(esps_output, " packet%s out\n"); - p(esps_invalid, " packet%s dropped; invalid TDB\n"); - p(esps_ibytes, " byte%s in\n"); - p(esps_obytes, " byte%s out\n"); - p(esps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); - p(esps_pdrops, " packet%s blocked due to policy\n"); - p(esps_crypto, " crypto processing failure%s\n"); - p(esps_tunnel, " tunnel sanity check failure%s\n"); - hist(espstat->esps_hist, ipsec_espnames, "ESP output"); + xo_open_container("esp-statictics"); +#define p(f, n, m) if (espstat->f || sflag <= 1) \ + xo_emit("\t{:" n "/%ju} {N:/" m "}\n", \ + (uintmax_t)espstat->f, plural(espstat->f)) +#define hist(f, n, t, c) \ + ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t), (c)); + + p(esps_hdrops, "dropped-short-header", + "packet%s shorter than header shows"); + p(esps_nopf, "dropped-bad-protocol", + "packet%s dropped; protocol family not supported"); + p(esps_notdb, "dropped-no-tdb", "packet%s dropped; no TDB"); + p(esps_badkcr, "dropped-bad-kcr", "packet%s dropped; bad KCR"); + p(esps_qfull, "dropped-queue-full", "packet%s dropped; queue full"); + p(esps_noxform, "dropped-no-transform", + "packet%s dropped; no transform"); + p(esps_badilen, "dropped-bad-length", "packet%s dropped; bad ilen"); + p(esps_wrap, "replay-counter-wraps", "replay counter wrap%s"); + p(esps_badenc, "dropped-bad-crypto", + "packet%s dropped; bad encryption detected"); + p(esps_badauth, "dropped-bad-auth", + "packet%s dropped; bad authentication detected"); + p(esps_replay, "possible-replay-detected", + "possible replay packet%s detected"); + p(esps_input, "received-packets", "packet%s in"); + p(esps_output, "sent-packets", "packet%s out"); + p(esps_invalid, "dropped-bad-tdb", "packet%s dropped; invalid TDB"); + p(esps_ibytes, "receieve-bytes", "byte%s in"); + p(esps_obytes, "sent-bytes", "byte%s out"); + p(esps_toobig, "dropped-too-large", + "packet%s dropped; larger than IP_MAXPACKET"); + p(esps_pdrops, "dropped-policy-violation", + "packet%s blocked due to policy"); + p(esps_crypto, "crypto-failures", "crypto processing failure%s"); + p(esps_tunnel, "tunnel-failures", "tunnel sanity check failure%s"); + hist(espstat->esps_hist, ipsec_espnames, + "ESP output", "esp-output-histogram"); #undef p #undef hist + xo_close_container("esp-statictics"); } void @@ -334,7 +376,7 @@ esp_stats(u_long off, const char *name, int family __unused, int proto __unused) if (off == 0) return; - printf ("%s:\n", name); + xo_emit("{T:/%s}:\n", name); kread_counters(off, (char *)&espstat, sizeof(espstat)); print_espstats(&espstat); @@ -343,32 +385,44 @@ esp_stats(u_long off, const char *name, int family __unused, int proto __unused) static void print_ipcompstats(const struct ipcompstat *ipcompstat) { -#define p(f, m) if (ipcompstat->f || sflag <= 1) \ - printf("\t%ju" m, (uintmax_t)ipcompstat->f, plural(ipcompstat->f)) -#define hist(f, n, t) \ - ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t)); - - p(ipcomps_hdrops, " packet%s shorter than header shows\n"); - p(ipcomps_nopf, " packet%s dropped; protocol family not supported\n"); - p(ipcomps_notdb, " packet%s dropped; no TDB\n"); - p(ipcomps_badkcr, " packet%s dropped; bad KCR\n"); - p(ipcomps_qfull, " packet%s dropped; queue full\n"); - p(ipcomps_noxform, " packet%s dropped; no transform\n"); - p(ipcomps_wrap, " replay counter wrap%s\n"); - p(ipcomps_input, " packet%s in\n"); - p(ipcomps_output, " packet%s out\n"); - p(ipcomps_invalid, " packet%s dropped; invalid TDB\n"); - p(ipcomps_ibytes, " byte%s in\n"); - p(ipcomps_obytes, " byte%s out\n"); - p(ipcomps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); - p(ipcomps_pdrops, " packet%s blocked due to policy\n"); - p(ipcomps_crypto, " crypto processing failure%s\n"); - hist(ipcompstat->ipcomps_hist, ipsec_compnames, "COMP output"); - p(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n"); - p(ipcomps_uncompr, " packet%s sent uncompressed; compression was useless\n"); + xo_open_container("ipcomp-statictics"); + +#define p(f, n, m) if (ipcompstat->f || sflag <= 1) \ + xo_emit("\t{:" n "/%ju} {N:/" m "}\n", \ + (uintmax_t)ipcompstat->f, plural(ipcompstat->f)) +#define hist(f, n, t, c) \ + ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t), (c)); + + p(ipcomps_hdrops, "dropped-short-header", + "packet%s shorter than header shows"); + p(ipcomps_nopf, "dropped-bad-protocol", + "packet%s dropped; protocol family not supported"); + p(ipcomps_notdb, "dropped-no-tdb", "packet%s dropped; no TDB"); + p(ipcomps_badkcr, "dropped-bad-kcr", "packet%s dropped; bad KCR"); + p(ipcomps_qfull, "dropped-queue-full", "packet%s dropped; queue full"); + p(ipcomps_noxform, "dropped-no-transform", + "packet%s dropped; no transform"); + p(ipcomps_wrap, "replay-counter-wraps", "replay counter wrap%s"); + p(ipcomps_input, "receieve-packets", "packet%s in"); + p(ipcomps_output, "sent-packets", "packet%s out"); + p(ipcomps_invalid, "dropped-bad-tdb", "packet%s dropped; invalid TDB"); + p(ipcomps_ibytes, "receieved-bytes", "byte%s in"); + p(ipcomps_obytes, "sent-bytes", "byte%s out"); + p(ipcomps_toobig, "dropped-too-large", + "packet%s dropped; larger than IP_MAXPACKET"); + p(ipcomps_pdrops, "dropped-policy-violation", + "packet%s blocked due to policy"); + p(ipcomps_crypto, "crypto-failure", "crypto processing failure%s"); + hist(ipcompstat->ipcomps_hist, ipsec_compnames, + "COMP output", "comp-output-histogram"); + p(ipcomps_threshold, "sent-uncompressed-small-packets", + "packet%s sent uncompressed; size < compr. algo. threshold"); + p(ipcomps_uncompr, "sent-uncompressed-useless-packets", + "packet%s sent uncompressed; compression was useless"); #undef p #undef hist + xo_close_container("ipcomp-statictics"); } void @@ -379,7 +433,7 @@ ipcomp_stats(u_long off, const char *name, int family __unused, if (off == 0) return; - printf ("%s:\n", name); + xo_emit("{T:/%s}:\n", name); kread_counters(off, (char *)&ipcompstat, sizeof(ipcompstat)); print_ipcompstats(&ipcompstat); diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 8fc2b4e..acc27f7 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -65,9 +65,11 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <unistd.h> #include "netstat.h" +#include <libxo/xo.h> static struct nlist nl[] = { #define N_RTSTAT 0 @@ -146,7 +148,7 @@ static struct nlist nl[] = { { .n_name = "_sctpstat" }, #define N_MFCTABLESIZE 37 { .n_name = "_mfctablesize" }, -#define N_ARPSTAT 38 +#define N_ARPSTAT 38 { .n_name = "_arpstat" }, #define N_UNP_SPHEAD 39 { .n_name = "unp_sphead" }, @@ -271,7 +273,7 @@ struct protox *protoprotox[] = { #endif NULL }; -static void printproto(struct protox *, const char *); +static void printproto(struct protox *, const char *, bool *); static void usage(void); static struct protox *name2protox(const char *); static struct protox *knownname(const char *); @@ -317,9 +319,12 @@ main(int argc, char *argv[]) int ch; int fib = -1; char *endptr; + bool first = true; af = AF_UNSPEC; + argc = xo_parse_args(argc, argv); + while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz")) != -1) switch(ch) { @@ -356,7 +361,7 @@ main(int argc, char *argv[]) fib = strtol(optarg, &endptr, 0); if (*endptr != '\0' || (fib == 0 && (errno == EINVAL || errno == ERANGE))) - errx(1, "%s: invalid fib", optarg); + xo_errx(1, "%s: invalid fib", optarg); break; case 'f': if (strcmp(optarg, "inet") == 0) @@ -379,7 +384,8 @@ main(int argc, char *argv[]) else if (strcmp(optarg, "link") == 0) af = AF_LINK; else { - errx(1, "%s: unknown address family", optarg); + xo_errx(1, "%s: unknown address family", + optarg); } break; case 'g': @@ -417,9 +423,8 @@ main(int argc, char *argv[]) break; case 'p': if ((tp = name2protox(optarg)) == NULL) { - errx(1, - "%s: unknown or uninstrumented protocol", - optarg); + xo_errx(1, "%s: unknown or uninstrumented " + "protocol", optarg); } pflag = 1; break; @@ -496,13 +501,14 @@ main(int argc, char *argv[]) if (!live) setgid(getgid()); - if (xflag && Tflag) - errx(1, "-x and -T are incompatible, pick one."); + if (xflag && Tflag) + xo_errx(1, "-x and -T are incompatible, pick one."); if (Bflag) { if (!live) usage(); bpf_stats(interface); + xo_finish(); exit(0); } if (mflag) { @@ -511,6 +517,7 @@ main(int argc, char *argv[]) mbpr(kvmd, nl[N_SFSTAT].n_value); } else mbpr(NULL, 0); + xo_finish(); exit(0); } if (Qflag) { @@ -519,6 +526,7 @@ main(int argc, char *argv[]) netisr_stats(kvmd); } else netisr_stats(NULL); + xo_finish(); exit(0); } #if 0 @@ -536,19 +544,26 @@ main(int argc, char *argv[]) */ #endif if (iflag && !sflag) { + xo_open_container("statistics"); intpr(interval, NULL, af); + xo_close_container("statistics"); + xo_finish(); exit(0); } if (rflag) { + xo_open_container("statistics"); if (sflag) { rt_stats(); flowtable_stats(); } else routepr(fib, af); + xo_close_container("statistics"); + xo_finish(); exit(0); } if (gflag) { + xo_open_container("statistics"); if (sflag) { if (af == AF_INET || af == AF_UNSPEC) mrt_stats(); @@ -564,6 +579,8 @@ main(int argc, char *argv[]) mroute6pr(); #endif } + xo_close_container("statistics"); + xo_finish(); exit(0); } @@ -571,31 +588,43 @@ main(int argc, char *argv[]) kresolve_list(nl); if (tp) { - printproto(tp, tp->pr_name); + xo_open_container("statistics"); + printproto(tp, tp->pr_name, &first); + if (!first) + xo_close_list("socket"); + xo_close_container("statistics"); + xo_finish(); exit(0); } + + xo_open_container("statistics"); if (af == AF_INET || af == AF_UNSPEC) for (tp = protox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); + printproto(tp, tp->pr_name, &first); #ifdef INET6 if (af == AF_INET6 || af == AF_UNSPEC) for (tp = ip6protox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); + printproto(tp, tp->pr_name, &first); #endif /*INET6*/ #ifdef IPSEC if (af == PF_KEY || af == AF_UNSPEC) for (tp = pfkeyprotox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); + printproto(tp, tp->pr_name, &first); #endif /*IPSEC*/ #ifdef NETGRAPH if (af == AF_NETGRAPH || af == AF_UNSPEC) for (tp = netgraphprotox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); + printproto(tp, tp->pr_name, &first); #endif /* NETGRAPH */ if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value, nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value, - nl[N_UNP_SPHEAD].n_value); + nl[N_UNP_SPHEAD].n_value, &first); + + if (!first) + xo_close_list("socket"); + xo_close_container("statistics"); + xo_finish(); exit(0); } @@ -605,24 +634,25 @@ main(int argc, char *argv[]) * is not in the namelist, ignore this one. */ static void -printproto(struct protox *tp, const char *name) +printproto(struct protox *tp, const char *name, bool *first) { void (*pr)(u_long, const char *, int, int); u_long off; + bool doingdblocks = false; if (sflag) { if (iflag) { if (tp->pr_istats) intpr(interval, tp->pr_istats, af); else if (pflag) - printf("%s: no per-interface stats routine\n", + xo_message("%s: no per-interface stats routine", tp->pr_name); return; } else { pr = tp->pr_stats; if (!pr) { if (pflag) - printf("%s: no stats routine\n", + xo_message("%s: no stats routine", tp->pr_name); return; } @@ -630,34 +660,39 @@ printproto(struct protox *tp, const char *name) off = 0; else if (tp->pr_sindex < 0) { if (pflag) - printf( - "%s: stats routine doesn't work on cores\n", - tp->pr_name); + xo_message("%s: stats routine doesn't " + "work on cores", tp->pr_name); return; } else off = nl[tp->pr_sindex].n_value; } } else { + doingdblocks = true; pr = tp->pr_cblocks; if (!pr) { if (pflag) - printf("%s: no PCB routine\n", tp->pr_name); + xo_message("%s: no PCB routine", tp->pr_name); return; } if (tp->pr_usesysctl && live) off = 0; else if (tp->pr_index < 0) { if (pflag) - printf( - "%s: PCB routine doesn't work on cores\n", - tp->pr_name); + xo_message("%s: PCB routine doesn't work on " + "cores", tp->pr_name); return; } else off = nl[tp->pr_index].n_value; } if (pr != NULL && (off || (live && tp->pr_usesysctl) || - af != AF_UNSPEC)) + af != AF_UNSPEC)) { + if (doingdblocks && *first) { + xo_open_list("socket"); + *first = false; + } + (*pr)(off, name, af, tp->pr_protocol); + } } static int @@ -672,7 +707,7 @@ kvmd_init(void) setgid(getgid()); if (kvmd == NULL) { - warnx("kvm not available: %s", errbuf); + xo_warnx("kvm not available: %s", errbuf); return (-1); } @@ -694,10 +729,10 @@ kresolve_list(struct nlist *_nl) if (kvm_nlist(kvmd, _nl) < 0) { if (nlistf) - errx(1, "%s: kvm_nlist: %s", nlistf, - kvm_geterr(kvmd)); + xo_errx(1, "%s: kvm_nlist: %s", nlistf, + kvm_geterr(kvmd)); else - errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); + xo_errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); } return (0); @@ -716,7 +751,7 @@ kread(u_long addr, void *buf, size_t size) if (!buf) return (0); if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) { - warnx("%s", kvm_geterr(kvmd)); + xo_warnx("%s", kvm_geterr(kvmd)); return (-1); } return (0); @@ -823,7 +858,7 @@ name2protox(const char *name) static void usage(void) { - (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", + (void)xo_error("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: netstat [-46AaLnRSTWx] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", " netstat -i | -I interface [-46abdhnW] [-f address_family]\n" @@ -842,5 +877,6 @@ usage(void) " netstat -g [-46W] [-f address_family] [-M core] [-N system]", " netstat -gs [-46s] [-f address_family] [-M core] [-N system]", " netstat -Q"); + xo_finish(); exit(1); } diff --git a/usr.bin/netstat/mbuf.c b/usr.bin/netstat/mbuf.c index ebd843f..26b7095 100644 --- a/usr.bin/netstat/mbuf.c +++ b/usr.bin/netstat/mbuf.c @@ -56,7 +56,9 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> +#include <libxo/xo.h> #include "netstat.h" /* @@ -88,7 +90,7 @@ mbpr(void *kvmd, u_long mbaddr) mtlp = memstat_mtl_alloc(); if (mtlp == NULL) { - warn("memstat_mtl_alloc"); + xo_warn("memstat_mtl_alloc"); return; } @@ -98,7 +100,7 @@ mbpr(void *kvmd, u_long mbaddr) */ if (live) { if (memstat_sysctl_all(mtlp, 0) < 0) { - warnx("memstat_sysctl_all: %s", + xo_warnx("memstat_sysctl_all: %s", memstat_strerror(memstat_mtl_geterror(mtlp))); goto out; } @@ -106,10 +108,10 @@ mbpr(void *kvmd, u_long mbaddr) if (memstat_kvm_all(mtlp, kvmd) < 0) { error = memstat_mtl_geterror(mtlp); if (error == MEMSTAT_ERROR_KVM) - warnx("memstat_kvm_all: %s", + xo_warnx("memstat_kvm_all: %s", kvm_geterr(kvmd)); else - warnx("memstat_kvm_all: %s", + xo_warnx("memstat_kvm_all: %s", memstat_strerror(error)); goto out; } @@ -117,7 +119,7 @@ mbpr(void *kvmd, u_long mbaddr) mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_MEM_NAME); if (mtp == NULL) { - warnx("memstat_mtl_find: zone %s not found", MBUF_MEM_NAME); + xo_warnx("memstat_mtl_find: zone %s not found", MBUF_MEM_NAME); goto out; } mbuf_count = memstat_get_count(mtp); @@ -129,7 +131,7 @@ mbpr(void *kvmd, u_long mbaddr) mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_PACKET_MEM_NAME); if (mtp == NULL) { - warnx("memstat_mtl_find: zone %s not found", + xo_warnx("memstat_mtl_find: zone %s not found", MBUF_PACKET_MEM_NAME); goto out; } @@ -141,7 +143,7 @@ mbpr(void *kvmd, u_long mbaddr) mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_CLUSTER_MEM_NAME); if (mtp == NULL) { - warnx("memstat_mtl_find: zone %s not found", + xo_warnx("memstat_mtl_find: zone %s not found", MBUF_CLUSTER_MEM_NAME); goto out; } @@ -154,7 +156,7 @@ mbpr(void *kvmd, u_long mbaddr) mtp = memstat_mtl_find(mtlp, ALLOCATOR_MALLOC, MBUF_TAG_MEM_NAME); if (mtp == NULL) { - warnx("memstat_mtl_find: malloc type %s not found", + xo_warnx("memstat_mtl_find: malloc type %s not found", MBUF_TAG_MEM_NAME); goto out; } @@ -162,7 +164,7 @@ mbpr(void *kvmd, u_long mbaddr) mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBOP_MEM_NAME); if (mtp == NULL) { - warnx("memstat_mtl_find: zone %s not found", + xo_warnx("memstat_mtl_find: zone %s not found", MBUF_JUMBOP_MEM_NAME); goto out; } @@ -175,7 +177,7 @@ mbpr(void *kvmd, u_long mbaddr) mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO9_MEM_NAME); if (mtp == NULL) { - warnx("memstat_mtl_find: zone %s not found", + xo_warnx("memstat_mtl_find: zone %s not found", MBUF_JUMBO9_MEM_NAME); goto out; } @@ -188,7 +190,7 @@ mbpr(void *kvmd, u_long mbaddr) mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO16_MEM_NAME); if (mtp == NULL) { - warnx("memstat_mtl_find: zone %s not found", + xo_warnx("memstat_mtl_find: zone %s not found", MBUF_JUMBO16_MEM_NAME); goto out; } @@ -199,36 +201,44 @@ mbpr(void *kvmd, u_long mbaddr) jumbo16_sleeps = memstat_get_sleeps(mtp); jumbo16_size = memstat_get_size(mtp); - printf("%ju/%ju/%ju mbufs in use (current/cache/total)\n", + xo_open_container("mbuf-statistics"); + + xo_emit("{:mbuf-current/%ju}/{:mbuf-cache/%ju}/{:mbuf-total/%ju} " + "{N:mbufs in use (current\\/cache\\/total)}\n", mbuf_count + packet_count, mbuf_free + packet_free, mbuf_count + packet_count + mbuf_free + packet_free); - printf("%ju/%ju/%ju/%ju mbuf clusters in use " - "(current/cache/total/max)\n", + xo_emit("{:cluster-current/%ju}/{:cluster-cache/%ju}/" + "{:cluster-total/%ju}/{:cluster-max/%ju} " + "{N:mbuf clusters in use (current\\/cache\\/total\\/max)}\n", cluster_count - packet_free, cluster_free + packet_free, cluster_count + cluster_free, cluster_limit); - printf("%ju/%ju mbuf+clusters out of packet secondary zone in use " - "(current/cache)\n", + xo_emit("{:packet-count/%ju}/{:packet-free/%ju} " + "{N:mbuf+clusters out of packet secondary zone in use " + "(current\\/cache)}\n", packet_count, packet_free); - printf("%ju/%ju/%ju/%ju %juk (page size) jumbo clusters in use " - "(current/cache/total/max)\n", + xo_emit("{:jumbo-count/%ju}/{:jumbo-cache/%ju}/{:jumbo-total/%ju}/" + "{:jumbo-max/%ju} {:jumbo-page-size/%ju}{U:k} {N:(page size)} " + "{N:jumbo clusters in use (current\\/cache\\/total\\/max)}\n", jumbop_count, jumbop_free, jumbop_count + jumbop_free, jumbop_limit, jumbop_size / 1024); - printf("%ju/%ju/%ju/%ju 9k jumbo clusters in use " - "(current/cache/total/max)\n", + xo_emit("{:jumbo9-count/%ju}/{:jumbo9-cache/%ju}/" + "{:jumbo9-total/%ju}/{:jumbo9-max/%ju} " + "{N:9k jumbo clusters in use (current\\/cache\\/total\\/max)}\n", jumbo9_count, jumbo9_free, jumbo9_count + jumbo9_free, jumbo9_limit); - printf("%ju/%ju/%ju/%ju 16k jumbo clusters in use " - "(current/cache/total/max)\n", + xo_emit("{:jumbo16-count/%ju}/{:jumbo16-cache/%ju}/" + "{:jumbo16-total/%ju}/{:jumbo16-limit/%ju} " + "{N:16k jumbo clusters in use (current\\/cache\\/total\\/max)}\n", jumbo16_count, jumbo16_free, jumbo16_count + jumbo16_free, jumbo16_limit); #if 0 - printf("%ju mbuf tags in use\n", tag_count); + xo_emit("{:tag-count/%ju} {N:mbuf tags in use}\n", tag_count); #endif /*- @@ -276,23 +286,29 @@ mbpr(void *kvmd, u_long mbaddr) */ bytes_total = bytes_inuse + bytes_incache; - printf("%juK/%juK/%juK bytes allocated to network " - "(current/cache/total)\n", bytes_inuse / 1024, - bytes_incache / 1024, bytes_total / 1024); + xo_emit("{:bytes-in-use/%ju}{U:K}/{:bytes-in-cache/%ju}{U:K}/" + "{:bytes-total/%ju}{U:K} " + "{N:bytes allocated to network (current\\/cache\\/total)}\n", + bytes_inuse / 1024, bytes_incache / 1024, bytes_total / 1024); - printf("%ju/%ju/%ju requests for mbufs denied (mbufs/clusters/" - "mbuf+clusters)\n", mbuf_failures, cluster_failures, - packet_failures); - printf("%ju/%ju/%ju requests for mbufs delayed (mbufs/clusters/" - "mbuf+clusters)\n", mbuf_sleeps, cluster_sleeps, - packet_sleeps); + xo_emit("{:mbuf-failures/%ju}/{:cluster-failures/%ju}/" + "{:packet-failures/%ju} {N:requests for mbufs denied " + "(mbufs\\/clusters\\/mbuf+clusters)}\n", + mbuf_failures, cluster_failures, packet_failures); + xo_emit("{:mbuf-sleeps/%ju}/{:cluster-sleeps/%ju}/{:packet-sleeps/%ju} " + "{N:requests for mbufs delayed " + "(mbufs\\/clusters\\/mbuf+clusters)}\n", + mbuf_sleeps, cluster_sleeps, packet_sleeps); - printf("%ju/%ju/%ju requests for jumbo clusters delayed " - "(%juk/9k/16k)\n", jumbop_sleeps, jumbo9_sleeps, - jumbo16_sleeps, jumbop_size / 1024); - printf("%ju/%ju/%ju requests for jumbo clusters denied " - "(%juk/9k/16k)\n", jumbop_failures, jumbo9_failures, - jumbo16_failures, jumbop_size / 1024); + xo_emit("{:jumbop-sleeps/%ju}/{:jumbo9-sleeps/%ju}/" + "{:jumbo16-sleeps/%ju} {N:/requests for jumbo clusters delayed " + "(%juk\\/9k\\/16k)}\n", + jumbop_sleeps, jumbo9_sleeps, jumbo16_sleeps, jumbop_size / 1024); + xo_emit("{:jumbop-failures/%ju}/{:jumbo9-failures/%ju}/" + "{:jumbo16-failures/%ju} {N:/requests for jumbo clusters denied " + "(%juk\\/9k\\/16k)}\n", + jumbop_failures, jumbo9_failures, jumbo16_failures, + jumbop_size / 1024); if (live) { mlen = sizeof(nsfbufs); @@ -302,23 +318,27 @@ mbpr(void *kvmd, u_long mbaddr) &mlen, NULL, 0) && !sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, &mlen, NULL, 0)) - printf("%d/%d/%d sfbufs in use (current/peak/max)\n", + xo_emit("{:nsfbufs-current/%d}/{:nsfbufs-peak/%d}/" + "{:nsfbufs/%d} " + "{N:sfbufs in use (current\\/peak\\/max)}\n", nsfbufsused, nsfbufspeak, nsfbufs); mlen = sizeof(sfstat); if (sysctlbyname("kern.ipc.sfstat", &sfstat, &mlen, NULL, 0)) { - warn("kern.ipc.sfstat"); + xo_warn("kern.ipc.sfstat"); goto out; } } else { if (kread_counters(mbaddr, (char *)&sfstat, sizeof sfstat) != 0) goto out; } - printf("%ju requests for sfbufs denied\n", + xo_emit("{:sfbufs-alloc-failed/%ju} {N:requests for sfbufs denied}\n", (uintmax_t)sfstat.sf_allocfail); - printf("%ju requests for sfbufs delayed\n", + xo_emit("{:sfbufs-alloc-wait/%ju} {N:requests for sfbufs delayed}\n", (uintmax_t)sfstat.sf_allocwait); - printf("%ju requests for I/O initiated by sendfile\n", + xo_emit("{:sfbufs-io-count/%ju} " + "{N:requests for I\\/O initiated by sendfile}\n", (uintmax_t)sfstat.sf_iocnt); out: + xo_close_container("mbuf-statistics"); memstat_mtl_free(mtlp); } diff --git a/usr.bin/netstat/mroute.c b/usr.bin/netstat/mroute.c index 3ec716d..37c8868 100644 --- a/usr.bin/netstat/mroute.c +++ b/usr.bin/netstat/mroute.c @@ -69,6 +69,8 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> +#include <libxo/xo.h> #include "netstat.h" /* @@ -92,77 +94,85 @@ static void print_mfc(struct mfc *, int, int *); static void print_bw_meter(struct bw_meter *bw_meter, int *banner_printed) { - char s0[256], s1[256], s2[256], s3[256]; + char s1[256], s2[256], s3[256]; struct timeval now, end, delta; gettimeofday(&now, NULL); if (! *banner_printed) { - printf(" Bandwidth Meters\n"); - printf(" %-30s", "Measured(Start|Packets|Bytes)"); - printf(" %s", "Type"); - printf(" %-30s", "Thresh(Interval|Packets|Bytes)"); - printf(" Remain"); - printf("\n"); + xo_open_list("bandwidth-meter"); + xo_emit(" {T:Bandwidth Meters}\n"); + xo_emit(" {T:/%-30s}", "Measured(Start|Packets|Bytes)"); + xo_emit(" {T:/%s}", "Type"); + xo_emit(" {T:/%-30s}", "Thresh(Interval|Packets|Bytes)"); + xo_emit(" {T:Remain}"); + xo_emit("\n"); *banner_printed = 1; } + xo_open_instance("bandwidth-meter"); + /* The measured values */ - if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) + if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) { sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_measured.b_packets); - else + xo_emit("{e:measured-packets/%ju}", + (uintmax_t)bw_meter->bm_measured.b_packets); + } else sprintf(s1, "?"); - if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) + if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) { sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_measured.b_bytes); - else + xo_emit("{e:measured-bytes/%ju}", + (uintmax_t)bw_meter->bm_measured.b_bytes); + } else sprintf(s2, "?"); - sprintf(s0, "%lu.%lu|%s|%s", - (u_long)bw_meter->bm_start_time.tv_sec, - (u_long)bw_meter->bm_start_time.tv_usec, - s1, s2); - printf(" %-30s", s0); + xo_emit(" {[:-30}{:start-time/%lu.%06lu}|{q:measured-packets/%s}" + "|{q:measured-bytes%s}{]:}", + (u_long)bw_meter->bm_start_time.tv_sec, + (u_long)bw_meter->bm_start_time.tv_usec, s1, s2); /* The type of entry */ - sprintf(s0, "%s", "?"); - if (bw_meter->bm_flags & BW_METER_GEQ) - sprintf(s0, "%s", ">="); - else if (bw_meter->bm_flags & BW_METER_LEQ) - sprintf(s0, "%s", "<="); - printf(" %-3s", s0); + xo_emit(" {t:type/%-3s}", (bw_meter->bm_flags & BW_METER_GEQ) ? ">=" : + (bw_meter->bm_flags & BW_METER_LEQ) ? "<=" : "?"); /* The threshold values */ - if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) + if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) { sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_threshold.b_packets); - else + xo_emit("{e:threshold-packets/%ju}", + (uintmax_t)bw_meter->bm_threshold.b_packets); + } else sprintf(s1, "?"); - if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) + if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) { sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_threshold.b_bytes); - else + xo_emit("{e:threshold-bytes/%ju}", + (uintmax_t)bw_meter->bm_threshold.b_bytes); + } else sprintf(s2, "?"); - sprintf(s0, "%lu.%lu|%s|%s", - (u_long)bw_meter->bm_threshold.b_time.tv_sec, - (u_long)bw_meter->bm_threshold.b_time.tv_usec, - s1, s2); - printf(" %-30s", s0); + + xo_emit(" {[:-30}{:threshold-time/%lu.%06lu}|{q:threshold-packets/%s}" + "|{q:threshold-bytes%s}{]:}", + (u_long)bw_meter->bm_threshold.b_time.tv_sec, + (u_long)bw_meter->bm_threshold.b_time.tv_usec, s1, s2); /* Remaining time */ timeradd(&bw_meter->bm_start_time, &bw_meter->bm_threshold.b_time, &end); if (timercmp(&now, &end, <=)) { timersub(&end, &now, &delta); - sprintf(s3, "%lu.%lu", + sprintf(s3, "%lu.%06lu", (u_long)delta.tv_sec, (u_long)delta.tv_usec); } else { /* Negative time */ timersub(&now, &end, &delta); - sprintf(s3, "-%lu.%lu", + sprintf(s3, "-%lu.06%lu", (u_long)delta.tv_sec, (u_long)delta.tv_usec); } - printf(" %s", s3); + xo_emit(" {:remaining-time/%s}", s3); - printf("\n"); + xo_open_instance("bandwidth-meter"); + + xo_emit("\n"); } static void @@ -176,21 +186,29 @@ print_mfc(struct mfc *m, int maxvif, int *banner_printed) bw_banner_printed = 0; if (! *banner_printed) { - printf("\nIPv4 Multicast Forwarding Table\n" - " Origin Group " - " Packets In-Vif Out-Vifs:Ttls\n"); + xo_open_list("multicast-forwarding-entry"); + xo_emit("\n{T:IPv4 Multicast Forwarding Table}\n" + " {T:Origin} {T:Group} " + " {T:Packets In-Vif} {T:Out-Vifs:Ttls}\n"); *banner_printed = 1; } - printf(" %-15.15s", routename(m->mfc_origin.s_addr)); - printf(" %-15.15s", routename(m->mfc_mcastgrp.s_addr)); - printf(" %9lu", m->mfc_pkt_cnt); - printf(" %3d ", m->mfc_parent); + xo_emit(" {:origin-address/%-15.15s}", routename(m->mfc_origin.s_addr)); + xo_emit(" {:group-address/%-15.15s}", + routename(m->mfc_mcastgrp.s_addr)); + xo_emit(" {:sent-packets/%9lu}", m->mfc_pkt_cnt); + xo_emit(" {:parent/%3d} ", m->mfc_parent); + xo_open_list("vif-ttl"); for (vifi = 0; vifi <= maxvif; vifi++) { - if (m->mfc_ttls[vifi] > 0) - printf(" %u:%u", vifi, m->mfc_ttls[vifi]); + if (m->mfc_ttls[vifi] > 0) { + xo_open_instance("vif-ttl"); + xo_emit(" {k:vif/%u}:{:ttl/%u}", vifi, + m->mfc_ttls[vifi]); + xo_close_instance("vif-ttl"); + } } - printf("\n"); + xo_close_list("vif-ttl"); + xo_emit("\n"); /* * XXX We break the rules and try to use KVM to read the @@ -205,6 +223,8 @@ print_mfc(struct mfc *m, int maxvif, int *banner_printed) print_bw_meter(&bw_meter, &bw_banner_printed); bwm = bw_meter.bm_mfc_next; } + if (banner_printed) + xo_close_list("bandwidth-meter"); } void @@ -242,7 +262,7 @@ mroutepr() if (live) { if (sysctlbyname("net.inet.ip.viftable", viftable, &len, NULL, 0) < 0) { - warn("sysctl: net.inet.ip.viftable"); + xo_warn("sysctl: net.inet.ip.viftable"); return; } } else { @@ -252,7 +272,7 @@ mroutepr() pviftbl = mrl[N_VIFTABLE].n_value; if (pmfchashtbl == 0 || pmfctablesize == 0 || pviftbl == 0) { - fprintf(stderr, "No IPv4 MROUTING kernel support.\n"); + xo_warnx("No IPv4 MROUTING kernel support."); return; } @@ -266,23 +286,29 @@ mroutepr() maxvif = vifi; if (!banner_printed) { - printf("\nIPv4 Virtual Interface Table\n" - " Vif Thresh Local-Address " - "Remote-Address Pkts-In Pkts-Out\n"); + xo_emit("\n{T:IPv4 Virtual Interface Table\n" + " Vif Thresh Local-Address " + "Remote-Address Pkts-In Pkts-Out}\n"); banner_printed = 1; + xo_open_list("vif"); } - printf(" %2u %6u %-15.15s", + xo_open_instance("vif"); + xo_emit(" {:vif/%2u} {:threshold/%6u} {:route/%-15.15s}", /* opposite math of add_vif() */ vifi, v->v_threshold, routename(v->v_lcl_addr.s_addr)); - printf(" %-15.15s", (v->v_flags & VIFF_TUNNEL) ? + xo_emit(" {:source/%-15.15s}", (v->v_flags & VIFF_TUNNEL) ? routename(v->v_rmt_addr.s_addr) : ""); - printf(" %9lu %9lu\n", v->v_pkt_in, v->v_pkt_out); + xo_emit(" {:received-packets/%9lu} {:sent-packets/%9lu}\n", + v->v_pkt_in, v->v_pkt_out); + xo_close_instance("vif"); } - if (!banner_printed) - printf("\nIPv4 Virtual Interface Table is empty\n"); + if (banner_printed) + xo_close_list("vif"); + else + xo_emit("\n{T:IPv4 Virtual Interface Table is empty}\n"); banner_printed = 0; @@ -302,19 +328,19 @@ mroutepr() len = 0; if (sysctlbyname("net.inet.ip.mfctable", NULL, &len, NULL, 0) < 0) { - warn("sysctl: net.inet.ip.mfctable"); + xo_warn("sysctl: net.inet.ip.mfctable"); return; } mfctable = malloc(len); if (mfctable == NULL) { - warnx("malloc %lu bytes", (u_long)len); + xo_warnx("malloc %lu bytes", (u_long)len); return; } if (sysctlbyname("net.inet.ip.mfctable", mfctable, &len, NULL, 0) < 0) { free(mfctable); - warn("sysctl: net.inet.ip.mfctable"); + xo_warn("sysctl: net.inet.ip.mfctable"); return; } @@ -323,8 +349,10 @@ mroutepr() print_mfc(m++, maxvif, &banner_printed); len -= sizeof(*m); } + if (banner_printed) + xo_close_list("multicast-forwarding-entry"); if (len != 0) - warnx("print_mfc: %lu trailing bytes", (u_long)len); + xo_warnx("print_mfc: %lu trailing bytes", (u_long)len); free(mfctable); } else { @@ -336,14 +364,14 @@ mroutepr() error = kread(pmfctablesize, (char *)&mfctablesize, sizeof(u_long)); if (error) { - warn("kread: mfctablesize"); + xo_warn("kread: mfctablesize"); return; } len = sizeof(*mfchashtbl) * mfctablesize; mfchashtbl = malloc(len); if (mfchashtbl == NULL) { - warnx("malloc %lu bytes", (u_long)len); + xo_warnx("malloc %lu bytes", (u_long)len); return; } kread(pmfchashtbl, (char *)&mfchashtbl, len); @@ -354,14 +382,16 @@ mroutepr() print_mfc(m, maxvif, &banner_printed); } } + if (banner_printed) + xo_close_list("multicast-forwarding-entry"); free(mfchashtbl); } if (!banner_printed) - printf("\nIPv4 Multicast Forwarding Table is empty\n"); + xo_emit("\n{T:IPv4 Multicast Forwarding Table is empty}\n"); - printf("\n"); + xo_emit("\n"); numeric_addr = saved_numeric_addr; } @@ -383,33 +413,48 @@ mrt_stats() if (live) { if (sysctlbyname("net.inet.ip.mrtstat", &mrtstat, &len, NULL, 0) < 0) { - warn("sysctl: net.inet.ip.mrtstat failed."); + xo_warn("sysctl: net.inet.ip.mrtstat failed."); return; } } else kread_counters(mstaddr, &mrtstat, len); - printf("IPv4 multicast forwarding:\n"); + xo_emit("{T:IPv4 multicast forwarding}:\n"); #define p(f, m) if (mrtstat.f || sflag <= 1) \ - printf(m, (uintmax_t)mrtstat.f, plural(mrtstat.f)) + xo_emit(m, (uintmax_t)mrtstat.f, plural(mrtstat.f)) #define p2(f, m) if (mrtstat.f || sflag <= 1) \ - printf(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f)) - - p(mrts_mfc_lookups, "\t%ju multicast forwarding cache lookup%s\n"); - p2(mrts_mfc_misses, "\t%ju multicast forwarding cache miss%s\n"); - p(mrts_upcalls, "\t%ju upcall%s to multicast routing daemon\n"); - p(mrts_upq_ovflw, "\t%ju upcall queue overflow%s\n"); + xo_emit(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f)) + + xo_open_container("multicast-statistics"); + + p(mrts_mfc_lookups, "\t{:cache-lookups/%ju} " + "{N:/multicast forwarding cache lookup%s}\n"); + p2(mrts_mfc_misses, "\t{:cache-misses/%ju} " + "{N:/multicast forwarding cache miss%s}\n"); + p(mrts_upcalls, "\t{:upcalls-total/%ju} " + "{N:/upcall%s to multicast routing daemon}\n"); + p(mrts_upq_ovflw, "\t{:upcall-overflows/%ju} " + "{N:/upcall queue overflow%s}\n"); p(mrts_upq_sockfull, - "\t%ju upcall%s dropped due to full socket buffer\n"); - p(mrts_cache_cleanups, "\t%ju cache cleanup%s\n"); - p(mrts_no_route, "\t%ju datagram%s with no route for origin\n"); - p(mrts_bad_tunnel, "\t%ju datagram%s arrived with bad tunneling\n"); - p(mrts_cant_tunnel, "\t%ju datagram%s could not be tunneled\n"); - p(mrts_wrong_if, "\t%ju datagram%s arrived on wrong interface\n"); - p(mrts_drop_sel, "\t%ju datagram%s selectively dropped\n"); - p(mrts_q_overflow, "\t%ju datagram%s dropped due to queue overflow\n"); - p(mrts_pkt2large, "\t%ju datagram%s dropped for being too large\n"); + "\t{:upcalls-dropped-full-buffer/%ju} " + "{N:/upcall%s dropped due to full socket buffer}\n"); + p(mrts_cache_cleanups, "\t{:cache-cleanups/%ju} " + "{N:/cache cleanup%s}\n"); + p(mrts_no_route, "\t{:dropped-no-origin/%ju} " + "{N:/datagram%s with no route for origin}\n"); + p(mrts_bad_tunnel, "\t{:dropped-bad-tunnel/%ju} " + "{N:/datagram%s arrived with bad tunneling}\n"); + p(mrts_cant_tunnel, "\t{:dropped-could-not-tunnel/%ju} " + "{N:/datagram%s could not be tunneled}\n"); + p(mrts_wrong_if, "\t{:dropped-wrong-incoming-interface/%ju} " + "{N:/datagram%s arrived on wrong interface}\n"); + p(mrts_drop_sel, "\t{:dropped-selectively/%ju} " + "{N:/datagram%s selectively dropped}\n"); + p(mrts_q_overflow, "\t{:dropped-queue-overflow/%ju} " + "{N:/datagram%s dropped due to queue overflow}\n"); + p(mrts_pkt2large, "\t{:dropped-too-large/%ju} " + "{N:/datagram%s dropped for being too large}\n"); #undef p2 #undef p diff --git a/usr.bin/netstat/mroute6.c b/usr.bin/netstat/mroute6.c index ac31f5e..d9c127a 100644 --- a/usr.bin/netstat/mroute6.c +++ b/usr.bin/netstat/mroute6.c @@ -79,16 +79,16 @@ __FBSDID("$FreeBSD$"); #include <sys/time.h> #include <net/if.h> -#include <net/if_var.h> #include <net/route.h> #include <netinet/in.h> #include <err.h> -#include <nlist.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> +#include <libxo/xo.h> #define KERNEL 1 #include <netinet6/ip6_mroute.h> @@ -96,20 +96,6 @@ __FBSDID("$FreeBSD$"); #include "netstat.h" -/* - * kvm(3) bindings for every needed symbol - */ -static struct nlist mrl[] = { -#define N_MF6CTABLE 0 - { .n_name = "_mf6ctable" }, -#define N_MIF6TABLE 1 - { .n_name = "_mif6table" }, -#define N_MRT6STAT 2 - { .n_name = "_mrt6stat" }, - { .n_name = NULL }, -}; - - #define WID_ORG (Wflag ? 39 : (numeric_addr ? 29 : 18)) /* width of origin column */ #define WID_GRP (Wflag ? 18 : (numeric_addr ? 16 : 18)) /* width of group column */ @@ -117,11 +103,10 @@ void mroute6pr() { struct mf6c *mf6ctable[MF6CTBLSIZ], *mfcp; - struct mif6 mif6table[MAXMIFS]; + struct mif6_sctl mif6table[MAXMIFS]; struct mf6c mfc; struct rtdetq rte, *rtep; - struct mif6 *mifp; - u_long mfcaddr, mifaddr; + struct mif6_sctl *mifp; mifi_t mifi; int i; int banner_printed; @@ -130,67 +115,56 @@ mroute6pr() long int waitings; size_t len; - kresolve_list(mrl); - mfcaddr = mrl[N_MF6CTABLE].n_value; - mifaddr = mrl[N_MIF6TABLE].n_value; - - if (mfcaddr == 0 || mifaddr == 0) { - fprintf(stderr, "No IPv6 MROUTING kernel support.\n"); + if (live == 0) return; - } len = sizeof(mif6table); - if (live) { - if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len, - NULL, 0) < 0) { - warn("sysctl: net.inet6.ip6.mif6table"); - return; - } - } else - kread(mifaddr, (char *)mif6table, sizeof(mif6table)); + if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len, NULL, 0) < + 0) { + xo_warn("sysctl: net.inet6.ip6.mif6table"); + return; + } saved_numeric_addr = numeric_addr; numeric_addr = 1; banner_printed = 0; for (mifi = 0, mifp = mif6table; mifi < MAXMIFS; ++mifi, ++mifp) { - struct ifnet ifnet; char ifname[IFNAMSIZ]; - if (mifp->m6_ifp == NULL) + if (mifp->m6_ifp == 0) continue; - /* XXX KVM */ - kread((u_long)mifp->m6_ifp, (char *)&ifnet, sizeof(ifnet)); - maxmif = mifi; if (!banner_printed) { - printf("\nIPv6 Multicast Interface Table\n" - " Mif Rate PhyIF " - "Pkts-In Pkts-Out\n"); + xo_open_list("multicast-interface"); + xo_emit("\n{T:IPv6 Multicast Interface Table}\n" + "{T: Mif Rate PhyIF Pkts-In Pkts-Out}\n"); banner_printed = 1; } - printf(" %2u %4d", - mifi, mifp->m6_rate_limit); - printf(" %5s", (mifp->m6_flags & MIFF_REGISTER) ? - "reg0" : if_indextoname(ifnet.if_index, ifname)); + xo_open_instance("multicast-interface"); + xo_emit(" {:mif/%2u} {:rate-limit/%4d}", + mifi, mifp->m6_rate_limit); + xo_emit(" {:ifname/%5s}", (mifp->m6_flags & MIFF_REGISTER) ? + "reg0" : if_indextoname(mifp->m6_ifp, ifname)); - printf(" %9ju %9ju\n", (uintmax_t)mifp->m6_pkt_in, + xo_emit(" {:received-packets/%9ju} {:sent-packets/%9ju}\n", + (uintmax_t)mifp->m6_pkt_in, (uintmax_t)mifp->m6_pkt_out); + xo_close_instance("multicast-interface"); } - if (!banner_printed) - printf("\nIPv6 Multicast Interface Table is empty\n"); + if (banner_printed) + xo_open_list("multicast-interface"); + else + xo_emit("\n{T:IPv6 Multicast Interface Table is empty}\n"); len = sizeof(mf6ctable); - if (live) { - if (sysctlbyname("net.inet6.ip6.mf6ctable", mf6ctable, &len, - NULL, 0) < 0) { - warn("sysctl: net.inet6.ip6.mf6ctable"); - return; - } - } else - kread(mfcaddr, (char *)mf6ctable, sizeof(mf6ctable)); + if (sysctlbyname("net.inet6.ip6.mf6ctable", mf6ctable, &len, NULL, 0) < + 0) { + xo_warn("sysctl: net.inet6.ip6.mf6ctable"); + return; + } banner_printed = 0; @@ -199,19 +173,24 @@ mroute6pr() while(mfcp) { kread((u_long)mfcp, (char *)&mfc, sizeof(mfc)); if (!banner_printed) { - printf ("\nIPv6 Multicast Forwarding Cache\n"); - printf(" %-*.*s %-*.*s %s", - WID_ORG, WID_ORG, "Origin", - WID_GRP, WID_GRP, "Group", - " Packets Waits In-Mif Out-Mifs\n"); + xo_open_list("multicast-forwarding-cache"); + xo_emit("\n" + "{T:IPv6 Multicast Forwarding Cache}\n"); + xo_emit(" {T:%-*.*s} {T:%-*.*s} {T:%s}", + WID_ORG, WID_ORG, "Origin", + WID_GRP, WID_GRP, "Group", + " Packets Waits In-Mif Out-Mifs\n"); banner_printed = 1; } - printf(" %-*.*s", WID_ORG, WID_ORG, - routename6(&mfc.mf6c_origin)); - printf(" %-*.*s", WID_GRP, WID_GRP, - routename6(&mfc.mf6c_mcastgrp)); - printf(" %9ju", (uintmax_t)mfc.mf6c_pkt_cnt); + xo_open_instance("multicast-forwarding-cache"); + + xo_emit(" {:origin/%-*.*s}", WID_ORG, WID_ORG, + routename6(&mfc.mf6c_origin)); + xo_emit(" {:group/%-*.*s}", WID_GRP, WID_GRP, + routename6(&mfc.mf6c_mcastgrp)); + xo_emit(" {:total-packets/%9ju}", + (uintmax_t)mfc.mf6c_pkt_cnt); for (waitings = 0, rtep = mfc.mf6c_stall; rtep; ) { waitings++; @@ -219,25 +198,30 @@ mroute6pr() kread((u_long)rtep, (char *)&rte, sizeof(rte)); rtep = rte.next; } - printf(" %3ld", waitings); + xo_emit(" {:waitings/%3ld}", waitings); if (mfc.mf6c_parent == MF6C_INCOMPLETE_PARENT) - printf(" --- "); + xo_emit(" --- "); else - printf(" %3d ", mfc.mf6c_parent); + xo_emit(" {:parent/%3d} ", mfc.mf6c_parent); + xo_open_list("mif"); for (mifi = 0; mifi <= maxmif; mifi++) { if (IF_ISSET(mifi, &mfc.mf6c_ifset)) - printf(" %u", mifi); + xo_emit(" {l:%u}", mifi); } - printf("\n"); + xo_close_list("mif"); + xo_emit("\n"); mfcp = mfc.mf6c_next; + xo_close_instance("multicast-forwarding-cache"); } } - if (!banner_printed) - printf("\nIPv6 Multicast Forwarding Table is empty\n"); + if (banner_printed) + xo_close_list("multicast-forwarding-cache"); + else + xo_emit("\n{T:IPv6 Multicast Forwarding Table is empty}\n"); - printf("\n"); + xo_emit("\n"); numeric_addr = saved_numeric_addr; } @@ -245,50 +229,51 @@ void mrt6_stats() { struct mrt6stat mrtstat; - u_long mstaddr; size_t len = sizeof mrtstat; - kresolve_list(mrl); - mstaddr = mrl[N_MRT6STAT].n_value; - - if (mstaddr == 0) { - fprintf(stderr, "No IPv6 MROUTING kernel support.\n"); + if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len, NULL, 0) < + 0) { + xo_warn("sysctl: net.inet6.ip6.mrt6stat"); return; } - if (live) { - if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len, - NULL, 0) < 0) { - warn("sysctl: net.inet6.ip6.mrt6stat"); - return; - } - } else - kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat)); - - printf("IPv6 multicast forwarding:\n"); + xo_open_container("multicast-statistics"); + xo_emit("{T:IPv6 multicast forwarding}:\n"); #define p(f, m) if (mrtstat.f || sflag <= 1) \ - printf(m, (uintmax_t)mrtstat.f, plural(mrtstat.f)) + xo_emit(m, (uintmax_t)mrtstat.f, plural(mrtstat.f)) #define p2(f, m) if (mrtstat.f || sflag <= 1) \ - printf(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f)) - - p(mrt6s_mfc_lookups, "\t%ju multicast forwarding cache lookup%s\n"); - p2(mrt6s_mfc_misses, "\t%ju multicast forwarding cache miss%s\n"); - p(mrt6s_upcalls, "\t%ju upcall%s to multicast routing daemon\n"); - p(mrt6s_upq_ovflw, "\t%ju upcall queue overflow%s\n"); - p(mrt6s_upq_sockfull, - "\t%ju upcall%s dropped due to full socket buffer\n"); - p(mrt6s_cache_cleanups, "\t%ju cache cleanup%s\n"); - p(mrt6s_no_route, "\t%ju datagram%s with no route for origin\n"); - p(mrt6s_bad_tunnel, "\t%ju datagram%s arrived with bad tunneling\n"); - p(mrt6s_cant_tunnel, "\t%ju datagram%s could not be tunneled\n"); - p(mrt6s_wrong_if, "\t%ju datagram%s arrived on wrong interface\n"); - p(mrt6s_drop_sel, "\t%ju datagram%s selectively dropped\n"); - p(mrt6s_q_overflow, - "\t%ju datagram%s dropped due to queue overflow\n"); - p(mrt6s_pkt2large, "\t%ju datagram%s dropped for being too large\n"); + xo_emit(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f)) + + p(mrt6s_mfc_lookups, "\t{:cache-lookups/%ju} " + "{N:/multicast forwarding cache lookup%s}\n"); + p2(mrt6s_mfc_misses, "\t{:cache-misses/%ju} " + "{N:/multicast forwarding cache miss%s}\n"); + p(mrt6s_upcalls, "\t{:upcalls/%ju} " + "{N:/upcall%s to multicast routing daemon}\n"); + p(mrt6s_upq_ovflw, "\t{:upcall-overflows/%ju} " + "{N:/upcall queue overflow%s}\n"); + p(mrt6s_upq_sockfull, "\t{:upcalls-dropped-full-buffer/%ju} " + "{N:/upcall%s dropped due to full socket buffer}\n"); + p(mrt6s_cache_cleanups, "\t{:cache-cleanups/%ju} " + "{N:/cache cleanup%s}\n"); + p(mrt6s_no_route, "\t{:dropped-no-origin/%ju} " + "{N:/datagram%s with no route for origin}\n"); + p(mrt6s_bad_tunnel, "\t{:dropped-bad-tunnel/%ju} " + "{N:/datagram%s arrived with bad tunneling}\n"); + p(mrt6s_cant_tunnel, "\t{:dropped-could-not-tunnel/%ju} " + "{N:/datagram%s could not be tunneled}\n"); + p(mrt6s_wrong_if, "\t{:dropped-wrong-incoming-interface/%ju} " + "{N:/datagram%s arrived on wrong interface}\n"); + p(mrt6s_drop_sel, "\t{:dropped-selectively/%ju} " + "{N:/datagram%s selectively dropped}\n"); + p(mrt6s_q_overflow, "\t{:dropped-queue-overflow/%ju} " + "{N:/datagram%s dropped due to queue overflow}\n"); + p(mrt6s_pkt2large, "\t{:dropped-too-large/%ju} " + "{N:/datagram%s dropped for being too large}\n"); #undef p2 #undef p + xo_close_container("multicast-statistics"); } #endif /*INET6*/ diff --git a/usr.bin/netstat/netgraph.c b/usr.bin/netstat/netgraph.c index 95578af..e28de2c 100644 --- a/usr.bin/netstat/netgraph.c +++ b/usr.bin/netstat/netgraph.c @@ -53,9 +53,11 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <stdint.h> #include <stdio.h> +#include <stdbool.h> #include <string.h> #include <unistd.h> #include <err.h> +#include <libxo/xo.h> #include "netstat.h" static int first = 1; @@ -73,8 +75,7 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused, /* If symbol not found, try looking in the KLD module */ if (off == 0) { if (debug) - fprintf(stderr, - "Error reading symbols from ng_socket.ko"); + xo_warnx("Error reading symbols from ng_socket.ko"); return; } @@ -106,20 +107,22 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused, /* Do headline */ if (first) { - printf("Netgraph sockets\n"); + xo_emit("{T: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"); + xo_emit("{T:/%-8.8s} ", "PCB"); + xo_emit("{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} " + "{T:/%-14.14s} {T:/%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); + xo_emit("{:address/%8lx} ", (u_long) this); + xo_emit("{t:name/%-5.5s} {:receive-bytes-waiting/%6u} " + "{:send-byte-waiting/%6u} ", + name, sockb.so_rcv.sb_ccc, sockb.so_snd.sb_ccc); /* Get info on associated node */ if (ngpcb.node_id == 0 || csock == -1) @@ -134,9 +137,9 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused, /* Display associated node info */ if (*ni->name != '\0') snprintf(path, sizeof(path), "%s:", ni->name); - printf("%-14.14s %4d", path, ni->hooks); + xo_emit("{t:path/%-14.14s} {:hooks/%4d}", path, ni->hooks); finish: - putchar('\n'); + xo_emit("\n"); } } diff --git a/usr.bin/netstat/netisr.c b/usr.bin/netstat/netisr.c index 6c945c3..8f6fe3d 100644 --- a/usr.bin/netstat/netisr.c +++ b/usr.bin/netstat/netisr.c @@ -46,8 +46,9 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> - +#include <libxo/xo.h> #include "netstat.h" /* @@ -112,13 +113,13 @@ netisr_load_kvm_uint(kvm_t *kd, const char *name, u_int *p) ret = kvm_nlist(kd, nl); if (ret < 0) - errx(-1, "%s: kvm_nlist(%s): %s", __func__, name, + xo_errx(-1, "%s: kvm_nlist(%s): %s", __func__, name, kvm_geterr(kd)); if (ret != 0) - errx(-1, "%s: kvm_nlist(%s): unresolved symbol", __func__, + xo_errx(-1, "%s: kvm_nlist(%s): unresolved symbol", __func__, name); if (kvm_read(kd, nl[0].n_value, p, sizeof(*p)) != sizeof(*p)) - errx(-1, "%s: kvm_read(%s): %s", __func__, name, + xo_errx(-1, "%s: kvm_read(%s): %s", __func__, name, kvm_geterr(kd)); } @@ -134,7 +135,7 @@ netisr_load_kvm_string(kvm_t *kd, uintptr_t addr, char *dest, u_int limit) for (i = 0; i < limit; i++) { if (kvm_read(kd, addr + i, &dest[i], sizeof(dest[i])) != sizeof(dest[i])) - err(-1, "%s: kvm_read: %s", __func__, + xo_err(-1, "%s: kvm_read: %s", __func__, kvm_geterr(kd)); if (dest[i] == '\0') break; @@ -190,9 +191,9 @@ netisr_load_sysctl_uint(const char *name, u_int *p) retlen = sizeof(u_int); if (sysctlbyname(name, p, &retlen, NULL, 0) < 0) - err(-1, "%s", name); + xo_err(-1, "%s", name); if (retlen != sizeof(u_int)) - errx(-1, "%s: invalid len %ju", name, (uintmax_t)retlen); + xo_errx(-1, "%s: invalid len %ju", name, (uintmax_t)retlen); } static void @@ -202,7 +203,7 @@ netisr_load_sysctl_string(const char *name, char *p, size_t len) retlen = len; if (sysctlbyname(name, p, &retlen, NULL, 0) < 0) - err(-1, "%s", name); + xo_err(-1, "%s", name); p[len - 1] = '\0'; } @@ -241,21 +242,21 @@ netisr_load_kvm_proto(kvm_t *kd) */ netisr_load_kvm_uint(kd, "_netisr_maxprot", &maxprot); if (maxprot != NETISR_MAXPROT) - errx(-1, "%s: NETISR_MAXPROT mismatch", __func__); + xo_errx(-1, "%s: NETISR_MAXPROT mismatch", __func__); len = maxprot * sizeof(*np_array); np_array = malloc(len); if (np_array == NULL) - err(-1, "%s: malloc", __func__); + xo_err(-1, "%s: malloc", __func__); ret = kvm_nlist(kd, nl); if (ret < 0) - errx(-1, "%s: kvm_nlist(_netisr_proto): %s", __func__, + xo_errx(-1, "%s: kvm_nlist(_netisr_proto): %s", __func__, kvm_geterr(kd)); if (ret != 0) - errx(-1, "%s: kvm_nlist(_netisr_proto): unresolved symbol", + xo_errx(-1, "%s: kvm_nlist(_netisr_proto): unresolved symbol", __func__); if (kvm_read(kd, nl[NLIST_NETISR_PROTO].n_value, np_array, len) != (ssize_t)len) - errx(-1, "%s: kvm_read(_netisr_proto): %s", __func__, + xo_errx(-1, "%s: kvm_read(_netisr_proto): %s", __func__, kvm_geterr(kd)); /* @@ -301,21 +302,21 @@ netisr_load_sysctl_proto(void) size_t len; if (sysctlbyname("net.isr.proto", NULL, &len, NULL, 0) < 0) - err(-1, "net.isr.proto: query len"); + xo_err(-1, "net.isr.proto: query len"); if (len % sizeof(*proto_array) != 0) - errx(-1, "net.isr.proto: invalid len"); + xo_errx(-1, "net.isr.proto: invalid len"); proto_array = malloc(len); if (proto_array == NULL) - err(-1, "malloc"); + xo_err(-1, "malloc"); if (sysctlbyname("net.isr.proto", proto_array, &len, NULL, 0) < 0) - err(-1, "net.isr.proto: query data"); + xo_err(-1, "net.isr.proto: query data"); if (len % sizeof(*proto_array) != 0) - errx(-1, "net.isr.proto: invalid len"); + xo_errx(-1, "net.isr.proto: invalid len"); proto_array_len = len / sizeof(*proto_array); if (proto_array_len < 1) - errx(-1, "net.isr.proto: no data"); + xo_errx(-1, "net.isr.proto: no data"); if (proto_array[0].snp_version != sizeof(proto_array[0])) - errx(-1, "net.isr.proto: invalid version"); + xo_errx(-1, "net.isr.proto: invalid version"); } static void @@ -338,41 +339,41 @@ netisr_load_kvm_workstream(kvm_t *kd) len = numthreads * sizeof(*nws_array); nws_array = malloc(len); if (nws_array == NULL) - err(-1, "malloc"); + xo_err(-1, "malloc"); ret = kvm_nlist(kd, nl); if (ret < 0) - errx(-1, "%s: kvm_nlist: %s", __func__, kvm_geterr(kd)); + xo_errx(-1, "%s: kvm_nlist: %s", __func__, kvm_geterr(kd)); if (ret != 0) - errx(-1, "%s: kvm_nlist: unresolved symbol", __func__); + xo_errx(-1, "%s: kvm_nlist: unresolved symbol", __func__); if (kvm_read(kd, nl[NLIST_NWS_ARRAY].n_value, nws_array, len) != (ssize_t)len) - errx(-1, "%s: kvm_read(_nws_array): %s", __func__, + xo_errx(-1, "%s: kvm_read(_nws_array): %s", __func__, kvm_geterr(kd)); workstream_array = calloc(numthreads, sizeof(*workstream_array)); if (workstream_array == NULL) - err(-1, "calloc"); + xo_err(-1, "calloc"); workstream_array_len = numthreads; work_array = calloc(numthreads * proto_array_len, sizeof(*work_array)); if (work_array == NULL) - err(-1, "calloc"); + xo_err(-1, "calloc"); counter = 0; for (wsid = 0; wsid < numthreads; wsid++) { cpuid = nws_array[wsid]; if (kvm_dpcpu_setcpu(kd, cpuid) < 0) - errx(-1, "%s: kvm_dpcpu_setcpu(%u): %s", __func__, + xo_errx(-1, "%s: kvm_dpcpu_setcpu(%u): %s", __func__, cpuid, kvm_geterr(kd)); bzero(nl_nws, sizeof(nl_nws)); nl_nws[0].n_name = "_nws"; ret = kvm_nlist(kd, nl_nws); if (ret < 0) - errx(-1, "%s: kvm_nlist looking up nws on CPU %u: %s", - __func__, cpuid, kvm_geterr(kd)); + xo_errx(-1, "%s: kvm_nlist looking up nws on CPU " + "%u: %s", __func__, cpuid, kvm_geterr(kd)); if (ret != 0) - errx(-1, "%s: kvm_nlist(nws): unresolved symbol on " + xo_errx(-1, "%s: kvm_nlist(nws): unresolved symbol on " "CPU %u", __func__, cpuid); if (kvm_read(kd, nl_nws[0].n_value, &nws, sizeof(nws)) != sizeof(nws)) - errx(-1, "%s: kvm_read(nw): %s", __func__, + xo_errx(-1, "%s: kvm_read(nw): %s", __func__, kvm_geterr(kd)); snwsp = &workstream_array[wsid]; snwsp->snws_version = sizeof(*snwsp); @@ -384,7 +385,7 @@ netisr_load_kvm_workstream(kvm_t *kd) /* * Extract the CPU's per-protocol work information. */ - printf("counting to maxprot: %u\n", maxprot); + xo_emit("counting to maxprot: {:maxprot/%u}\n", maxprot); for (proto = 0; proto < maxprot; proto++) { if (!netisr_protoispresent(proto)) continue; @@ -413,22 +414,22 @@ netisr_load_sysctl_workstream(void) size_t len; if (sysctlbyname("net.isr.workstream", NULL, &len, NULL, 0) < 0) - err(-1, "net.isr.workstream: query len"); + xo_err(-1, "net.isr.workstream: query len"); if (len % sizeof(*workstream_array) != 0) - errx(-1, "net.isr.workstream: invalid len"); + xo_errx(-1, "net.isr.workstream: invalid len"); workstream_array = malloc(len); if (workstream_array == NULL) - err(-1, "malloc"); + xo_err(-1, "malloc"); if (sysctlbyname("net.isr.workstream", workstream_array, &len, NULL, 0) < 0) - err(-1, "net.isr.workstream: query data"); + xo_err(-1, "net.isr.workstream: query data"); if (len % sizeof(*workstream_array) != 0) - errx(-1, "net.isr.workstream: invalid len"); + xo_errx(-1, "net.isr.workstream: invalid len"); workstream_array_len = len / sizeof(*workstream_array); if (workstream_array_len < 1) - errx(-1, "net.isr.workstream: no data"); + xo_errx(-1, "net.isr.workstream: no data"); if (workstream_array[0].snws_version != sizeof(workstream_array[0])) - errx(-1, "net.isr.workstream: invalid version"); + xo_errx(-1, "net.isr.workstream: invalid version"); } static void @@ -437,21 +438,21 @@ netisr_load_sysctl_work(void) size_t len; if (sysctlbyname("net.isr.work", NULL, &len, NULL, 0) < 0) - err(-1, "net.isr.work: query len"); + xo_err(-1, "net.isr.work: query len"); if (len % sizeof(*work_array) != 0) - errx(-1, "net.isr.work: invalid len"); + xo_errx(-1, "net.isr.work: invalid len"); work_array = malloc(len); if (work_array == NULL) - err(-1, "malloc"); + xo_err(-1, "malloc"); if (sysctlbyname("net.isr.work", work_array, &len, NULL, 0) < 0) - err(-1, "net.isr.work: query data"); + xo_err(-1, "net.isr.work: query data"); if (len % sizeof(*work_array) != 0) - errx(-1, "net.isr.work: invalid len"); + xo_errx(-1, "net.isr.work: invalid len"); work_array_len = len / sizeof(*work_array); if (work_array_len < 1) - errx(-1, "net.isr.work: no data"); + xo_errx(-1, "net.isr.work: no data"); if (work_array[0].snw_version != sizeof(work_array[0])) - errx(-1, "net.isr.work: invalid version"); + xo_errx(-1, "net.isr.work: invalid version"); } static void @@ -459,17 +460,17 @@ netisr_print_proto(struct sysctl_netisr_proto *snpp) { char tmp[20]; - printf("%-6s", snpp->snp_name); - printf(" %5u", snpp->snp_proto); - printf(" %6u", snpp->snp_qlimit); - printf(" %6s", + xo_emit("{[:-6}{k:name/%s}{]:}", snpp->snp_name); + xo_emit(" {:protocol/%5u}", snpp->snp_proto); + xo_emit(" {:queue-limit/%6u}", snpp->snp_qlimit); + xo_emit(" {:policy-type/%6s}", (snpp->snp_policy == NETISR_POLICY_SOURCE) ? "source" : (snpp->snp_policy == NETISR_POLICY_FLOW) ? "flow" : (snpp->snp_policy == NETISR_POLICY_CPU) ? "cpu" : "-"); netisr_dispatch_policy_to_string(snpp->snp_dispatch, tmp, sizeof(tmp)); - printf(" %8s", tmp); - printf(" %s%s%s\n", + xo_emit(" {:policy/%8s}", tmp); + xo_emit(" {:flags/%s%s%s}\n", (snpp->snp_flags & NETISR_SNP_FLAGS_M2CPUID) ? "C" : "-", (snpp->snp_flags & NETISR_SNP_FLAGS_DRAINEDCPU) ? "D" : "-", (snpp->snp_flags & NETISR_SNP_FLAGS_M2FLOW) ? "F" : "-"); @@ -481,23 +482,28 @@ netisr_print_workstream(struct sysctl_netisr_workstream *snwsp) struct sysctl_netisr_work *snwp; u_int i; + xo_open_list("work"); for (i = 0; i < work_array_len; i++) { snwp = &work_array[i]; if (snwp->snw_wsid != snwsp->snws_wsid) continue; - printf("%4u ", snwsp->snws_wsid); - printf("%3u ", snwsp->snws_cpu); - printf("%2s", ""); - printf("%-6s", netisr_proto2name(snwp->snw_proto)); - printf(" %5u", snwp->snw_len); - printf(" %5u", snwp->snw_watermark); - printf(" %8ju", snwp->snw_dispatched); - printf(" %8ju", snwp->snw_hybrid_dispatched); - printf(" %8ju", snwp->snw_qdrops); - printf(" %8ju", snwp->snw_queued); - printf(" %8ju", snwp->snw_handled); - printf("\n"); + xo_open_instance("work"); + xo_emit("{t:workstream/%4u} ", snwsp->snws_wsid); + xo_emit("{t:cpu/%3u} ", snwsp->snws_cpu); + xo_emit("{P: }"); + xo_emit("{t:name/%-6s}", netisr_proto2name(snwp->snw_proto)); + xo_emit(" {t:length/%5u}", snwp->snw_len); + xo_emit(" {t:watermark/%5u}", snwp->snw_watermark); + xo_emit(" {t:dispatched/%8ju}", snwp->snw_dispatched); + xo_emit(" {t:hybrid-dispatched/%8ju}", + snwp->snw_hybrid_dispatched); + xo_emit(" {t:queue-drops/%8ju}", snwp->snw_qdrops); + xo_emit(" {t:queued/%8ju}", snwp->snw_queued); + xo_emit(" {t:handled/%8ju}", snwp->snw_handled); + xo_emit("\n"); + xo_close_instance("work"); } + xo_close_list("work"); } void @@ -515,39 +521,55 @@ netisr_stats(void *kvmd) netisr_load_sysctl_work(); } else { if (kd == NULL) - errx(-1, "netisr_stats: !live but !kd"); + xo_errx(-1, "netisr_stats: !live but !kd"); netisr_load_kvm_config(kd); netisr_load_kvm_proto(kd); netisr_load_kvm_workstream(kd); /* Also does work. */ } - printf("Configuration:\n"); - printf("%-25s %12s %12s\n", "Setting", "Current", "Limit"); - printf("%-25s %12u %12u\n", "Thread count", numthreads, maxthreads); - printf("%-25s %12u %12u\n", "Default queue limit", defaultqlimit, - maxqlimit); - printf("%-25s %12s %12s\n", "Dispatch policy", dispatch_policy, + xo_open_container("netisr"); + + xo_emit("{T:Configuration}:\n"); + xo_emit("{T:/%-25s} {T:/%12s} {T:/%12s}\n", + "Setting", "Current", "Limit"); + xo_emit("{T:/%-25s} {T:/%12u} {T:/%12u}\n", + "Thread count", numthreads, maxthreads); + xo_emit("{T:/%-25s} {T:/%12u} {T:/%12u}\n", + "Default queue limit", defaultqlimit, maxqlimit); + xo_emit("{T:/%-25s} {T:/%12s} {T:/%12s}\n", + "Dispatch policy", dispatch_policy, "n/a"); + xo_emit("{T:/%-25s} {T:/%12s} {T:/%12s}\n", + "Threads bound to CPUs", bindthreads ? "enabled" : "disabled", "n/a"); - printf("%-25s %12s %12s\n", "Threads bound to CPUs", - bindthreads ? "enabled" : "disabled", "n/a"); - printf("\n"); + xo_emit("\n"); - printf("Protocols:\n"); - printf("%-6s %5s %6s %-6s %-8s %-5s\n", "Name", "Proto", "QLimit", - "Policy", "Dispatch", "Flags"); + xo_emit("{T:Protocols}:\n"); + xo_emit("{T:/%-6s} {T:/%5s} {T:/%6s} {T:/%-6s} {T:/%-8s} {T:/%-5s}\n", + "Name", "Proto", "QLimit", "Policy", "Dispatch", "Flags"); + xo_open_list("protocol"); for (i = 0; i < proto_array_len; i++) { + xo_open_instance("protocol"); snpp = &proto_array[i]; netisr_print_proto(snpp); + xo_close_instance("protocol"); } - printf("\n"); - - printf("Workstreams:\n"); - printf("%4s %3s ", "WSID", "CPU"); - printf("%2s", ""); - printf("%-6s %5s %5s %8s %8s %8s %8s %8s\n", "Name", "Len", "WMark", - "Disp'd", "HDisp'd", "QDrops", "Queued", "Handled"); + xo_close_list("protocol"); + xo_emit("\n"); + + xo_emit("{T:Workstreams}:\n"); + xo_emit("{T:/%4s} {T:/%3s} ", "WSID", "CPU"); + xo_emit("{P:/%2s}", ""); + xo_emit("{T:/%-6s} {T:/%5s} {T:/%5s} {T:/%8s} {T:/%8s} {T:/%8s} " + "{T:/%8s} {T:/%8s}\n", + "Name", "Len", "WMark", "Disp'd", "HDisp'd", "QDrops", "Queued", + "Handled"); + xo_open_list("workstream"); for (i = 0; i < workstream_array_len; i++) { + xo_open_instance("workstream"); snwsp = &workstream_array[i]; netisr_print_workstream(snwsp); + xo_close_instance("workstream"); } + xo_close_list("workstream"); + xo_close_container("netisr"); } diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1 index 1f2bb01..c9d3e42 100644 --- a/usr.bin/netstat/netstat.1 +++ b/usr.bin/netstat/netstat.1 @@ -28,7 +28,7 @@ .\" @(#)netstat.1 8.8 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd June 4, 2014 +.Dd April 7, 2015 .Dt NETSTAT 1 .Os .Sh NAME @@ -38,58 +38,66 @@ .Bk -words .Bl -tag -width "netstat" .It Nm +.Op Fl -libxo .Op Fl 46AaLnRSTWx .Op Fl f Ar protocol_family | Fl p Ar protocol .Op Fl M Ar core .Op Fl N Ar system .It Nm Fl i | I Ar interface +.Op Fl -libxo .Op Fl 46abdhnW .Op Fl f Ar address_family .Op Fl M Ar core .Op Fl N Ar system .It Nm Fl w Ar wait +.Op Fl -libxo .Op Fl I Ar interface .Op Fl 46d .Op Fl M Ar core .Op Fl N Ar system .Op Fl q Ar howmany .It Nm Fl s +.Op Fl -libxo .Op Fl 46sz .Op Fl f Ar protocol_family | Fl p Ar protocol .Op Fl M Ar core .Op Fl N Ar system .It Nm Fl i | I Ar interface Fl s +.Op Fl -libxo .Op Fl 46s .Op Fl f Ar protocol_family | Fl p Ar protocol .Op Fl M Ar core .Op Fl N Ar system .It Nm Fl m +.Op Fl -libxo .Op Fl M Ar core .Op Fl N Ar system .It Nm Fl B +.Op Fl -libxo .Op Fl z .Op Fl I Ar interface .It Nm Fl r -.Op Fl 46AnW +.Op Fl -libxo +.Op Fl 46nW .Op Fl F Ar fibnum .Op Fl f Ar address_family -.Op Fl M Ar core -.Op Fl N Ar system .It Nm Fl rs +.Op Fl -libxo .Op Fl s .Op Fl M Ar core .Op Fl N Ar system .It Nm Fl g +.Op Fl -libxo .Op Fl 46W .Op Fl f Ar address_family -.Op Fl M Ar core -.Op Fl N Ar system .It Nm Fl gs +.Op Fl -libxo .Op Fl 46s .Op Fl f Ar address_family .Op Fl M Ar core .Op Fl N Ar system .It Nm Fl Q +.Op Fl -libxo .El .Ek .Sh DESCRIPTION @@ -571,9 +579,6 @@ See Show IPv6 only. See .Sx GENERAL OPTIONS . -.It Fl A -Show the contents of the internal Patricia tree -structures; used for debugging. .It Fl n Do not resolve numeric addresses and port numbers to names. See @@ -784,6 +789,8 @@ and display them symbolically. .Xr procstat 1 , .Xr ps 1 , .Xr sockstat 1 , +.Xr libxo 3 , +.Xr xo_parse_args 3 , .Xr bpf 4 , .Xr inet 4 , .Xr route 4 , diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index cb46c0f..29e4d0f 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -108,7 +108,7 @@ struct in6_addr; void in6_fillscopeid(struct sockaddr_in6 *); char *routename6(struct sockaddr_in6 *); const char *netname6(struct sockaddr_in6 *, struct in6_addr *); -void inet6print(struct in6_addr *, int, const char *, int); +void inet6print(const char *, struct in6_addr *, int, const char *, int); #endif /*INET6*/ #ifdef IPSEC @@ -143,7 +143,7 @@ void nserr_stats(u_long, const char *, int, int); void netgraphprotopr(u_long, const char *, int, int); #endif -void unixpr(u_long, u_long, u_long, u_long, u_long); +void unixpr(u_long, u_long, u_long, u_long, u_long, bool *); void esis_stats(u_long, const char *, int, int); void clnp_stats(u_long, const char *, int, int); diff --git a/usr.bin/netstat/pfkey.c b/usr.bin/netstat/pfkey.c index da81485..fbf330f 100644 --- a/usr.bin/netstat/pfkey.c +++ b/usr.bin/netstat/pfkey.c @@ -81,6 +81,8 @@ __FBSDID("$FreeBSD$"); #include <stdio.h> #include <string.h> #include <unistd.h> +#include <stdbool.h> +#include <libxo/xo.h> #include "netstat.h" #ifdef IPSEC @@ -118,59 +120,89 @@ pfkey_stats(u_long off, const char *name, int family __unused, if (off == 0) return; - printf ("%s:\n", name); + xo_emit("{T:/%s}:\n", name); + xo_open_container(name); kread_counters(off, (char *)&pfkeystat, sizeof(pfkeystat)); #define p(f, m) if (pfkeystat.f || sflag <= 1) \ - printf(m, (uintmax_t)pfkeystat.f, plural(pfkeystat.f)) + xo_emit(m, (uintmax_t)pfkeystat.f, plural(pfkeystat.f)) /* userland -> kernel */ - p(out_total, "\t%ju request%s sent from userland\n"); - p(out_bytes, "\t%ju byte%s sent from userland\n"); + p(out_total, "\t{:sent-requests//%ju} " + "{N:/request%s sent from userland}\n"); + p(out_bytes, "\t{:sent-bytes/%ju} " + "{N:/byte%s sent from userland}\n"); for (first = 1, type = 0; - type < sizeof(pfkeystat.out_msgtype)/sizeof(pfkeystat.out_msgtype[0]); - type++) { + type<sizeof(pfkeystat.out_msgtype)/sizeof(pfkeystat.out_msgtype[0]); + type++) { if (pfkeystat.out_msgtype[type] <= 0) continue; if (first) { - printf("\thistogram by message type:\n"); + xo_open_list("output-histogram"); + xo_emit("\t{T:histogram by message type}:\n"); first = 0; } - printf("\t\t%s: %ju\n", pfkey_msgtype_names(type), - (uintmax_t)pfkeystat.out_msgtype[type]); + xo_open_instance("output-histogram"); + xo_emit("\t\t{k::type/%s}: {:count/%ju}\n", + pfkey_msgtype_names(type), + (uintmax_t)pfkeystat.out_msgtype[type]); + xo_close_instance("output-histogram"); } - p(out_invlen, "\t%ju message%s with invalid length field\n"); - p(out_invver, "\t%ju message%s with invalid version field\n"); - p(out_invmsgtype, "\t%ju message%s with invalid message type field\n"); - p(out_tooshort, "\t%ju message%s too short\n"); - p(out_nomem, "\t%ju message%s with memory allocation failure\n"); - p(out_dupext, "\t%ju message%s with duplicate extension\n"); - p(out_invexttype, "\t%ju message%s with invalid extension type\n"); - p(out_invsatype, "\t%ju message%s with invalid sa type\n"); - p(out_invaddr, "\t%ju message%s with invalid address extension\n"); + if (!first) + xo_close_list("output-histogram"); + + p(out_invlen, "\t{:dropped-bad-length/%ju} " + "{N:/message%s with invalid length field}\n"); + p(out_invver, "\t{:dropped-bad-version/%ju} " + "{N:/message%s with invalid version field}\n"); + p(out_invmsgtype, "\t{:dropped-bad-type/%ju} " + "{N:/message%s with invalid message type field}\n"); + p(out_tooshort, "\t{:dropped-too-short/%ju} " + "{N:/message%s too short}\n"); + p(out_nomem, "\t{:dropped-no-memory/%ju} " + "{N:/message%s with memory allocation failure}\n"); + p(out_dupext, "\t{:dropped-duplicate-extension/%ju} " + "{N:/message%s with duplicate extension}\n"); + p(out_invexttype, "\t{:dropped-bad-extension/%ju} " + "{N:/message%s with invalid extension type}\n"); + p(out_invsatype, "\t:dropped-bad-sa-type/%ju} " + "{N:/message%s with invalid sa type}\n"); + p(out_invaddr, "\t{:dropped-bad-address-extension/%ju} " + "{N:/message%s with invalid address extension}\n"); /* kernel -> userland */ - p(in_total, "\t%ju request%s sent to userland\n"); - p(in_bytes, "\t%ju byte%s sent to userland\n"); + p(in_total, "\t{:received-requests/%ju} " + "{N:/request%s sent to userland}\n"); + p(in_bytes, "\t{:received-bytes/%ju} " + "{N:/byte%s sent to userland}\n"); for (first = 1, type = 0; - type < sizeof(pfkeystat.in_msgtype)/sizeof(pfkeystat.in_msgtype[0]); - type++) { + type < sizeof(pfkeystat.in_msgtype)/sizeof(pfkeystat.in_msgtype[0]); + type++) { if (pfkeystat.in_msgtype[type] <= 0) continue; if (first) { - printf("\thistogram by message type:\n"); + xo_open_list("input-histogram"); + xo_emit("\t{T:histogram by message type}:\n"); first = 0; } - printf("\t\t%s: %ju\n", pfkey_msgtype_names(type), - (uintmax_t)pfkeystat.in_msgtype[type]); + xo_open_instance("input-histogram"); + xo_emit("\t\t{k:type/%s}: {:count/%ju}\n", + pfkey_msgtype_names(type), + (uintmax_t)pfkeystat.in_msgtype[type]); + xo_close_instance("input-histogram"); } - p(in_msgtarget[KEY_SENDUP_ONE], - "\t%ju message%s toward single socket\n"); - p(in_msgtarget[KEY_SENDUP_ALL], - "\t%ju message%s toward all sockets\n"); + if (!first) + xo_close_list("input-histogram"); + p(in_msgtarget[KEY_SENDUP_ONE], "\t{:received-one-socket/%ju} " + "{N:/message%s toward single socket}\n"); + p(in_msgtarget[KEY_SENDUP_ALL], "\t{:received-all-sockets/%ju} " + "{N:/message%s toward all sockets}\n"); p(in_msgtarget[KEY_SENDUP_REGISTERED], - "\t%ju message%s toward registered sockets\n"); - p(in_nomem, "\t%ju message%s with memory allocation failure\n"); + "\t{:received-registered-sockets/%ju} " + "{N:/message%s toward registered sockets}\n"); + p(in_nomem, "\t{:discarded-no-memory/%ju} " + "{N:/message%s with memory allocation failure}\n"); #undef p + xo_close_container(name); } #endif /* IPSEC */ diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index 7555615..ab5a3ed 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -40,22 +40,18 @@ __FBSDID("$FreeBSD$"); #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sysctl.h> #include <sys/time.h> #include <net/ethernet.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <net/if_types.h> -#include <net/radix.h> -#define _WANT_RTENTRY #include <net/route.h> #include <netinet/in.h> #include <netgraph/ng_socket.h> -#include <sys/sysctl.h> - #include <arpa/inet.h> #include <ifaddrs.h> #include <libutil.h> @@ -64,39 +60,40 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <sysexits.h> #include <unistd.h> #include <err.h> +#include <libxo/xo.h> #include "netstat.h" -#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) - /* * Definitions for showing gateway flags. */ struct bits { u_long b_mask; char b_val; + const char *b_name; } bits[] = { - { RTF_UP, 'U' }, - { RTF_GATEWAY, 'G' }, - { RTF_HOST, 'H' }, - { RTF_REJECT, 'R' }, - { RTF_DYNAMIC, 'D' }, - { RTF_MODIFIED, 'M' }, - { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ - { RTF_XRESOLVE, 'X' }, - { RTF_STATIC, 'S' }, - { RTF_PROTO1, '1' }, - { RTF_PROTO2, '2' }, - { RTF_PROTO3, '3' }, - { RTF_BLACKHOLE,'B' }, - { RTF_BROADCAST,'b' }, + { RTF_UP, 'U', "up" }, + { RTF_GATEWAY, 'G', "gateway" }, + { RTF_HOST, 'H', "host" }, + { RTF_REJECT, 'R', "reject" }, + { RTF_DYNAMIC, 'D', "dynamic" }, + { RTF_MODIFIED, 'M', "modified" }, + { RTF_DONE, 'd', "done" }, /* Completed -- for routing msgs only */ + { RTF_XRESOLVE, 'X', "xresolve" }, + { RTF_STATIC, 'S', "static" }, + { RTF_PROTO1, '1', "proto1" }, + { RTF_PROTO2, '2', "proto2" }, + { RTF_PROTO3, '3', "proto3" }, + { RTF_BLACKHOLE,'B', "blackhole" }, + { RTF_BROADCAST,'b', "broadcast" }, #ifdef RTF_LLINFO - { RTF_LLINFO, 'L' }, + { RTF_LLINFO, 'L', "llinfo" }, #endif - { 0 , 0 } + { 0 , 0, NULL } }; /* @@ -105,9 +102,7 @@ struct bits { static struct nlist rl[] = { #define N_RTSTAT 0 { .n_name = "_rtstat" }, -#define N_RTREE 1 - { .n_name = "_rt_tables"}, -#define N_RTTRASH 2 +#define N_RTTRASH 1 { .n_name = "_rttrash" }, { .n_name = NULL }, }; @@ -118,39 +113,21 @@ typedef union { u_short u_data[128]; } sa_u; -static sa_u pt_u; - struct ifmap_entry { char ifname[IFNAMSIZ]; }; - static struct ifmap_entry *ifmap; static int ifmap_size; - -int do_rtent = 0; -struct rtentry rtentry; -struct radix_node rnode; -struct radix_mask rmask; - -int NewTree = 1; - struct timespec uptime; -static struct sockaddr *kgetsa(struct sockaddr *); -static void size_cols(int ef, struct radix_node *rn); -static void size_cols_tree(struct radix_node *rn); -static void size_cols_rtentry(struct rtentry *rt); -static void p_rtnode_kvm(void); static void p_rtable_sysctl(int, int); -static void p_rtable_kvm(int, int ); -static void p_rtree_kvm(struct radix_node *); -static void p_rtentry_sysctl(struct rt_msghdr *); -static void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); +static void p_rtentry_sysctl(const char *name, struct rt_msghdr *); +static void p_sockaddr(const char *name, struct sockaddr *, struct sockaddr *, + int, int); static const char *fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags); static void p_flags(int, const char *); static const char *fmt_flags(int f); -static void p_rtentry_kvm(struct rtentry *); static void domask(char *, in_addr_t, u_long); /* @@ -162,6 +139,9 @@ routepr(int fibnum, int af) size_t intsize; int numfibs; + if (live == 0) + return; + intsize = sizeof(int); if (fibnum == -1 && sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1) @@ -178,15 +158,13 @@ routepr(int fibnum, int af) if (clock_gettime(CLOCK_UPTIME, &uptime) < 0) err(EX_OSERR, "clock_gettime() failed"); - printf("Routing tables"); + xo_open_container("route-information"); + xo_emit("{T:Routing tables}"); if (fibnum) - printf(" (fib: %d)", fibnum); - printf("\n"); - - if (Aflag == 0 && live != 0 && NewTree) - p_rtable_sysctl(fibnum, af); - else - p_rtable_kvm(fibnum, af); + xo_emit(" ({L:fib}: {:fib/%d})", fibnum); + xo_emit("\n"); + p_rtable_sysctl(fibnum, af); + xo_close_container("route-information"); } @@ -221,9 +199,9 @@ pr_family(int af1) break; } if (afname) - printf("\n%s:\n", afname); + xo_emit("\n{k:address-family/%s}:\n", afname); else - printf("\nProtocol Family %d:\n", af1); + xo_emit("\n{L:Protocol Family} {k:address-family/%d}:\n", af1); } /* column widths; each followed by one space */ @@ -247,100 +225,6 @@ static int wid_mtu; static int wid_if; static int wid_expire; -static void -size_cols(int ef, struct radix_node *rn) -{ - wid_dst = WID_DST_DEFAULT(ef); - wid_gw = WID_GW_DEFAULT(ef); - wid_flags = 6; - wid_pksent = 8; - wid_mtu = 6; - wid_if = WID_IF_DEFAULT(ef); - wid_expire = 6; - - if (Wflag && rn != NULL) - size_cols_tree(rn); -} - -static void -size_cols_tree(struct radix_node *rn) -{ -again: - if (kget(rn, rnode) != 0) - return; - if (!(rnode.rn_flags & RNF_ACTIVE)) - return; - if (rnode.rn_bit < 0) { - if ((rnode.rn_flags & RNF_ROOT) == 0) { - if (kget(rn, rtentry) != 0) - return; - size_cols_rtentry(&rtentry); - } - if ((rn = rnode.rn_dupedkey)) - goto again; - } else { - rn = rnode.rn_right; - size_cols_tree(rnode.rn_left); - size_cols_tree(rn); - } -} - -static void -size_cols_rtentry(struct rtentry *rt) -{ - static struct ifnet ifnet, *lastif; - static char buffer[100]; - const char *bp; - struct sockaddr *sa; - sa_u addr, mask; - int len; - - bzero(&addr, sizeof(addr)); - if ((sa = kgetsa(rt_key(rt)))) - bcopy(sa, &addr, sa->sa_len); - bzero(&mask, sizeof(mask)); - if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt)))) - bcopy(sa, &mask, sa->sa_len); - bp = fmt_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags); - len = strlen(bp); - wid_dst = MAX(len, wid_dst); - - bp = fmt_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST); - len = strlen(bp); - wid_gw = MAX(len, wid_gw); - - bp = fmt_flags(rt->rt_flags); - len = strlen(bp); - wid_flags = MAX(len, wid_flags); - - if (Wflag) { - len = snprintf(buffer, sizeof(buffer), "%ju", - (uintmax_t )kread_counter((u_long )rt->rt_pksent)); - wid_pksent = MAX(len, wid_pksent); - } - if (rt->rt_ifp) { - if (rt->rt_ifp != lastif) { - if (kget(rt->rt_ifp, ifnet) == 0) - len = strlen(ifnet.if_xname); - else - len = strlen("---"); - lastif = rt->rt_ifp; - wid_if = MAX(len, wid_if); - } - if (rt->rt_expire) { - time_t expire_time; - - if ((expire_time = - rt->rt_expire - uptime.tv_sec) > 0) { - len = snprintf(buffer, sizeof(buffer), "%d", - (int)expire_time); - wid_expire = MAX(len, wid_expire); - } - } - } -} - - /* * Print header for routing table columns. */ @@ -349,9 +233,10 @@ pr_rthdr(int af1) { if (Aflag) - printf("%-8.8s ","Address"); + xo_emit("{T:/%-8.8s} ","Address"); if (Wflag) { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n", + xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} " + "{T:/%*.*s} {T:/%*.*s} {T:/%*s}\n", wid_dst, wid_dst, "Destination", wid_gw, wid_gw, "Gateway", wid_flags, wid_flags, "Flags", @@ -360,7 +245,8 @@ pr_rthdr(int af1) wid_if, wid_if, "Netif", wid_expire, "Expire"); } else { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*s\n", + xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} " + "{T:/%*s}\n", wid_dst, wid_dst, "Destination", wid_gw, wid_gw, "Gateway", wid_flags, wid_flags, "Flags", @@ -369,168 +255,6 @@ pr_rthdr(int af1) } } -static struct sockaddr * -kgetsa(struct sockaddr *dst) -{ - - if (kget(dst, pt_u.u_sa) != 0) - return (NULL); - if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) - kread((u_long)dst, (char *)pt_u.u_data, pt_u.u_sa.sa_len); - return (&pt_u.u_sa); -} - -/* - * Print kernel routing tables for given fib - * using debugging kvm(3) interface. - */ -static void -p_rtable_kvm(int fibnum, int af) -{ - struct radix_node_head **rnhp, *rnh, head; - struct radix_node_head **rt_tables; - u_long rtree; - int fam, af_size; - - kresolve_list(rl); - if ((rtree = rl[N_RTREE].n_value) == 0) { - printf("rt_tables: symbol not in namelist\n"); - return; - } - - af_size = (AF_MAX + 1) * sizeof(struct radix_node_head *); - rt_tables = calloc(1, af_size); - if (rt_tables == NULL) - err(EX_OSERR, "memory allocation failed"); - - if (kread((u_long)(rtree), (char *)(rt_tables) + fibnum * af_size, - af_size) != 0) - err(EX_OSERR, "error retrieving radix pointers"); - for (fam = 0; fam <= AF_MAX; fam++) { - int tmpfib; - - switch (fam) { - case AF_INET6: - case AF_INET: - tmpfib = fibnum; - break; - default: - tmpfib = 0; - } - rnhp = (struct radix_node_head **)*rt_tables; - /* Calculate the in-kernel address. */ - rnhp += tmpfib * (AF_MAX + 1) + fam; - /* Read the in kernel rhn pointer. */ - if (kget(rnhp, rnh) != 0) - continue; - if (rnh == NULL) - continue; - /* Read the rnh data. */ - if (kget(rnh, head) != 0) - continue; - if (fam == AF_UNSPEC) { - if (Aflag && af == 0) { - printf("Netmasks:\n"); - p_rtree_kvm(head.rnh_treetop); - } - } else if (af == AF_UNSPEC || af == fam) { - size_cols(fam, head.rnh_treetop); - pr_family(fam); - do_rtent = 1; - pr_rthdr(fam); - p_rtree_kvm(head.rnh_treetop); - } - } - - free(rt_tables); -} - -/* - * Print given kernel radix tree using - * debugging kvm(3) interface. - */ -static void -p_rtree_kvm(struct radix_node *rn) -{ - -again: - if (kget(rn, rnode) != 0) - return; - if (!(rnode.rn_flags & RNF_ACTIVE)) - return; - if (rnode.rn_bit < 0) { - if (Aflag) - printf("%-8.8lx ", (u_long)rn); - if (rnode.rn_flags & RNF_ROOT) { - if (Aflag) - printf("(root node)%s", - rnode.rn_dupedkey ? " =>\n" : "\n"); - } else if (do_rtent) { - if (kget(rn, rtentry) == 0) { - p_rtentry_kvm(&rtentry); - if (Aflag) - p_rtnode_kvm(); - } - } else { - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), - NULL, 0, 44); - putchar('\n'); - } - if ((rn = rnode.rn_dupedkey)) - goto again; - } else { - if (Aflag && do_rtent) { - printf("%-8.8lx ", (u_long)rn); - p_rtnode_kvm(); - } - rn = rnode.rn_right; - p_rtree_kvm(rnode.rn_left); - p_rtree_kvm(rn); - } -} - -char nbuf[20]; - -static void -p_rtnode_kvm(void) -{ - struct radix_mask *rm = rnode.rn_mklist; - - if (rnode.rn_bit < 0) { - if (rnode.rn_mask) { - printf("\t mask "); - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask), - NULL, 0, -1); - } else if (rm == 0) - return; - } else { - sprintf(nbuf, "(%d)", rnode.rn_bit); - printf("%6.6s %8.8lx : %8.8lx", nbuf, (u_long)rnode.rn_left, (u_long)rnode.rn_right); - } - while (rm) { - if (kget(rm, rmask) != 0) - break; - sprintf(nbuf, " %d refs, ", rmask.rm_refs); - printf(" mk = %8.8lx {(%d),%s", - (u_long)rm, -1 - rmask.rm_bit, rmask.rm_refs ? nbuf : " "); - if (rmask.rm_flags & RNF_NORMAL) { - struct radix_node rnode_aux; - printf(" <normal>, "); - if (kget(rmask.rm_leaf, rnode_aux) == 0) - p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask), - NULL, 0, -1); - else - p_sockaddr(NULL, NULL, 0, -1); - } else - p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), - NULL, 0, -1); - putchar('}'); - if ((rm = rmask.rm_mklist)) - printf(" ->"); - } - putchar('\n'); -} - static void p_rtable_sysctl(int fibnum, int af) { @@ -539,7 +263,8 @@ p_rtable_sysctl(int fibnum, int af) char *buf, *next, *lim; struct rt_msghdr *rtm; struct sockaddr *sa; - int fam = 0, ifindex = 0, size; + int fam = AF_UNSPEC, ifindex = 0, size; + int need_table_close = false; struct ifaddrs *ifap, *ifa; struct sockaddr_dl *sdl; @@ -566,7 +291,7 @@ p_rtable_sysctl(int fibnum, int af) errx(2, "realloc(%d) failed", size); memset(&ifmap[ifmap_size], 0, size - ifmap_size * - sizeof(struct ifmap_entry)); + sizeof(struct ifmap_entry)); ifmap_size = roundup(ifindex + 1, 32); } @@ -594,6 +319,8 @@ p_rtable_sysctl(int fibnum, int af) if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum); lim = buf + needed; + xo_open_container("route-table"); + xo_open_list("rt-family"); for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; if (rtm->rtm_version != RTM_VERSION) @@ -602,19 +329,41 @@ p_rtable_sysctl(int fibnum, int af) * Peek inside header to determine AF */ sa = (struct sockaddr *)(rtm + 1); + /* Only print family first time. */ if (fam != sa->sa_family) { + if (need_table_close) { + xo_close_list("rt-entry"); + xo_close_instance("rt-family"); + } + need_table_close = true; + fam = sa->sa_family; - size_cols(fam, NULL); + wid_dst = WID_DST_DEFAULT(fam); + wid_gw = WID_GW_DEFAULT(fam); + wid_flags = 6; + wid_pksent = 8; + wid_mtu = 6; + wid_if = WID_IF_DEFAULT(fam); + wid_expire = 6; + xo_open_instance("rt-family"); pr_family(fam); + xo_open_list("rt-entry"); + pr_rthdr(fam); } - p_rtentry_sysctl(rtm); + p_rtentry_sysctl("rt-entry", rtm); } + if (need_table_close) { + xo_close_list("rt-entry"); + xo_close_instance("rt-family"); + } + xo_close_list("rt-family"); + xo_close_container("route-table"); free(buf); } static void -p_rtentry_sysctl(struct rt_msghdr *rtm) +p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm) { struct sockaddr *sa = (struct sockaddr *)(rtm + 1); char buffer[128]; @@ -622,6 +371,8 @@ p_rtentry_sysctl(struct rt_msghdr *rtm) sa_u addr, mask, gw; unsigned int l; + xo_open_instance(name); + #define GETSA(_s, _f) { \ bzero(&(_s), sizeof(_s)); \ if (rtm->rtm_addrs & _f) { \ @@ -634,18 +385,20 @@ p_rtentry_sysctl(struct rt_msghdr *rtm) GETSA(addr, RTA_DST); GETSA(gw, RTA_GATEWAY); GETSA(mask, RTA_NETMASK); - p_sockaddr(&addr.u_sa, &mask.u_sa, rtm->rtm_flags, wid_dst); - p_sockaddr(&gw.u_sa, NULL, RTF_HOST, wid_gw); - snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); + p_sockaddr("destination", &addr.u_sa, &mask.u_sa, rtm->rtm_flags, + wid_dst); + p_sockaddr("gateway", &gw.u_sa, NULL, RTF_HOST, wid_gw); + snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:} ", + wid_flags); p_flags(rtm->rtm_flags, buffer); if (Wflag) { - printf("%*lu ", wid_pksent, rtm->rtm_rmx.rmx_pksent); + xo_emit("{t:use/%*lu} ", wid_pksent, rtm->rtm_rmx.rmx_pksent); if (rtm->rtm_rmx.rmx_mtu != 0) - printf("%*lu ", wid_mtu, rtm->rtm_rmx.rmx_mtu); + xo_emit("{t:mtu/%*lu} ", wid_mtu, rtm->rtm_rmx.rmx_mtu); else - printf("%*s ", wid_mtu, ""); + xo_emit("{P:/%*s} ", wid_mtu, ""); } memset(prettyname, 0, sizeof(prettyname)); @@ -656,32 +409,41 @@ p_rtentry_sysctl(struct rt_msghdr *rtm) strlcpy(prettyname, "---", sizeof(prettyname)); } - printf("%*.*s", wid_if, wid_if, prettyname); + xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if, prettyname); if (rtm->rtm_rmx.rmx_expire) { time_t expire_time; - if ((expire_time = - rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0) - printf(" %*d", wid_expire, (int)expire_time); + if ((expire_time = rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0) + xo_emit(" {:expire-time/%*d}", wid_expire, + (int)expire_time); } - putchar('\n'); + xo_emit("\n"); + xo_close_instance(name); } static void -p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) +p_sockaddr(const char *name, struct sockaddr *sa, struct sockaddr *mask, + int flags, int width) { const char *cp; + char buf[128]; cp = fmt_sockaddr(sa, mask, flags); - if (width < 0 ) - printf("%s ", cp); - else { - if (numeric_addr) - printf("%-*s ", width, cp); - else - printf("%-*.*s ", width, width, cp); + if (width < 0) { + snprintf(buf, sizeof(buf), "{:%s/%%s} ", name); + xo_emit(buf, cp); + } else { + if (numeric_addr) { + snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%s}{]:} ", + -width, name); + xo_emit(buf, cp); + } else { + snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%-.*s}{]:} ", + -width, name); + xo_emit(buf, width, cp); + } } } @@ -742,7 +504,7 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) case AF_NETGRAPH: { strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data, - sizeof(workbuf)); + sizeof(workbuf)); cp = workbuf; break; } @@ -798,7 +560,15 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) static void p_flags(int f, const char *format) { - printf(format, fmt_flags(f)); + struct bits *p; + + xo_emit(format, fmt_flags(f)); + + xo_open_list("flags_pretty"); + for (p = bits; p->b_mask; p++) + if (p->b_mask & f) + xo_emit("{le:flags_pretty/%s}", p->b_name); + xo_close_list("flags_pretty"); } static const char * @@ -815,57 +585,6 @@ fmt_flags(int f) return (name); } -static void -p_rtentry_kvm(struct rtentry *rt) -{ - static struct ifnet ifnet, *lastif; - static char buffer[128]; - static char prettyname[128]; - struct sockaddr *sa; - sa_u addr, mask; - - bzero(&addr, sizeof(addr)); - if ((sa = kgetsa(rt_key(rt)))) - bcopy(sa, &addr, sa->sa_len); - bzero(&mask, sizeof(mask)); - if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt)))) - bcopy(sa, &mask, sa->sa_len); - p_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags, wid_dst); - p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw); - snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); - p_flags(rt->rt_flags, buffer); - if (Wflag) { - printf("%*ju ", wid_pksent, - (uintmax_t )kread_counter((u_long )rt->rt_pksent)); - - if (rt->rt_mtu != 0) - printf("%*lu ", wid_mtu, rt->rt_mtu); - else - printf("%*s ", wid_mtu, ""); - } - if (rt->rt_ifp) { - if (rt->rt_ifp != lastif) { - if (kget(rt->rt_ifp, ifnet) == 0) - strlcpy(prettyname, ifnet.if_xname, - sizeof(prettyname)); - else - strlcpy(prettyname, "---", sizeof(prettyname)); - lastif = rt->rt_ifp; - } - printf("%*.*s", wid_if, wid_if, prettyname); - if (rt->rt_expire) { - time_t expire_time; - - if ((expire_time = - rt->rt_expire - uptime.tv_sec) > 0) - printf(" %*d", wid_expire, (int)expire_time); - } - if (rt->rt_nodes[0].rn_dupedkey) - printf(" =>"); - } - putchar('\n'); -} - char * routename(in_addr_t in) { @@ -1022,7 +741,7 @@ netname6(struct sockaddr_in6 *sa6, struct in6_addr *mask) } } if (illegal) - fprintf(stderr, "illegal prefixlen\n"); + xo_error("illegal prefixlen\n"); } else masklen = 128; @@ -1077,28 +796,34 @@ rt_stats(void) kresolve_list(rl); if ((rtsaddr = rl[N_RTSTAT].n_value) == 0) { - printf("rtstat: symbol not in namelist\n"); + xo_emit("{W:rtstat: symbol not in namelist}\n"); return; } if ((rttaddr = rl[N_RTTRASH].n_value) == 0) { - printf("rttrash: symbol not in namelist\n"); + xo_emit("{W:rttrash: symbol not in namelist}\n"); return; } kread(rtsaddr, (char *)&rtstat, sizeof (rtstat)); kread(rttaddr, (char *)&rttrash, sizeof (rttrash)); - printf("routing:\n"); + xo_emit("{T:routing}:\n"); #define p(f, m) if (rtstat.f || sflag <= 1) \ - printf(m, rtstat.f, plural(rtstat.f)) - - p(rts_badredirect, "\t%hu bad routing redirect%s\n"); - p(rts_dynamic, "\t%hu dynamically created route%s\n"); - p(rts_newgateway, "\t%hu new gateway%s due to redirects\n"); - p(rts_unreach, "\t%hu destination%s found unreachable\n"); - p(rts_wildcard, "\t%hu use%s of a wildcard route\n"); + xo_emit(m, rtstat.f, plural(rtstat.f)) + + p(rts_badredirect, "\t{:bad-redirects/%hu} " + "{N:/bad routing redirect%s}\n"); + p(rts_dynamic, "\t{:dynamically-created/%hu} " + "{N:/dynamically created route%s}\n"); + p(rts_newgateway, "\t{:new-gateways/%hu} " + "{N:/new gateway%s due to redirects}\n"); + p(rts_unreach, "\t{:unreachable-destination/%hu} " + "{N:/destination%s found unreachable}\n"); + p(rts_wildcard, "\t{:wildcard-uses/%hu} " + "{N:/use%s of a wildcard route}\n"); #undef p if (rttrash || sflag <= 1) - printf("\t%u route%s not in table but not freed\n", + xo_emit("\t{:unused-but-not-freed/%u} " + "{N:/route%s not in table but not freed}\n", rttrash, plural(rttrash)); } diff --git a/usr.bin/netstat/sctp.c b/usr.bin/netstat/sctp.c index a2ef7d568..cdbbc49 100644 --- a/usr.bin/netstat/sctp.c +++ b/usr.bin/netstat/sctp.c @@ -58,9 +58,11 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <unistd.h> #include "netstat.h" +#include <libxo/xo.h> #ifdef SCTP @@ -98,8 +100,8 @@ struct xladdr_entry { LIST_HEAD(xraddr_list, xraddr_entry) xraddr_head; struct xraddr_entry { - struct xsctp_raddr *xraddr; - LIST_ENTRY(xraddr_entry) xraddr_entries; + struct xsctp_raddr *xraddr; + LIST_ENTRY(xraddr_entry) xraddr_entries; }; /* @@ -192,12 +194,16 @@ inet6name(struct in6_addr *in6p) #endif static void -sctp_print_address(union sctp_sockstore *address, int port, int num_port) +sctp_print_address(const char *container, union sctp_sockstore *address, + int port, int num_port) { struct servent *sp = 0; char line[80], *cp; int width; + if (container) + xo_open_container(container); + switch (address->sa.sa_family) { #ifdef INET case AF_INET: @@ -221,7 +227,14 @@ sctp_print_address(union sctp_sockstore *address, int port, int num_port) else sprintf(cp, "%d ", ntohs((u_short)port)); width = Wflag ? 45 : 22; - printf("%-*.*s ", width, width, line); + xo_emit("{d:target/%-*.*s} ", width, width, line); + + int alen = cp - line - 1, plen = strlen(cp) - 1; + xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen, + plen, cp); + + if (container) + xo_close_container(container); } static int @@ -297,7 +310,7 @@ sctp_process_tcb(struct xsctp_tcb *xstcb, prev_xl = xl; xl = malloc(sizeof(struct xladdr_entry)); if (xl == NULL) { - warnx("malloc %lu bytes", + xo_warnx("malloc %lu bytes", (u_long)sizeof(struct xladdr_entry)); goto out; } @@ -318,7 +331,7 @@ sctp_process_tcb(struct xsctp_tcb *xstcb, prev_xr = xr; xr = malloc(sizeof(struct xraddr_entry)); if (xr == NULL) { - warnx("malloc %lu bytes", + xo_warnx("malloc %lu bytes", (u_long)sizeof(struct xraddr_entry)); goto out; } @@ -333,26 +346,29 @@ sctp_process_tcb(struct xsctp_tcb *xstcb, /* * Let's print the address infos. */ + xo_open_list("address"); xl = LIST_FIRST(&xladdr_head); xr = LIST_FIRST(&xraddr_head); x_max = (xl_total > xr_total) ? xl_total : xr_total; for (i = 0; i < x_max; i++) { + xo_open_instance("address"); + if (((*indent == 0) && i > 0) || *indent > 0) - printf("%-12s ", " "); + xo_emit("{P:/%-12s} ", " "); if (xl != NULL) { - sctp_print_address(&(xl->xladdr->address), + sctp_print_address("local", &(xl->xladdr->address), htons(xstcb->local_port), numeric_port); } else { if (Wflag) { - printf("%-45s ", " "); + xo_emit("{P:/%-45s} ", " "); } else { - printf("%-22s ", " "); + xo_emit("{P:/%-22s} ", " "); } } if (xr != NULL && !Lflag) { - sctp_print_address(&(xr->xraddr->address), + sctp_print_address("remote", &(xr->xraddr->address), htons(xstcb->remote_port), numeric_port); } @@ -365,7 +381,8 @@ sctp_process_tcb(struct xsctp_tcb *xstcb, sctp_statesprint(xstcb->state); if (i < x_max) - putchar('\n'); + xo_emit("\n"); + xo_close_instance("address"); } out: @@ -404,23 +421,26 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb, if (first) { if (!Lflag) { - printf("Active SCTP associations"); + xo_emit("Active SCTP associations"); if (aflag) - printf(" (including servers)"); + xo_emit(" (including servers)"); } else - printf("Current listen queue sizes (qlen/maxqlen)"); - putchar('\n'); + xo_emit("Current listen queue sizes (qlen/maxqlen)"); + xo_emit("\n"); if (Lflag) - printf("%-6.6s %-5.5s %-8.8s %-22.22s\n", + xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-8.8s} " + "{T:/%-22.22s}\n", "Proto", "Type", "Listen", "Local Address"); else if (Wflag) - printf("%-6.6s %-5.5s %-45.45s %-45.45s %s\n", + xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-45.45s} " + "{T:/%-45.45s} {T:/%s}\n", "Proto", "Type", "Local Address", "Foreign Address", "(state)"); else - printf("%-6.6s %-5.5s %-22.22s %-22.22s %s\n", + xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-22.22s} " + "{T:/%-22.22s} {T:/%s}\n", "Proto", "Type", "Local Address", "Foreign Address", "(state)"); @@ -450,27 +470,38 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb, char buf1[9]; snprintf(buf1, 9, "%hu/%hu", xinpcb->qlen, xinpcb->maxqlen); - printf("%-6.6s %-5.5s ", pname, tname); - printf("%-8.8s ", buf1); + xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ", + pname, tname); + xo_emit("{d:queues/%-8.8s}{e:queue-len/%hu}" + "{e:max-queue-len/%hu} ", + buf1, xinpcb->qlen, xinpcb->maxqlen); } offset_laddr = *offset; process_closed = 0; + + xo_open_list("local-address"); retry: while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); if (xladdr->last) { if (aflag && !Lflag && (xladdr_total == 0) && process_closed) { - printf("%-6.6s %-5.5s ", pname, tname); + xo_open_instance("local-address"); + + xo_emit("{:protocol/%-6.6s/%s} " + "{:type/%-5.5s/%s} ", pname, tname); if (Wflag) { - printf("%-91.91s CLOSED", " "); + xo_emit("{P:/%-91.91s/%s} " + "{:state/CLOSED}", " "); } else { - printf("%-45.45s CLOSED", " "); + xo_emit("{P:/%-45.45s/%s} " + "{:state/CLOSED}", " "); } + xo_close_instance("local-address"); } if (process_closed || is_listening) { - putchar('\n'); + xo_emit("\n"); } break; } @@ -478,31 +509,39 @@ retry: if (!Lflag && !is_listening && !process_closed) continue; + xo_open_instance("local-address"); + if (xladdr_total == 0) { - printf("%-6.6s %-5.5s ", pname, tname); + xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ", + pname, tname); } else { - putchar('\n'); - printf((Lflag) ? - "%-21.21s " : "%-12.12s ", " "); + xo_emit("\n"); + xo_emit(Lflag ? "{P:/%-21.21s} " : "{P:/%-12.12s} ", + " "); } - sctp_print_address(&(xladdr->address), + sctp_print_address("local", &(xladdr->address), htons(xinpcb->local_port), numeric_port); if (aflag && !Lflag && xladdr_total == 0) { if (Wflag) { if (process_closed) { - printf("%-45.45s CLOSED", " "); + xo_emit("{P:/%-45.45s} " + "{:state/CLOSED}", " "); } else { - printf("%-45.45s LISTEN", " "); + xo_emit("{P:/%-45.45s} " + "{:state:LISTEN}", " "); } } else { if (process_closed) { - printf("%-22.22s CLOSED", " "); + xo_emit("{P:/%-22.22s} " + "{:state/CLOSED}", " "); } else { - printf("%-22.22s LISTEN", " "); + xo_emit("{P:/%-22.22s} " + "{:state/LISTEN}", " "); } } } xladdr_total++; + xo_close_instance("local-address"); } xstcb = (struct xsctp_tcb *)(buf + *offset); @@ -513,12 +552,15 @@ retry: goto retry; } while (xstcb->last == 0 && *offset < buflen) { - printf("%-6.6s %-5.5s ", pname, tname); + xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ", + pname, tname); sctp_process_tcb(xstcb, buf, buflen, offset, &indent); indent++; xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); } + + xo_close_list("local-address"); } /* @@ -540,15 +582,15 @@ sctp_protopr(u_long off __unused, if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { if (errno != ENOENT) - warn("sysctl: %s", mibvar); + xo_warn("sysctl: %s", mibvar); return; } if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); + xo_warnx("malloc %lu bytes", (u_long)len); return; } if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { - warn("sysctl: %s", mibvar); + xo_warn("sysctl: %s", mibvar); free(buf); return; } @@ -594,11 +636,11 @@ sctp_statesprint(uint32_t state) idx = NETSTAT_SCTP_STATES_SHUTDOWN_PENDING; break; default: - printf("UNKNOWN 0x%08x", state); + xo_emit("UNKNOWN {:state/0x%08x}", state); return; } - printf("%s", sctpstates[idx]); + xo_emit("{:state/%s}", sctpstates[idx]); } /* @@ -616,96 +658,160 @@ sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) if (sysctlbyname("net.inet.sctp.stats", &sctpstat, &len, zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { if (errno != ENOENT) - warn("sysctl: net.inet.sctp.stats"); + xo_warn("sysctl: net.inet.sctp.stats"); return; } } else kread(off, &sctpstat, len); - printf ("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (sctpstat.f || sflag <= 1) \ - printf(m, (uintmax_t)sctpstat.f, plural(sctpstat.f)) + xo_emit(m, (uintmax_t)sctpstat.f, plural(sctpstat.f)) #define p1a(f, m) if (sctpstat.f || sflag <= 1) \ - printf(m, (uintmax_t)sctpstat.f) + xo_emit(m, (uintmax_t)sctpstat.f) /* * input statistics */ - p(sctps_recvpackets, "\t%ju input packet%s\n"); - p(sctps_recvdatagrams, "\t\t%ju datagram%s\n"); - p(sctps_recvpktwithdata, "\t\t%ju packet%s that had data\n"); - p(sctps_recvsacks, "\t\t%ju input SACK chunk%s\n"); - p(sctps_recvdata, "\t\t%ju input DATA chunk%s\n"); - p(sctps_recvdupdata, "\t\t%ju duplicate DATA chunk%s\n"); - p(sctps_recvheartbeat, "\t\t%ju input HB chunk%s\n"); - p(sctps_recvheartbeatack, "\t\t%ju HB-ACK chunk%s\n"); - p(sctps_recvecne, "\t\t%ju input ECNE chunk%s\n"); - p(sctps_recvauth, "\t\t%ju input AUTH chunk%s\n"); - p(sctps_recvauthmissing, "\t\t%ju chunk%s missing AUTH\n"); - p(sctps_recvivalhmacid, "\t\t%ju invalid HMAC id%s received\n"); - p(sctps_recvivalkeyid, "\t\t%ju invalid secret id%s received\n"); - p1a(sctps_recvauthfailed, "\t\t%ju auth failed\n"); - p1a(sctps_recvexpress, "\t\t%ju fast path receives all one chunk\n"); - p1a(sctps_recvexpressm, "\t\t%ju fast path multi-part data\n"); + p(sctps_recvpackets, "\t{:received-packets/%ju} " + "{N:/input packet%s}\n"); + p(sctps_recvdatagrams, "\t\t{:received-datagrams/%ju} " + "{N:/datagram%s}\n"); + p(sctps_recvpktwithdata, "\t\t{:received-with-data/%ju} " + "{N:/packet%s that had data}\n"); + p(sctps_recvsacks, "\t\t{:received-sack-chunks/%ju} " + "{N:/input SACK chunk%s}\n"); + p(sctps_recvdata, "\t\t{:received-data-chunks/%ju} " + "{N:/input DATA chunk%s}\n"); + p(sctps_recvdupdata, "\t\t{:received-duplicate-data-chunks/%ju} " + "{N:/duplicate DATA chunk%s}\n"); + p(sctps_recvheartbeat, "\t\t{:received-hb-chunks/%ju} " + "{N:/input HB chunk%s}\n"); + p(sctps_recvheartbeatack, "\t\t{:received-hb-ack-chunks/%ju} " + "{N:/HB-ACK chunk%s}\n"); + p(sctps_recvecne, "\t\t{:received-ecne-chunks/%ju} " + "{N:/input ECNE chunk%s}\n"); + p(sctps_recvauth, "\t\t{:received-auth-chunks/%ju} " + "{N:/input AUTH chunk%s}\n"); + p(sctps_recvauthmissing, "\t\t{:dropped-missing-auth/%ju} " + "{N:/chunk%s missing AUTH}\n"); + p(sctps_recvivalhmacid, "\t\t{:dropped-invalid-hmac/%ju} " + "{N:/invalid HMAC id%s received}\n"); + p(sctps_recvivalkeyid, "\t\t{:dropped-invalid-secret/%ju} " + "{N:/invalid secret id%s received}\n"); + p1a(sctps_recvauthfailed, "\t\t{:dropped-auth-failed/%ju} " + "{N:/auth failed}\n"); + p1a(sctps_recvexpress, "\t\t{:received-fast-path/%ju} " + "{N:/fast path receives all one chunk}\n"); + p1a(sctps_recvexpressm, "\t\t{:receives-fast-path-multipart/%ju} " + "{N:/fast path multi-part data}\n"); /* * output statistics */ - p(sctps_sendpackets, "\t%ju output packet%s\n"); - p(sctps_sendsacks, "\t\t%ju output SACK%s\n"); - p(sctps_senddata, "\t\t%ju output DATA chunk%s\n"); - p(sctps_sendretransdata, "\t\t%ju retransmitted DATA chunk%s\n"); - p(sctps_sendfastretrans, "\t\t%ju fast retransmitted DATA chunk%s\n"); - p(sctps_sendmultfastretrans, "\t\t%ju FR'%s that happened more " - "than once to same chunk\n"); - p(sctps_sendheartbeat, "\t\t%ju output HB chunk%s\n"); - p(sctps_sendecne, "\t\t%ju output ECNE chunk%s\n"); - p(sctps_sendauth, "\t\t%ju output AUTH chunk%s\n"); - p1a(sctps_senderrors, "\t\t%ju ip_output error counter\n"); + p(sctps_sendpackets, "\t{:sent-packets/%ju} " + "{N:/output packet%s}\n"); + p(sctps_sendsacks, "\t\t{:sent-sacks/%ju} " + "{N:/output SACK%s}\n"); + p(sctps_senddata, "\t\t{:sent-data-chunks/%ju} " + "{N:/output DATA chunk%s}\n"); + p(sctps_sendretransdata, "\t\t{:sent-retransmitted-data-chunks/%ju} " + "{N:/retransmitted DATA chunk%s}\n"); + p(sctps_sendfastretrans, "\t\t" + "{:sent-fast-retransmitted-data-chunks/%ju} " + "{N:/fast retransmitted DATA chunk%s}\n"); + p(sctps_sendmultfastretrans, "\t\t" + "{:sent-fast-retransmitted-data-chunk-multiple-times/%ju} " + "{N:/FR'%s that happened more than once to same chunk}\n"); + p(sctps_sendheartbeat, "\t\t{:sent-hb-chunks/%ju} " + "{N:/output HB chunk%s}\n"); + p(sctps_sendecne, "\t\t{:sent-ecne-chunks/%ju} " + "{N:/output ECNE chunk%s}\n"); + p(sctps_sendauth, "\t\t{:sent-auth-chunks/%ju} " + "{N:/output AUTH chunk%s}\n"); + p1a(sctps_senderrors, "\t\t{:send-errors/%ju} " + "{N:/ip_output error counter}\n"); /* * PCKDROPREP statistics */ - printf("\tPacket drop statistics:\n"); - p1a(sctps_pdrpfmbox, "\t\t%ju from middle box\n"); - p1a(sctps_pdrpfehos, "\t\t%ju from end host\n"); - p1a(sctps_pdrpmbda, "\t\t%ju with data\n"); - p1a(sctps_pdrpmbct, "\t\t%ju non-data, non-endhost\n"); - p1a(sctps_pdrpbwrpt, "\t\t%ju non-endhost, bandwidth rep only\n"); - p1a(sctps_pdrpcrupt, "\t\t%ju not enough for chunk header\n"); - p1a(sctps_pdrpnedat, "\t\t%ju not enough data to confirm\n"); - p1a(sctps_pdrppdbrk, "\t\t%ju where process_chunk_drop said break\n"); - p1a(sctps_pdrptsnnf, "\t\t%ju failed to find TSN\n"); - p1a(sctps_pdrpdnfnd, "\t\t%ju attempt reverse TSN lookup\n"); - p1a(sctps_pdrpdiwnp, "\t\t%ju e-host confirms zero-rwnd\n"); - p1a(sctps_pdrpdizrw, "\t\t%ju midbox confirms no space\n"); - p1a(sctps_pdrpbadd, "\t\t%ju data did not match TSN\n"); - p(sctps_pdrpmark, "\t\t%ju TSN'%s marked for Fast Retran\n"); + xo_emit("\t{T:Packet drop statistics}:\n"); + xo_open_container("drop-statistics"); + p1a(sctps_pdrpfmbox, "\t\t{:middle-box/%ju} " + "{N:/from middle box}\n"); + p1a(sctps_pdrpfehos, "\t\t{:end-host/%ju} " + "{N:/from end host}\n"); + p1a(sctps_pdrpmbda, "\t\t{:with-data/%ju} " + "{N:/with data}\n"); + p1a(sctps_pdrpmbct, "\t\t{:non-data/%ju} " + "{N:/non-data, non-endhost}\n"); + p1a(sctps_pdrpbwrpt, "\t\t{:non-endhost/%ju} " + "{N:/non-endhost, bandwidth rep only}\n"); + p1a(sctps_pdrpcrupt, "\t\t{:short-header/%ju} " + "{N:/not enough for chunk header}\n"); + p1a(sctps_pdrpnedat, "\t\t{:short-data/%ju} " + "{N:/not enough data to confirm}\n"); + p1a(sctps_pdrppdbrk, "\t\t{:chunk-break/%ju} " + "{N:/where process_chunk_drop said break}\n"); + p1a(sctps_pdrptsnnf, "\t\t{:tsn-not-found/%ju} " + "{N:/failed to find TSN}\n"); + p1a(sctps_pdrpdnfnd, "\t\t{:reverse-tsn/%ju} " + "{N:/attempt reverse TSN lookup}\n"); + p1a(sctps_pdrpdiwnp, "\t\t{:confirmed-zero-window/%ju} " + "{N:/e-host confirms zero-rwnd}\n"); + p1a(sctps_pdrpdizrw, "\t\t{:middle-box-no-space/%ju} " + "{N:/midbox confirms no space}\n"); + p1a(sctps_pdrpbadd, "\t\t{:bad-data/%ju} " + "{N:/data did not match TSN}\n"); + p(sctps_pdrpmark, "\t\t{:tsn-marked-fast-retransmission/%ju} " + "{N:/TSN'%s marked for Fast Retran}\n"); + xo_close_container("drop-statistics"); /* * Timeouts */ - printf("\tTimeouts:\n"); - p(sctps_timoiterator, "\t\t%ju iterator timer%s fired\n"); - p(sctps_timodata, "\t\t%ju T3 data time out%s\n"); - p(sctps_timowindowprobe, "\t\t%ju window probe (T3) timer%s fired\n"); - p(sctps_timoinit, "\t\t%ju INIT timer%s fired\n"); - p(sctps_timosack, "\t\t%ju sack timer%s fired\n"); - p(sctps_timoshutdown, "\t\t%ju shutdown timer%s fired\n"); - p(sctps_timoheartbeat, "\t\t%ju heartbeat timer%s fired\n"); - p1a(sctps_timocookie, "\t\t%ju a cookie timeout fired\n"); - p1a(sctps_timosecret, "\t\t%ju an endpoint changed its cookie" + xo_emit("\t{T:Timeouts}:\n"); + xo_open_container("timeouts"); + p(sctps_timoiterator, "\t\t{:iterator/%ju} " + "{N:/iterator timer%s fired}\n"); + p(sctps_timodata, "\t\t{:t3-data/%ju} " + "{N:/T3 data time out%s}\n"); + p(sctps_timowindowprobe, "\t\t{:window-probe/%ju} " + "{N:/window probe (T3) timer%s fired}\n"); + p(sctps_timoinit, "\t\t{:init-timer/%ju} " + "{N:/INIT timer%s fired}\n"); + p(sctps_timosack, "\t\t{:sack-timer/%ju} " + "{N:/sack timer%s fired}\n"); + p(sctps_timoshutdown, "\t\t{:shutdown-timer/%ju} " + "{N:/shutdown timer%s fired}\n"); + p(sctps_timoheartbeat, "\t\t{:heartbeat-timer/%ju} " + "{N:/heartbeat timer%s fired}\n"); + p1a(sctps_timocookie, "\t\t{:cookie-timer/%ju} " + "{N:/a cookie timeout fired}\n"); + p1a(sctps_timosecret, "\t\t{:endpoint-changed-cookie/%ju} " + "{N:/an endpoint changed its cook}ie" "secret\n"); - p(sctps_timopathmtu, "\t\t%ju PMTU timer%s fired\n"); - p(sctps_timoshutdownack, "\t\t%ju shutdown ack timer%s fired\n"); - p(sctps_timoshutdownguard, "\t\t%ju shutdown guard timer%s fired\n"); - p(sctps_timostrmrst, "\t\t%ju stream reset timer%s fired\n"); - p(sctps_timoearlyfr, "\t\t%ju early FR timer%s fired\n"); - p1a(sctps_timoasconf, "\t\t%ju an asconf timer fired\n"); - p1a(sctps_timoautoclose, "\t\t%ju auto close timer fired\n"); - p(sctps_timoassockill, "\t\t%ju asoc free timer%s expired\n"); - p(sctps_timoinpkill, "\t\t%ju inp free timer%s expired\n"); + p(sctps_timopathmtu, "\t\t{:pmtu-timer/%ju} " + "{N:/PMTU timer%s fired}\n"); + p(sctps_timoshutdownack, "\t\t{:shutdown-timer/%ju} " + "{N:/shutdown ack timer%s fired}\n"); + p(sctps_timoshutdownguard, "\t\t{:shutdown-guard-timer/%ju} " + "{N:/shutdown guard timer%s fired}\n"); + p(sctps_timostrmrst, "\t\t{:stream-reset-timer/%ju} " + "{N:/stream reset timer%s fired}\n"); + p(sctps_timoearlyfr, "\t\t{:early-fast-retransmission-timer/%ju} " + "{N:/early FR timer%s fired}\n"); + p1a(sctps_timoasconf, "\t\t{:asconf-timer/%ju} " + "{N:/an asconf timer fired}\n"); + p1a(sctps_timoautoclose, "\t\t{:auto-close-timer/%ju} " + "{N:/auto close timer fired}\n"); + p(sctps_timoassockill, "\t\t{:asoc-free-timer/%ju} " + "{N:/asoc free timer%s expired}\n"); + p(sctps_timoinpkill, "\t\t{:input-free-timer/%ju} " + "{N:/inp free timer%s expired}\n"); + xo_close_container("timeouts"); #if 0 /* @@ -727,60 +833,86 @@ sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) /* * Others */ - p1a(sctps_hdrops, "\t%ju packet shorter than header\n"); - p1a(sctps_badsum, "\t%ju checksum error\n"); - p1a(sctps_noport, "\t%ju no endpoint for port\n"); - p1a(sctps_badvtag, "\t%ju bad v-tag\n"); - p1a(sctps_badsid, "\t%ju bad SID\n"); - p1a(sctps_nomem, "\t%ju no memory\n"); - p1a(sctps_fastretransinrtt, "\t%ju number of multiple FR in a RTT " - "window\n"); + p1a(sctps_hdrops, "\t{:dropped-too-short/%ju} " + "{N:/packet shorter than header}\n"); + p1a(sctps_badsum, "\t{:dropped-bad-checksum/%ju} " + "{N:/checksum error}\n"); + p1a(sctps_noport, "\t{:dropped-no-endpoint/%ju} " + "{N:/no endpoint for port}\n"); + p1a(sctps_badvtag, "\t{:dropped-bad-v-tag/%ju} " + "{N:/bad v-tag}\n"); + p1a(sctps_badsid, "\t{:dropped-bad-sid/%ju} " + "{N:/bad SID}\n"); + p1a(sctps_nomem, "\t{:dropped-no-memory/%ju} " + "{N:/no memory}\n"); + p1a(sctps_fastretransinrtt, "\t{:multiple-fast-retransmits-in-rtt/%ju} " + "{N:/number of multiple FR in a RT}T window\n"); #if 0 p(sctps_markedretrans, "\t%ju TODO:sctps_markedretrans\n"); #endif - p1a(sctps_naglesent, "\t%ju RFC813 allowed sending\n"); - p1a(sctps_naglequeued, "\t%ju RFC813 does not allow sending\n"); - p1a(sctps_maxburstqueued, "\t%ju times max burst prohibited sending\n"); - p1a(sctps_ifnomemqueued, "\t%ju look ahead tells us no memory in " - "interface\n"); - p(sctps_windowprobed, "\t%ju number%s of window probes sent\n"); - p(sctps_lowlevelerr, "\t%ju time%s an output error to clamp " - "down on next user send\n"); - p(sctps_lowlevelerrusr, "\t%ju time%s sctp_senderrors were " - "caused from a user\n"); - p(sctps_datadropchklmt, "\t%ju number of in data drop%s due to " - "chunk limit reached\n"); - p(sctps_datadroprwnd, "\t%ju number of in data drop%s due to rwnd " - "limit reached\n"); - p(sctps_ecnereducedcwnd, "\t%ju time%s a ECN reduced " - "the cwnd\n"); - p1a(sctps_vtagexpress, "\t%ju used express lookup via vtag\n"); - p1a(sctps_vtagbogus, "\t%ju collision in express lookup\n"); - p(sctps_primary_randry, "\t%ju time%s the sender ran dry " - "of user data on primary\n"); - p1a(sctps_cmt_randry, "\t%ju same for above\n"); - p(sctps_slowpath_sack, "\t%ju sack%s the slow way\n"); - p(sctps_wu_sacks_sent, "\t%ju window update only sack%s sent\n"); - p(sctps_sends_with_flags, "\t%ju send%s with sinfo_flags !=0\n"); - p(sctps_sends_with_unord, "\t%ju unordered send%s\n"); - p(sctps_sends_with_eof, "\t%ju send%s with EOF flag set\n"); - p(sctps_sends_with_abort, "\t%ju send%s with ABORT flag set\n"); - p(sctps_protocol_drain_calls, "\t%ju time%s protocol drain called\n"); - p(sctps_protocol_drains_done, "\t%ju time%s we did a protocol " - "drain\n"); - p(sctps_read_peeks, "\t%ju time%s recv was called with peek\n"); - p(sctps_cached_chk, "\t%ju cached chunk%s used\n"); - p1a(sctps_cached_strmoq, "\t%ju cached stream oq's used\n"); - p(sctps_left_abandon, "\t%ju unread message%s abandonded by close\n"); - p1a(sctps_send_burst_avoid, "\t%ju send burst avoidance, already " - "max burst inflight to net\n"); - p1a(sctps_send_cwnd_avoid, "\t%ju send cwnd full avoidance, already " - "max burst inflight to net\n"); - p(sctps_fwdtsn_map_over, "\t%ju number of map array over-run%s via " - "fwd-tsn's\n"); + p1a(sctps_naglesent, "\t{:rfc813-sent/%ju} " + "{N:/RFC813 allowed sending}\n"); + p1a(sctps_naglequeued, "\t{:rfc813-queued/%ju} " + "{N:/RFC813 does not allow sending}\n"); + p1a(sctps_maxburstqueued, "\t{:max-burst-queued/%ju} " + "{N:/times max burst prohibited sending}\n"); + p1a(sctps_ifnomemqueued, "\t{:no-memory-in-interface/%ju} " + "{N:/look ahead tells us no memory in interface}\n"); + p(sctps_windowprobed, "\t{:sent-window-probes/%ju} " + "{N:/number%s of window probes sent}\n"); + p(sctps_lowlevelerr, "\t{:low-level-err/%ju} " + "{N:/time%s an output error to clamp down on next user send}\n"); + p(sctps_lowlevelerrusr, "\t{:low-level-user-error/%ju} " + "{N:/time%s sctp_senderrors were caused from a user}\n"); + p(sctps_datadropchklmt, "\t{:dropped-chunk-limit/%ju} " + "{N:/number of in data drop%s due to chunk limit reached}\n"); + p(sctps_datadroprwnd, "\t{:dropped-rwnd-limit/%ju} " + "{N:/number of in data drop%s due to rwnd limit reached}\n"); + p(sctps_ecnereducedcwnd, "\t{:ecn-reduced-cwnd/%ju} " + "{N:/time%s a ECN reduced the cwnd}\n"); + p1a(sctps_vtagexpress, "\t{:v-tag-express-lookup/%ju} " + "{N:/used express lookup via vtag}\n"); + p1a(sctps_vtagbogus, "\t{:v-tag-collision/%ju} " + "{N:/collision in express lookup}\n"); + p(sctps_primary_randry, "\t{:sender-ran-dry/%ju} " + "{N:/time%s the sender ran dry of user data on primary}\n"); + p1a(sctps_cmt_randry, "\t{:cmt-ran-dry/%ju} " + "{N:/same for above}\n"); + p(sctps_slowpath_sack, "\t{:slow-path-sack/%ju} " + "{N:/sack%s the slow way}\n"); + p(sctps_wu_sacks_sent, "\t{:sent-window-update-only-sack/%ju} " + "{N:/window update only sack%s sent}\n"); + p(sctps_sends_with_flags, "\t{:sent-with-sinfo/%ju} " + "{N:/send%s with sinfo_flags !=0}\n"); + p(sctps_sends_with_unord, "\t{:sent-with-unordered/%ju} " + "{N:/unordered send%s}\n"); + p(sctps_sends_with_eof, "\t{:sent-with-eof/%ju} " + "{N:/send%s with EOF flag set}\n"); + p(sctps_sends_with_abort, "\t{:sent-with-abort/%ju} " + "{N:/send%s with ABORT flag set}\n"); + p(sctps_protocol_drain_calls, "\t{:protocol-drain-called/%ju} " + "{N:/time%s protocol drain called}\n"); + p(sctps_protocol_drains_done, "\t{:protocol-drain/%ju} " + "{N:/time%s we did a protocol drain}\n"); + p(sctps_read_peeks, "\t{:read-with-peek/%ju} " + "{N:/time%s recv was called with peek}\n"); + p(sctps_cached_chk, "\t{:cached-chunks/%ju} " + "{N:/cached chunk%s used}\n"); + p1a(sctps_cached_strmoq, "\t{:cached-output-queue-used/%ju} " + "{N:/cached stream oq's used}\n"); + p(sctps_left_abandon, "\t{:messages-abandoned/%ju} " + "{N:/unread message%s abandonded by close}\n"); + p1a(sctps_send_burst_avoid, "\t{:send-burst-avoidance/%ju} " + "{N:/send burst avoidance, already max burst inflight to net}\n"); + p1a(sctps_send_cwnd_avoid, "\t{:send-cwnd-avoidance/%ju} " + "{N:/send cwnd full avoidance, already max burst inflight " + "to net}\n"); + p(sctps_fwdtsn_map_over, "\t{:tsn-map-overruns/%ju} " + "{N:/number of map array over-run%s via fwd-tsn's}\n"); #undef p #undef p1a + xo_close_container(name); } #endif /* SCTP */ diff --git a/usr.bin/netstat/unix.c b/usr.bin/netstat/unix.c index 027e812..a7503f5 100644 --- a/usr.bin/netstat/unix.c +++ b/usr.bin/netstat/unix.c @@ -57,8 +57,10 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <strings.h> #include <kvm.h> +#include <libxo/xo.h> #include "netstat.h" static void unixdomainpr(struct xunpcb *, struct xsocket *); @@ -78,15 +80,15 @@ pcblist_sysctl(int type, char **bufp) len = 0; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { if (errno != ENOENT) - warn("sysctl: %s", mibvar); + xo_warn("sysctl: %s", mibvar); return (-1); } if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); + xo_warnx("malloc %lu bytes", (u_long)len); return (-2); } if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { - warn("sysctl: %s", mibvar); + xo_warn("sysctl: %s", mibvar); free(buf); return (-2); } @@ -115,14 +117,14 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) 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); + xo_warnx("malloc %lu bytes", (u_long)len); return (-2); } p = buf; #define COPYOUT(obj, size) do { \ if (len < (size)) { \ - warnx("buffer size exceeded"); \ + xo_warnx("buffer size exceeded"); \ goto fail; \ } \ bcopy((obj), p, (size)); \ @@ -190,7 +192,7 @@ fail: void unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off, - u_long sphead_off) + u_long sphead_off, bool *first) { char *buf; int ret, type; @@ -228,26 +230,35 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off, 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)) { + 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; + if (*first) { + xo_open_list("socket"); + *first = false; + } + xo_open_instance("socket"); unixdomainpr(xunp, so); + xo_close_instance("socket"); } 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]); + xo_emit("Some {:type/%s} sockets may have " + "been {:action/deleted}.\n", + socktype[type]); } else if (oxug->xug_count < xug->xug_count) { - printf("Some %s sockets may have been created.\n", - socktype[type]); + xo_emit("Some {:type/%s} sockets may have " + "been {:action/created}.\n", + socktype[type]); } else { - printf("Some %s sockets may have been created or deleted", - socktype[type]); + xo_emit("Some {:type/%s} sockets may have " + "been {:action/created or deleted}", + socktype[type]); } } free(buf); @@ -261,6 +272,25 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) struct sockaddr_un *sa; static int first = 1; char buf1[15]; + static const char *titles[2] = { + "{T:/%-8.8s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%8.8s} " + "{T:/%8.8s} {T:/%8.8s} {T:/%8.8s} {T:Addr}\n", + "{T:/%-16.16s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%16.16s} " + "{T:/%16.16s} {T:/%16.16s} {T:/%16.16s} {T:Addr}\n" + }; + static const char *format[2] = { + "{q:address/%8lx} {t:type/%-6.6s} " + "{:receive-bytes-waiting/%6u} " + "{:send-bytes-waiting/%6u} " + "{q:vnode/%8lx} {q:connection/%8lx} " + "{q:first-reference/%8lx} {q:next-reference/%8lx}", + "{q:address/%16lx} {t:type/%-6.6s} " + "{:receive-bytes-waiting/%6u} " + "{:send-bytes-waiting/%6u} " + "{q:vnode/%16lx} {q:connection/%16lx} " + "{q:first-reference/%16lx} {q:next-reference/%16lx}" + }; + int fmt = (sizeof(void *) == 8) ? 1 : 0; unp = &xunp->xu_unp; if (unp->unp_addr) @@ -269,9 +299,8 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) 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", + xo_emit("{T:Active UNIX domain sockets}\n"); + xo_emit(titles[fmt], "Address", "Type", "Recv-Q", "Send-Q", "Inode", "Conn", "Refs", "Nextref"); first = 0; @@ -283,17 +312,20 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) if (Lflag) { snprintf(buf1, 15, "%d/%d/%d", so->so_qlen, so->so_incqlen, so->so_qlimit); - printf("unix %-14.14s", buf1); + xo_emit("unix {d:socket/%-14.14s}{e:queue-length/%d}" + "{e:incomplete-queue-length/%d}{e:queue-limit/%d}", + buf1, so->so_qlen, so->so_incqlen, so->so_qlimit); } else { - printf("%8lx %-6.6s %6u %6u %8lx %8lx %8lx %8lx", + xo_emit(format[fmt], (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", + xo_emit(" {:path/%.*s}", (int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)), sa->sun_path); - putchar('\n'); + xo_emit("\n"); } |