diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-10-07 15:10:20 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:31 +0100 |
commit | c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f (patch) | |
tree | ad4f2519067709f00ab98b3c591186c26dc3a21f /freebsd/usr.bin | |
parent | userspace-header-gen.py: Simplify program ports (diff) | |
download | rtems-libbsd-c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f.tar.bz2 |
Update to FreeBSD head 2016-08-23
Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
Diffstat (limited to 'freebsd/usr.bin')
34 files changed, 4110 insertions, 3340 deletions
diff --git a/freebsd/usr.bin/netstat/bpf.c b/freebsd/usr.bin/netstat/bpf.c index 97f2fd81..6b8cb819 100644 --- a/freebsd/usr.bin/netstat/bpf.c +++ b/freebsd/usr.bin/netstat/bpf.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 2005 Christian S.J. Peron * All rights reserved. @@ -26,6 +30,9 @@ * SUCH DAMAGE. */ +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -38,7 +45,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> @@ -48,10 +54,15 @@ __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" +#ifdef __rtems__ +#include "rtems-bsd-netstat-bpf-data.h" +#endif /* __rtems__ */ /* print bpf stats */ @@ -70,7 +81,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)); @@ -92,6 +103,23 @@ bpf_flags(struct xbpf_d *bd, char *flagbuf) #endif /* __rtems__ */ *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/}"); +#ifndef __rtems__ + if (bd->bd_async) + xo_emit("{e:async/}"); +#endif /* __rtems__ */ + if (bd->bd_locked) + xo_emit("{e:locked/}"); } void @@ -105,50 +133,61 @@ 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"); #ifndef __rtems__ pname = bpf_pidname(d->bd_pid); #else /* __rtems__ */ pname = "??????"; #endif /* __rtems__ */ - (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); #ifndef __rtems__ free(pname); #endif /* __rtems__ */ + xo_close_instance("bpf-entry"); } + xo_close_list("bpf-entry"); + xo_close_container("bpf-statistics"); free(bd); } diff --git a/freebsd/usr.bin/netstat/flowtable.c b/freebsd/usr.bin/netstat/flowtable.c new file mode 100644 index 00000000..fda45657 --- /dev/null +++ b/freebsd/usr.bin/netstat/flowtable.c @@ -0,0 +1,100 @@ +#include <machine/rtems-bsd-user-space.h> + +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + +/*- + * Copyright (c) 2014 Gleb Smirnoff <glebius@FreeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <rtems/bsd/sys/param.h> + +#include <net/flowtable.h> + +#include <stdint.h> +#include <stdio.h> +#include <stdbool.h> + +#include "netstat.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-flowtable-data.h" +#endif /* __rtems__ */ + +/* + * Print flowtable statistics. + */ + +static void +print_stats(struct flowtable_stat *stat) +{ + +#define p(f, m) if (stat->f || sflag <= 1) \ + printf(m, (uintmax_t)stat->f, plural(stat->f)) +#define p2(f, m) if (stat->f || sflag <= 1) \ + printf(m, (uintmax_t)stat->f, plurales(stat->f)) + + p(ft_lookups, "\t%ju lookup%s\n"); + p(ft_hits, "\t%ju hit%s\n"); + p2(ft_misses, "\t%ju miss%s\n"); + p(ft_inserts, "\t%ju insert%s\n"); + p(ft_collisions, "\t%ju collision%s\n"); + p(ft_free_checks, "\t%ju free check%s\n"); + p(ft_frees, "\t%ju free%s\n"); + p(ft_fail_lle_invalid, + "\t%ju lookup%s with not resolved Layer 2 address\n"); + +#undef p2 +#undef p +} + +void +flowtable_stats(void) +{ + struct flowtable_stat stat; + + if (!live) + return; + + if (fetch_stats("net.flowtable.ip4.stat", 0, &stat, + sizeof(stat), NULL) == 0) { + printf("flowtable for IPv4:\n"); + print_stats(&stat); + } + + if (fetch_stats("net.flowtable.ip6.stat", 0, &stat, + sizeof(stat), NULL) == 0) { + printf("flowtable for IPv6:\n"); + print_stats(&stat); + } +} diff --git a/freebsd/usr.bin/netstat/if.c b/freebsd/usr.bin/netstat/if.c index 9edff32f..384c8f20 100644 --- a/freebsd/usr.bin/netstat/if.c +++ b/freebsd/usr.bin/netstat/if.c @@ -1,6 +1,11 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- + * Copyright (c) 2013 Gleb Smirnoff <glebius@FreeBSD.org> * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * @@ -36,66 +41,103 @@ static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95"; #endif #ifdef __rtems__ -#define RTEMS_BSD_PROGRAM_NO_OPEN_WRAP -#define RTEMS_BSD_PROGRAM_NO_SOCKET_WRAP -#define RTEMS_BSD_PROGRAM_NO_CLOSE_WRAP -#define RTEMS_BSD_PROGRAM_NO_FOPEN_WRAP -#define RTEMS_BSD_PROGRAM_NO_FCLOSE_WRAP -#define RTEMS_BSD_PROGRAM_NO_MALLOC_WRAP -#define RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP -#define RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP -#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP #include <machine/rtems-bsd-program.h> #endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/types.h> +#include <rtems/bsd/sys/param.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> -#include <sys/sysctl.h> #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> -#include <net/pfvar.h> -#include <net/if_pfsync.h> #include <netinet/in.h> #include <netinet/in_var.h> -#ifndef __rtems__ -#include <netipx/ipx.h> -#include <netipx/ipx_if.h> -#endif /* __rtems__ */ #include <arpa/inet.h> +#ifdef PF +#include <net/pfvar.h> +#include <net/if_pfsync.h> +#endif #include <err.h> #include <errno.h> +#include <ifaddrs.h> #include <libutil.h> #ifdef INET6 #include <netdb.h> #endif #include <signal.h> +#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sysexits.h> #include <unistd.h> +#include <libxo/xo.h> #include "netstat.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-if-data.h" +#endif /* __rtems__ */ -#define YES 1 -#define NO 0 +static void sidewaysintpr(void); + +#ifdef PF +static const char* pfsyncacts[] = { + /* 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 sidewaysintpr(int, u_long); -static void catchalarm(int); +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", +}; -#ifdef INET6 -static char addr_buf[NI_MAXHOST]; /* for getnameinfo() */ -#endif +static void +pfsync_acts_stats(const char *list, const char *desc, uint64_t *a) +{ + int i; + + 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); +} /* * Dump pfsync statistics structure. @@ -103,56 +145,68 @@ static char addr_buf[NI_MAXHOST]; /* for getnameinfo() */ void pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct pfsyncstats pfsyncstat, zerostat; - size_t len = sizeof(struct pfsyncstats); - - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.pfsync.stats", &pfsyncstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet.pfsync.stats"); - return; - } - } else - kread(off, &pfsyncstat, len); + struct pfsyncstats pfsyncstat; - printf("%s:\n", name); + if (fetch_stats("net.pfsync.stats", off, &pfsyncstat, + sizeof(pfsyncstat), kread) != 0) + return; + + 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)) -#define p2(f, m) if (pfsyncstat.f || sflag <= 1) \ - printf(m, (uintmax_t)pfsyncstat.f) - - p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n"); - p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n"); - 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"); - p2(pfsyncs_onomem, "\t\t%ju send failed due to mbuf memory error\n"); - p2(pfsyncs_oerrors, "\t\t%ju send error\n"); + xo_emit(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f)) + + 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/{: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{: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 -#undef p2 + xo_close_container(name); } +#endif /* PF */ /* * 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, int div1000) { const char *lsep, *rsep; - char newfmt[32]; + char newfmt[64]; lsep = ""; if (strncmp(fmt, "LS", 2) == 0) { @@ -166,542 +220,403 @@ 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); + HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL | \ + ((div1000) ? HN_DIVISOR_1000 : 0)); + 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); + } +} + +/* + * Find next multiaddr for a given interface name. + */ +static struct ifmaddrs * +next_ifma(struct ifmaddrs *ifma, const char *name, const sa_family_t family) +{ + + for(; ifma != NULL; ifma = ifma->ifma_next) { + struct sockaddr_dl *sdl; + + sdl = (struct sockaddr_dl *)ifma->ifma_name; + if (ifma->ifma_addr->sa_family == family && + strcmp(sdl->sdl_data, name) == 0) + break; } + + return (ifma); } /* * Print a description of the network interfaces. */ void -intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) +intpr(void (*pfunc)(char *), int af) { - struct ifnet ifnet; - struct ifnethead ifnethead; - union { - struct ifaddr ifa; - struct in_ifaddr in; -#ifdef INET6 - struct in6_ifaddr in6; -#endif -#ifndef __rtems__ - struct ipx_ifaddr ipx; -#endif /* __rtems__ */ - } ifaddr; - u_long ifaddraddr; - u_long ifaddrfound; - u_long opackets; - u_long ipackets; - u_long obytes; - u_long ibytes; - u_long omcasts; - u_long imcasts; - u_long oerrors; - u_long ierrors; - u_long idrops; - u_long collisions; - int drops; - struct sockaddr *sa = NULL; - char name[IFNAMSIZ]; - short network_layer; - short link_layer; - - if (ifnetaddr == 0) { - printf("ifnet: symbol not defined\n"); - return; - } - if (interval1) { - sidewaysintpr(interval1, ifnetaddr); - return; + struct ifaddrs *ifap, *ifa; + struct ifmaddrs *ifmap, *ifma; + u_int ifn_len_max = 5, ifn_len; + u_int has_ipv6 = 0, net_len = 13, addr_len = 17; + + if (interval) + return sidewaysintpr(); + + if (getifaddrs(&ifap) != 0) + err(EX_OSERR, "getifaddrs"); + if (aflag && getifmaddrs(&ifmap) != 0) + err(EX_OSERR, "getifmaddrs"); + + if (Wflag) { + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (interface != NULL && + strcmp(ifa->ifa_name, interface) != 0) + continue; + if (af != AF_UNSPEC && ifa->ifa_addr->sa_family != af) + continue; + ifn_len = strlen(ifa->ifa_name); + if ((ifa->ifa_flags & IFF_UP) == 0) + ++ifn_len; + ifn_len_max = MAX(ifn_len_max, ifn_len); + if (ifa->ifa_addr->sa_family == AF_INET6) + has_ipv6 = 1; + } + if (has_ipv6) { + net_len = 24; + addr_len = 39; + } else + net_len = 18; } - if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead) != 0) - return; - ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead); - if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0) - return; + xo_open_list("interface"); if (!pfunc) { - if (Wflag) - printf("%-7.7s", "Name"); - else - printf("%-5.5s", "Name"); - printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s", - "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop"); + xo_emit("{T:/%-*.*s}", ifn_len_max, ifn_len_max, "Name"); + xo_emit(" {T:/%5.5s} {T:/%-*.*s} {T:/%-*.*s} {T:/%8.8s} " + "{T:/%5.5s} {T:/%5.5s}", + "Mtu", net_len, net_len, "Network", addr_len, addr_len, + "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:/%5.5s}", "Drop"); + xo_emit("\n"); } - ifaddraddr = 0; - while (ifnetaddr || ifaddraddr) { - struct sockaddr_in *sockin; -#ifdef INET6 - struct sockaddr_in6 *sockin6; -#endif - char *cp; - int n, m; - - network_layer = 0; - link_layer = 0; - - if (ifaddraddr == 0) { - if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0) - return; - strlcpy(name, ifnet.if_xname, sizeof(name)); - ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link); - if (interface != 0 && strcmp(name, interface) != 0) - continue; - cp = index(name, '\0'); - if (pfunc) { - (*pfunc)(name); - continue; - } + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + bool network = false, link = false; + char *name, *xname, buf[IFNAMSIZ+1]; + const char *nn, *rn; - if ((ifnet.if_flags&IFF_UP) == 0) - *cp++ = '*'; - *cp = '\0'; - ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead); - } - ifaddrfound = ifaddraddr; + if (interface != NULL && strcmp(ifa->ifa_name, interface) != 0) + continue; - /* - * Get the interface stats. These may get - * overriden below on a per-interface basis. - */ - opackets = ifnet.if_opackets; - ipackets = ifnet.if_ipackets; - obytes = ifnet.if_obytes; - ibytes = ifnet.if_ibytes; - omcasts = ifnet.if_omcasts; - imcasts = ifnet.if_imcasts; - oerrors = ifnet.if_oerrors; - ierrors = ifnet.if_ierrors; - idrops = ifnet.if_iqdrops; - collisions = ifnet.if_collisions; - drops = ifnet.if_snd.ifq_drops; - - if (ifaddraddr == 0) { - if (Wflag) - printf("%-7.7s", name); - else - printf("%-5.5s", name); - printf(" %5lu ", ifnet.if_mtu); - printf("%-13.13s ", "none"); - printf("%-17.17s ", "none"); - } else { - if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr) - != 0) { - ifaddraddr = 0; - continue; - } -#define CP(x) ((char *)(x)) - cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + - CP(&ifaddr); - sa = (struct sockaddr *)cp; - if (af != AF_UNSPEC && sa->sa_family != af) { - ifaddraddr = - (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); - continue; - } - if (Wflag) - printf("%-7.7s", name); - else - printf("%-5.5s", name); - printf(" %5lu ", ifnet.if_mtu); - switch (sa->sa_family) { - case AF_UNSPEC: - printf("%-13.13s ", "none"); - printf("%-15.15s ", "none"); - break; - case AF_INET: - sockin = (struct sockaddr_in *)sa; -#ifdef notdef - /* can't use inet_makeaddr because kernel - * keeps nets unshifted. - */ - in = inet_makeaddr(ifaddr.in.ia_subnet, - INADDR_ANY); - printf("%-13.13s ", netname(in.s_addr, - ifaddr.in.ia_subnetmask)); -#else - printf("%-13.13s ", - netname(htonl(ifaddr.in.ia_subnet), - ifaddr.in.ia_subnetmask)); -#endif - printf("%-17.17s ", - routename(sockin->sin_addr.s_addr)); + name = ifa->ifa_name; - network_layer = 1; - break; -#ifdef INET6 - case AF_INET6: - sockin6 = (struct sockaddr_in6 *)sa; - in6_fillscopeid(&ifaddr.in6.ia_addr); - printf("%-13.13s ", - netname6(&ifaddr.in6.ia_addr, - &ifaddr.in6.ia_prefixmask.sin6_addr)); - in6_fillscopeid(sockin6); - getnameinfo(sa, sa->sa_len, addr_buf, - sizeof(addr_buf), 0, 0, NI_NUMERICHOST); - printf("%-17.17s ", addr_buf); - - network_layer = 1; - break; -#endif /*INET6*/ -#ifndef __rtems__ - case AF_IPX: - { - struct sockaddr_ipx *sipx = - (struct sockaddr_ipx *)sa; - u_long net; - char netnum[10]; - - *(union ipx_net *) &net = sipx->sipx_addr.x_net; - sprintf(netnum, "%lx", (u_long)ntohl(net)); - printf("ipx:%-8s ", netnum); -/* printf("ipx:%-8s ", netname(net, 0L)); */ - printf("%-17s ", - ipx_phost((struct sockaddr *)sipx)); - } - - network_layer = 1; - break; -#endif /* __rtems__ */ + if (pfunc) { -#ifndef __rtems__ - case AF_APPLETALK: - printf("atalk:%-12.12s ",atalk_print(sa,0x10) ); - printf("%-11.11s ",atalk_print(sa,0x0b) ); - break; -#endif /* __rtems__ */ - case AF_LINK: - { - struct sockaddr_dl *sdl = - (struct sockaddr_dl *)sa; - char linknum[10]; - cp = (char *)LLADDR(sdl); - n = sdl->sdl_alen; - sprintf(linknum, "<Link#%d>", sdl->sdl_index); - m = printf("%-13.13s ", linknum); - } - goto hexprint; - default: - m = printf("(%d)", sa->sa_family); - for (cp = sa->sa_len + (char *)sa; - --cp > sa->sa_data && (*cp == 0);) {} - n = cp - sa->sa_data + 1; - cp = sa->sa_data; - hexprint: - while ((--n >= 0) && (m < 30)) - m += printf("%02x%c", *cp++ & 0xff, - n > 0 ? ':' : ' '); - m = 32 - m; - while (m-- > 0) - putchar(' '); - - link_layer = 1; - break; - } + (*pfunc)(name); /* - * Fixup the statistics for interfaces that - * update stats for their network addresses + * Skip all ifaddrs belonging to same interface. */ - if (network_layer) { - opackets = ifaddr.in.ia_ifa.if_opackets; - ipackets = ifaddr.in.ia_ifa.if_ipackets; - obytes = ifaddr.in.ia_ifa.if_obytes; - ibytes = ifaddr.in.ia_ifa.if_ibytes; + while(ifa->ifa_next != NULL && + (strcmp(ifa->ifa_next->ifa_name, name) == 0)) { + ifa = ifa->ifa_next; } - - ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); + continue; } - show_stat("lu", 8, ipackets, link_layer|network_layer); - show_stat("lu", 5, ierrors, link_layer); - show_stat("lu", 5, idrops, link_layer); - if (bflag) - show_stat("lu", 10, ibytes, link_layer|network_layer); + if (af != AF_UNSPEC && ifa->ifa_addr->sa_family != af) + continue; - show_stat("lu", 8, opackets, link_layer|network_layer); - show_stat("lu", 5, oerrors, link_layer); - if (bflag) - show_stat("lu", 10, obytes, link_layer|network_layer); + xo_open_instance("interface"); - show_stat("NRSlu", 5, collisions, link_layer); - if (dflag) - show_stat("LSd", 4, drops, link_layer); - putchar('\n'); + if ((ifa->ifa_flags & IFF_UP) == 0) { + xname = stpcpy(buf, name); + *xname++ = '*'; + *xname = '\0'; + xname = buf; + } else + xname = name; - if (aflag && ifaddrfound) { - /* - * Print family's multicast addresses - */ - struct ifmultiaddr *multiaddr; - struct ifmultiaddr ifma; - union { - struct sockaddr sa; - struct sockaddr_in in; + xo_emit("{d:/%-*.*s}{etk:name}{eq:flags/0x%x}", + ifn_len_max, ifn_len_max, xname, name, ifa->ifa_flags); + +#define IFA_MTU(ifa) (((struct if_data *)(ifa)->ifa_data)->ifi_mtu) + show_stat("lu", 6, "mtu", IFA_MTU(ifa), IFA_MTU(ifa), 0); +#undef IFA_MTU + + switch (ifa->ifa_addr->sa_family) { + case AF_UNSPEC: + xo_emit("{:network/%-*.*s} ", net_len, net_len, + "none"); + xo_emit("{:address/%-*.*s} ", addr_len, addr_len, + "none"); + break; + case AF_INET: #ifdef INET6 - struct sockaddr_in6 in6; + case AF_INET6: #endif /* INET6 */ - struct sockaddr_dl dl; - } msa; - const char *fmt; + nn = netname(ifa->ifa_addr, ifa->ifa_netmask); + rn = routename(ifa->ifa_addr, numeric_addr); + if (Wflag) { + xo_emit("{t:network/%-*s} ", net_len, nn); + xo_emit("{t:address/%-*s} ", addr_len, rn); + } else { + xo_emit("{d:network/%-*.*s}{et:network} ", + net_len, net_len, nn, nn); + xo_emit("{d:address/%-*.*s}{et:address} ", + addr_len, addr_len, rn, rn); + } - TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) { - if (kread((u_long)multiaddr, (char *)&ifma, - sizeof ifma) != 0) - break; - multiaddr = &ifma; - if (kread((u_long)ifma.ifma_addr, (char *)&msa, - sizeof msa) != 0) - break; - if (msa.sa.sa_family != sa->sa_family) - continue; + network = true; + break; + case AF_LINK: + { + struct sockaddr_dl *sdl; + char linknum[10]; + + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + sprintf(linknum, "<Link#%d>", sdl->sdl_index); + xo_emit("{t:network/%-*.*s} ", net_len, net_len, + linknum); + if (sdl->sdl_nlen == 0 && + sdl->sdl_alen == 0 && + sdl->sdl_slen == 0) + xo_emit("{P:/%*s} ", addr_len, ""); + else + xo_emit("{t:address/%-*.*s} ", addr_len, + addr_len, routename(ifa->ifa_addr, 1)); + link = true; + break; + } + } + +#define IFA_STAT(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s) + show_stat("lu", 8, "received-packets", IFA_STAT(ipackets), + link|network, 1); + show_stat("lu", 5, "received-errors", IFA_STAT(ierrors), + link, 1); + show_stat("lu", 5, "dropped-packets", IFA_STAT(iqdrops), + link, 1); + if (bflag) + show_stat("lu", 10, "received-bytes", IFA_STAT(ibytes), + link|network, 0); + show_stat("lu", 8, "sent-packets", IFA_STAT(opackets), + link|network, 1); + show_stat("lu", 5, "send-errors", IFA_STAT(oerrors), link, 1); + if (bflag) + show_stat("lu", 10, "sent-bytes", IFA_STAT(obytes), + link|network, 0); + show_stat("NRSlu", 5, "collisions", IFA_STAT(collisions), + link, 1); + if (dflag) + show_stat("LSlu", 5, "dropped-packets", + IFA_STAT(oqdrops), link, 1); + xo_emit("\n"); - fmt = 0; - switch (msa.sa.sa_family) { - case AF_INET: - fmt = routename(msa.in.sin_addr.s_addr); + 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)) { + const char *fmt = NULL; + + xo_open_instance("multicast-address"); + switch (ifma->ifma_addr->sa_family) { + case AF_LINK: + { + struct sockaddr_dl *sdl; + + sdl = (struct sockaddr_dl *)ifma->ifma_addr; + if (sdl->sdl_type != IFT_ETHER && + sdl->sdl_type != IFT_FDDI) break; + } + /* FALLTHROUGH */ + case AF_INET: #ifdef INET6 - case AF_INET6: - in6_fillscopeid(&msa.in6); - getnameinfo(&msa.sa, msa.sa.sa_len, - addr_buf, sizeof(addr_buf), 0, 0, - NI_NUMERICHOST); - printf("%*s %-19.19s(refs: %d)\n", - Wflag ? 27 : 25, "", - addr_buf, ifma.ifma_refcount); - break; + case AF_INET6: #endif /* INET6 */ - case AF_LINK: - switch (msa.dl.sdl_type) { - case IFT_ETHER: - case IFT_FDDI: - fmt = ether_ntoa( - (struct ether_addr *) - LLADDR(&msa.dl)); - break; - } - break; - } - if (fmt) { - printf("%*s %-17.17s", - Wflag ? 27 : 25, "", fmt); - if (msa.sa.sa_family == AF_LINK) { - printf(" %8lu", imcasts); - printf("%*s", - bflag ? 17 : 6, ""); - printf(" %8lu", omcasts); - } - putchar('\n'); - } + fmt = routename(ifma->ifma_addr, numeric_addr); + break; + } + if (fmt) { + if (Wflag) + xo_emit("{P:/%27s }" + "{t:address/%-17s/}", "", fmt); + else + xo_emit("{P:/%25s }" + "{t:address/%-17.17s/}", "", fmt); + if (ifma->ifma_addr->sa_family == AF_LINK) { + 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) + freeifmaddrs(ifmap); } -struct iftot { - SLIST_ENTRY(iftot) chain; - char ift_name[IFNAMSIZ]; /* interface name */ +struct iftot { u_long ift_ip; /* input packets */ u_long ift_ie; /* input errors */ u_long ift_id; /* input drops */ u_long ift_op; /* output packets */ u_long ift_oe; /* output errors */ + u_long ift_od; /* output drops */ u_long ift_co; /* collisions */ - u_int ift_dr; /* drops */ u_long ift_ib; /* input bytes */ u_long ift_ob; /* output bytes */ }; -u_char signalled; /* set if alarm goes off "early" */ - /* - * Print a running summary of interface statistics. - * Repeat display every interval1 seconds, showing statistics - * collected over that interval. Assumes that interval1 is non-zero. - * First line printed at top of screen is always cumulative. - * XXX - should be rewritten to use ifmib(4). + * Obtain stats for interface(s). */ static void -sidewaysintpr(int interval1, u_long off) +fill_iftot(struct iftot *st) { - struct ifnet ifnet; - u_long firstifnet; - struct ifnethead ifnethead; - struct itimerval interval_it; - struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting; - int line; - int oldmask, first; - u_long interesting_off; + struct ifaddrs *ifap, *ifa; + bool found = false; - if (kread(off, (char *)&ifnethead, sizeof ifnethead) != 0) - return; - firstifnet = (u_long)TAILQ_FIRST(&ifnethead); - - if ((iftot = malloc(sizeof(struct iftot))) == NULL) { - printf("malloc failed\n"); - exit(1); - } - memset(iftot, 0, sizeof(struct iftot)); + if (getifaddrs(&ifap) != 0) + xo_err(EX_OSERR, "getifaddrs"); - interesting = NULL; - interesting_off = 0; - for (off = firstifnet, ip = iftot; off;) { - char name[IFNAMSIZ]; + bzero(st, sizeof(*st)); - if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) - break; - strlcpy(name, ifnet.if_xname, sizeof(name)); - if (interface && strcmp(name, interface) == 0) { - interesting = ip; - interesting_off = off; - } - snprintf(ip->ift_name, sizeof(ip->ift_name), "(%s)", name); - if ((ipn = malloc(sizeof(struct iftot))) == NULL) { - printf("malloc failed\n"); - exit(1); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family != AF_LINK) + continue; + if (interface) { + if (strcmp(ifa->ifa_name, interface) == 0) + found = true; + else + continue; } - memset(ipn, 0, sizeof(struct iftot)); - SLIST_NEXT(ip, chain) = ipn; - ip = ipn; - off = (u_long)TAILQ_NEXT(&ifnet, if_link); - } - if (interface && interesting == NULL) - errx(1, "%s: unknown interface", interface); - if ((total = malloc(sizeof(struct iftot))) == NULL) { - printf("malloc failed\n"); - exit(1); - } - memset(total, 0, sizeof(struct iftot)); - if ((sum = malloc(sizeof(struct iftot))) == NULL) { - printf("malloc failed\n"); - exit(1); + + st->ift_ip += IFA_STAT(ipackets); + st->ift_ie += IFA_STAT(ierrors); + st->ift_id += IFA_STAT(iqdrops); + st->ift_ib += IFA_STAT(ibytes); + st->ift_op += IFA_STAT(opackets); + st->ift_oe += IFA_STAT(oerrors); + st->ift_od += IFA_STAT(oqdrops); + st->ift_ob += IFA_STAT(obytes); + st->ift_co += IFA_STAT(collisions); } - memset(sum, 0, sizeof(struct iftot)); + + if (interface && found == false) + xo_err(EX_DATAERR, "interface %s not found", interface); + + freeifaddrs(ifap); +} + +/* + * Set a flag to indicate that a signal from the periodic itimer has been + * caught. + */ +static sig_atomic_t signalled; +static void +catchalarm(int signo __unused) +{ + signalled = true; +} + +/* + * Print a running summary of interface statistics. + * Repeat display every interval seconds, showing statistics + * collected over that interval. Assumes that interval is non-zero. + * First line printed at top of screen is always cumulative. + */ +static void +sidewaysintpr(void) +{ + struct iftot ift[2], *new, *old; + struct itimerval interval_it; + int oldmask, line; + + new = &ift[0]; + old = &ift[1]; + fill_iftot(old); (void)signal(SIGALRM, catchalarm); - signalled = NO; - interval_it.it_interval.tv_sec = interval1; + signalled = false; + interval_it.it_interval.tv_sec = interval; interval_it.it_interval.tv_usec = 0; interval_it.it_value = interval_it.it_interval; setitimer(ITIMER_REAL, &interval_it, NULL); - first = 1; + xo_open_list("interface-statistics"); + banner: - printf("%17s %14s %16s", "input", - interesting ? interesting->ift_name : "(Total)", "output"); - putchar('\n'); - printf("%10s %5s %5s %10s %10s %5s %10s %5s", + xo_emit("{T:/%17s} {T:/%14s} {T:/%16s}\n", "input", + interface != NULL ? interface : "(Total)", "output"); + 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 (interesting != NULL) { - ip = interesting; - if (kread(interesting_off, (char *)&ifnet, sizeof ifnet) != 0) { - printf("???\n"); - exit(1); - }; - if (!first) { - show_stat("lu", 10, ifnet.if_ipackets - ip->ift_ip, 1); - show_stat("lu", 5, ifnet.if_ierrors - ip->ift_ie, 1); - show_stat("lu", 5, ifnet.if_iqdrops - ip->ift_id, 1); - show_stat("lu", 10, ifnet.if_ibytes - ip->ift_ib, 1); - show_stat("lu", 10, ifnet.if_opackets - ip->ift_op, 1); - show_stat("lu", 5, ifnet.if_oerrors - ip->ift_oe, 1); - show_stat("lu", 10, ifnet.if_obytes - ip->ift_ob, 1); - show_stat("NRSlu", 5, - ifnet.if_collisions - ip->ift_co, 1); - if (dflag) - show_stat("LSu", 5, - ifnet.if_snd.ifq_drops - ip->ift_dr, 1); - } - ip->ift_ip = ifnet.if_ipackets; - ip->ift_ie = ifnet.if_ierrors; - ip->ift_id = ifnet.if_iqdrops; - ip->ift_ib = ifnet.if_ibytes; - ip->ift_op = ifnet.if_opackets; - ip->ift_oe = ifnet.if_oerrors; - ip->ift_ob = ifnet.if_obytes; - ip->ift_co = ifnet.if_collisions; - ip->ift_dr = ifnet.if_snd.ifq_drops; - } else { - sum->ift_ip = 0; - sum->ift_ie = 0; - sum->ift_id = 0; - sum->ift_ib = 0; - sum->ift_op = 0; - sum->ift_oe = 0; - sum->ift_ob = 0; - sum->ift_co = 0; - sum->ift_dr = 0; - for (off = firstifnet, ip = iftot; - off && SLIST_NEXT(ip, chain) != NULL; - ip = SLIST_NEXT(ip, chain)) { - if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) { - off = 0; - continue; - } - sum->ift_ip += ifnet.if_ipackets; - sum->ift_ie += ifnet.if_ierrors; - sum->ift_id += ifnet.if_iqdrops; - sum->ift_ib += ifnet.if_ibytes; - sum->ift_op += ifnet.if_opackets; - sum->ift_oe += ifnet.if_oerrors; - sum->ift_ob += ifnet.if_obytes; - sum->ift_co += ifnet.if_collisions; - sum->ift_dr += ifnet.if_snd.ifq_drops; - off = (u_long)TAILQ_NEXT(&ifnet, if_link); - } - if (!first) { - show_stat("lu", 10, sum->ift_ip - total->ift_ip, 1); - show_stat("lu", 5, sum->ift_ie - total->ift_ie, 1); - show_stat("lu", 5, sum->ift_id - total->ift_id, 1); - show_stat("lu", 10, sum->ift_ib - total->ift_ib, 1); - show_stat("lu", 10, sum->ift_op - total->ift_op, 1); - show_stat("lu", 5, sum->ift_oe - total->ift_oe, 1); - show_stat("lu", 10, sum->ift_ob - total->ift_ob, 1); - show_stat("NRSlu", 5, sum->ift_co - total->ift_co, 1); - if (dflag) - show_stat("LSu", 5, - sum->ift_dr - total->ift_dr, 1); - } - *total = *sum; + if ((noutputs != 0) && (--noutputs == 0)) { + xo_close_list("interface-statistics"); + return; } - if (!first) - putchar('\n'); - fflush(stdout); - if ((noutputs != 0) && (--noutputs == 0)) - exit(0); #ifdef __rtems__ { sigset_t oldmask, desired, empty; @@ -712,31 +627,56 @@ loop: sigprocmask(SIG_BLOCK, &desired, &oldmask); while (!signalled) sigsuspend(&desired); - signalled = NO; + signalled = false; sigprocmask(SIG_SETMASK, &oldmask, NULL); } #else /* __rtems__ */ oldmask = sigblock(sigmask(SIGALRM)); while (!signalled) sigpause(0); - signalled = NO; + signalled = false; sigsetmask(oldmask); #endif /* __rtems__ */ line++; - first = 0; + + fill_iftot(new); + + xo_open_instance("stats"); + show_stat("lu", 10, "received-packets", + new->ift_ip - old->ift_ip, 1, 1); + show_stat("lu", 5, "received-errors", + new->ift_ie - old->ift_ie, 1, 1); + show_stat("lu", 5, "dropped-packets", + new->ift_id - old->ift_id, 1, 1); + show_stat("lu", 10, "received-bytes", + new->ift_ib - old->ift_ib, 1, 0); + show_stat("lu", 10, "sent-packets", + new->ift_op - old->ift_op, 1, 1); + show_stat("lu", 5, "send-errors", + new->ift_oe - old->ift_oe, 1, 1); + show_stat("lu", 10, "sent-bytes", + new->ift_ob - old->ift_ob, 1, 0); + show_stat("NRSlu", 5, "collisions", + new->ift_co - old->ift_co, 1, 1); + if (dflag) + show_stat("LSlu", 5, "dropped-packets", + new->ift_od - old->ift_od, 1, 1); + xo_close_instance("stats"); + xo_emit("\n"); + xo_flush(); + + if (new == &ift[0]) { + new = &ift[1]; + old = &ift[0]; + } else { + new = &ift[0]; + old = &ift[1]; + } + if (line == 21) goto banner; else goto loop; - /*NOTREACHED*/ -} -/* - * Set a flag to indicate that a signal from the periodic itimer has been - * caught. - */ -static void -catchalarm(int signo __unused) -{ - signalled = YES; + /* NOTREACHED */ } diff --git a/freebsd/usr.bin/netstat/inet.c b/freebsd/usr.bin/netstat/inet.c index e67ef0a6..c5a5042d 100644 --- a/freebsd/usr.bin/netstat/inet.c +++ b/freebsd/usr.bin/netstat/inet.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 1983, 1988, 1993, 1995 * The Regents of the University of California. All rights reserved. @@ -35,6 +39,9 @@ static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -68,7 +75,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/tcp_fsm.h> #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> -#include <netinet/tcp_debug.h> #include <netinet/udp.h> #include <netinet/udp_var.h> @@ -80,29 +86,25 @@ __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" +#include "nl_defs.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-inet-data.h" +#endif /* __rtems__ */ 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, + const int); #ifdef INET6 static int udp_done, tcp_done, sdp_done; #endif /* INET6 */ -#ifdef __rtems__ -void -rtems_bsd_netstat_inet_init(void) -{ -#ifdef INET6 - udp_done = 0; - tcp_done = 0; - sdp_done = 0; -#endif /* INET6 */ -} -#endif /* __rtems__ */ static int -pcblist_sysctl(int proto, const char *name, char **bufp, int istcp) +pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused) { const char *mibvar; char *buf; @@ -127,15 +129,15 @@ pcblist_sysctl(int proto, const char *name, char **bufp, int istcp) 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); + if ((buf = malloc(len)) == NULL) { + 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); } @@ -150,7 +152,7 @@ pcblist_sysctl(int proto, const char *name, char **bufp, int istcp) 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; @@ -217,15 +219,15 @@ pcblist_kvm(u_long off, char **bufp, int istcp) len = 2 * sizeof(xig) + (pcbinfo.ipi_count + pcbinfo.ipi_count / 8) * sizeof(struct xinpcb); - if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); + if ((buf = malloc(len)) == NULL) { + 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)); \ @@ -306,6 +308,9 @@ fail: #undef KREAD } +#ifdef __rtems__ +static int protopr_first = 1; +#endif /* __rtems__ */ /* * Print a summary of connections related to an Internet * protocol. For TCP, also give state of connection. @@ -316,6 +321,9 @@ void protopr(u_long off, const char *name, int af1, int proto) { int istcp; +#ifndef __rtems__ + static int first = 1; +#endif /* __rtems__ */ char *buf; const char *vchar; struct tcpcb *tp = NULL; @@ -361,8 +369,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; @@ -413,179 +421,237 @@ protopr(u_long off, const char *name, int af1, int proto) )) continue; - if (!protopr_initialized) { +#ifndef __rtems__ + if (first) { +#else /* __rtems__ */ + if (protopr_first) { +#endif /* __rtems__ */ 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:/%-32.32s} {T:/%-18.18s}" : + ((!Wflag || af1 == AF_INET) ? + "{T:/%-5.5s} {T:/%-32.32s} {T:/%-22.22s}" : + "{T:/%-5.5s} {T:/%-32.32s} {T:/%-45.45s}"), "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}" : + ((!Wflag || af1 == AF_INET) ? + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%s}" : + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {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"); - if (!xflag) - printf(" (state)"); + xo_emit((Aflag && !Wflag) ? + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%-18.18s}" : + ((!Wflag || af1 == AF_INET) ? + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%-22.22s}" : + "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%-45.45s}"), + "Proto", "Recv-Q", "Send-Q", + "Local Address", "Foreign Address"); + if (!xflag && !Rflag) + 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) { + xo_emit(" {T:/%8.8s} {T:/%5.5s}", + "flowid", "ftype"); } - putchar('\n'); - protopr_initialized = 1; + xo_emit("\n"); +#ifndef __rtems__ + first = 0; +#else /* __rtems__ */ + protopr_first = 0; +#endif /* __rtems__ */ } 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]; + char buf1[33]; - snprintf(buf1, 15, "%d/%d/%d", so->so_qlen, + snprintf(buf1, sizeof buf1, "%u/%u/%u", so->so_qlen, so->so_incqlen, so->so_qlimit); - printf("%-14.14s ", buf1); + xo_emit("{:listen-queue-sizes/%-32.32s} ", 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 + xo_emit("{P:/%21s}", ""); } 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, af1); if (!Lflag) - inetprint(&inp->inp_faddr, - (int)inp->inp_fport, name, 1); + inetprint("remote", &inp->inp_faddr, + (int)inp->inp_fport, name, 1, af1); } #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, af1); if (!Lflag) - inetprint(&inp->inp_faddr, - (int)inp->inp_fport, name, 0); + inetprint("remote", &inp->inp_faddr, + (int)inp->inp_fport, name, 0, af1); } #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, af1); if (!Lflag) - inetprint(&inp->inp_faddr, + inetprint("remote", &inp->inp_faddr, (int)inp->inp_fport, name, - inp->inp_lport != inp->inp_fport); + inp->inp_lport != inp->inp_fport, + af1); } #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) { + 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) */ } - } - putchar('\n'); + } + if (Rflag) { + /* XXX: is this right Alfred */ + xo_emit(" {:flow-id/%08x} {:flow-type/%5d}", + inp->inp_flowid, + inp->inp_flowtype); + } + 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); @@ -597,8 +663,8 @@ protopr(u_long off, const char *name, int af1, int proto) void tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct tcpstat tcpstat, zerostat; - size_t len = sizeof tcpstat; + struct tcpstat tcpstat; + uint64_t tcps_states[TCP_NSTATES]; #ifdef INET6 if (tcp_done != 0) @@ -607,133 +673,240 @@ tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) tcp_done = 1; #endif - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - warn("sysctl: net.inet.tcp.stats"); - return; - } - } else - kread(off, &tcpstat, len); - - printf ("%s:\n", name); - -#define p(f, m) if (tcpstat.f || sflag <= 1) \ - printf(m, tcpstat.f, plural(tcpstat.f)) -#define p1a(f, m) if (tcpstat.f || sflag <= 1) \ - printf(m, tcpstat.f) -#define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ - printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) -#define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ - printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2) -#define p3(f, m) if (tcpstat.f || sflag <= 1) \ - printf(m, tcpstat.f, pluralies(tcpstat.f)) - - p(tcps_sndtotal, "\t%lu packet%s sent\n"); - p2(tcps_sndpack,tcps_sndbyte, "\t\t%lu data packet%s (%lu byte%s)\n"); - p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, - "\t\t%lu data packet%s (%lu byte%s) retransmitted\n"); - p(tcps_sndrexmitbad, - "\t\t%lu data packet%s unnecessarily retransmitted\n"); - p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n"); - p2a(tcps_sndacks, tcps_delack, - "\t\t%lu ack-only packet%s (%lu delayed)\n"); - p(tcps_sndurg, "\t\t%lu URG only packet%s\n"); - p(tcps_sndprobe, "\t\t%lu window probe packet%s\n"); - p(tcps_sndwinup, "\t\t%lu window update packet%s\n"); - p(tcps_sndctrl, "\t\t%lu control packet%s\n"); - p(tcps_rcvtotal, "\t%lu packet%s received\n"); - p2(tcps_rcvackpack, tcps_rcvackbyte, - "\t\t%lu ack%s (for %lu byte%s)\n"); - p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n"); - p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n"); - p2(tcps_rcvpack, tcps_rcvbyte, - "\t\t%lu packet%s (%lu byte%s) received in-sequence\n"); - p2(tcps_rcvduppack, tcps_rcvdupbyte, - "\t\t%lu completely duplicate packet%s (%lu byte%s)\n"); - p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n"); - p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, - "\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n"); - p2(tcps_rcvoopack, tcps_rcvoobyte, - "\t\t%lu out-of-order packet%s (%lu byte%s)\n"); - p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, - "\t\t%lu packet%s (%lu byte%s) of data after window\n"); - p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n"); - p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n"); - p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n"); - p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n"); - p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n"); - p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n"); - p1a(tcps_rcvmemdrop, "\t\t%lu discarded due to memory problems\n"); - p(tcps_connattempt, "\t%lu connection request%s\n"); - p(tcps_accepts, "\t%lu connection accept%s\n"); - p(tcps_badsyn, "\t%lu bad connection attempt%s\n"); - p(tcps_listendrop, "\t%lu listen queue overflow%s\n"); - p(tcps_badrst, "\t%lu ignored RSTs in the window%s\n"); - p(tcps_connects, "\t%lu connection%s established (including accepts)\n"); - p2(tcps_closed, tcps_drops, - "\t%lu connection%s closed (including %lu drop%s)\n"); - p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n"); - p(tcps_cachedrttvar, - "\t\t%lu connection%s updated cached RTT variance on close\n"); - p(tcps_cachedssthresh, - "\t\t%lu connection%s updated cached ssthresh on close\n"); - p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n"); - p2(tcps_rttupdated, tcps_segstimed, - "\t%lu segment%s updated rtt (of %lu attempt%s)\n"); - p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n"); - p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n"); - p(tcps_persisttimeo, "\t%lu persist timeout%s\n"); - p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n"); - p(tcps_finwait2_drops, - "\t%lu Connection%s (fin_wait_2) dropped because of timeout\n"); - p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n"); - p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n"); - p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n"); - p(tcps_predack, "\t%lu correct ACK header prediction%s\n"); - p(tcps_preddat, "\t%lu correct data packet header prediction%s\n"); - - p3(tcps_sc_added, "\t%lu syncache entr%s added\n"); - p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n"); - p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n"); - p1a(tcps_sc_dropped, "\t\t%lu dropped\n"); - p1a(tcps_sc_completed, "\t\t%lu completed\n"); - p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n"); - p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n"); - p1a(tcps_sc_reset, "\t\t%lu reset\n"); - p1a(tcps_sc_stale, "\t\t%lu stale\n"); - p1a(tcps_sc_aborted, "\t\t%lu aborted\n"); - p1a(tcps_sc_badack, "\t\t%lu badack\n"); - p1a(tcps_sc_unreach, "\t\t%lu unreach\n"); - p(tcps_sc_zonefail, "\t\t%lu zone failure%s\n"); - p(tcps_sc_sendcookie, "\t%lu cookie%s sent\n"); - p(tcps_sc_recvcookie, "\t%lu cookie%s received\n"); - - p(tcps_hc_added, "\t%lu hostcache entrie%s added\n"); - p1a(tcps_hc_bucketoverflow, "\t\t%lu bucket overflow\n"); - - p(tcps_sack_recovery_episode, "\t%lu SACK recovery episode%s\n"); - p(tcps_sack_rexmits, - "\t%lu segment rexmit%s in SACK recovery episodes\n"); - p(tcps_sack_rexmit_bytes, - "\t%lu byte rexmit%s in SACK recovery episodes\n"); - p(tcps_sack_rcv_blocks, - "\t%lu SACK option%s (SACK blocks) received\n"); - p(tcps_sack_send_blocks, "\t%lu SACK option%s (SACK blocks) sent\n"); - p1a(tcps_sack_sboverflow, "\t%lu SACK scoreboard overflow\n"); - - p(tcps_ecn_ce, "\t%lu packet%s with ECN CE bit set\n"); - p(tcps_ecn_ect0, "\t%lu packet%s with ECN ECT(0) bit set\n"); - p(tcps_ecn_ect1, "\t%lu packet%s with ECN ECT(1) bit set\n"); - p(tcps_ecn_shs, "\t%lu successful ECN handshake%s\n"); - p(tcps_ecn_rcwnd, "\t%lu time%s ECN reduced the congestion window\n"); -#undef p -#undef p1a -#undef p2 -#undef p2a -#undef p3 + if (fetch_stats("net.inet.tcp.stats", off, &tcpstat, + sizeof(tcpstat), kread_counters) != 0) + return; + + if (fetch_stats_ro("net.inet.tcp.states", nl[N_TCPS_STATES].n_value, + &tcps_states, sizeof(tcps_states), kread_counters) != 0) + return; + + xo_open_container("tcp"); + xo_emit("{T:/%s}:\n", name); + +#define p(f, m) if (tcpstat.f || sflag <= 1) \ + xo_emit(m, (uintmax_t )tcpstat.f, plural(tcpstat.f)) +#define p1a(f, m) if (tcpstat.f || sflag <= 1) \ + xo_emit(m, (uintmax_t )tcpstat.f) +#define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ + 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) \ + xo_emit(m, (uintmax_t )tcpstat.f1, plural(tcpstat.f1), \ + (uintmax_t )tcpstat.f2) +#define p3(f, m) if (tcpstat.f || sflag <= 1) \ + 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_open_container("TCP connection count by state"); + xo_emit("{T:/TCP connection count by state}:\n"); + for (int i = 0; i < TCP_NSTATES; i++) { + /* + * XXXGL: is there a way in libxo to use %s + * in the "content string" of a format + * string? I failed to do that, that's why + * a temporary buffer is used to construct + * format string for xo_emit(). + */ + char fmtbuf[80]; + + if (sflag > 1 && tcps_states[i] == 0) + continue; + snprintf(fmtbuf, sizeof(fmtbuf), "\t{:%s/%%ju} " + "{Np:/connection ,connections} in %s state\n", + tcpstates[i], tcpstates[i]); + xo_emit(fmtbuf, (uintmax_t )tcps_states[i]); + } + xo_close_container("TCP connection count by state"); + + xo_close_container("tcp"); } /* @@ -742,9 +915,8 @@ tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) void udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct udpstat udpstat, zerostat; - size_t len = sizeof udpstat; - u_long delivered; + struct udpstat udpstat; + uint64_t delivered; #ifdef INET6 if (udp_done != 0) @@ -753,32 +925,36 @@ udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) udp_done = 1; #endif - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - warn("sysctl: net.inet.udp.stats"); - return; - } - } else - kread(off, &udpstat, len); + if (fetch_stats("net.inet.udp.stats", off, &udpstat, + sizeof(udpstat), kread_counters) != 0) + return; + + xo_open_container("udp"); + xo_emit("{T:/%s}:\n", name); - printf("%s:\n", name); #define p(f, m) if (udpstat.f || sflag <= 1) \ - printf(m, 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(m, udpstat.f) - p(udps_ipackets, "\t%lu datagram%s received\n"); - p1a(udps_hdrops, "\t%lu with incomplete header\n"); - p1a(udps_badlen, "\t%lu with bad data length field\n"); - p1a(udps_badsum, "\t%lu with bad checksum\n"); - p1a(udps_nosum, "\t%lu with no checksum\n"); - p1a(udps_noport, "\t%lu dropped due to no socket\n"); - p(udps_noportbcast, - "\t%lu broadcast/multicast datagram%s undelivered\n"); - p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); - p1a(udpps_pcbhashmiss, "\t%lu 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 - @@ -787,13 +963,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%lu delivered\n", delivered); - p(udps_opackets, "\t%lu 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, - "\t%lu 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"); } /* @@ -802,49 +980,53 @@ udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) void carp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct carpstats carpstat, zerostat; - size_t len = sizeof(struct carpstats); + struct carpstats carpstat; - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.carp.stats", &carpstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet.carp.stats"); - return; - } - } else { - if (off == 0) - return; - kread(off, &carpstat, len); - } + if (fetch_stats("net.inet.carp.stats", off, &carpstat, + sizeof(carpstat), kread_counters) != 0) + return; - 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); } /* @@ -853,62 +1035,83 @@ carp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) void ip_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct ipstat ipstat, zerostat; - size_t len = sizeof ipstat; + struct ipstat ipstat; - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - warn("sysctl: net.inet.ip.stats"); - return; - } - } else - kread(off, &ipstat, len); + if (fetch_stats("net.inet.ip.stats", off, &ipstat, + sizeof(ipstat), kread_counters) != 0) + return; - 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, 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, ipstat.f) - - p(ips_total, "\t%lu total packet%s received\n"); - p(ips_badsum, "\t%lu bad header checksum%s\n"); - p1a(ips_toosmall, "\t%lu with size smaller than minimum\n"); - p1a(ips_tooshort, "\t%lu with data size < data length\n"); - p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n"); - p1a(ips_badhlen, "\t%lu with header length < data size\n"); - p1a(ips_badlen, "\t%lu with data length < header length\n"); - p1a(ips_badoptions, "\t%lu with bad options\n"); - p1a(ips_badvers, "\t%lu with incorrect version number\n"); - p(ips_fragments, "\t%lu fragment%s received\n"); - p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); - p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); - p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); - p(ips_delivered, "\t%lu packet%s for this host\n"); - p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); - p(ips_forward, "\t%lu packet%s forwarded"); - p(ips_fastforward, " (%lu 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%lu packet%s not forwardable\n"); - p(ips_notmember, - "\t%lu packet%s received for unknown multicast group\n"); - p(ips_redirectsent, "\t%lu redirect%s sent\n"); - p(ips_localout, "\t%lu packet%s sent from this host\n"); - p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); - p(ips_odropped, - "\t%lu output packet%s dropped due to no bufs, etc.\n"); - p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); - p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); - p(ips_ofragments, "\t%lu fragment%s created\n"); - p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); - p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n"); - p(ips_badaddr, "\t%lu 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); } /* @@ -917,42 +1120,46 @@ ip_stats(u_long off, const char *name, int af1 __unused, int proto __unused) void arp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct arpstat arpstat, zerostat; - size_t len = sizeof(arpstat); + struct arpstat arpstat; - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.link.ether.arp.stats", &arpstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - warn("sysctl: net.link.ether.arp.stats"); - return; - } - } else - kread(off, &arpstat, len); + if (fetch_stats("net.link.ether.arp.stats", off, &arpstat, + sizeof(arpstat), kread_counters) != 0) + return; - printf("%s:\n", name); + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); #define p(f, m) if (arpstat.f || sflag <= 1) \ - printf(m, 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(m, arpstat.f, pluralies(arpstat.f)) - - p(txrequests, "\t%lu ARP request%s sent\n"); - p2(txreplies, "\t%lu ARP repl%s sent\n"); - p(rxrequests, "\t%lu ARP request%s received\n"); - p2(rxreplies, "\t%lu ARP repl%s received\n"); - p(received, "\t%lu ARP packet%s received\n"); - p(dropped, "\t%lu total packet%s dropped due to no ARP entry\n"); - p(timeouts, "\t%lu ARP entry%s timed out\n"); - p(dupips, "\t%lu 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); } +#ifndef __rtems__ +static const char *icmpnames[ICMP_MAXTYPE + 1] = { +#else /* __rtems__ */ static const char *const icmpnames[ICMP_MAXTYPE + 1] = { +#endif /* __rtems__ */ "echo reply", /* RFC 792 */ "#1", "#2", @@ -1002,69 +1209,91 @@ static const char *const icmpnames[ICMP_MAXTYPE + 1] = { void icmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct icmpstat icmpstat, zerostat; - int i, first; + struct icmpstat icmpstat; size_t len; + int i, first; - len = sizeof icmpstat; - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - warn("sysctl: net.inet.icmp.stats"); - return; - } - } else - kread(off, &icmpstat, len); + if (fetch_stats("net.inet.icmp.stats", off, &icmpstat, + sizeof(icmpstat), kread_counters) != 0) + return; - 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{: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"); - 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++) + 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 @@ -1073,51 +1302,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. @@ -1125,80 +1315,66 @@ igmp_stats_live_old(const char *name) void igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct igmpstat igmpstat, zerostat; - size_t len; - -#ifndef BURN_BRIDGES - if (live) { - /* - * Detect if we are being run against a pre-IGMPv3 kernel. - * We cannot do this for a core file as the legacy - * struct igmpstat has no size field, nor does it - * export it in any readily-available symbols. - */ - len = 0; - if (sysctlbyname("net.inet.igmp.stats", NULL, &len, NULL, - 0) < 0) { - warn("sysctl: net.inet.igmp.stats"); - return; - } - if (len < sizeof(igmpstat)) { - igmp_stats_live_old(name); - return; - } - } -#endif /* !BURN_BRIDGES */ + struct igmpstat igmpstat; - len = sizeof(igmpstat); - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - warn("sysctl: net.inet.igmp.stats"); - return; - } - } else { - len = sizeof(igmpstat); - kread(off, &igmpstat, len); - } + if (fetch_stats("net.inet.igmp.stats", 0, &igmpstat, + sizeof(igmpstat), kread) != 0) + return; 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); } /* @@ -1208,72 +1384,86 @@ void pim_stats(u_long off __unused, const char *name, int af1 __unused, int proto __unused) { - struct pimstat pimstat, zerostat; - size_t len = sizeof pimstat; + struct pimstat pimstat; - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.pim.stats", &pimstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet.pim.stats"); - return; - } - } else { - if (off == 0) - return; - kread(off, &pimstat, len); - } + if (fetch_stats("net.inet.pim.stats", off, &pimstat, + sizeof(pimstat), kread_counters) != 0) + return; - 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, const int af1) { struct servent *sp = 0; char line[80], *cp; int width; + if (container) + xo_open_container(container); + if (Wflag) sprintf(line, "%s.", inetname(in)); else sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in)); - cp = index(line, '\0'); + cp = strchr(line, '\0'); if (!num_port && port) sp = getservbyport((int)port, proto); if (sp || port == 0) sprintf(cp, "%.15s ", sp ? sp->s_name : "*"); else sprintf(cp, "%d ", ntohs((u_short)port)); - width = (Aflag && !Wflag) ? 18 : 22; + width = (Aflag && !Wflag) ? 18 : + ((!Wflag || af1 == AF_INET) ? 22 : 45); 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); } /* @@ -1299,7 +1489,7 @@ inetname(struct in_addr *inp) if (np) cp = np->n_name; } - if (cp == 0) { + if (cp == NULL) { hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); if (hp) { cp = hp->h_name; diff --git a/freebsd/usr.bin/netstat/inet6.c b/freebsd/usr.bin/netstat/inet6.c index 07086318..941a2000 100644 --- a/freebsd/usr.bin/netstat/inet6.c +++ b/freebsd/usr.bin/netstat/inet6.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ /*- * Copyright (c) 1983, 1988, 1993 @@ -36,6 +40,9 @@ static char sccsid[] = "@(#)inet6.c 8.4 (Berkeley) 4/20/94"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -46,11 +53,9 @@ __FBSDID("$FreeBSD$"); #include <sys/ioctl.h> #include <sys/mbuf.h> #include <sys/protosw.h> -#include <sys/sysctl.h> #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> @@ -67,12 +72,15 @@ __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; +#ifdef __rtems__ +#include "rtems-bsd-netstat-inet6-data.h" +#endif /* __rtems__ */ char *inet6name(struct in6_addr *); @@ -211,11 +219,11 @@ static const char *ip6nh[] = { "#129", "#130", "#131", - "#132", + "SCTP", "#133", "#134", "#135", - "#136", + "UDPLite", "#137", "#138", "#139", @@ -337,7 +345,7 @@ static const char *ip6nh[] = { "#255", }; -static char *srcrule_str[] = { +static const char *srcrule_str[] = { "first candidate", "same address", "appropriate scope", @@ -347,7 +355,7 @@ static char *srcrule_str[] = { "matching label", "public/temporary address", "alive interface", - "preferred interface", + "better virtual status", "preferred source", "rule #11", "rule #12", @@ -362,165 +370,248 @@ static char *srcrule_str[] = { void ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct ip6stat ip6stat, zerostat; + struct ip6stat ip6stat; int first, i; - size_t len; - - len = sizeof ip6stat; - if (live) { - memset(&ip6stat, 0, len); - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet6.ip6.stats"); - return; - } - } else - kread(off, &ip6stat, len); - printf("%s:\n", name); + if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat, + sizeof(ip6stat), kread_counters) != 0) + return; + + 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} " \ + "{N:/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); } /* @@ -531,52 +622,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[] = { @@ -844,88 +957,119 @@ static const char *icmp6names[] = { void icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct icmp6stat icmp6stat, zerostat; + struct icmp6stat icmp6stat; int i, first; - size_t len; - - len = sizeof icmp6stat; - if (live) { - memset(&icmp6stat, 0, len); - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet6.icmp6.stats"); - return; - } - } else - kread(off, &icmp6stat, len); - printf("%s:\n", name); + if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat, + sizeof(icmp6stat), kread_counters) != 0) + return; + + 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); } /* @@ -936,61 +1080,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 } @@ -1001,36 +1186,34 @@ icmp6_ifstats(char *ifname) void pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct pim6stat pim6stat, zerostat; - size_t len = sizeof pim6stat; - - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet6.pim.stats"); - return; - } - } else { - if (off == 0) - return; - kread(off, &pim6stat, len); - } + struct pim6stat pim6stat; + + if (fetch_stats("net.inet6.pim.stats", off, &pim6stat, + sizeof(pim6stat), kread) != 0) + return; - 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); } /* @@ -1039,44 +1222,43 @@ pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) void rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct rip6stat rip6stat, zerostat; + struct rip6stat rip6stat; u_quad_t delivered; - size_t len; - - len = sizeof(rip6stat); - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet6.ip6.rip6stats"); - return; - } - } else - kread(off, &rip6stat, len); - printf("%s:\n", name); + if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat, + sizeof(rip6stat), kread_counters) != 0) + return; + + 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); } /* @@ -1094,15 +1276,19 @@ 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)); - cp = index(line, '\0'); + 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); if (sp || port == 0) @@ -1110,7 +1296,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); } /* @@ -1122,38 +1316,45 @@ inet6print(struct in6_addr *in6, int port, const char *proto, int numeric) char * inet6name(struct in6_addr *in6p) { - char *cp; + struct sockaddr_in6 sin6; + char hbuf[NI_MAXHOST], *cp; static char line[50]; - struct hostent *hp; static char domain[MAXHOSTNAMELEN]; static int first = 1; + int flags, error; + if (IN6_IS_ADDR_UNSPECIFIED(in6p)) { + strcpy(line, "*"); + return (line); + } if (first && !numeric_addr) { first = 0; if (gethostname(domain, MAXHOSTNAMELEN) == 0 && - (cp = index(domain, '.'))) + (cp = strchr(domain, '.'))) (void) strcpy(domain, cp + 1); else domain[0] = 0; } - cp = 0; - if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) { - hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6); - if (hp) { - if ((cp = index(hp->h_name, '.')) && - !strcmp(cp + 1, domain)) - *cp = 0; - cp = hp->h_name; - } - } - if (IN6_IS_ADDR_UNSPECIFIED(in6p)) - strcpy(line, "*"); - else if (cp) - strcpy(line, cp); - else + 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. */ + in6_fillscopeid(&sin6); + flags = (numeric_addr) ? NI_NUMERICHOST : 0; + error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf, + sizeof(hbuf), NULL, 0, flags); + if (error == 0) { + if ((flags & NI_NUMERICHOST) == 0 && + (cp = strchr(hbuf, '.')) && + !strcmp(cp + 1, domain)) + *cp = 0; + strcpy(line, hbuf); + } else { + /* XXX: this should not happen. */ sprintf(line, "%s", - inet_ntop(AF_INET6, (void *)in6p, ntop_buf, + inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf, sizeof(ntop_buf))); + } return (line); } #endif /*INET6*/ diff --git a/freebsd/usr.bin/netstat/ipsec.c b/freebsd/usr.bin/netstat/ipsec.c index 53dfdbe1..5b7c185b 100644 --- a/freebsd/usr.bin/netstat/ipsec.c +++ b/freebsd/usr.bin/netstat/ipsec.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /* $KAME: ipsec.c,v 1.33 2003/07/25 09:54:32 itojun Exp $ */ /*- @@ -90,6 +94,9 @@ static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -109,9 +116,14 @@ __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 __rtems__ +#include "rtems-bsd-netstat-ipsec-data.h" +#endif /* __rtems__ */ #ifdef IPSEC struct val2str { @@ -157,6 +169,9 @@ static struct val2str ipsec_espnames[] = { #ifdef SADB_X_EALG_AESCTR { SADB_X_EALG_AESCTR, "aes-ctr", }, #endif +#ifdef SADB_X_EALG_AESGCM16 + { SADB_X_EALG_AESGCM16, "aes-gcm-16", }, +#endif { -1, NULL }, }; @@ -168,98 +183,44 @@ static struct val2str ipsec_compnames[] = { { -1, NULL }, }; -static void ipsec_hist(const u_quad_t *hist, size_t histmax, - const struct val2str *name, const char *title); static void print_ipsecstats(const struct ipsecstat *ipsecstat); - -/* - * Dump IPSEC statistics structure. - */ -static void -ipsec_hist(const u_quad_t *hist, size_t histmax, const struct val2str *name, - const char *title) -{ - int first; - size_t proto; - const struct val2str *p; - - first = 1; - for (proto = 0; proto < histmax; proto++) { - if (hist[proto] <= 0) - continue; - if (first) { - printf("\t%s histogram:\n", title); - first = 0; - } - 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, (uintmax_t)hist[proto]); - } else { - printf("\t\t#%ld: %ju\n", (long)proto, - (uintmax_t)hist[proto]); - } - } -} - 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)) -#define pes(f, m) if (ipsecstat->f || sflag <= 1) \ - printf(m, (uintmax_t)ipsecstat->f, plurales(ipsecstat->f)) -#define hist(f, n, t) \ - ipsec_hist((f), sizeof(f)/sizeof(f[0]), (n), (t)); - - p(in_success, "\t%ju inbound packet%s processed successfully\n"); - p(in_polvio, "\t%ju inbound packet%s violated process security " - "policy\n"); - p(in_nosa, "\t%ju inbound packet%s with no SA available\n"); - p(in_inval, "\t%ju invalid inbound packet%s\n"); - p(in_nomem, "\t%ju inbound packet%s failed due to insufficient memory\n"); - p(in_badspi, "\t%ju inbound packet%s failed getting SPI\n"); - p(in_ahreplay, "\t%ju inbound packet%s failed on AH replay check\n"); - p(in_espreplay, "\t%ju inbound packet%s failed on ESP replay check\n"); - p(in_ahauthsucc, "\t%ju inbound packet%s considered authentic\n"); - p(in_ahauthfail, "\t%ju inbound packet%s failed on authentication\n"); - hist(ipsecstat->in_ahhist, ipsec_ahnames, "AH input"); - hist(ipsecstat->in_esphist, ipsec_espnames, "ESP input"); - hist(ipsecstat->in_comphist, ipsec_compnames, "IPComp input"); - - p(out_success, "\t%ju outbound packet%s processed successfully\n"); - p(out_polvio, "\t%ju outbound packet%s violated process security " - "policy\n"); - p(out_nosa, "\t%ju outbound packet%s with no SA available\n"); - p(out_inval, "\t%ju invalid outbound packet%s\n"); - p(out_nomem, "\t%ju outbound packet%s failed due to insufficient memory\n"); - p(out_noroute, "\t%ju outbound packet%s with no route\n"); - hist(ipsecstat->out_ahhist, ipsec_ahnames, "AH output"); - hist(ipsecstat->out_esphist, ipsec_espnames, "ESP output"); - hist(ipsecstat->out_comphist, ipsec_compnames, "IPComp output"); - p(spdcachelookup, "\t%ju SPD cache lookup%s\n"); - pes(spdcachemiss, "\t%ju SPD cache miss%s\n"); -#undef pes -#undef hist - p(ips_in_polvio, "\t%ju inbound packet%s violated process " - "security policy\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 @@ -267,17 +228,22 @@ ipsec_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct ipsecstat ipsecstat; - if (off == 0) - return; - printf ("%s:\n", name); - kread(off, (char *)&ipsecstat, sizeof(ipsecstat)); + if (strcmp(name, "ipsec6") == 0) { + if (fetch_stats("net.inet6.ipsec6.ipsecstats", off,&ipsecstat, + sizeof(ipsecstat), kread_counters) != 0) + return; + } else { + if (fetch_stats("net.inet.ipsec.ipsecstats", off, &ipsecstat, + sizeof(ipsecstat), kread_counters) != 0) + return; + } + + xo_emit("{T:/%s}:\n", name); print_ipsecstats(&ipsecstat); } -static void ipsec_hist_new(const u_int32_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); @@ -286,8 +252,8 @@ static void print_ipcompstats(const struct ipcompstat *ipcompstat); * Dump IPSEC statistics structure. */ static void -ipsec_hist_new(const u_int32_t *hist, size_t histmax, - const struct val2str *name, const char *title) +ipsec_hist_new(const uint64_t *hist, size_t histmax, + const struct val2str *name, const char *title, const char *cname) { int first; size_t proto; @@ -298,56 +264,72 @@ ipsec_hist_new(const u_int32_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: %u\n", p->str, hist[proto]); + xo_emit("\t\t{k:name}: {:count/%ju}\n", p->str, + (uintmax_t)hist[proto]); } else { - printf("\t\t#%lu: %u\n", (unsigned long)proto, - 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 p32(f, m) if (ahstat->f || sflag <= 1) \ - printf("\t%u" m, (unsigned int)ahstat->f, plural(ahstat->f)) -#define p64(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)); - - p32(ahs_hdrops, " packet%s shorter than header shows\n"); - p32(ahs_nopf, " packet%s dropped; protocol family not supported\n"); - p32(ahs_notdb, " packet%s dropped; no TDB\n"); - p32(ahs_badkcr, " packet%s dropped; bad KCR\n"); - p32(ahs_qfull, " packet%s dropped; queue full\n"); - p32(ahs_noxform, " packet%s dropped; no transform\n"); - p32(ahs_wrap, " replay counter wrap%s\n"); - p32(ahs_badauth, " packet%s dropped; bad authentication detected\n"); - p32(ahs_badauthl, " packet%s dropped; bad authentication length\n"); - p32(ahs_replay, " possible replay packet%s detected\n"); - p32(ahs_input, " packet%s in\n"); - p32(ahs_output, " packet%s out\n"); - p32(ahs_invalid, " packet%s dropped; invalid TDB\n"); - p64(ahs_ibytes, " byte%s in\n"); - p64(ahs_obytes, " byte%s out\n"); - p32(ahs_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); - p32(ahs_pdrops, " packet%s blocked due to policy\n"); - p32(ahs_crypto, " crypto processing failure%s\n"); - p32(ahs_tunnel, " tunnel sanity check failure%s\n"); - hist(ahstat->ahs_hist, ipsec_ahnames, "AH output"); - -#undef p32 -#undef p64 + 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 @@ -355,10 +337,11 @@ ah_stats(u_long off, const char *name, int family __unused, int proto __unused) { struct ahstat ahstat; - if (off == 0) + if (fetch_stats("net.inet.ah.stats", off, &ahstat, + sizeof(ahstat), kread_counters) != 0) return; - printf ("%s:\n", name); - kread(off, (char *)&ahstat, sizeof(ahstat)); + + xo_emit("{T:/%s}:\n", name); print_ahstats(&ahstat); } @@ -366,38 +349,47 @@ ah_stats(u_long off, const char *name, int family __unused, int proto __unused) static void print_espstats(const struct espstat *espstat) { -#define p32(f, m) if (espstat->f || sflag <= 1) \ - printf("\t%u" m, (unsigned int)espstat->f, plural(espstat->f)) -#define p64(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)); - - p32(esps_hdrops, " packet%s shorter than header shows\n"); - p32(esps_nopf, " packet%s dropped; protocol family not supported\n"); - p32(esps_notdb, " packet%s dropped; no TDB\n"); - p32(esps_badkcr, " packet%s dropped; bad KCR\n"); - p32(esps_qfull, " packet%s dropped; queue full\n"); - p32(esps_noxform, " packet%s dropped; no transform\n"); - p32(esps_badilen, " packet%s dropped; bad ilen\n"); - p32(esps_wrap, " replay counter wrap%s\n"); - p32(esps_badenc, " packet%s dropped; bad encryption detected\n"); - p32(esps_badauth, " packet%s dropped; bad authentication detected\n"); - p32(esps_replay, " possible replay packet%s detected\n"); - p32(esps_input, " packet%s in\n"); - p32(esps_output, " packet%s out\n"); - p32(esps_invalid, " packet%s dropped; invalid TDB\n"); - p64(esps_ibytes, " byte%s in\n"); - p64(esps_obytes, " byte%s out\n"); - p32(esps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); - p32(esps_pdrops, " packet%s blocked due to policy\n"); - p32(esps_crypto, " crypto processing failure%s\n"); - p32(esps_tunnel, " tunnel sanity check failure%s\n"); - hist(espstat->esps_hist, ipsec_espnames, "ESP output"); - -#undef p32 -#undef p64 + 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 @@ -405,10 +397,11 @@ esp_stats(u_long off, const char *name, int family __unused, int proto __unused) { struct espstat espstat; - if (off == 0) + if (fetch_stats("net.inet.esp.stats", off, &espstat, + sizeof(espstat), kread_counters) != 0) return; - printf ("%s:\n", name); - kread(off, (char *)&espstat, sizeof(espstat)); + + xo_emit("{T:/%s}:\n", name); print_espstats(&espstat); } @@ -416,43 +409,44 @@ esp_stats(u_long off, const char *name, int family __unused, int proto __unused) static void print_ipcompstats(const struct ipcompstat *ipcompstat) { - uint32_t version; -#define p32(f, m) if (ipcompstat->f || sflag <= 1) \ - printf("\t%u" m, (unsigned int)ipcompstat->f, plural(ipcompstat->f)) -#define p64(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)); - -#ifndef IPCOMPSTAT_VERSION - version = 0; -#else - version = ipcompstat->version; -#endif - p32(ipcomps_hdrops, " packet%s shorter than header shows\n"); - p32(ipcomps_nopf, " packet%s dropped; protocol family not supported\n"); - p32(ipcomps_notdb, " packet%s dropped; no TDB\n"); - p32(ipcomps_badkcr, " packet%s dropped; bad KCR\n"); - p32(ipcomps_qfull, " packet%s dropped; queue full\n"); - p32(ipcomps_noxform, " packet%s dropped; no transform\n"); - p32(ipcomps_wrap, " replay counter wrap%s\n"); - p32(ipcomps_input, " packet%s in\n"); - p32(ipcomps_output, " packet%s out\n"); - p32(ipcomps_invalid, " packet%s dropped; invalid TDB\n"); - p64(ipcomps_ibytes, " byte%s in\n"); - p64(ipcomps_obytes, " byte%s out\n"); - p32(ipcomps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); - p32(ipcomps_pdrops, " packet%s blocked due to policy\n"); - p32(ipcomps_crypto, " crypto processing failure%s\n"); - hist(ipcompstat->ipcomps_hist, ipsec_compnames, "COMP output"); - if (version >= 1) { - p32(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n"); - p32(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 p32 -#undef p64 +#undef p #undef hist + xo_close_container("ipcomp-statictics"); } void @@ -461,10 +455,11 @@ ipcomp_stats(u_long off, const char *name, int family __unused, { struct ipcompstat ipcompstat; - if (off == 0) + if (fetch_stats("net.inet.ipcomp.stats", off, &ipcompstat, + sizeof(ipcompstat), kread_counters) != 0) return; - printf ("%s:\n", name); - kread(off, (char *)&ipcompstat, sizeof(ipcompstat)); + + xo_emit("{T:/%s}:\n", name); print_ipcompstats(&ipcompstat); } diff --git a/freebsd/usr.bin/netstat/main.c b/freebsd/usr.bin/netstat/main.c index a1d66376..a58ee648 100644 --- a/freebsd/usr.bin/netstat/main.c +++ b/freebsd/usr.bin/netstat/main.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 1983, 1988, 1993 * Regents of the University of California. All rights reserved. @@ -30,7 +34,7 @@ */ #ifndef lint -char const copyright[] = +static char const copyright[] = "@(#) Copyright (c) 1983, 1988, 1993\n\ Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ @@ -44,15 +48,6 @@ static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94"; #ifdef __rtems__ #define __need_getopt_newlib #include <getopt.h> -#define RTEMS_BSD_PROGRAM_NO_OPEN_WRAP -#define RTEMS_BSD_PROGRAM_NO_SOCKET_WRAP -#define RTEMS_BSD_PROGRAM_NO_CLOSE_WRAP -#define RTEMS_BSD_PROGRAM_NO_FOPEN_WRAP -#define RTEMS_BSD_PROGRAM_NO_FCLOSE_WRAP -#define RTEMS_BSD_PROGRAM_NO_MALLOC_WRAP -#define RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP -#define RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP -#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP #include <machine/rtems-bsd-program.h> #include <machine/rtems-bsd-commands.h> #endif /* __rtems__ */ @@ -64,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sysctl.h> #include <netinet/in.h> @@ -82,129 +78,21 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> #include <unistd.h> #include "netstat.h" +#include "nl_defs.h" +#include <libxo/xo.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-main-data.h" +#endif /* __rtems__ */ -static struct nlist nl[] = { -#define N_IFNET 0 - { .n_name = "_ifnet" }, -#define N_RTSTAT 1 - { .n_name = "_rtstat" }, -#define N_RTREE 2 - { .n_name = "_rt_tables"}, -#define N_MRTSTAT 3 - { .n_name = "_mrtstat" }, -#define N_MFCHASHTBL 4 - { .n_name = "_mfchashtbl" }, -#define N_VIFTABLE 5 - { .n_name = "_viftable" }, -#define N_IPX 6 - { .n_name = "_ipxpcb_list"}, -#define N_IPXSTAT 7 - { .n_name = "_ipxstat"}, -#define N_SPXSTAT 8 - { .n_name = "_spx_istat"}, -#define N_DDPSTAT 9 - { .n_name = "_ddpstat"}, -#define N_DDPCB 10 - { .n_name = "_ddpcb"}, -#define N_NGSOCKS 11 - { .n_name = "_ngsocklist"}, -#define N_IP6STAT 12 - { .n_name = "_ip6stat" }, -#define N_ICMP6STAT 13 - { .n_name = "_icmp6stat" }, -#define N_IPSECSTAT 14 - { .n_name = "_ipsec4stat" }, -#define N_IPSEC6STAT 15 - { .n_name = "_ipsec6stat" }, -#define N_PIM6STAT 16 - { .n_name = "_pim6stat" }, -#define N_MRT6STAT 17 - { .n_name = "_mrt6stat" }, -#define N_MF6CTABLE 18 - { .n_name = "_mf6ctable" }, -#define N_MIF6TABLE 19 - { .n_name = "_mif6table" }, -#define N_PFKEYSTAT 20 - { .n_name = "_pfkeystat" }, -#define N_MBSTAT 21 - { .n_name = "_mbstat" }, -#define N_MBTYPES 22 - { .n_name = "_mbtypes" }, -#define N_NMBCLUSTERS 23 - { .n_name = "_nmbclusters" }, -#define N_NMBUFS 24 - { .n_name = "_nmbufs" }, -#define N_MBHI 25 - { .n_name = "_mbuf_hiwm" }, -#define N_CLHI 26 - { .n_name = "_clust_hiwm" }, -#define N_NCPUS 27 - { .n_name = "_smp_cpus" }, -#define N_PAGESZ 28 - { .n_name = "_pagesize" }, -#define N_MBPSTAT 29 - { .n_name = "_mb_statpcpu" }, -#define N_RTTRASH 30 - { .n_name = "_rttrash" }, -#define N_MBLO 31 - { .n_name = "_mbuf_lowm" }, -#define N_CLLO 32 - { .n_name = "_clust_lowm" }, -#define N_CARPSTAT 33 - { .n_name = "_carpstats" }, -#define N_PFSYNCSTAT 34 - { .n_name = "_pfsyncstats" }, -#define N_AHSTAT 35 - { .n_name = "_ahstat" }, -#define N_ESPSTAT 36 - { .n_name = "_espstat" }, -#define N_IPCOMPSTAT 37 - { .n_name = "_ipcompstat" }, -#define N_TCPSTAT 38 - { .n_name = "_tcpstat" }, -#define N_UDPSTAT 39 - { .n_name = "_udpstat" }, -#define N_IPSTAT 40 - { .n_name = "_ipstat" }, -#define N_ICMPSTAT 41 - { .n_name = "_icmpstat" }, -#define N_IGMPSTAT 42 - { .n_name = "_igmpstat" }, -#define N_PIMSTAT 43 - { .n_name = "_pimstat" }, -#define N_TCBINFO 44 - { .n_name = "_tcbinfo" }, -#define N_UDBINFO 45 - { .n_name = "_udbinfo" }, -#define N_DIVCBINFO 46 - { .n_name = "_divcbinfo" }, -#define N_RIPCBINFO 47 - { .n_name = "_ripcbinfo" }, -#define N_UNP_COUNT 48 - { .n_name = "_unp_count" }, -#define N_UNP_GENCNT 49 - { .n_name = "_unp_gencnt" }, -#define N_UNP_DHEAD 50 - { .n_name = "_unp_dhead" }, -#define N_UNP_SHEAD 51 - { .n_name = "_unp_shead" }, -#define N_RIP6STAT 52 - { .n_name = "_rip6stat" }, -#define N_SCTPSTAT 53 - { .n_name = "_sctpstat" }, -#define N_MFCTABLESIZE 54 - { .n_name = "_mfctablesize" }, -#define N_ARPSTAT 55 - { .n_name = "_arpstat" }, -#define N_UNP_SPHEAD 56 - { .n_name = "unp_sphead" }, - { .n_name = NULL }, -}; - -struct protox { +#ifndef __rtems__ +static struct protox { +#else /* __rtems__ */ +static const struct protox { +#endif /* __rtems__ */ int pr_index; /* index into nlist of cb head */ int pr_sindex; /* index into nlist of stat block */ u_char pr_wanted; /* 1 if wanted, 0 otherwise */ @@ -216,7 +104,7 @@ struct protox { const char *pr_name; /* well-known name */ int pr_usesysctl; /* non-zero if we use sysctl, not kvm */ int pr_protocol; -} static const protox[] = { +} protox[] = { { N_TCBINFO, N_TCPSTAT, 1, protopr, tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, { N_UDBINFO, N_UDPSTAT, 1, protopr, @@ -238,21 +126,23 @@ struct protox { { N_RIPCBINFO, N_IGMPSTAT, 1, protopr, igmp_stats, NULL, "igmp", 1, IPPROTO_IGMP }, #ifdef IPSEC - { -1, N_IPSECSTAT, 1, NULL, /* keep as compat */ - ipsec_stats, NULL, "ipsec", 0, 0}, + { -1, N_IPSEC4STAT, 1, NULL, /* keep as compat */ + ipsec_stats, NULL, "ipsec", 1, 0}, { -1, N_AHSTAT, 1, NULL, - ah_stats, NULL, "ah", 0, 0}, + ah_stats, NULL, "ah", 1, 0}, { -1, N_ESPSTAT, 1, NULL, - esp_stats, NULL, "esp", 0, 0}, + esp_stats, NULL, "esp", 1, 0}, { -1, N_IPCOMPSTAT, 1, NULL, - ipcomp_stats, NULL, "ipcomp", 0, 0}, + ipcomp_stats, NULL, "ipcomp", 1, 0}, #endif { N_RIPCBINFO, N_PIMSTAT, 1, protopr, pim_stats, NULL, "pim", 1, IPPROTO_PIM }, - { -1, N_CARPSTAT, 1, NULL, + { -1, N_CARPSTATS, 1, NULL, carp_stats, NULL, "carp", 1, 0 }, - { -1, N_PFSYNCSTAT, 1, NULL, +#ifdef PF + { -1, N_PFSYNCSTATS, 1, NULL, pfsync_stats, NULL, "pfsync", 1, 0 }, +#endif { -1, N_ARPSTAT, 1, NULL, arp_stats, NULL, "arp", 1, 0 }, { -1, -1, 0, NULL, @@ -260,7 +150,11 @@ struct protox { }; #ifdef INET6 +#ifndef __rtems__ +static struct protox ip6protox[] = { +#else /* __rtems__ */ static const struct protox ip6protox[] = { +#endif /* __rtems__ */ { N_TCBINFO, N_TCPSTAT, 1, protopr, tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, { N_UDBINFO, N_UDPSTAT, 1, protopr, @@ -275,7 +169,7 @@ static const struct protox ip6protox[] = { #endif #ifdef IPSEC { -1, N_IPSEC6STAT, 1, NULL, - ipsec_stats, NULL, "ipsec6", 0, 0 }, + ipsec_stats, NULL, "ipsec6", 1, 0 }, #endif #ifdef notyet { -1, N_PIM6STAT, 1, NULL, @@ -289,7 +183,11 @@ static const struct protox ip6protox[] = { #endif /*INET6*/ #ifdef IPSEC +#ifndef __rtems__ +static struct protox pfkeyprotox[] = { +#else /* __rtems__ */ static const struct protox pfkeyprotox[] = { +#endif /* __rtems__ */ { -1, N_PFKEYSTAT, 1, NULL, pfkey_stats, NULL, "pfkey", 0, 0 }, { -1, -1, 0, NULL, @@ -297,36 +195,26 @@ static const struct protox pfkeyprotox[] = { }; #endif -#ifndef __rtems__ -static const struct protox atalkprotox[] = { - { N_DDPCB, N_DDPSTAT, 1, atalkprotopr, - ddp_stats, NULL, "ddp", 0, 0 }, - { -1, -1, 0, NULL, - NULL, NULL, NULL, 0, 0 } -}; -#endif #ifdef NETGRAPH +#ifndef __rtems__ +static struct protox netgraphprotox[] = { +#else /* __rtems__ */ static const struct protox netgraphprotox[] = { - { N_NGSOCKS, -1, 1, netgraphprotopr, +#endif /* __rtems__ */ + { N_NGSOCKLIST, -1, 1, netgraphprotopr, NULL, NULL, "ctrl", 0, 0 }, - { N_NGSOCKS, -1, 1, netgraphprotopr, + { N_NGSOCKLIST, -1, 1, netgraphprotopr, NULL, NULL, "data", 0, 0 }, { -1, -1, 0, NULL, NULL, NULL, NULL, 0, 0 } }; #endif -#ifdef IPX -static const struct protox ipxprotox[] = { - { N_IPX, N_IPXSTAT, 1, ipxprotopr, - ipx_stats, NULL, "ipx", 0, 0 }, - { N_IPX, N_SPXSTAT, 1, ipxprotopr, - spx_stats, NULL, "spx", 0, 0 }, - { -1, -1, 0, NULL, - NULL, NULL, 0, 0, 0 } -}; -#endif -static const struct protox *protoprotox[] = { +#ifndef __rtems__ +static struct protox *protoprotox[] = { +#else /* __rtems__ */ +static const struct protox *const protoprotox[] = { +#endif /* __rtems__ */ protox, #ifdef INET6 ip6protox, @@ -334,26 +222,30 @@ static const struct protox *protoprotox[] = { #ifdef IPSEC pfkeyprotox, #endif -#ifdef IPX - ipxprotox, -#endif -#ifndef __rtems__ - atalkprotox, NULL }; -#else - NULL }; -#endif + NULL }; -static void printproto(const struct protox *, const char *); +#ifndef __rtems__ +static void printproto(struct protox *, const char *, bool *); +#else /* __rtems__ */ +static void printproto(const struct protox *, const char *, bool *); +#endif /* __rtems__ */ static void usage(void); +#ifndef __rtems__ +static struct protox *name2protox(const char *); +static struct protox *knownname(const char *); +#else /* __rtems__ */ static const struct protox *name2protox(const char *); static const struct protox *knownname(const char *); +#endif /* __rtems__ */ + +static int kresolve_list(struct nlist *_nl); static kvm_t *kvmd; static char *nlistf = NULL, *memf = NULL; int Aflag; /* show addresses of protocol control block */ int aflag; /* show all sockets (including servers) */ -int Bflag; /* show information about bpf consumers */ +static int Bflag; /* show information about bpf consumers */ int bflag; /* show i/f total bytes in/out */ int dflag; /* show i/f dropped packets */ int gflag; /* show group (multicast) routing or stats */ @@ -366,9 +258,10 @@ int numeric_addr; /* show addresses numerically */ int numeric_port; /* show ports numerically */ static int pflag; /* show given protocol */ #ifndef __rtems__ -int Qflag; /* show netisr information */ +static int Qflag; /* show netisr information */ #endif /* __rtems__ */ int rflag; /* show routing tables (or routing stats) */ +int Rflag; /* show flow / RSS statistics */ int sflag; /* show protocol statistics */ int Wflag; /* wide display */ int Tflag; /* TCP Information */ @@ -380,60 +273,27 @@ int interval; /* repeat interval for i/f stats */ char *interface; /* desired i/f for stats, or NULL for all i/fs */ int unit; /* unit number for above */ -int af; /* address family */ +static int af; /* address family */ int live; /* true if we are examining a live system */ #ifdef __rtems__ -int protopr_initialized; -int do_rtent; -struct radix_node_head **rt_tables; - static int main(int argc, char *argv[]); -int rtems_bsd_command_netstat(int argc, char *argv[]) +RTEMS_LINKER_RWSET(bsd_prog_netstat, char); + +int +rtems_bsd_command_netstat(int argc, char *argv[]) { int exit_code; + void *data_begin; + size_t data_size; - rtems_bsd_program_lock(); - - nlistf = NULL; - memf = NULL; - - Aflag = 0; - aflag = 0; - Bflag = 0; - bflag = 0; - dflag = 0; - gflag = 0; - hflag = 0; - iflag = 0; - Lflag = 0; - mflag = 0; - noutputs = 0; - numeric_addr = 0; - numeric_port = 0; - pflag = 0; - rflag = 0; - sflag = 0; - Wflag = 0; - xflag = 0; - zflag = 0; - interval = 0; - interface = 0; - unit = 0; - af = 0; - live = 0; - - protopr_initialized = 0; - do_rtent = 0; - - rtems_bsd_netstat_inet_init(); - - exit_code = rtems_bsd_program_call_main("netstat", main, argc, argv); - - free(rt_tables); - rt_tables = NULL; + data_begin = RTEMS_LINKER_SET_BEGIN(bsd_prog_netstat); + data_size = RTEMS_LINKER_SET_SIZE(bsd_prog_netstat); + rtems_bsd_program_lock(); + exit_code = rtems_bsd_program_call_main_with_data_restore("netstat", + main, argc, argv, data_begin, data_size); rtems_bsd_program_unlock(); return exit_code; @@ -442,8 +302,15 @@ int rtems_bsd_command_netstat(int argc, char *argv[]) int main(int argc, char *argv[]) { +#ifndef __rtems__ + struct protox *tp = NULL; /* for printing cblocks & stats */ +#else /* __rtems__ */ const struct protox *tp = NULL; /* for printing cblocks & stats */ +#endif /* __rtems__ */ int ch; + int fib = -1; + char *endptr; + bool first = true; #ifdef __rtems__ struct getopt_data getopt_data; memset(&getopt_data, 0, sizeof(getopt_data)); @@ -456,7 +323,11 @@ main(int argc, char *argv[]) af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "46AaBbdf:ghI:iLlM:mN:np:Qq:rSTsuWw:xz")) + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(EXIT_FAILURE); + + while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz")) != -1) switch(ch) { case '4': @@ -488,10 +359,14 @@ main(int argc, char *argv[]) case 'd': dflag = 1; break; + case 'F': + fib = strtol(optarg, &endptr, 0); + if (*endptr != '\0' || + (fib == 0 && (errno == EINVAL || errno == ERANGE))) + xo_errx(1, "%s: invalid fib", optarg); + break; case 'f': - if (strcmp(optarg, "ipx") == 0) - af = AF_IPX; - else if (strcmp(optarg, "inet") == 0) + if (strcmp(optarg, "inet") == 0) af = AF_INET; #ifdef INET6 else if (strcmp(optarg, "inet6") == 0) @@ -501,10 +376,9 @@ main(int argc, char *argv[]) else if (strcmp(optarg, "pfkey") == 0) af = PF_KEY; #endif - else if (strcmp(optarg, "unix") == 0) + else if (strcmp(optarg, "unix") == 0 || + strcmp(optarg, "local") == 0) af = AF_UNIX; - else if (strcmp(optarg, "atalk") == 0) - af = AF_APPLETALK; #ifdef NETGRAPH else if (strcmp(optarg, "ng") == 0 || strcmp(optarg, "netgraph") == 0) @@ -513,7 +387,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': @@ -526,7 +401,12 @@ main(int argc, char *argv[]) char *cp; iflag = 1; - for (cp = interface = optarg; isalpha((unsigned char) *cp); cp++) +#ifndef __rtems__ + for (cp = interface = optarg; isalpha(*cp); cp++) +#else /* __rtems__ */ + for (cp = interface = optarg; isalpha( + (unsigned char) *cp); cp++) +#endif /* __rtems__ */ continue; unit = atoi(cp); break; @@ -551,9 +431,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; @@ -570,6 +449,9 @@ main(int argc, char *argv[]) case 'r': rflag = 1; break; + case 'R': + Rflag = 1; + break; case 's': ++sflag; break; @@ -606,7 +488,11 @@ main(int argc, char *argv[]) #define BACKWARD_COMPATIBILITY #ifdef BACKWARD_COMPATIBILITY if (*argv) { +#ifndef __rtems__ + if (isdigit(**argv)) { +#else /* __rtems__ */ if (isdigit((unsigned char) **argv)) { +#endif /* __rtems__ */ interval = atoi(*argv); if (interval <= 0) usage(); @@ -626,33 +512,38 @@ main(int argc, char *argv[]) * guys can't print interesting stuff from kernel memory. */ live = (nlistf == NULL && memf == NULL); - if (!live) - setgid(getgid()); + if (!live) { + if (setgid(getgid()) != 0) + xo_err(-1, "setgid"); + } - 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) { if (!live) { if (kread(0, NULL, 0) == 0) - mbpr(kvmd, nl[N_MBSTAT].n_value); + mbpr(kvmd, nl[N_SFSTAT].n_value); } else mbpr(NULL, 0); + xo_finish(); exit(0); } #ifndef __rtems__ if (Qflag) { if (!live) { if (kread(0, NULL, 0) == 0) - netisr_stats(kvmd); + netisr_stats(); } else - netisr_stats(NULL); + netisr_stats(); + xo_finish(); exit(0); } #endif /* __rtems__ */ @@ -670,109 +561,162 @@ main(int argc, char *argv[]) * used for the queries, which is slower. */ #endif - kread(0, NULL, 0); if (iflag && !sflag) { - intpr(interval, nl[N_IFNET].n_value, NULL); + xo_open_container("statistics"); + intpr(NULL, af); + xo_close_container("statistics"); + xo_finish(); exit(0); } if (rflag) { - if (sflag) - rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value); - else - routepr(nl[N_RTREE].n_value); + 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(nl[N_MRTSTAT].n_value); + mrt_stats(); #ifdef INET6 if (af == AF_INET6 || af == AF_UNSPEC) - mrt6_stats(nl[N_MRT6STAT].n_value); + mrt6_stats(); #endif } else { if (af == AF_INET || af == AF_UNSPEC) - mroutepr(nl[N_MFCHASHTBL].n_value, - nl[N_MFCTABLESIZE].n_value, - nl[N_VIFTABLE].n_value); + mroutepr(); #ifdef INET6 if (af == AF_INET6 || af == AF_UNSPEC) - mroute6pr(nl[N_MF6CTABLE].n_value, - nl[N_MIF6TABLE].n_value); + mroute6pr(); #endif } + xo_close_container("statistics"); + xo_finish(); exit(0); } + /* Load all necessary kvm symbols */ + 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 IPX - if (af == AF_IPX || af == AF_UNSPEC) { - for (tp = ipxprotox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); - } -#endif /* IPX */ -#ifndef __rtems__ - if (af == AF_APPLETALK || af == AF_UNSPEC) - for (tp = atalkprotox; tp->pr_name; tp++) - printproto(tp, tp->pr_name); -#endif #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 */ #ifndef __rtems__ 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); -#endif + nl[N_UNP_SPHEAD].n_value, &first); +#endif /* __rtems__ */ + + if (!first) + xo_close_list("socket"); + xo_close_container("statistics"); + xo_finish(); exit(0); } +static int +fetch_stats_internal(const char *sysctlname, u_long off, void *stats, + size_t len, kreadfn_t kreadfn, int zero) +{ + int error; + + if (live) { + memset(stats, 0, len); + if (zero) + error = sysctlbyname(sysctlname, NULL, NULL, stats, + len); + else + error = sysctlbyname(sysctlname, stats, &len, NULL, 0); + if (error == -1 && errno != ENOENT) + xo_warn("sysctl %s", sysctlname); + } else { + if (off == 0) + return (1); + error = kreadfn(off, stats, len); + } + return (error); +} + +int +fetch_stats(const char *sysctlname, u_long off, void *stats, + size_t len, kreadfn_t kreadfn) +{ + + return (fetch_stats_internal(sysctlname, off, stats, len, kreadfn, + zflag)); +} + +int +fetch_stats_ro(const char *sysctlname, u_long off, void *stats, + size_t len, kreadfn_t kreadfn) +{ + + return (fetch_stats_internal(sysctlname, off, stats, len, kreadfn, 0)); +} + /* * Print out protocol statistics or control blocks (per sflag). * If the interface was not specifically requested, and the symbol * is not in the namelist, ignore this one. */ static void -printproto(tp, name) - const struct protox *tp; - const char *name; +#ifndef __rtems__ +printproto(struct protox *tp, const char *name, bool *first) +#else /* __rtems__ */ +printproto(const struct protox *tp, const char *name, bool *first) +#endif /* __rtems__ */ { void (*pr)(u_long, const char *, int, int); u_long off; + bool doingdblocks = false; if (sflag) { if (iflag) { if (tp->pr_istats) - intpr(interval, nl[N_IFNET].n_value, - tp->pr_istats); + intpr(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; } @@ -780,34 +724,99 @@ printproto(tp, 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 +kvmd_init(void) +{ + char errbuf[_POSIX2_LINE_MAX]; + + if (kvmd != NULL) + return (0); + + kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); + if (setgid(getgid()) != 0) + xo_err(-1, "setgid"); + + if (kvmd == NULL) { + xo_warnx("kvm not available: %s", errbuf); + return (-1); + } + + return (0); +} + +/* + * Resolve symbol list, return 0 on success. + */ +static int +kresolve_list(struct nlist *_nl) +{ + + if ((kvmd == NULL) && (kvmd_init() != 0)) + return (-1); + + if (_nl[0].n_type != 0) + return (0); + + if (kvm_nlist(kvmd, _nl) < 0) { + if (nlistf) + xo_errx(1, "%s: kvm_nlist: %s", nlistf, + kvm_geterr(kvmd)); + else + xo_errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); + } + + return (0); +} + +/* + * Wrapper of kvm_dpcpu_setcpu(). + */ +void +kset_dpcpu(u_int cpuid) +{ + + if ((kvmd == NULL) && (kvmd_init() != 0)) + xo_errx(-1, "%s: kvm is not available", __func__); + + if (kvm_dpcpu_setcpu(kvmd, cpuid) < 0) + xo_errx(-1, "%s: kvm_dpcpu_setcpu(%u): %s", __func__, + cpuid, kvm_geterr(kvmd)); + return; } /* @@ -816,40 +825,70 @@ printproto(tp, name) int kread(u_long addr, void *buf, size_t size) { - char errbuf[_POSIX2_LINE_MAX]; - if (kvmd == NULL) { - kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); - setgid(getgid()); - if (kvmd != NULL) { - if (kvm_nlist(kvmd, nl) < 0) { - if (nlistf) - errx(1, "%s: kvm_nlist: %s", nlistf, - kvm_geterr(kvmd)); - else - errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); - } + if (kvmd_init() < 0) + return (-1); - if (nl[0].n_type == 0) { - if (nlistf) - errx(1, "%s: no namelist", nlistf); - else - errx(1, "no namelist"); - } - } else { - warnx("kvm not available: %s", errbuf); - return(-1); - } - } 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); } +/* + * Read single counter(9). + */ +uint64_t +kread_counter(u_long addr) +{ + + if (kvmd_init() < 0) + return (-1); + + return (kvm_counter_u64_fetch(kvmd, addr)); +} + +/* + * Read an array of N counters in kernel memory into array of N uint64_t's. + */ +int +kread_counters(u_long addr, void *buf, size_t size) +{ +#ifndef __rtems__ + uint64_t *c; + u_long *counters; + size_t i, n; + + if (kvmd_init() < 0) + return (-1); + + if (size % sizeof(uint64_t) != 0) { + xo_warnx("kread_counters: invalid counter set size"); + return (-1); + } + + n = size / sizeof(uint64_t); + if ((counters = malloc(n * sizeof(u_long))) == NULL) + xo_err(-1, "malloc"); + if (kread(addr, counters, n * sizeof(u_long)) < 0) { + free(counters); + return (-1); + } + + c = buf; + for (i = 0; i < n; i++) + c[i] = kvm_counter_u64_fetch(kvmd, counters[i]); + + free(counters); + return (0); +#else /* __rtems__ */ + return (-1); +#endif /* __rtems__ */ +} + const char * plural(uintmax_t n) { @@ -871,10 +910,18 @@ pluralies(uintmax_t n) /* * Find the protox for the given "well-known" name. */ +#ifndef __rtems__ +static struct protox * +#else /* __rtems__ */ static const struct protox * +#endif /* __rtems__ */ knownname(const char *name) { - const struct protox **tpp, *tp; +#ifndef __rtems__ + struct protox **tpp, *tp; +#else /* __rtems__ */ + const struct protox *const *tpp, *tp; +#endif /* __rtems__ */ for (tpp = protoprotox; *tpp; tpp++) for (tp = *tpp; tp->pr_name; tp++) @@ -886,10 +933,18 @@ knownname(const char *name) /* * Find the protox corresponding to name. */ +#ifndef __rtems__ +static struct protox * +#else /* __rtems__ */ static const struct protox * +#endif /* __rtems__ */ name2protox(const char *name) { +#ifndef __rtems__ + struct protox *tp; +#else /* __rtems__ */ const struct protox *tp; +#endif /* __rtems__ */ char **alias; /* alias from p->aliases */ struct protoent *p; @@ -916,22 +971,25 @@ 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", -"usage: netstat [-46AaLnSTWx] [-f protocol_family | -p protocol]\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" " [-M core] [-N system]", -" netstat -w wait [-I interface] [-46d] [-M core] [-N system] [-q howmany]", -" netstat -s [-s] [-46z] [-f protocol_family | -p protocol]\n" -" [-M core] [-N system]", -" netstat -i | -I interface [-46s] [-f protocol_family | -p protocol]\n" +" netstat -w wait [-I interface] [-46d] [-M core] [-N system]\n" +" [-q howmany]", +" netstat -s [-46sz] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", +" netstat -i | -I interface -s [-46s]\n" +" [-f protocol_family | -p protocol] [-M core] [-N system]", " netstat -m [-M core] [-N system]", -" netstat -B [-I interface]", -" netstat -r [-46AanW] [-f address_family] [-M core] [-N system]", +" netstat -B [-z] [-I interface]", +" netstat -r [-46AnW] [-F fibnum] [-f address_family]\n" +" [-M core] [-N system]", " netstat -rs [-s] [-M core] [-N system]", " 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/freebsd/usr.bin/netstat/mbuf.c b/freebsd/usr.bin/netstat/mbuf.c index a005d167..81f57292 100644 --- a/freebsd/usr.bin/netstat/mbuf.c +++ b/freebsd/usr.bin/netstat/mbuf.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. @@ -41,12 +45,16 @@ static char sccsid[] = "@(#)mbuf.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <rtems/bsd/sys/param.h> #include <sys/mbuf.h> #include <sys/protosw.h> +#include <sys/sf_buf.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sysctl.h> @@ -57,8 +65,13 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <string.h> +#include <libxo/xo.h> #include "netstat.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-mbuf-data.h" +#endif /* __rtems__ */ /* * Print mbuf statistics. @@ -70,26 +83,26 @@ mbpr(void *kvmd, u_long mbaddr) struct memory_type *mtp; uintmax_t mbuf_count, mbuf_bytes, mbuf_free, mbuf_failures, mbuf_size; uintmax_t mbuf_sleeps; - uintmax_t cluster_count, cluster_bytes, cluster_limit, cluster_free; + uintmax_t cluster_count, cluster_limit, cluster_free; uintmax_t cluster_failures, cluster_size, cluster_sleeps; uintmax_t packet_count, packet_bytes, packet_free, packet_failures; uintmax_t packet_sleeps; - uintmax_t tag_count, tag_bytes; - uintmax_t jumbop_count, jumbop_bytes, jumbop_limit, jumbop_free; + uintmax_t tag_bytes; + uintmax_t jumbop_count, jumbop_limit, jumbop_free; uintmax_t jumbop_failures, jumbop_sleeps, jumbop_size; - uintmax_t jumbo9_count, jumbo9_bytes, jumbo9_limit, jumbo9_free; + uintmax_t jumbo9_count, jumbo9_limit, jumbo9_free; uintmax_t jumbo9_failures, jumbo9_sleeps, jumbo9_size; - uintmax_t jumbo16_count, jumbo16_bytes, jumbo16_limit, jumbo16_free; + uintmax_t jumbo16_count, jumbo16_limit, jumbo16_free; uintmax_t jumbo16_failures, jumbo16_sleeps, jumbo16_size; uintmax_t bytes_inuse, bytes_incache, bytes_total; int nsfbufs, nsfbufspeak, nsfbufsused; - struct mbstat mbstat; + struct sfstat sfstat; size_t mlen; int error; mtlp = memstat_mtl_alloc(); if (mtlp == NULL) { - warn("memstat_mtl_alloc"); + xo_warn("memstat_mtl_alloc"); return; } @@ -99,7 +112,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; } @@ -108,10 +121,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; } @@ -123,7 +136,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); @@ -135,7 +148,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; } @@ -147,12 +160,11 @@ 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; } cluster_count = memstat_get_count(mtp); - cluster_bytes = memstat_get_bytes(mtp); cluster_limit = memstat_get_countlimit(mtp); cluster_free = memstat_get_free(mtp); cluster_failures = memstat_get_failures(mtp); @@ -162,25 +174,22 @@ mbpr(void *kvmd, u_long mbaddr) #ifndef __rtems__ 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; } - tag_count = memstat_get_count(mtp); tag_bytes = memstat_get_bytes(mtp); #else /* __rtems__ */ - tag_count = 0; tag_bytes = 0; #endif /* __rtems__ */ 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; } jumbop_count = memstat_get_count(mtp); - jumbop_bytes = memstat_get_bytes(mtp); jumbop_limit = memstat_get_countlimit(mtp); jumbop_free = memstat_get_free(mtp); jumbop_failures = memstat_get_failures(mtp); @@ -189,12 +198,11 @@ 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; } jumbo9_count = memstat_get_count(mtp); - jumbo9_bytes = memstat_get_bytes(mtp); jumbo9_limit = memstat_get_countlimit(mtp); jumbo9_free = memstat_get_free(mtp); jumbo9_failures = memstat_get_failures(mtp); @@ -203,48 +211,55 @@ 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; } jumbo16_count = memstat_get_count(mtp); - jumbo16_bytes = memstat_get_bytes(mtp); jumbo16_limit = memstat_get_countlimit(mtp); jumbo16_free = memstat_get_free(mtp); jumbo16_failures = memstat_get_failures(mtp); 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 /*- @@ -292,48 +307,74 @@ 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); - if (!sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL, - 0) && - !sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused, - &mlen, NULL, 0) && - !sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, - &mlen, NULL, 0)) - printf("%d/%d/%d sfbufs in use (current/peak/max)\n", - nsfbufsused, nsfbufspeak, nsfbufs); - mlen = sizeof(mbstat); - if (sysctlbyname("kern.ipc.mbstat", &mbstat, &mlen, NULL, 0)) { - warn("kern.ipc.mbstat"); - goto out; - } - } else { - if (kread(mbaddr, (char *)&mbstat, sizeof mbstat) != 0) - goto out; - } - printf("%lu requests for sfbufs denied\n", mbstat.sf_allocfail); - printf("%lu requests for sfbufs delayed\n", mbstat.sf_allocwait); - printf("%lu requests for I/O initiated by sendfile\n", - mbstat.sf_iocnt); - printf("%lu calls to protocol drain routines\n", mbstat.m_drain); + mlen = sizeof(nsfbufs); + if (live && + sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL, 0) == 0 && + sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused, &mlen, + NULL, 0) == 0 && + sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, &mlen, + NULL, 0) == 0) + xo_emit("{:nsfbufs-current/%d}/{:nsfbufs-peak/%d}/" + "{:nsfbufs/%d} " + "{N:sfbufs in use (current\\/peak\\/max)}\n", + nsfbufsused, nsfbufspeak, nsfbufs); + + if (fetch_stats("kern.ipc.sfstat", mbaddr, &sfstat, sizeof(sfstat), + kread_counters) != 0) + goto out; + + xo_emit("{:sendfile-syscalls/%ju} {N:sendfile syscalls}\n", + (uintmax_t)sfstat.sf_syscalls); + xo_emit("{:sendfile-no-io/%ju} " + "{N:sendfile syscalls completed without I\\/O request}\n", + (uintmax_t)sfstat.sf_noiocnt); + xo_emit("{:sendfile-io-count/%ju} " + "{N:requests for I\\/O initiated by sendfile}\n", + (uintmax_t)sfstat.sf_iocnt); + xo_emit("{:sendfile-pages-sent/%ju} " + "{N:pages read by sendfile as part of a request}\n", + (uintmax_t)sfstat.sf_pages_read); + xo_emit("{:sendfile-pages-valid/%ju} " + "{N:pages were valid at time of a sendfile request}\n", + (uintmax_t)sfstat.sf_pages_valid); + xo_emit("{:sendfile-requested-readahead/%ju} " + "{N:pages were requested for read ahead by applications}\n", + (uintmax_t)sfstat.sf_rhpages_requested); + xo_emit("{:sendfile-readahead/%ju} " + "{N:pages were read ahead by sendfile}\n", + (uintmax_t)sfstat.sf_rhpages_read); + xo_emit("{:sendfile-busy-encounters/%ju} " + "{N:times sendfile encountered an already busy page}\n", + (uintmax_t)sfstat.sf_busy); + xo_emit("{:sfbufs-alloc-failed/%ju} {N:requests for sfbufs denied}\n", + (uintmax_t)sfstat.sf_allocfail); + xo_emit("{:sfbufs-alloc-wait/%ju} {N:requests for sfbufs delayed}\n", + (uintmax_t)sfstat.sf_allocwait); out: + xo_close_container("mbuf-statistics"); memstat_mtl_free(mtlp); } diff --git a/freebsd/usr.bin/netstat/mroute.c b/freebsd/usr.bin/netstat/mroute.c index 7a860cd3..4d9d5b1d 100644 --- a/freebsd/usr.bin/netstat/mroute.c +++ b/freebsd/usr.bin/netstat/mroute.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 1989 Stephen Deering * Copyright (c) 1992, 1993 @@ -39,6 +43,9 @@ * @(#)mroute.c 8.2 (Berkeley) 4/28/95 */ +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -70,8 +77,14 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <libxo/xo.h> #include "netstat.h" - +#include "nl_defs.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-mroute-data.h" +#endif /* __rtems__ */ static void print_bw_meter(struct bw_meter *, int *); static void print_mfc(struct mfc *, int, int *); @@ -79,105 +92,128 @@ 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); + + xo_open_instance("bandwidth-meter"); - printf("\n"); + xo_emit("\n"); } static void print_mfc(struct mfc *m, int maxvif, int *banner_printed) { + struct sockaddr_in sin; + struct sockaddr *sa = (struct sockaddr *)&sin; struct bw_meter bw_meter, *bwm; int bw_banner_printed; int error; vifi_t vifi; bw_banner_printed = 0; + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; 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); + memcpy(&sin.sin_addr, &m->mfc_origin, sizeof(sin.sin_addr)); + xo_emit(" {:origin-address/%-15.15s}", routename(sa, numeric_addr)); + memcpy(&sin.sin_addr, &m->mfc_mcastgrp, sizeof(sin.sin_addr)); + xo_emit(" {:group-address/%-15.15s}", + routename(sa, numeric_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 @@ -192,14 +228,19 @@ 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 -mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) +mroutepr() { + struct sockaddr_in sin; + struct sockaddr *sa = (struct sockaddr *)&sin; struct vif viftable[MAXVIFS]; struct vif *v; struct mfc *m; + u_long pmfchashtbl, pmfctablesize, pviftbl; int banner_printed; int saved_numeric_addr; size_t len; @@ -208,6 +249,10 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) saved_numeric_addr = numeric_addr; numeric_addr = 1; + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + /* * TODO: * The VIF table will move to hanging off the struct if_info for @@ -222,23 +267,27 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) * functionality was deprecated, as PIM does not use it. */ maxvif = 0; + pmfchashtbl = pmfctablesize = pviftbl = 0; len = sizeof(viftable); 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 -#ifndef __rtems__ + } else { + pmfchashtbl = nl[N_MFCHASHTBL].n_value; + pmfctablesize = nl[N_MFCTABLESIZE].n_value; + pviftbl = nl[N_VIFTABLE].n_value; + + if (pmfchashtbl == 0 || pmfctablesize == 0 || pviftbl == 0) { + xo_warnx("No IPv4 MROUTING kernel support."); + return; + } + kread(pviftbl, (char *)viftable, sizeof(viftable)); -#else /* __rtems__ */ - { - warnx("mroutepr: not implemented"); - return; } -#endif /* __rtems__ */ banner_printed = 0; for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) { @@ -247,23 +296,31 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) 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"); + memcpy(&sin.sin_addr, &v->v_lcl_addr, sizeof(sin.sin_addr)); + 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) ? - routename(v->v_rmt_addr.s_addr) : ""); - - printf(" %9lu %9lu\n", v->v_pkt_in, v->v_pkt_out); + routename(sa, numeric_addr)); + memcpy(&sin.sin_addr, &v->v_rmt_addr, sizeof(sin.sin_addr)); + xo_emit(" {:source/%-15.15s}", (v->v_flags & VIFF_TUNNEL) ? + routename(sa, numeric_addr) : ""); + + 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; @@ -283,19 +340,19 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) 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; } @@ -304,8 +361,10 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) 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 { @@ -318,14 +377,14 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) 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); @@ -336,6 +395,8 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) print_mfc(m, maxvif, &banner_printed); } } + if (banner_printed) + xo_close_list("multicast-forwarding-entry"); free(mfchashtbl); #else /* __rtems__ */ @@ -345,55 +406,65 @@ mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl) } 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; } void -mrt_stats(u_long mstaddr) +mrt_stats() { struct mrtstat mrtstat; - size_t len = sizeof mrtstat; + u_long mstaddr; - if (live) { - if (sysctlbyname("net.inet.ip.mrtstat", &mrtstat, &len, NULL, - 0) < 0) { - warn("sysctl: net.inet.ip.mrtstat"); - return; - } - } else -#ifndef __rtems__ - kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat)); -#else /* __rtems__ */ - { - warnx("mrt_stats: not implemented"); + mstaddr = nl[N_MRTSTAT].n_value; + + if (mstaddr == 0) { + fprintf(stderr, "No IPv4 MROUTING kernel support.\n"); return; } -#endif /* __rtems__ */ - printf("IPv4 multicast forwarding:\n"); + if (fetch_stats("net.inet.ip.mrtstat", mstaddr, &mrtstat, + sizeof(mrtstat), kread_counters) != 0) + return; + + xo_emit("{T:IPv4 multicast forwarding}:\n"); #define p(f, m) if (mrtstat.f || sflag <= 1) \ - printf(m, 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, mrtstat.f, plurales(mrtstat.f)) - - p(mrts_mfc_lookups, "\t%lu multicast forwarding cache lookup%s\n"); - p2(mrts_mfc_misses, "\t%lu multicast forwarding cache miss%s\n"); - p(mrts_upcalls, "\t%lu upcall%s to multicast routing daemon\n"); - p(mrts_upq_ovflw, "\t%lu 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%lu upcall%s dropped due to full socket buffer\n"); - p(mrts_cache_cleanups, "\t%lu cache cleanup%s\n"); - p(mrts_no_route, "\t%lu datagram%s with no route for origin\n"); - p(mrts_bad_tunnel, "\t%lu datagram%s arrived with bad tunneling\n"); - p(mrts_cant_tunnel, "\t%lu datagram%s could not be tunneled\n"); - p(mrts_wrong_if, "\t%lu datagram%s arrived on wrong interface\n"); - p(mrts_drop_sel, "\t%lu datagram%s selectively dropped\n"); - p(mrts_q_overflow, "\t%lu datagram%s dropped due to queue overflow\n"); - p(mrts_pkt2large, "\t%lu 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/freebsd/usr.bin/netstat/mroute6.c b/freebsd/usr.bin/netstat/mroute6.c index 3a5b25b0..8a5ca63d 100644 --- a/freebsd/usr.bin/netstat/mroute6.c +++ b/freebsd/usr.bin/netstat/mroute6.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (C) 1998 WIDE Project. * All rights reserved. @@ -67,6 +71,9 @@ * @(#)mroute.c 8.2 (Berkeley) 4/28/95 */ +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -81,7 +88,6 @@ __FBSDID("$FreeBSD$"); #include <sys/time.h> #include <net/if.h> -#include <net/if_var.h> #include <net/route.h> #include <netinet/in.h> @@ -90,24 +96,29 @@ __FBSDID("$FreeBSD$"); #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> +#include <libxo/xo.h> #define KERNEL 1 #include <netinet6/ip6_mroute.h> #undef KERNEL #include "netstat.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-mroute6-data.h" +#endif /* __rtems__ */ #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 */ void -mroute6pr(u_long mfcaddr, u_long mifaddr) +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; + struct mif6_sctl *mifp; mifi_t mifi; int i; int banner_printed; @@ -116,72 +127,56 @@ mroute6pr(u_long mfcaddr, u_long mifaddr) long int waitings; size_t len; + 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 -#ifndef __rtems__ - kread(mifaddr, (char *)mif6table, sizeof(mif6table)); -#else /* __rtems__ */ - { - warnx("mroute6pr: not implemented"); + if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len, NULL, 0) < + 0) { + xo_warn("sysctl: net.inet6.ip6.mif6table"); return; } -#endif /* __rtems__ */ 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 -#ifndef __rtems__ - kread(mfcaddr, (char *)mf6ctable, sizeof(mf6ctable)); -#else /* __rtems__ */ - { - warnx("mroute6pr: not implemented"); + if (sysctlbyname("net.inet6.ip6.mf6ctable", mf6ctable, &len, NULL, 0) < + 0) { + xo_warn("sysctl: net.inet6.ip6.mf6ctable"); return; } -#endif /* __rtems__ */ banner_printed = 0; @@ -190,19 +185,26 @@ mroute6pr(u_long mfcaddr, u_long mifaddr) 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, + routename(sin6tosa(&mfc.mf6c_origin), + numeric_addr)); + xo_emit(" {:group/%-*.*s}", WID_GRP, WID_GRP, + routename(sin6tosa(&mfc.mf6c_mcastgrp), + numeric_addr)); + xo_emit(" {:total-packets/%9ju}", + (uintmax_t)mfc.mf6c_pkt_cnt); for (waitings = 0, rtep = mfc.mf6c_stall; rtep; ) { waitings++; @@ -210,74 +212,79 @@ mroute6pr(u_long mfcaddr, u_long mifaddr) 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; } void -mrt6_stats(u_long mstaddr) +mrt6_stats() { struct mrt6stat mrtstat; - size_t len = sizeof mrtstat; - if (live) { - if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len, - NULL, 0) < 0) { - warn("sysctl: net.inet6.ip6.mrt6stat"); - return; - } - } else -#ifndef __rtems__ - kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat)); -#else /* __rtems__ */ - { - warnx("mrt6_stats: not implemented"); + if (fetch_stats("net.inet6.ip6.mrt6stat", 0, &mrtstat, + sizeof(mrtstat), kread_counters) != 0) return; - } -#endif /* __rtems__ */ - 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/freebsd/usr.bin/netstat/netstat.h b/freebsd/usr.bin/netstat/netstat.h index b25b40c6..042a1c78 100644 --- a/freebsd/usr.bin/netstat/netstat.h +++ b/freebsd/usr.bin/netstat/netstat.h @@ -32,12 +32,10 @@ #include <sys/cdefs.h> -#ifdef __rtems__ -#define rt_tables netstat_rt_tables -#define routename rtems_shell_netstats_routername -#define netname rtems_shell_netstats_netname -#define sotoxsocket rtems_shell_netstats_sotoxsocket -#endif /* __rtems__ */ +#define satosin(sa) ((struct sockaddr_in *)(sa)) +#define satosin6(sa) ((struct sockaddr_in6 *)(sa)) +#define sin6tosa(sin6) ((struct sockaddr *)(sin6)) + extern int Aflag; /* show addresses of protocol control block */ extern int aflag; /* show all sockets (including servers) */ extern int bflag; /* show i/f total bytes in/out */ @@ -51,6 +49,7 @@ extern int noutputs; /* how much outputs before we exit */ extern int numeric_addr; /* show addresses numerically */ extern int numeric_port; /* show ports numerically */ extern int rflag; /* show routing tables (or routing stats) */ +extern int Rflag; /* show flowid / RSS information */ extern int sflag; /* show protocol statistics */ extern int Tflag; /* show TCP control block info */ extern int Wflag; /* wide display */ @@ -62,15 +61,16 @@ extern int interval; /* repeat interval for i/f stats */ extern char *interface; /* desired i/f for stats, or NULL for all i/fs */ extern int unit; /* unit number for above */ -extern int af; /* address family */ extern int live; /* true if we are examining a live system */ -#ifdef __rtems__ -extern int protopr_initialized; -extern int do_rtent; -extern struct radix_node_head **rt_tables; -#endif /* __rtems__ */ + +typedef int kreadfn_t(u_long, void *, size_t); +int fetch_stats(const char *, u_long, void *, size_t, kreadfn_t); +int fetch_stats_ro(const char *, u_long, void *, size_t, kreadfn_t); int kread(u_long addr, void *buf, size_t size); +uint64_t kread_counter(u_long addr); +int kread_counters(u_long addr, void *buf, size_t size); +void kset_dpcpu(u_int); const char *plural(uintmax_t); const char *plurales(uintmax_t); const char *pluralies(uintmax_t); @@ -107,15 +107,13 @@ void icmp6_stats(u_long, const char *, int, int); void icmp6_ifstats(char *); void pim6_stats(u_long, const char *, int, int); void rip6_stats(u_long, const char *, int, int); -void mroute6pr(u_long, u_long); -void mrt6_stats(u_long); +void mroute6pr(void); +void mrt6_stats(void); struct sockaddr_in6; 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 @@ -124,60 +122,30 @@ void pfkey_stats(u_long, const char *, int, int); void mbpr(void *, u_long); -void netisr_stats(void *); +void netisr_stats(void); void hostpr(u_long, u_long); void impstats(u_long, u_long); -void intpr(int, u_long, void (*)(char *)); +void intpr(void (*)(char *), int); -void pr_rthdr(int); void pr_family(int); -void rt_stats(u_long, u_long); -char *ipx_pnet(struct sockaddr *); -char *ipx_phost(struct sockaddr *); -char *ns_phost(struct sockaddr *); -void upHex(char *); - -char *routename(in_addr_t); -char *netname(in_addr_t, u_long); -char *atalk_print(struct sockaddr *, int); -char *atalk_print2(struct sockaddr *, struct sockaddr *, int); -char *ipx_print(struct sockaddr *); -char *ns_print(struct sockaddr *); -void routepr(u_long); - -void ipxprotopr(u_long, const char *, int, int); -void spx_stats(u_long, const char *, int, int); -void ipx_stats(u_long, const char *, int, int); -void ipxerr_stats(u_long, const char *, int, int); - -void nsprotopr(u_long, const char *, int, int); -void spp_stats(u_long, const char *, int, int); -void idp_stats(u_long, const char *, int, int); -void nserr_stats(u_long, const char *, int, int); - -void atalkprotopr(u_long, const char *, int, int); -void ddp_stats(u_long, const char *, int, int); +void rt_stats(void); +void flowtable_stats(void); + +char *routename(struct sockaddr *, int); +const char *netname(struct sockaddr *, struct sockaddr *); +void routepr(int, int); #ifdef NETGRAPH void netgraphprotopr(u_long, const char *, int, int); #endif -void unixpr(u_long, u_long, u_long, u_long, u_long); - -void esis_stats(u_long, const char *, int, int); -void clnp_stats(u_long, const char *, int, int); -void cltp_stats(u_long, const char *, int, int); -void iso_protopr(u_long, const char *, int, int); -void iso_protopr1(u_long, int); -void tp_protopr(u_long, const char *, int, int); -void tp_inproto(u_long); -void tp_stats(caddr_t, caddr_t); +void unixpr(u_long, u_long, u_long, u_long, u_long, bool *); -void mroutepr(u_long, u_long, u_long); -void mrt_stats(u_long); +void mroutepr(void); +void mrt_stats(void); void bpf_stats(char *); #ifdef __rtems__ -void rtems_bsd_netstat_inet_init(void); +#include <nlist.h> /* necessary for global "nl" variable */ #endif /* __rtems__ */ diff --git a/freebsd/usr.bin/netstat/nl_defs.h b/freebsd/usr.bin/netstat/nl_defs.h new file mode 100644 index 00000000..b043d45e --- /dev/null +++ b/freebsd/usr.bin/netstat/nl_defs.h @@ -0,0 +1,58 @@ +#include <nlist.h> +#ifndef __rtems__ +extern const struct nlist nl[]; +#else /* __rtems__ */ +extern struct nlist nl[]; +#endif /* __rtems__ */ +#define N_AHSTAT 0 +#define N_ARPSTAT 1 +#define N_CARPSTATS 2 +#define N_DIVCBINFO 3 +#define N_ESPSTAT 4 +#define N_ICMP6STAT 5 +#define N_ICMPSTAT 6 +#define N_IGMPSTAT 7 +#define N_IP6STAT 8 +#define N_IPCOMPSTAT 9 +#define N_IPSEC4STAT 10 +#define N_IPSEC6STAT 11 +#define N_IPSTAT 12 +#define N_MF6CTABLE 13 +#define N_MFCHASHTBL 14 +#define N_MFCTABLESIZE 15 +#define N_MIF6TABLE 16 +#define N_MRT6STAT 17 +#define N_MRTSTAT 18 +#define N_NETISR_BINDTHREADS 19 +#define N_NETISR_DEFAULTQLIMIT 20 +#define N_NETISR_DISPATCH_POLICY 21 +#define N_NETISR_MAXPROT 22 +#define N_NETISR_MAXQLIMIT 23 +#define N_NETISR_MAXTHREADS 24 +#define N_NETISR_PROTO 25 +#define N_NGSOCKLIST 26 +#define N_NWS 27 +#define N_NWS_ARRAY 28 +#define N_NWS_COUNT 29 +#define N_PFKEYSTAT 30 +#define N_PFSYNCSTATS 31 +#define N_PIM6STAT 32 +#define N_PIMSTAT 33 +#define N_RIP6STAT 34 +#define N_RIPCBINFO 35 +#define N_RTREE 36 +#define N_RTSTAT 37 +#define N_RTTRASH 38 +#define N_SCTPSTAT 39 +#define N_SFSTAT 40 +#define N_TCBINFO 41 +#define N_TCPSTAT 42 +#define N_TCPS_STATES 43 +#define N_UDBINFO 44 +#define N_UDPSTAT 45 +#define N_UNP_COUNT 46 +#define N_UNP_DHEAD 47 +#define N_UNP_GENCNT 48 +#define N_UNP_SHEAD 49 +#define N_UNP_SPHEAD 50 +#define N_VIFTABLE 51 diff --git a/freebsd/usr.bin/netstat/nl_symbols.c b/freebsd/usr.bin/netstat/nl_symbols.c new file mode 100644 index 00000000..d719f8f5 --- /dev/null +++ b/freebsd/usr.bin/netstat/nl_symbols.c @@ -0,0 +1,75 @@ +#include <machine/rtems-bsd-user-space.h> + +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ +#include <rtems/bsd/sys/param.h> +#include <nlist.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-nl_symbols-data.h" +#endif /* __rtems__ */ +#ifndef __rtems__ +const struct nlist nl[] = { +#else /* __rtems__ */ +/* This is not as constant as it seems. The call to kresolve_list(..) in main.c + * might change something. */ +struct nlist nl[] = { +#endif /* __rtems__ */ + { .n_name = "_ahstat" }, + { .n_name = "_arpstat" }, + { .n_name = "_carpstats" }, + { .n_name = "_divcbinfo" }, + { .n_name = "_espstat" }, + { .n_name = "_icmp6stat" }, + { .n_name = "_icmpstat" }, + { .n_name = "_igmpstat" }, + { .n_name = "_ip6stat" }, + { .n_name = "_ipcompstat" }, + { .n_name = "_ipsec4stat" }, + { .n_name = "_ipsec6stat" }, + { .n_name = "_ipstat" }, + { .n_name = "_mf6ctable" }, + { .n_name = "_mfchashtbl" }, + { .n_name = "_mfctablesize" }, + { .n_name = "_mif6table" }, + { .n_name = "_mrt6stat" }, + { .n_name = "_mrtstat" }, + { .n_name = "_netisr_bindthreads" }, + { .n_name = "_netisr_defaultqlimit" }, + { .n_name = "_netisr_dispatch_policy" }, + { .n_name = "_netisr_maxprot" }, + { .n_name = "_netisr_maxqlimit" }, + { .n_name = "_netisr_maxthreads" }, + { .n_name = "_netisr_proto" }, + { .n_name = "_ngsocklist" }, + { .n_name = "_nws" }, + { .n_name = "_nws_array" }, + { .n_name = "_nws_count" }, + { .n_name = "_pfkeystat" }, + { .n_name = "_pfsyncstats" }, + { .n_name = "_pim6stat" }, + { .n_name = "_pimstat" }, + { .n_name = "_rip6stat" }, + { .n_name = "_ripcbinfo" }, + { .n_name = "_rtree" }, + { .n_name = "_rtstat" }, + { .n_name = "_rttrash" }, + { .n_name = "_sctpstat" }, + { .n_name = "_sfstat" }, + { .n_name = "_tcbinfo" }, + { .n_name = "_tcpstat" }, + { .n_name = "_tcps_states" }, + { .n_name = "_udbinfo" }, + { .n_name = "_udpstat" }, + { .n_name = "_unp_count" }, + { .n_name = "_unp_dhead" }, + { .n_name = "_unp_gencnt" }, + { .n_name = "_unp_shead" }, + { .n_name = "_unp_sphead" }, + { .n_name = "_viftable" }, + { .n_name = NULL }, +}; diff --git a/freebsd/usr.bin/netstat/pfkey.c b/freebsd/usr.bin/netstat/pfkey.c index 45fcb977..8feb91e9 100644 --- a/freebsd/usr.bin/netstat/pfkey.c +++ b/freebsd/usr.bin/netstat/pfkey.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /* $NetBSD: inet.c,v 1.35.2.1 1999/04/29 14:57:08 perry Exp $ */ /* $KAME: ipsec.c,v 1.25 2001/03/12 09:04:39 itojun Exp $ */ /*- @@ -65,6 +69,9 @@ static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -83,7 +90,12 @@ __FBSDID("$FreeBSD$"); #include <stdio.h> #include <string.h> #include <unistd.h> +#include <stdbool.h> +#include <libxo/xo.h> #include "netstat.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-pfkey-data.h" +#endif /* __rtems__ */ #ifdef IPSEC @@ -101,8 +113,7 @@ static const char *pfkey_msgtype_names (int); static const char * pfkey_msgtype_names(int x) { - const int max = - sizeof(pfkey_msgtypenames)/sizeof(pfkey_msgtypenames[0]); + const int max = nitems(pfkey_msgtypenames); static char buf[20]; if (x < max && pfkey_msgtypenames[x]) @@ -120,59 +131,89 @@ pfkey_stats(u_long off, const char *name, int family __unused, if (off == 0) return; - printf ("%s:\n", name); - kread(off, (char *)&pfkeystat, sizeof(pfkeystat)); + 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/freebsd/usr.bin/netstat/route.c b/freebsd/usr.bin/netstat/route.c index afa55cee..bed58b06 100644 --- a/freebsd/usr.bin/netstat/route.c +++ b/freebsd/usr.bin/netstat/route.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. @@ -35,203 +39,146 @@ static char sccsid[] = "From: @(#)route.c 8.6 (Berkeley) 4/28/95"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <rtems/bsd/sys/param.h> +#ifdef __rtems__ +#include <rtems/rtems/clock.h> +#endif /* __rtems__ */ #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> #include <net/route.h> #include <netinet/in.h> -#ifdef __rtems__ -/* no IPX on RTEMS */ -/* no AppleTalk on RTEMS */ -#else /* __rtems__ */ -#include <netipx/ipx.h> -#include <netatalk/at.h> -#endif /* __rtems__ */ -#ifdef __rtems__ -/* why isn't this protected by a NETGRAPH define */ -#else /* __rtems__ */ +#ifndef __rtems__ #include <netgraph/ng_socket.h> #endif /* __rtems__ */ -#include <sys/sysctl.h> - #include <arpa/inet.h> +#include <ifaddrs.h> #include <libutil.h> #include <netdb.h> #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))) +#include "nl_defs.h" +#ifdef __rtems__ +#include "rtems-bsd-netstat-route-data.h" +#endif /* __rtems__ */ /* * Definitions for showing gateway flags. */ -struct bits { +#ifndef __rtems__ +static struct bits { +#else /* __rtems__ */ +static const struct bits { +#endif /* __rtems__ */ u_long b_mask; char b_val; -} static const 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_PRCLONING,'c' }, - { RTF_PROTO3, '3' }, - { RTF_BLACKHOLE,'B' }, - { RTF_BROADCAST,'b' }, + const char *b_name; +} bits[] = { + { 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' }, -#endif -#ifdef RTF_WASCLONED - { RTF_WASCLONED,'W' }, + { RTF_LLINFO, 'L', "llinfo" }, #endif -#ifdef RTF_CLONING - { RTF_CLONING, 'C' }, -#endif - { 0 , 0 } + { 0 , 0, NULL } }; -typedef union { - long dummy; /* Helps align structure. */ - struct sockaddr u_sa; - u_short u_data[128]; -} sa_u; - -static sa_u pt_u; - -static struct rtentry rtentry; -static struct radix_node rnode; -static struct radix_mask rmask; - -static const int NewTree = 0; - -static 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_tree(struct radix_node *); -static void p_rtnode(void); -static void ntreestuff(void); -static void np_rtentry(struct rt_msghdr *); -static void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); +struct ifmap_entry { + char ifname[IFNAMSIZ]; +}; +static struct ifmap_entry *ifmap; +static int ifmap_size; +static struct timespec uptime; + +static const char *netname4(in_addr_t, in_addr_t); +static const char *netname6(struct sockaddr_in6 *, struct sockaddr_in6 *); +static void p_rtable_sysctl(int, int); +static void p_rtentry_sysctl(const char *name, struct rt_msghdr *); +static int 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(struct rtentry *); static void domask(char *, in_addr_t, u_long); + /* * Print routing tables. */ void -routepr(u_long rtree) +routepr(int fibnum, int af) { - struct radix_node_head **rnhp, *rnh, head; size_t intsize; - int fam, fibnum, numfibs; + int numfibs; + + if (live == 0) + return; intsize = sizeof(int); - if (sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1) + if (fibnum == -1 && + sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1) fibnum = 0; if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1) numfibs = 1; - rt_tables = calloc(numfibs * (AF_MAX+1), - sizeof(struct radix_node_head *)); - if (rt_tables == NULL) - err(EX_OSERR, "memory allocation failed"); + if (fibnum < 0 || fibnum > numfibs - 1) + errx(EX_USAGE, "%d: invalid fib", fibnum); /* * Since kernel & userland use different timebase * (time_uptime vs time_second) and we are reading kernel memory - * directly we should do rt_rmx.rmx_expire --> expire_time conversion. + * directly we should do rt_expire --> expire_time conversion. */ -#ifdef __rtems__ - { - rtems_clock_get_uptime(&uptime); - } -#else /* __rtems__ */ +#ifndef __rtems__ if (clock_gettime(CLOCK_UPTIME, &uptime) < 0) err(EX_OSERR, "clock_gettime() failed"); +#else /* __rtems__ */ + rtems_clock_get_uptime(&uptime); #endif /* __rtems__ */ - printf("Routing tables\n"); - - if (Aflag == 0 && NewTree) - ntreestuff(); - else { - if (rtree == 0) { - printf("rt_tables: symbol not in namelist\n"); - return; - } - - if (kread((u_long)(rtree), (char *)(rt_tables), (numfibs * - (AF_MAX+1) * sizeof(struct radix_node_head *))) != 0) - return; - 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_tree(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_tree(head.rnh_treetop); - } - } - } + xo_open_container("route-information"); + xo_emit("{T:Routing tables}"); + if (fibnum) + xo_emit(" ({L:fib}: {:fib/%d})", fibnum); + xo_emit("\n"); + p_rtable_sysctl(fibnum, af); + xo_close_container("route-information"); } + /* * Print address family header before a section of the routing table. */ @@ -249,15 +196,9 @@ pr_family(int af1) afname = "Internet6"; break; #endif /*INET6*/ - case AF_IPX: - afname = "IPX"; - break; case AF_ISO: afname = "ISO"; break; - case AF_APPLETALK: - afname = "AppleTalk"; - break; case AF_CCITT: afname = "X.25"; break; @@ -269,166 +210,52 @@ 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 */ #ifndef INET6 #define WID_DST_DEFAULT(af) 18 /* width of destination column */ #define WID_GW_DEFAULT(af) 18 /* width of gateway column */ -#define WID_IF_DEFAULT(af) (Wflag ? 8 : 6) /* width of netif column */ +#define WID_IF_DEFAULT(af) (Wflag ? 10 : 8) /* width of netif column */ #else #define WID_DST_DEFAULT(af) \ ((af) == AF_INET6 ? (numeric_addr ? 33: 18) : 18) #define WID_GW_DEFAULT(af) \ ((af) == AF_INET6 ? (numeric_addr ? 29 : 18) : 18) -#define WID_IF_DEFAULT(af) ((af) == AF_INET6 ? 8 : (Wflag ? 8 : 6)) +#define WID_IF_DEFAULT(af) ((af) == AF_INET6 ? 8 : (Wflag ? 10 : 8)) #endif /*INET6*/ static int wid_dst; static int wid_gw; static int wid_flags; -static int wid_refs; -static int wid_use; +static int wid_pksent; static int wid_mtu; static int wid_if; static int wid_expire; -static void -size_cols(int ef __unused, struct radix_node *rn) -{ - wid_dst = WID_DST_DEFAULT(ef); - wid_gw = WID_GW_DEFAULT(ef); - wid_flags = 6; - wid_refs = 6; - wid_use = 8; - wid_mtu = 6; - wid_if = WID_IF_DEFAULT(ef); - wid_expire = 6; - - if (Wflag) - 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 (addr.u_sa.sa_family == AF_INET || Wflag) { - len = snprintf(buffer, sizeof(buffer), "%d", rt->rt_refcnt); - wid_refs = MAX(len, wid_refs); - len = snprintf(buffer, sizeof(buffer), "%lu", rt->rt_use); - wid_use = MAX(len, wid_use); - if (Wflag && rt->rt_rmx.rmx_mtu != 0) { - len = snprintf(buffer, sizeof(buffer), - "%lu", rt->rt_rmx.rmx_mtu); - wid_mtu = MAX(len, wid_mtu); - } - } - 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_rmx.rmx_expire) { - time_t expire_time; - - if ((expire_time = - rt->rt_rmx.rmx_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. */ -void -pr_rthdr(int af1) +static void +pr_rthdr(int af1 __unused) { - if (Aflag) - printf("%-8.8s ","Address"); - if (af1 == AF_INET || Wflag) { - if (Wflag) { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*.*s %*s\n", - wid_dst, wid_dst, "Destination", - wid_gw, wid_gw, "Gateway", - wid_flags, wid_flags, "Flags", - wid_refs, wid_refs, "Refs", - wid_use, wid_use, "Use", - wid_mtu, wid_mtu, "Mtu", - wid_if, wid_if, "Netif", - wid_expire, "Expire"); - } else { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n", - wid_dst, wid_dst, "Destination", - wid_gw, wid_gw, "Gateway", - wid_flags, wid_flags, "Flags", - wid_refs, wid_refs, "Refs", - wid_use, wid_use, "Use", - wid_if, wid_if, "Netif", - wid_expire, "Expire"); - } + if (Wflag) { + 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", + wid_pksent, wid_pksent, "Use", + wid_mtu, wid_mtu, "Mtu", + 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", @@ -437,309 +264,272 @@ pr_rthdr(int af1) } } -static struct sockaddr * -kgetsa(struct sockaddr *dst) +static void +p_rtable_sysctl(int fibnum, int af) { + size_t needed; + int mib[7]; + char *buf, *next, *lim; + struct rt_msghdr *rtm; + struct sockaddr *sa; + int fam = AF_UNSPEC, ifindex = 0, size; + int need_table_close = false; - 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); -} + struct ifaddrs *ifap, *ifa; + struct sockaddr_dl *sdl; -static void -p_tree(struct radix_node *rn) -{ + /* + * Retrieve interface list at first + * since we need #ifindex -> if_xname match + */ + if (getifaddrs(&ifap) != 0) + err(EX_OSERR, "getifaddrs"); -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(&rtentry); - if (Aflag) - p_rtnode(); - } - } 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(); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + + if (ifa->ifa_addr->sa_family != AF_LINK) + continue; + + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + ifindex = sdl->sdl_index; + + if (ifindex >= ifmap_size) { + size = roundup(ifindex + 1, 32) * + sizeof(struct ifmap_entry); + if ((ifmap = realloc(ifmap, size)) == NULL) + errx(2, "realloc(%d) failed", size); + memset(&ifmap[ifmap_size], 0, + size - ifmap_size * + sizeof(struct ifmap_entry)); + + ifmap_size = roundup(ifindex + 1, 32); } - rn = rnode.rn_right; - p_tree(rnode.rn_left); - p_tree(rn); - } -} -static char nbuf[20]; + if (*ifmap[ifindex].ifname != '\0') + continue; -static void -p_rtnode(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(" ->"); + strlcpy(ifmap[ifindex].ifname, ifa->ifa_name, IFNAMSIZ); } - putchar('\n'); -} -static void -ntreestuff(void) -{ - size_t needed; - int mib[6]; - char *buf, *next, *lim; - struct rt_msghdr *rtm; + freeifaddrs(ifap); mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; - mib[3] = 0; + mib[3] = af; mib[4] = NET_RT_DUMP; mib[5] = 0; - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { - err(1, "sysctl: net.route.0.0.dump estimate"); - } - - if ((buf = malloc(needed)) == 0) { + mib[6] = fibnum; + if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0) + err(EX_OSERR, "sysctl: net.route.0.%d.dump.%d estimate", af, + fibnum); + if ((buf = malloc(needed)) == NULL) errx(2, "malloc(%lu)", (unsigned long)needed); - } - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { - err(1, "sysctl: net.route.0.0.dump"); - } + 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; - np_rtentry(rtm); + if (rtm->rtm_version != RTM_VERSION) + continue; + /* + * 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; + 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("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 -np_rtentry(struct rt_msghdr *rtm) +p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm) { - struct sockaddr *sa = (struct sockaddr *)(rtm + 1); -#ifdef notdef - static int masks_done, banner_printed; -#endif - static int old_af; - int af1 = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST; - -#ifdef notdef - /* for the moment, netmasks are skipped over */ - if (!banner_printed) { - printf("Netmasks:\n"); - banner_printed = 1; + struct sockaddr *sa, *addr[RTAX_MAX]; + char buffer[128]; + char prettyname[128]; + int i, protrusion; + + xo_open_instance(name); + sa = (struct sockaddr *)(rtm + 1); + for (i = 0; i < RTAX_MAX; i++) { + if (rtm->rtm_addrs & (1 << i)) + addr[i] = sa; + sa = (struct sockaddr *)((char *)sa + SA_SIZE(sa)); + } + + protrusion = p_sockaddr("destination", addr[RTAX_DST], + addr[RTAX_NETMASK], + rtm->rtm_flags, wid_dst); + protrusion = p_sockaddr("gateway", addr[RTAX_GATEWAY], NULL, RTF_HOST, + wid_gw - protrusion); + snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:} ", + wid_flags - protrusion); + p_flags(rtm->rtm_flags, buffer); + if (Wflag) { + xo_emit("{t:use/%*lu} ", wid_pksent, rtm->rtm_rmx.rmx_pksent); + + if (rtm->rtm_rmx.rmx_mtu != 0) + xo_emit("{t:mtu/%*lu} ", wid_mtu, rtm->rtm_rmx.rmx_mtu); + else + xo_emit("{P:/%*s} ", wid_mtu, ""); } - if (masks_done == 0) { - if (rtm->rtm_addrs != RTA_DST ) { - masks_done = 1; - af1 = sa->sa_family; - } - } else -#endif - af1 = sa->sa_family; - if (af1 != old_af) { - pr_family(af1); - old_af = af1; + + memset(prettyname, 0, sizeof(prettyname)); + if (rtm->rtm_index < ifmap_size) { + strlcpy(prettyname, ifmap[rtm->rtm_index].ifname, + sizeof(prettyname)); + if (*prettyname == '\0') + strlcpy(prettyname, "---", sizeof(prettyname)); } - if (rtm->rtm_addrs == RTA_DST) - p_sockaddr(sa, NULL, 0, 36); - else { - p_sockaddr(sa, NULL, rtm->rtm_flags, 16); - sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa); - p_sockaddr(sa, NULL, 0, 18); + + if (Wflag) + xo_emit("{t:interface-name/%*s}", wid_if, prettyname); + else + 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) + xo_emit(" {:expire-time/%*d}", wid_expire, + (int)expire_time); } - p_flags(rtm->rtm_flags & interesting, "%-6.6s "); - putchar('\n'); + + xo_emit("\n"); + xo_close_instance(name); } -static void -p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) +static int +p_sockaddr(const char *name, struct sockaddr *sa, struct sockaddr *mask, + int flags, int width) { const char *cp; + char buf[128]; + int protrusion; 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); + protrusion = 0; + } else { + if (Wflag != 0 || numeric_addr) { + snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%s}{]:} ", + -width, name); + xo_emit(buf, cp); + protrusion = strlen(cp) - width; + if (protrusion < 0) + protrusion = 0; + } else { + snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%-.*s}{]:} ", + -width, name); + xo_emit(buf, width, cp); + protrusion = 0; + } } + return (protrusion); } static const char * fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) { - static char workbuf[128]; + static char buf[128]; const char *cp; if (sa == NULL) return ("null"); switch(sa->sa_family) { - case AF_INET: - { - struct sockaddr_in *sockin = (struct sockaddr_in *)sa; - - if ((sockin->sin_addr.s_addr == INADDR_ANY) && - mask && - ntohl(((struct sockaddr_in *)mask)->sin_addr.s_addr) - ==0L) - cp = "default" ; - else if (flags & RTF_HOST) - cp = routename(sockin->sin_addr.s_addr); - else if (mask) - cp = netname(sockin->sin_addr.s_addr, - ntohl(((struct sockaddr_in *)mask) - ->sin_addr.s_addr)); - else - cp = netname(sockin->sin_addr.s_addr, 0L); - break; - } - #ifdef INET6 case AF_INET6: - { - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; - - in6_fillscopeid(sa6); - + /* + * The sa6->sin6_scope_id must be filled here because + * this sockaddr is extracted from kmem(4) directly + * and has KAME-specific embedded scope id in + * sa6->sin6_addr.s6_addr[2]. + */ + in6_fillscopeid(satosin6(sa)); + /* FALLTHROUGH */ +#endif /*INET6*/ + case AF_INET: if (flags & RTF_HOST) - cp = routename6(sa6); + cp = routename(sa, numeric_addr); else if (mask) - cp = netname6(sa6, - &((struct sockaddr_in6 *)mask)->sin6_addr); - else { - cp = netname6(sa6, NULL); - } - break; - } -#endif /*INET6*/ - -#ifndef __rtems__ - case AF_IPX: - { - struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr; - if (ipx_nullnet(satoipx_addr(work))) - cp = "default"; - else - cp = ipx_print(sa); - break; - } - case AF_APPLETALK: - { - if (!(flags & RTF_HOST) && mask) - cp = atalk_print2(sa,mask,9); + cp = netname(sa, mask); else - cp = atalk_print(sa,11); + cp = netname(sa, NULL); break; - } -#endif /* __rtems__ */ case AF_NETGRAPH: { #ifdef __rtems__ /* netgraph not supported yet */ err(EX_OSERR, "memory allocation failed"); #else /* __rtems__ */ - strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data, - sizeof(workbuf)); - cp = workbuf; + strlcpy(buf, ((struct sockaddr_ng *)sa)->sg_data, + sizeof(buf)); + cp = buf; #endif /* __rtems__ */ break; } - case AF_LINK: { +#if 0 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; - if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && - sdl->sdl_slen == 0) { - (void) sprintf(workbuf, "link#%d", sdl->sdl_index); - cp = workbuf; - } else - switch (sdl->sdl_type) { - - case IFT_ETHER: - case IFT_L2VLAN: - case IFT_BRIDGE: - if (sdl->sdl_alen == ETHER_ADDR_LEN) { - cp = ether_ntoa((struct ether_addr *) - (sdl->sdl_data + sdl->sdl_nlen)); - break; - } - /* FALLTHROUGH */ - default: - cp = link_ntoa(sdl); - break; - } + /* Interface route. */ + if (sdl->sdl_nlen) + cp = sdl->sdl_data; + else +#endif + cp = routename(sa, 1); break; } - default: { u_char *s = (u_char *)sa->sa_data, *slim; char *cq, *cqlim; - cq = workbuf; + cq = buf; slim = sa->sa_len + (u_char *) sa; - cqlim = cq + sizeof(workbuf) - 6; + cqlim = cq + sizeof(buf) - 6; cq += sprintf(cq, "(%d)", sa->sa_family); while (s < slim && cq < cqlim) { cq += sprintf(cq, " %02x", *s++); if (s < slim) cq += sprintf(cq, "%02x", *s++); } - cp = workbuf; + cp = buf; } } @@ -749,7 +539,19 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) static void p_flags(int f, const char *format) { - printf(format, fmt_flags(f)); +#ifndef __rtems__ + struct bits *p; +#else /* __rtems__ */ + const struct bits *p; +#endif /* __rtems__ */ + + 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 * @@ -757,7 +559,11 @@ fmt_flags(int f) { static char name[33]; char *flags; +#ifndef __rtems__ + struct bits *p = bits; +#else /* __rtems__ */ const struct bits *p = bits; +#endif /* __rtems__ */ for (flags = name; p->b_mask; p++) if (p->b_mask & f) @@ -766,81 +572,36 @@ fmt_flags(int f) return (name); } -static void -p_rtentry(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 (addr.u_sa.sa_family == AF_INET || Wflag) { - printf("%*d %*lu ", wid_refs, rt->rt_refcnt, - wid_use, rt->rt_use); - if (Wflag) { - if (rt->rt_rmx.rmx_mtu != 0) - printf("%*lu ", wid_mtu, rt->rt_rmx.rmx_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_rmx.rmx_expire) { - time_t expire_time; - - if ((expire_time = - rt->rt_rmx.rmx_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) +routename(struct sockaddr *sa, int flags) { - char *cp; - static char line[MAXHOSTNAMELEN]; - struct hostent *hp; - - cp = 0; - if (!numeric_addr) { - hp = gethostbyaddr(&in, sizeof (struct in_addr), AF_INET); - if (hp) { - cp = hp->h_name; - trimdomain(cp, strlen(cp)); + static char line[NI_MAXHOST]; + int error, f; + + f = (flags) ? NI_NUMERICHOST : 0; + error = getnameinfo(sa, sa->sa_len, line, sizeof(line), + NULL, 0, f); + if (error) { + const void *src; + switch (sa->sa_family) { +#ifdef INET + case AF_INET: + src = &satosin(sa)->sin_addr; + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + src = &satosin6(sa)->sin6_addr; + break; +#endif /* INET6 */ + default: + return(line); } + inet_ntop(sa->sa_family, src, line, sizeof(line) - 1); + return (line); } - if (cp) { - strlcpy(line, cp, sizeof(line)); - } else { -#define C(x) ((x) & 0xff) - in = ntohl(in); - sprintf(line, "%u.%u.%u.%u", - C(in >> 24), C(in >> 16), C(in >> 8), C(in)); - } + trimdomain(line, strlen(line)); + return (line); } @@ -855,7 +616,7 @@ domask(char *dst, in_addr_t addr __unused, u_long mask) { int b, i; - if (mask == 0 || (!numeric_addr && NSHIFT(mask) != 0)) { + if (mask == 0) { *dst = '\0'; return; } @@ -880,30 +641,61 @@ domask(char *dst, in_addr_t addr __unused, u_long mask) /* * Return the name of the network whose address is given. - * The address is assumed to be that of a net or subnet, not a host. */ -char * -netname(in_addr_t in, u_long mask) +const char * +netname(struct sockaddr *sa, struct sockaddr *mask) +{ + switch (sa->sa_family) { + case AF_INET: + if (mask != NULL) + return (netname4(satosin(sa)->sin_addr.s_addr, + satosin(mask)->sin_addr.s_addr)); + else + return (netname4(satosin(sa)->sin_addr.s_addr, + INADDR_ANY)); + break; +#ifdef INET6 + case AF_INET6: + return (netname6(satosin6(sa), satosin6(mask))); +#endif /* INET6 */ + default: + return (NULL); + } +} + +static const char * +netname4(in_addr_t in, in_addr_t mask) { char *cp = 0; - static char line[MAXHOSTNAMELEN]; + static char line[MAXHOSTNAMELEN + sizeof("/xx")]; + char nline[INET_ADDRSTRLEN]; struct netent *np = 0; in_addr_t i; + if (in == INADDR_ANY && mask == 0) { + strlcpy(line, "default", sizeof(line)); + return (line); + } + + /* It is ok to supply host address. */ + in &= mask; + i = ntohl(in); if (!numeric_addr && i) { - np = getnetbyaddr(i >> NSHIFT(mask), AF_INET); + np = getnetbyaddr(i >> NSHIFT(ntohl(mask)), AF_INET); if (np != NULL) { cp = np->n_name; trimdomain(cp, strlen(cp)); } } - if (cp != NULL) { + if (cp != NULL) strlcpy(line, cp, sizeof(line)); - } else { - inet_ntop(AF_INET, &in, line, sizeof(line) - 1); + else { + inet_ntop(AF_INET, &in, nline, sizeof(nline)); + strlcpy(line, nline, sizeof(line)); + domask(line + strlen(line), i, ntohl(mask)); } - domask(line + strlen(line), i, mask); + return (line); } @@ -921,58 +713,53 @@ in6_fillscopeid(struct sockaddr_in6 *sa6) if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&sa6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr)) { - /* XXX: override is ok? */ - sa6->sin6_scope_id = - ntohs(*(u_int16_t *)&sa6->sin6_addr.s6_addr[2]); + if (sa6->sin6_scope_id == 0) + sa6->sin6_scope_id = + ntohs(*(u_int16_t *)&sa6->sin6_addr.s6_addr[2]); sa6->sin6_addr.s6_addr[2] = sa6->sin6_addr.s6_addr[3] = 0; } #endif } -const char * -netname6(struct sockaddr_in6 *sa6, struct in6_addr *mask) +/* Mask to length table. To check an invalid value, (length + 1) is used. */ +static int masktolen[256] = { + [0xff] = 8 + 1, + [0xfe] = 7 + 1, + [0xfc] = 6 + 1, + [0xf8] = 5 + 1, + [0xf0] = 4 + 1, + [0xe0] = 3 + 1, + [0xc0] = 2 + 1, + [0x80] = 1 + 1, + [0x00] = 0 + 1, +}; + +static const char * +netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask) { - static char line[MAXHOSTNAMELEN]; - u_char *p = (u_char *)mask; - u_char *lim; - int masklen, illegal = 0, flag = 0; + static char line[NI_MAXHOST + sizeof("/xxx") - 1]; + struct sockaddr_in6 addr; + char nline[NI_MAXHOST]; + u_char *p, *lim; + int masklen, illegal = 0, i; if (mask) { + p = (u_char *)&mask->sin6_addr; for (masklen = 0, lim = p + 16; p < lim; p++) { - switch (*p) { - case 0xff: - masklen += 8; - break; - case 0xfe: - masklen += 7; - break; - case 0xfc: - masklen += 6; - break; - case 0xf8: - masklen += 5; - break; - case 0xf0: - masklen += 4; - break; - case 0xe0: - masklen += 3; - break; - case 0xc0: - masklen += 2; - break; - case 0x80: - masklen += 1; - break; - case 0x00: - break; - default: - illegal ++; - break; - } + if (masktolen[*p] > 0) + /* -1 is required. */ + masklen += masktolen[*p] - 1; + else + illegal++; } if (illegal) - fprintf(stderr, "illegal prefixlen\n"); + xo_error("illegal prefixlen\n"); + + memcpy(&addr, sa6, sizeof(addr)); + for (i = 0; i < 16; ++i) + addr.sin6_addr.s6_addr[i] &= + mask->sin6_addr.s6_addr[i]; + sa6 = &addr; } else masklen = 128; @@ -980,37 +767,17 @@ netname6(struct sockaddr_in6 *sa6, struct in6_addr *mask) if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr)) return("default"); + getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, nline, sizeof(nline), + NULL, 0, NI_NUMERICHOST); if (numeric_addr) - flag |= NI_NUMERICHOST; - getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, line, sizeof(line), - NULL, 0, flag); - - if (numeric_addr) + strlcpy(line, nline, sizeof(line)); + else + getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, line, + sizeof(line), NULL, 0, 0); + if (numeric_addr || strcmp(line, nline) == 0) sprintf(&line[strlen(line)], "/%d", masklen); - return line; -} - -char * -routename6(struct sockaddr_in6 *sa6) -{ - static char line[MAXHOSTNAMELEN]; - int flag = 0; - /* use local variable for safety */ - struct sockaddr_in6 sa6_local; - - sa6_local.sin6_family = AF_INET6; - sa6_local.sin6_len = sizeof(sa6_local); - sa6_local.sin6_addr = sa6->sin6_addr; - sa6_local.sin6_scope_id = sa6->sin6_scope_id; - - if (numeric_addr) - flag |= NI_NUMERICHOST; - - getnameinfo((struct sockaddr *)&sa6_local, sa6_local.sin6_len, - line, sizeof(line), NULL, 0, flag); - - return line; + return (line); } #endif /*INET6*/ @@ -1018,142 +785,41 @@ routename6(struct sockaddr_in6 *sa6) * Print routing statistics */ void -rt_stats(u_long rtsaddr, u_long rttaddr) +rt_stats(void) { struct rtstat rtstat; + u_long rtsaddr, rttaddr; int rttrash; - if (rtsaddr == 0) { - printf("rtstat: symbol not in namelist\n"); + if ((rtsaddr = nl[N_RTSTAT].n_value) == 0) { + xo_emit("{W:rtstat: symbol not in namelist}\n"); return; } - if (rttaddr == 0) { - printf("rttrash: symbol not in namelist\n"); + if ((rttaddr = nl[N_RTTRASH].n_value) == 0) { + 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)); } - -#ifndef __rtems__ -char * -ipx_print(struct sockaddr *sa) -{ - u_short port; - struct servent *sp = 0; - const char *net = "", *host = ""; - char *p; - u_char *q; - struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr; - static char mybuf[50]; - char cport[10], chost[15], cnet[15]; - - port = ntohs(work.x_port); - - if (ipx_nullnet(work) && ipx_nullhost(work)) { - - if (port) { - if (sp) - sprintf(mybuf, "*.%s", sp->s_name); - else - sprintf(mybuf, "*.%x", port); - } else - sprintf(mybuf, "*.*"); - - return (mybuf); - } - - if (ipx_wildnet(work)) - net = "any"; - else if (ipx_nullnet(work)) - net = "*"; - else { - q = work.x_net.c_net; - sprintf(cnet, "%02x%02x%02x%02x", - q[0], q[1], q[2], q[3]); - for (p = cnet; *p == '0' && p < cnet + 8; p++) - continue; - net = p; - } - - if (ipx_wildhost(work)) - host = "any"; - else if (ipx_nullhost(work)) - host = "*"; - else { - q = work.x_host.c_host; - sprintf(chost, "%02x%02x%02x%02x%02x%02x", - q[0], q[1], q[2], q[3], q[4], q[5]); - for (p = chost; *p == '0' && p < chost + 12; p++) - continue; - host = p; - } - - if (port) { - if (strcmp(host, "*") == 0) - host = ""; - if (sp) - snprintf(cport, sizeof(cport), - "%s%s", *host ? "." : "", sp->s_name); - else - snprintf(cport, sizeof(cport), - "%s%x", *host ? "." : "", port); - } else - *cport = 0; - - snprintf(mybuf, sizeof(mybuf), "%s.%s%s", net, host, cport); - return(mybuf); -} - -char * -ipx_phost(struct sockaddr *sa) -{ - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)sa; - struct sockaddr_ipx work; - static union ipx_net ipx_zeronet; - char *p; - - work = *sipx; - - work.sipx_addr.x_port = 0; - work.sipx_addr.x_net = ipx_zeronet; - p = ipx_print((struct sockaddr *)&work); - if (strncmp("*.", p, 2) == 0) p += 2; - - return(p); -} -#endif /* __rtems__ */ - -void -upHex(char *p0) -{ - char *p = p0; - - for (; *p; p++) - switch (*p) { - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - *p += ('A' - 'a'); - break; - } -} diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-bpf-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-bpf-data.h new file mode 100644 index 00000000..addc5819 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-bpf-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* bpf.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-data.h new file mode 100644 index 00000000..ad92820c --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-data.h @@ -0,0 +1,41 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +/* bpf.c */ +/* flowtable.c */ +/* if.c */ +/* inet6.c */ +/* inet.c */ +/* ipsec.c */ +/* main.c */ +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int Aflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int aflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int bflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int dflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int gflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int hflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int iflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int Lflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int mflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int noutputs); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int numeric_addr); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int numeric_port); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int rflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int Rflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int sflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int Wflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int Tflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int xflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int zflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int interval); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern char *interface); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int unit); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern int live); +/* mbuf.c */ +/* mroute6.c */ +/* mroute.c */ +/* nl_symbols.c */ +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, extern struct nlist nl[53]); +/* pfkey.c */ +/* route.c */ +/* sctp.c */ +/* unix.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-flowtable-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-flowtable-data.h new file mode 100644 index 00000000..47f5ff7b --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-flowtable-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* flowtable.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-if-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-if-data.h new file mode 100644 index 00000000..9e12b65e --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-if-data.h @@ -0,0 +1,5 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* if.c */ +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static sig_atomic_t signalled); diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-inet-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-inet-data.h new file mode 100644 index 00000000..668af81a --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-inet-data.h @@ -0,0 +1,8 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* inet.c */ +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int udp_done); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int tcp_done); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int sdp_done); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int protopr_first); diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-inet6-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-inet6-data.h new file mode 100644 index 00000000..2cf306a2 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-inet6-data.h @@ -0,0 +1,8 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* inet6.c */ +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static char ntop_buf[]); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static char const *ip6nh[]); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static char const *srcrule_str[]); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static char const *icmp6names[]); diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-ipsec-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-ipsec-data.h new file mode 100644 index 00000000..773181e5 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-ipsec-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* ipsec.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-main-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-main-data.h new file mode 100644 index 00000000..8adef4dd --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-main-data.h @@ -0,0 +1,10 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* main.c */ +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static kvm_t *kvmd); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static char *nlistf); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static char *memf); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int Bflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int pflag); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int af); diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-mbuf-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-mbuf-data.h new file mode 100644 index 00000000..debb7485 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-mbuf-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* mbuf.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-mroute-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-mroute-data.h new file mode 100644 index 00000000..06942d57 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-mroute-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* mroute.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-mroute6-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-mroute6-data.h new file mode 100644 index 00000000..91288a71 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-mroute6-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* mroute6.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-namespace.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-namespace.h new file mode 100644 index 00000000..dbbd2c90 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-namespace.h @@ -0,0 +1,83 @@ +/* generated by userspace-header-gen.py */ +/* bpf.c */ +#define bpf_stats _bsd_netstat_bpf_stats +/* flowtable.c */ +#define flowtable_stats _bsd_netstat_flowtable_stats +/* if.c */ +#define intpr _bsd_netstat_intpr +/* inet6.c */ +#define inet6name _bsd_netstat_inet6name +#define inet6print _bsd_netstat_inet6print +#define rip6_stats _bsd_netstat_rip6_stats +#define pim6_stats _bsd_netstat_pim6_stats +#define icmp6_ifstats _bsd_netstat_icmp6_ifstats +#define icmp6_stats _bsd_netstat_icmp6_stats +#define ip6_ifstats _bsd_netstat_ip6_ifstats +#define ip6_stats _bsd_netstat_ip6_stats +/* inet.c */ +#define inetname _bsd_netstat_inetname +#define inetprint _bsd_netstat_inetprint +#define pim_stats _bsd_netstat_pim_stats +#define igmp_stats _bsd_netstat_igmp_stats +#define icmp_stats _bsd_netstat_icmp_stats +#define arp_stats _bsd_netstat_arp_stats +#define ip_stats _bsd_netstat_ip_stats +#define carp_stats _bsd_netstat_carp_stats +#define udp_stats _bsd_netstat_udp_stats +#define tcp_stats _bsd_netstat_tcp_stats +#define protopr _bsd_netstat_protopr +#define sotoxsocket _bsd_netstat_sotoxsocket +/* ipsec.c */ +/* main.c */ +#define Aflag _bsd_netstat_Aflag +#define aflag _bsd_netstat_aflag +#define bflag _bsd_netstat_bflag +#define dflag _bsd_netstat_dflag +#define gflag _bsd_netstat_gflag +#define hflag _bsd_netstat_hflag +#define iflag _bsd_netstat_iflag +#define Lflag _bsd_netstat_Lflag +#define mflag _bsd_netstat_mflag +#define noutputs _bsd_netstat_noutputs +#define numeric_addr _bsd_netstat_numeric_addr +#define numeric_port _bsd_netstat_numeric_port +#define rflag _bsd_netstat_rflag +#define Rflag _bsd_netstat_Rflag +#define sflag _bsd_netstat_sflag +#define Wflag _bsd_netstat_Wflag +#define Tflag _bsd_netstat_Tflag +#define xflag _bsd_netstat_xflag +#define zflag _bsd_netstat_zflag +#define interval _bsd_netstat_interval +#define interface _bsd_netstat_interface +#define unit _bsd_netstat_unit +#define live _bsd_netstat_live +#define pluralies _bsd_netstat_pluralies +#define plurales _bsd_netstat_plurales +#define plural _bsd_netstat_plural +#define kread_counters _bsd_netstat_kread_counters +#define kread_counter _bsd_netstat_kread_counter +#define kread _bsd_netstat_kread +#define kset_dpcpu _bsd_netstat_kset_dpcpu +#define fetch_stats_ro _bsd_netstat_fetch_stats_ro +#define fetch_stats _bsd_netstat_fetch_stats +/* mbuf.c */ +#define mbpr _bsd_netstat_mbpr +/* mroute6.c */ +#define mrt6_stats _bsd_netstat_mrt6_stats +#define mroute6pr _bsd_netstat_mroute6pr +/* mroute.c */ +#define mrt_stats _bsd_netstat_mrt_stats +#define mroutepr _bsd_netstat_mroutepr +/* nl_symbols.c */ +#define nl _bsd_netstat_nl +/* pfkey.c */ +/* route.c */ +#define rt_stats _bsd_netstat_rt_stats +#define in6_fillscopeid _bsd_netstat_in6_fillscopeid +#define netname _bsd_netstat_netname +#define routename _bsd_netstat_routename +#define pr_family _bsd_netstat_pr_family +#define routepr _bsd_netstat_routepr +/* sctp.c */ +/* unix.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-nl_symbols-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-nl_symbols-data.h new file mode 100644 index 00000000..b1e466dc --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-nl_symbols-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* nl_symbols.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-pfkey-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-pfkey-data.h new file mode 100644 index 00000000..e1505d6d --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-pfkey-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* pfkey.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-route-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-route-data.h new file mode 100644 index 00000000..d701a079 --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-route-data.h @@ -0,0 +1,15 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* route.c */ +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static struct ifmap_entry *ifmap); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int ifmap_size); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static struct timespec uptime); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int wid_dst); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int wid_gw); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int wid_flags); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int wid_pksent); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int wid_mtu); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int wid_if); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int wid_expire); +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_netstat, static int masktolen[]); diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-sctp-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-sctp-data.h new file mode 100644 index 00000000..9c086d3a --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-sctp-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* sctp.c */ diff --git a/freebsd/usr.bin/netstat/rtems-bsd-netstat-unix-data.h b/freebsd/usr.bin/netstat/rtems-bsd-netstat-unix-data.h new file mode 100644 index 00000000..3edf8adb --- /dev/null +++ b/freebsd/usr.bin/netstat/rtems-bsd-netstat-unix-data.h @@ -0,0 +1,4 @@ +/* generated by userspace-header-gen.py */ +#include <rtems/linkersets.h> +#include "rtems-bsd-netstat-data.h" +/* unix.c */ diff --git a/freebsd/usr.bin/netstat/sctp.c b/freebsd/usr.bin/netstat/sctp.c index 4f27b2ca..88998c2f 100644 --- a/freebsd/usr.bin/netstat/sctp.c +++ b/freebsd/usr.bin/netstat/sctp.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 2001-2007, by Weongyo Jeong. All rights reserved. * Copyright (c) 2011, by Michael Tuexen. All rights reserved. @@ -37,6 +41,9 @@ static char sccsid[] = "@(#)sctp.c 0.1 (Berkeley) 4/18/2007"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -60,9 +67,14 @@ __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 __rtems__ +#include "rtems-bsd-netstat-sctp-data.h" +#endif /* __rtems__ */ #ifdef SCTP @@ -79,7 +91,7 @@ static void sctp_statesprint(uint32_t state); #define NETSTAT_SCTP_STATES_SHUTDOWN_ACK_SENT 0x8 #define NETSTAT_SCTP_STATES_SHUTDOWN_PENDING 0x9 -char *sctpstates[] = { +static const char *sctpstates[] = { "CLOSED", "BOUND", "LISTEN", @@ -92,114 +104,39 @@ char *sctpstates[] = { "SHUTDOWN_PENDING" }; -LIST_HEAD(xladdr_list, xladdr_entry) xladdr_head; +static LIST_HEAD(xladdr_list, xladdr_entry) xladdr_head; struct xladdr_entry { struct xsctp_laddr *xladdr; LIST_ENTRY(xladdr_entry) xladdr_entries; }; -LIST_HEAD(xraddr_list, xraddr_entry) xraddr_head; +static 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; }; -/* - * Construct an Internet address representation. - * If numeric_addr has been supplied, give - * numeric value, otherwise try for symbolic name. - */ #ifdef INET -static char * -inetname(struct in_addr *inp) -{ - char *cp; - static char line[MAXHOSTNAMELEN]; - struct hostent *hp; - struct netent *np; - - cp = 0; - if (!numeric_addr && inp->s_addr != INADDR_ANY) { - int net = inet_netof(*inp); - int lna = inet_lnaof(*inp); - - if (lna == INADDR_ANY) { - np = getnetbyaddr(net, AF_INET); - if (np) - cp = np->n_name; - } - if (cp == 0) { - hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); - if (hp) { - cp = hp->h_name; - trimdomain(cp, strlen(cp)); - } - } - } - if (inp->s_addr == INADDR_ANY) - strcpy(line, "*"); - else if (cp) { - strlcpy(line, cp, sizeof(line)); - } else { - inp->s_addr = ntohl(inp->s_addr); -#define C(x) ((u_int)((x) & 0xff)) - sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), - C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); - inp->s_addr = htonl(inp->s_addr); - } - return (line); -} +char * +inetname(struct in_addr *inp); #endif #ifdef INET6 -static char ntop_buf[INET6_ADDRSTRLEN]; - -static char * -inet6name(struct in6_addr *in6p) -{ - char *cp; - static char line[50]; - struct hostent *hp; - static char domain[MAXHOSTNAMELEN]; - static int first = 1; - - if (first && !numeric_addr) { - first = 0; - if (gethostname(domain, MAXHOSTNAMELEN) == 0 && - (cp = index(domain, '.'))) - (void) strcpy(domain, cp + 1); - else - domain[0] = 0; - } - cp = 0; - if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) { - hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6); - if (hp) { - if ((cp = index(hp->h_name, '.')) && - !strcmp(cp + 1, domain)) - *cp = 0; - cp = hp->h_name; - } - } - if (IN6_IS_ADDR_UNSPECIFIED(in6p)) - strcpy(line, "*"); - else if (cp) - strcpy(line, cp); - else - sprintf(line, "%s", - inet_ntop(AF_INET6, (void *)in6p, ntop_buf, - sizeof(ntop_buf))); - return (line); -} +char * +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: @@ -215,7 +152,7 @@ sctp_print_address(union sctp_sockstore *address, int port, int num_port) sprintf(line, "%.*s.", Wflag ? 39 : 16, ""); break; } - cp = index(line, '\0'); + cp = strchr(line, '\0'); if (!num_port && port) sp = getservbyport((int)port, "sctp"); if (sp || port == 0) @@ -223,7 +160,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 @@ -299,7 +243,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; } @@ -320,7 +264,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; } @@ -335,26 +279,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; + x_max = MAX(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); } @@ -367,7 +314,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: @@ -395,7 +343,7 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb, { int indent = 0, xladdr_total = 0, is_listening = 0; static int first = 1; - char *tname, *pname; + const char *tname, *pname; struct xsctp_tcb *xstcb; struct xsctp_laddr *xladdr; size_t offset_laddr; @@ -406,30 +354,34 @@ 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)"); first = 0; } xladdr = (struct xsctp_laddr *)(buf + *offset); - if (Lflag && !is_listening) { + if ((!aflag && is_listening) || + (Lflag && !is_listening)) { sctp_skip_xinpcb_ifneed(buf, buflen, offset); return; } @@ -449,30 +401,42 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb, tname = "????"; if (Lflag) { - char buf1[9]; - - snprintf(buf1, 9, "%hu/%hu", xinpcb->qlen, xinpcb->maxqlen); - printf("%-6.6s %-5.5s ", pname, tname); - printf("%-8.8s ", buf1); + char buf1[22]; + + snprintf(buf1, sizeof buf1, "%u/%u", + xinpcb->qlen, xinpcb->maxqlen); + 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; } @@ -480,31 +444,41 @@ retry: if (!Lflag && !is_listening && !process_closed) continue; + xo_open_instance("local-address"); + if (xladdr_total == 0) { - printf("%-6.6s %-5.5s ", pname, tname); + if (!Lflag) { + 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); @@ -515,12 +489,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"); } /* @@ -529,7 +506,7 @@ retry: */ void sctp_protopr(u_long off __unused, - const char *name, int af1, int proto) + const char *name __unused, int af1 __unused, int proto) { char *buf; const char *mibvar = "net.inet.sctp.assoclist"; @@ -542,15 +519,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); + if ((buf = malloc(len)) == NULL) { + 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; } @@ -574,33 +551,42 @@ sctp_statesprint(uint32_t state) int idx; switch (state) { - case SCTP_STATE_COOKIE_WAIT: + case SCTP_CLOSED: + idx = NETSTAT_SCTP_STATES_CLOSED; + break; + case SCTP_BOUND: + idx = NETSTAT_SCTP_STATES_BOUND; + break; + case SCTP_LISTEN: + idx = NETSTAT_SCTP_STATES_LISTEN; + break; + case SCTP_COOKIE_WAIT: idx = NETSTAT_SCTP_STATES_COOKIE_WAIT; break; - case SCTP_STATE_COOKIE_ECHOED: + case SCTP_COOKIE_ECHOED: idx = NETSTAT_SCTP_STATES_COOKIE_ECHOED; break; - case SCTP_STATE_OPEN: + case SCTP_ESTABLISHED: idx = NETSTAT_SCTP_STATES_ESTABLISHED; break; - case SCTP_STATE_SHUTDOWN_SENT: + case SCTP_SHUTDOWN_SENT: idx = NETSTAT_SCTP_STATES_SHUTDOWN_SENT; break; - case SCTP_STATE_SHUTDOWN_RECEIVED: + case SCTP_SHUTDOWN_RECEIVED: idx = NETSTAT_SCTP_STATES_SHUTDOWN_RECEIVED; break; - case SCTP_STATE_SHUTDOWN_ACK_SENT: + case SCTP_SHUTDOWN_ACK_SENT: idx = NETSTAT_SCTP_STATES_SHUTDOWN_ACK_SENT; break; - case SCTP_STATE_SHUTDOWN_PENDING: + case SCTP_SHUTDOWN_PENDING: 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]); } /* @@ -609,105 +595,160 @@ sctp_statesprint(uint32_t state) void sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { - struct sctpstat sctpstat, zerostat; - size_t len = sizeof(sctpstat); - - if (live) { - if (zflag) - memset(&zerostat, 0, len); - if (sysctlbyname("net.inet.sctp.stats", &sctpstat, &len, - zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { - if (errno != ENOENT) - warn("sysctl: net.inet.sctp.stats"); - return; - } - } else - kread(off, &sctpstat, len); + struct sctpstat sctpstat; + + if (fetch_stats("net.inet.sctp.stats", off, &sctpstat, + sizeof(sctpstat), kread) != 0) + return; - 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 /* @@ -729,60 +770,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/freebsd/usr.bin/netstat/unix.c b/freebsd/usr.bin/netstat/unix.c index afb35113..63f2b0ee 100644 --- a/freebsd/usr.bin/netstat/unix.c +++ b/freebsd/usr.bin/netstat/unix.c @@ -1,5 +1,9 @@ #include <machine/rtems-bsd-user-space.h> +#ifdef __rtems__ +#include "rtems-bsd-netstat-namespace.h" +#endif /* __rtems__ */ + /*- * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. @@ -35,6 +39,9 @@ static char sccsid[] = "@(#)unix.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif +#ifdef __rtems__ +#include <machine/rtems-bsd-program.h> +#endif /* __rtems__ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -59,9 +66,14 @@ __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" +#ifdef __rtems__ +#include "rtems-bsd-netstat-unix-data.h" +#endif /* __rtems__ */ static void unixdomainpr(struct xunpcb *, struct xsocket *); @@ -80,15 +92,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); + if ((buf = malloc(len)) == NULL) { + 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); } @@ -117,15 +129,15 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) return (-1); kread(count_off, &unp_count, sizeof(unp_count)); len = 2 * sizeof(xug) + (unp_count + unp_count / 8) * sizeof(xu); - if ((buf = malloc(len)) == 0) { - warnx("malloc %lu bytes", (u_long)len); + if ((buf = malloc(len)) == NULL) { + 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)); \ @@ -195,7 +207,7 @@ fail: #ifndef __rtems__ 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; @@ -204,6 +216,7 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off, struct xunpcb *xunp; u_long head_off; + buf = NULL; for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) { if (live) ret = pcblist_sysctl(type, &buf); @@ -232,26 +245,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); @@ -266,7 +288,26 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) struct unpcb *unp; struct sockaddr_un *sa; static int first = 1; - char buf1[15]; + char buf1[33]; + 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) @@ -275,9 +316,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; @@ -287,20 +327,23 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) return; if (Lflag) { - snprintf(buf1, 15, "%d/%d/%d", so->so_qlen, + snprintf(buf1, sizeof buf1, "%u/%u/%u", so->so_qlen, so->so_incqlen, so->so_qlimit); - printf("unix %-14.14s", buf1); + xo_emit("unix {d:socket/%-32.32s}{e:queue-length/%u}" + "{e:incomplete-queue-length/%u}{e:queue-limit/%u}", + 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"); } #endif /* __rtems__ */ |