Convert netstat to use libxo.
Obtained from: Phil Shafer <phil@juniper.net> Ported to -current by: alfred@ (mostly), Kim Shrier Formatting: marcel@ Sponsored by: Juniper Networks, Inc.
This commit is contained in:
parent
1b927988cf
commit
0ea1b83e37
@ -41,4 +41,6 @@ LIBADD+= netgraph
|
||||
CFLAGS+=-DNETGRAPH
|
||||
.endif
|
||||
|
||||
LIBADD+= xo
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -46,8 +46,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libxo/xo.h>
|
||||
|
||||
#include "netstat.h"
|
||||
|
||||
@ -67,7 +69,7 @@ bpf_pidname(pid_t pid)
|
||||
size = sizeof(newkp);
|
||||
error = sysctl(mib, 4, &newkp, &size, NULL, 0);
|
||||
if (error < 0) {
|
||||
warn("kern.proc.pid failed");
|
||||
xo_warn("kern.proc.pid failed");
|
||||
return (strdup("??????"));
|
||||
}
|
||||
return (strdup(newkp.ki_comm));
|
||||
@ -86,6 +88,21 @@ bpf_flags(struct xbpf_d *bd, char *flagbuf)
|
||||
*flagbuf++ = bd->bd_async ? 'a' : '-';
|
||||
*flagbuf++ = bd->bd_locked ? 'l' : '-';
|
||||
*flagbuf++ = '\0';
|
||||
|
||||
if (bd->bd_promisc)
|
||||
xo_emit("{e:promiscuous/}");
|
||||
if (bd->bd_immediate)
|
||||
xo_emit("{e:immediate/}");
|
||||
if (bd->bd_hdrcmplt)
|
||||
xo_emit("{e:header-complete/}");
|
||||
xo_emit("{e:direction}", (bd->bd_direction == BPF_D_IN) ? "input" :
|
||||
(bd->bd_direction == BPF_D_OUT) ? "output" : "bidirectional");
|
||||
if (bd->bd_feedback)
|
||||
xo_emit("{e:feedback/}");
|
||||
if (bd->bd_async)
|
||||
xo_emit("{e:async/}");
|
||||
if (bd->bd_locked)
|
||||
xo_emit("{e:locked/}");
|
||||
}
|
||||
|
||||
void
|
||||
@ -99,44 +116,55 @@ bpf_stats(char *ifname)
|
||||
bzero(&zerostat, sizeof(zerostat));
|
||||
if (sysctlbyname("net.bpf.stats", NULL, NULL,
|
||||
&zerostat, sizeof(zerostat)) < 0)
|
||||
warn("failed to zero bpf counters");
|
||||
xo_warn("failed to zero bpf counters");
|
||||
return;
|
||||
}
|
||||
if (sysctlbyname("net.bpf.stats", NULL, &size,
|
||||
NULL, 0) < 0) {
|
||||
warn("net.bpf.stats");
|
||||
xo_warn("net.bpf.stats");
|
||||
return;
|
||||
}
|
||||
if (size == 0)
|
||||
return;
|
||||
bd = malloc(size);
|
||||
if (bd == NULL) {
|
||||
warn("malloc failed");
|
||||
xo_warn("malloc failed");
|
||||
return;
|
||||
}
|
||||
if (sysctlbyname("net.bpf.stats", bd, &size,
|
||||
NULL, 0) < 0) {
|
||||
warn("net.bpf.stats");
|
||||
xo_warn("net.bpf.stats");
|
||||
free(bd);
|
||||
return;
|
||||
}
|
||||
(void) printf("%5s %6s %7s %9s %9s %9s %5s %5s %s\n",
|
||||
"Pid", "Netif", "Flags", "Recv", "Drop", "Match", "Sblen",
|
||||
"Hblen", "Command");
|
||||
xo_emit("{T:/%5s} {T:/%6s} {T:/%7s} {T:/%9s} {T:/%9s} {T:/%9s} "
|
||||
"{T:/%5s} {T:/%5s} {T:/%s}\n",
|
||||
"Pid", "Netif", "Flags", "Recv", "Drop", "Match",
|
||||
"Sblen", "Hblen", "Command");
|
||||
xo_open_container("bpf-statistics");
|
||||
xo_open_list("bpf-entry");
|
||||
for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) {
|
||||
if (d->bd_structsize != sizeof(*d)) {
|
||||
warnx("bpf_stats_extended: version mismatch");
|
||||
xo_warnx("bpf_stats_extended: version mismatch");
|
||||
return;
|
||||
}
|
||||
if (ifname && strcmp(ifname, d->bd_ifname) != 0)
|
||||
continue;
|
||||
bpf_flags(d, flagbuf);
|
||||
xo_open_instance("bpf-entry");
|
||||
pname = bpf_pidname(d->bd_pid);
|
||||
(void) printf("%5d %6s %7s %9ju %9ju %9ju %5d %5d %s\n",
|
||||
d->bd_pid, d->bd_ifname, flagbuf,
|
||||
d->bd_rcount, d->bd_dcount, d->bd_fcount,
|
||||
d->bd_slen, d->bd_hlen, pname);
|
||||
xo_emit("{k:pid/%5d} {k:interface-name/%6s} ",
|
||||
d->bd_pid, d->bd_ifname);
|
||||
bpf_flags(d, flagbuf);
|
||||
xo_emit("{d:flags/%7s} {:received-packets/%9ju} "
|
||||
"{:dropped-packets/%9ju} {:filter-packets/%9ju} "
|
||||
"{:store-buffer-length/%5d} {:hold-buffer-length/%5d} "
|
||||
"{:process/%s}\n",
|
||||
flagbuf, (uintmax_t)d->bd_rcount, (uintmax_t)d->bd_dcount,
|
||||
(uintmax_t)d->bd_fcount, d->bd_slen, d->bd_hlen, pname);
|
||||
free(pname);
|
||||
xo_close_instance("bpf-entry");
|
||||
}
|
||||
xo_close_list("bpf-entry");
|
||||
xo_close_container("bpf-statistics");
|
||||
free(bd);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "netstat.h"
|
||||
|
||||
/*
|
||||
|
@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
#include <libxo/xo.h>
|
||||
|
||||
#include "netstat.h"
|
||||
|
||||
@ -98,14 +99,38 @@ static const char* pfsyncacts[] = {
|
||||
/* PFSYNC_ACT_EOF */ "end of frame mark",
|
||||
};
|
||||
|
||||
static const char* pfsyncacts_name[] = {
|
||||
/* PFSYNC_ACT_CLR */ "clear-all-request",
|
||||
/* PFSYNC_ACT_INS */ "state-insert",
|
||||
/* PFSYNC_ACT_INS_ACK */ "state-inserted-ack",
|
||||
/* PFSYNC_ACT_UPD */ "state-update",
|
||||
/* PFSYNC_ACT_UPD_C */ "compressed-state-update",
|
||||
/* PFSYNC_ACT_UPD_REQ */ "uncompressed-state-request",
|
||||
/* PFSYNC_ACT_DEL */ "state-delete",
|
||||
/* PFSYNC_ACT_DEL_C */ "compressed-state-delete",
|
||||
/* PFSYNC_ACT_INS_F */ "fragment-insert",
|
||||
/* PFSYNC_ACT_DEL_F */ "fragment-delete",
|
||||
/* PFSYNC_ACT_BUS */ "bulk-update-mark",
|
||||
/* PFSYNC_ACT_TDB */ "TDB-replay-counter-update",
|
||||
/* PFSYNC_ACT_EOF */ "end-of-frame-mark",
|
||||
};
|
||||
|
||||
static void
|
||||
pfsync_acts_stats(const char *fmt, uint64_t *a)
|
||||
pfsync_acts_stats(const char *list, const char *desc, uint64_t *a)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PFSYNC_ACT_MAX; i++, a++)
|
||||
if (*a || sflag <= 1)
|
||||
printf(fmt, *a, pfsyncacts[i], plural(*a));
|
||||
xo_open_list(list);
|
||||
for (i = 0; i < PFSYNC_ACT_MAX; i++, a++) {
|
||||
if (*a || sflag <= 1) {
|
||||
xo_open_instance(list);
|
||||
xo_emit("\t\t{e:name}{:count/%ju} {N:/%s%s %s}\n",
|
||||
pfsyncacts_name[i], (uintmax_t)(*a),
|
||||
pfsyncacts[i], plural(*a), desc);
|
||||
xo_close_instance(list);
|
||||
}
|
||||
}
|
||||
xo_close_list(list);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,32 +154,50 @@ pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
} else
|
||||
kread(off, &pfsyncstat, len);
|
||||
|
||||
printf("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
xo_open_container(name);
|
||||
|
||||
#define p(f, m) if (pfsyncstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f))
|
||||
xo_emit(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f))
|
||||
|
||||
p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n");
|
||||
p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n");
|
||||
pfsync_acts_stats("\t %ju %s%s received\n",
|
||||
p(pfsyncs_ipackets, "\t{:received-inet-packets/%ju} "
|
||||
"{N:/packet%s received (IPv4)}\n");
|
||||
p(pfsyncs_ipackets6, "\t{:received-inet6-packets/%ju} "
|
||||
"{N:/packet%s received (IPv6)}\n");
|
||||
pfsync_acts_stats("input-histogram", "received",
|
||||
&pfsyncstat.pfsyncs_iacts[0]);
|
||||
p(pfsyncs_badif, "\t\t%ju packet%s discarded for bad interface\n");
|
||||
p(pfsyncs_badttl, "\t\t%ju packet%s discarded for bad ttl\n");
|
||||
p(pfsyncs_hdrops, "\t\t%ju packet%s shorter than header\n");
|
||||
p(pfsyncs_badver, "\t\t%ju packet%s discarded for bad version\n");
|
||||
p(pfsyncs_badauth, "\t\t%ju packet%s discarded for bad HMAC\n");
|
||||
p(pfsyncs_badact,"\t\t%ju packet%s discarded for bad action\n");
|
||||
p(pfsyncs_badlen, "\t\t%ju packet%s discarded for short packet\n");
|
||||
p(pfsyncs_badval, "\t\t%ju state%s discarded for bad values\n");
|
||||
p(pfsyncs_stale, "\t\t%ju stale state%s\n");
|
||||
p(pfsyncs_badstate, "\t\t%ju failed state lookup/insert%s\n");
|
||||
p(pfsyncs_opackets, "\t%ju packet%s sent (IPv4)\n");
|
||||
p(pfsyncs_opackets6, "\t%ju packet%s sent (IPv6)\n");
|
||||
pfsync_acts_stats("\t %ju %s%s sent\n",
|
||||
p(pfsyncs_badif, "\t\t/{:dropped-bad-interface/%ju} "
|
||||
"{N:/packet%s discarded for bad interface}\n");
|
||||
p(pfsyncs_badttl, "\t\t{:dropped-bad-ttl/%ju} "
|
||||
"{N:/packet%s discarded for bad ttl}\n");
|
||||
p(pfsyncs_hdrops, "\t\t{:dropped-short-header/%ju} "
|
||||
"{N:/packet%s shorter than header}\n");
|
||||
p(pfsyncs_badver, "\t\t{:dropped-bad-version/%ju} "
|
||||
"{N:/packet%s discarded for bad version}\n");
|
||||
p(pfsyncs_badauth, "\t\t{:dropped-bad-auth/%ju} "
|
||||
"{N:/packet%s discarded for bad HMAC}\n");
|
||||
p(pfsyncs_badact,"\t\t{:dropped-bad-action/%ju} "
|
||||
"{N:/packet%s discarded for bad action}\n");
|
||||
p(pfsyncs_badlen, "\t\t{:dropped-short/%ju} "
|
||||
"{N:/packet%s discarded for short packet}\n");
|
||||
p(pfsyncs_badval, "\t\t{:dropped-bad-values/%ju} "
|
||||
"{N:/state%s discarded for bad values}\n");
|
||||
p(pfsyncs_stale, "\t\t{:dropped-stale-state/%ju} "
|
||||
"{N:/stale state%s}\n");
|
||||
p(pfsyncs_badstate, "\t\t{:dropped-failed-lookup/%ju} "
|
||||
"{N:/failed state lookup\\/insert%s}\n");
|
||||
p(pfsyncs_opackets, "\t{:sent-inet-packets/%ju} "
|
||||
"{N:/packet%s sent (IPv4})\n");
|
||||
p(pfsyncs_opackets6, "\t{:send-inet6-packets/%ju} "
|
||||
"{N:/packet%s sent (IPv6})\n");
|
||||
pfsync_acts_stats("output-histogram", "sent",
|
||||
&pfsyncstat.pfsyncs_oacts[0]);
|
||||
p(pfsyncs_onomem, "\t\t%ju failure%s due to mbuf memory error\n");
|
||||
p(pfsyncs_oerrors, "\t\t%ju send error%s\n");
|
||||
p(pfsyncs_onomem, "\t\t{:discarded-no-memory/%ju} "
|
||||
"{N:/failure%s due to mbuf memory error}\n");
|
||||
p(pfsyncs_oerrors, "\t\t{:send-errors/%ju} "
|
||||
"{N:/send error%s}\n");
|
||||
#undef p
|
||||
xo_close_container(name);
|
||||
}
|
||||
#endif /* PF */
|
||||
|
||||
@ -162,10 +205,11 @@ pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
* Display a formatted value, or a '-' in the same space.
|
||||
*/
|
||||
static void
|
||||
show_stat(const char *fmt, int width, u_long value, short showvalue)
|
||||
show_stat(const char *fmt, int width, const char *name,
|
||||
u_long value, short showvalue)
|
||||
{
|
||||
const char *lsep, *rsep;
|
||||
char newfmt[32];
|
||||
char newfmt[64];
|
||||
|
||||
lsep = "";
|
||||
if (strncmp(fmt, "LS", 2) == 0) {
|
||||
@ -179,23 +223,42 @@ 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);
|
||||
snprintf(newfmt, sizeof(newfmt), "%s%%%ds%s",
|
||||
lsep, width, rsep);
|
||||
xo_emit(newfmt, buf);
|
||||
xo_attr("value", "%lu", value);
|
||||
maybe_pad(lsep);
|
||||
snprintf(newfmt, sizeof(newfmt), "{:%s/%%%ds}", name, width);
|
||||
xo_emit(newfmt, buf);
|
||||
maybe_pad(rsep);
|
||||
} else {
|
||||
/* Construct the format string. */
|
||||
sprintf(newfmt, "%s%%%d%s%s", lsep, width, fmt, rsep);
|
||||
printf(newfmt, value);
|
||||
maybe_pad(lsep);
|
||||
snprintf(newfmt, sizeof(newfmt), "{:%s/%%%d%s}",
|
||||
name, width, fmt);
|
||||
xo_emit(newfmt, value);
|
||||
maybe_pad(rsep);
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,34 +298,37 @@ intpr(int interval, void (*pfunc)(char *), int af)
|
||||
if (aflag && getifmaddrs(&ifmap) != 0)
|
||||
err(EX_OSERR, "getifmaddrs");
|
||||
|
||||
xo_open_list("interface");
|
||||
if (!pfunc) {
|
||||
if (Wflag)
|
||||
printf("%-7.7s", "Name");
|
||||
xo_emit("{T:/%-7.7s}", "Name");
|
||||
else
|
||||
printf("%-5.5s", "Name");
|
||||
printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s",
|
||||
xo_emit("{T:/%-5.5s}", "Name");
|
||||
xo_emit(" {T:/%5.5s} {T:/%-13.13s} {T:/%-17.17s} {T:/%8.8s} "
|
||||
"{T:/%5.5s} {T:/%5.5s}",
|
||||
"Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop");
|
||||
if (bflag)
|
||||
printf(" %10.10s","Ibytes");
|
||||
printf(" %8.8s %5.5s", "Opkts", "Oerrs");
|
||||
xo_emit(" {T:/%10.10s}","Ibytes");
|
||||
xo_emit(" {T:/%8.8s} {T:/%5.5s}", "Opkts", "Oerrs");
|
||||
if (bflag)
|
||||
printf(" %10.10s","Obytes");
|
||||
printf(" %5s", "Coll");
|
||||
xo_emit(" {T:/%10.10s}","Obytes");
|
||||
xo_emit(" {T:/%5s}", "Coll");
|
||||
if (dflag)
|
||||
printf(" %s", "Drop");
|
||||
putchar('\n');
|
||||
xo_emit(" {T:/%s}", "Drop");
|
||||
xo_emit("\n");
|
||||
}
|
||||
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
bool network = false, link = false;
|
||||
char *name;
|
||||
|
||||
if (interface != NULL && strcmp(ifa->ifa_name, interface) != 0)
|
||||
continue;
|
||||
|
||||
if (pfunc) {
|
||||
char *name;
|
||||
name = ifa->ifa_name;
|
||||
|
||||
if (pfunc) {
|
||||
|
||||
name = ifa->ifa_name;
|
||||
(*pfunc)(name);
|
||||
|
||||
/*
|
||||
@ -278,19 +344,21 @@ intpr(int interval, void (*pfunc)(char *), int af)
|
||||
if (af != AF_UNSPEC && ifa->ifa_addr->sa_family != af)
|
||||
continue;
|
||||
|
||||
xo_open_instance("interface");
|
||||
|
||||
if (Wflag)
|
||||
printf("%-7.7s", ifa->ifa_name);
|
||||
xo_emit("{tk:name/%-7.7s}", name);
|
||||
else
|
||||
printf("%-5.5s", ifa->ifa_name);
|
||||
xo_emit("{tk:name/%-5.5s}", name);
|
||||
|
||||
#define IFA_MTU(ifa) (((struct if_data *)(ifa)->ifa_data)->ifi_mtu)
|
||||
show_stat("lu", 6, IFA_MTU(ifa), IFA_MTU(ifa));
|
||||
show_stat("lu", 6, "mtu", IFA_MTU(ifa), IFA_MTU(ifa));
|
||||
#undef IFA_MTU
|
||||
|
||||
switch (ifa->ifa_addr->sa_family) {
|
||||
case AF_UNSPEC:
|
||||
printf("%-13.13s ", "none");
|
||||
printf("%-15.15s ", "none");
|
||||
xo_emit("{:network/%-13.13s} ", "none");
|
||||
xo_emit("{:address/%-15.15s} ", "none");
|
||||
break;
|
||||
case AF_INET:
|
||||
{
|
||||
@ -298,9 +366,10 @@ intpr(int interval, void (*pfunc)(char *), int af)
|
||||
|
||||
sin = (struct sockaddr_in *)ifa->ifa_addr;
|
||||
mask = (struct sockaddr_in *)ifa->ifa_netmask;
|
||||
printf("%-13.13s ", netname(sin->sin_addr.s_addr,
|
||||
xo_emit("{t:network/%-13.13s} ",
|
||||
netname(sin->sin_addr.s_addr,
|
||||
mask->sin_addr.s_addr));
|
||||
printf("%-17.17s ",
|
||||
xo_emit("{t:address/%-17.17s} ",
|
||||
routename(sin->sin_addr.s_addr));
|
||||
|
||||
network = true;
|
||||
@ -314,67 +383,82 @@ intpr(int interval, void (*pfunc)(char *), int af)
|
||||
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
||||
mask = (struct sockaddr_in6 *)ifa->ifa_netmask;
|
||||
|
||||
printf("%-13.13s ", netname6(sin6, &mask->sin6_addr));
|
||||
xo_emit("{t:network/%-13.13s} ",
|
||||
netname6(sin6, &mask->sin6_addr));
|
||||
getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
|
||||
addr_buf, sizeof(addr_buf), 0, 0, NI_NUMERICHOST);
|
||||
printf("%-17.17s ", addr_buf);
|
||||
xo_emit("{t:address/%-17.17s} ", addr_buf);
|
||||
|
||||
network = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* INET6 */
|
||||
case AF_LINK:
|
||||
{
|
||||
struct sockaddr_dl *sdl;
|
||||
char *cp, linknum[10];
|
||||
int n, m;
|
||||
int len = 32;
|
||||
char buf[len];
|
||||
int n, z;
|
||||
|
||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
||||
cp = (char *)LLADDR(sdl);
|
||||
n = sdl->sdl_alen;
|
||||
sprintf(linknum, "<Link#%d>", sdl->sdl_index);
|
||||
m = printf("%-13.13s ", linknum);
|
||||
|
||||
while ((--n >= 0) && (m < 30))
|
||||
m += printf("%02x%c", *cp++ & 0xff,
|
||||
n > 0 ? ':' : ' ');
|
||||
m = 32 - m;
|
||||
while (m-- > 0)
|
||||
putchar(' ');
|
||||
|
||||
xo_emit("{t:network/%-13.13s} ", linknum);
|
||||
buf[0] = '\0';
|
||||
z = 0;
|
||||
while ((--n >= 0) && (z < len)) {
|
||||
snprintf(buf + z, len - z, "%02x%c",
|
||||
*cp++ & 0xff, n > 0 ? ':' : ' ');
|
||||
z += 3;
|
||||
}
|
||||
if (z > 0)
|
||||
xo_emit("{:address/%*s}", 32 - z, buf);
|
||||
else
|
||||
xo_emit("{P: }");
|
||||
link = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define IFA_STAT(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
|
||||
show_stat("lu", 8, IFA_STAT(ipackets), link|network);
|
||||
show_stat("lu", 5, IFA_STAT(ierrors), link);
|
||||
show_stat("lu", 5, IFA_STAT(iqdrops), link);
|
||||
show_stat("lu", 8, "received-packets", IFA_STAT(ipackets),
|
||||
link|network);
|
||||
show_stat("lu", 5, "received-errors", IFA_STAT(ierrors), link);
|
||||
show_stat("lu", 5, "dropped-packet", IFA_STAT(iqdrops), link);
|
||||
if (bflag)
|
||||
show_stat("lu", 10, IFA_STAT(ibytes), link|network);
|
||||
show_stat("lu", 8, IFA_STAT(opackets), link|network);
|
||||
show_stat("lu", 5, IFA_STAT(oerrors), link);
|
||||
show_stat("lu", 10, "received-bytes", IFA_STAT(ibytes),
|
||||
link|network);
|
||||
show_stat("lu", 8, "sent-packets", IFA_STAT(opackets),
|
||||
link|network);
|
||||
show_stat("lu", 5, "send-errors", IFA_STAT(oerrors), link);
|
||||
if (bflag)
|
||||
show_stat("lu", 10, IFA_STAT(obytes), link|network);
|
||||
show_stat("NRSlu", 5, IFA_STAT(collisions), link);
|
||||
show_stat("lu", 10, "sent-bytes", IFA_STAT(obytes),
|
||||
link|network);
|
||||
show_stat("NRSlu", 5, "collisions", IFA_STAT(collisions), link);
|
||||
if (dflag)
|
||||
show_stat("LSlu", 5, IFA_STAT(oqdrops), link);
|
||||
putchar('\n');
|
||||
show_stat("LSlu", 5, "dropped-packets",
|
||||
IFA_STAT(oqdrops), link);
|
||||
xo_emit("\n");
|
||||
|
||||
if (!aflag)
|
||||
if (!aflag) {
|
||||
xo_close_instance("interface");
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print family's multicast addresses.
|
||||
*/
|
||||
xo_open_list("multicast-address");
|
||||
for (ifma = next_ifma(ifmap, ifa->ifa_name,
|
||||
ifa->ifa_addr->sa_family);
|
||||
ifma != NULL;
|
||||
ifma = next_ifma(ifma, ifa->ifa_name,
|
||||
ifa->ifa_addr->sa_family)) {
|
||||
ifa->ifa_addr->sa_family);
|
||||
ifma != NULL;
|
||||
ifma = next_ifma(ifma, ifa->ifa_name,
|
||||
ifa->ifa_addr->sa_family)) {
|
||||
const char *fmt = NULL;
|
||||
|
||||
xo_open_instance("multicast-address");
|
||||
switch (ifma->ifma_addr->sa_family) {
|
||||
case AF_INET:
|
||||
{
|
||||
@ -391,7 +475,7 @@ intpr(int interval, void (*pfunc)(char *), int af)
|
||||
getnameinfo(ifma->ifma_addr,
|
||||
ifma->ifma_addr->sa_len, addr_buf,
|
||||
sizeof(addr_buf), 0, 0, NI_NUMERICHOST);
|
||||
printf("%*s %s\n",
|
||||
xo_emit("{P:/%*s }{t:address/%-19.19s}",
|
||||
Wflag ? 27 : 25, "", addr_buf);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
@ -412,21 +496,24 @@ intpr(int interval, void (*pfunc)(char *), int af)
|
||||
}
|
||||
|
||||
if (fmt) {
|
||||
printf("%*s %-17.17s",
|
||||
xo_emit("{P:/%*s }{t:address/%-17.17s/}",
|
||||
Wflag ? 27 : 25, "", fmt);
|
||||
if (ifma->ifma_addr->sa_family == AF_LINK) {
|
||||
printf(" %8ju",
|
||||
(uintmax_t )IFA_STAT(imcasts));
|
||||
printf("%*s", bflag ? 17 : 6, "");
|
||||
printf(" %8ju",
|
||||
(uintmax_t )IFA_STAT(omcasts));
|
||||
}
|
||||
putchar('\n');
|
||||
xo_emit(" {:received-packets/%8lu}",
|
||||
IFA_STAT(imcasts));
|
||||
xo_emit("{P:/%*s}", bflag? 17 : 6, "");
|
||||
xo_emit(" {:sent-packets/%8lu}",
|
||||
IFA_STAT(omcasts));
|
||||
}
|
||||
xo_emit("\n");
|
||||
}
|
||||
|
||||
xo_close_instance("multicast-address");
|
||||
ifma = ifma->ifma_next;
|
||||
}
|
||||
xo_close_list("multicast-address");
|
||||
xo_close_instance("interface");
|
||||
}
|
||||
xo_close_list("interface");
|
||||
|
||||
freeifaddrs(ifap);
|
||||
if (aflag)
|
||||
@ -455,7 +542,7 @@ fill_iftot(struct iftot *st)
|
||||
bool found = false;
|
||||
|
||||
if (getifaddrs(&ifap) != 0)
|
||||
err(EX_OSERR, "getifaddrs");
|
||||
xo_err(EX_OSERR, "getifaddrs");
|
||||
|
||||
bzero(st, sizeof(*st));
|
||||
|
||||
@ -481,7 +568,7 @@ fill_iftot(struct iftot *st)
|
||||
}
|
||||
|
||||
if (interface && found == false)
|
||||
err(EX_DATAERR, "interface %s not found", interface);
|
||||
xo_err(EX_DATAERR, "interface %s not found", interface);
|
||||
|
||||
freeifaddrs(ifap);
|
||||
}
|
||||
@ -520,23 +607,26 @@ sidewaysintpr(int interval)
|
||||
interval_it.it_interval.tv_usec = 0;
|
||||
interval_it.it_value = interval_it.it_interval;
|
||||
setitimer(ITIMER_REAL, &interval_it, NULL);
|
||||
xo_open_list("interface-statistics");
|
||||
|
||||
banner:
|
||||
printf("%17s %14s %16s", "input",
|
||||
xo_emit("{T:/%17s} {T:/%14s} {T:/%16s}\n", "input",
|
||||
interface != NULL ? interface : "(Total)", "output");
|
||||
putchar('\n');
|
||||
printf("%10s %5s %5s %10s %10s %5s %10s %5s",
|
||||
xo_emit("{T:/%10s} {T:/%5s} {T:/%5s} {T:/%10s} {T:/%10s} {T:/%5s} "
|
||||
"{T:/%10s} {T:/%5s}",
|
||||
"packets", "errs", "idrops", "bytes", "packets", "errs", "bytes",
|
||||
"colls");
|
||||
if (dflag)
|
||||
printf(" %5.5s", "drops");
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
xo_emit(" {T:/%5.5s}", "drops");
|
||||
xo_emit("\n");
|
||||
xo_flush();
|
||||
line = 0;
|
||||
|
||||
loop:
|
||||
if ((noutputs != 0) && (--noutputs == 0))
|
||||
exit(0);
|
||||
if ((noutputs != 0) && (--noutputs == 0)) {
|
||||
xo_close_list("interface-statistics");
|
||||
return;
|
||||
}
|
||||
oldmask = sigblock(sigmask(SIGALRM));
|
||||
while (!signalled)
|
||||
sigpause(0);
|
||||
@ -546,18 +636,29 @@ sidewaysintpr(int interval)
|
||||
|
||||
fill_iftot(new);
|
||||
|
||||
show_stat("lu", 10, new->ift_ip - old->ift_ip, 1);
|
||||
show_stat("lu", 5, new->ift_ie - old->ift_ie, 1);
|
||||
show_stat("lu", 5, new->ift_id - old->ift_id, 1);
|
||||
show_stat("lu", 10, new->ift_ib - old->ift_ib, 1);
|
||||
show_stat("lu", 10, new->ift_op - old->ift_op, 1);
|
||||
show_stat("lu", 5, new->ift_oe - old->ift_oe, 1);
|
||||
show_stat("lu", 10, new->ift_ob - old->ift_ob, 1);
|
||||
show_stat("NRSlu", 5, new->ift_co - old->ift_co, 1);
|
||||
xo_open_instance("stats");
|
||||
show_stat("lu", 10, "received-packets",
|
||||
new->ift_ip - old->ift_ip, 1);
|
||||
show_stat("lu", 5, "received-errors",
|
||||
new->ift_ie - old->ift_ie, 1);
|
||||
show_stat("lu", 5, "dropped-packets",
|
||||
new->ift_id - old->ift_id, 1);
|
||||
show_stat("lu", 10, "received-bytes",
|
||||
new->ift_ib - old->ift_ib, 1);
|
||||
show_stat("lu", 10, "sent-packets",
|
||||
new->ift_op - old->ift_op, 1);
|
||||
show_stat("lu", 5, "send-errors",
|
||||
new->ift_oe - old->ift_oe, 1);
|
||||
show_stat("lu", 10, "sent-bytes",
|
||||
new->ift_ob - old->ift_ob, 1);
|
||||
show_stat("NRSlu", 5, "collisions",
|
||||
new->ift_co - old->ift_co, 1);
|
||||
if (dflag)
|
||||
show_stat("LSlu", 5, new->ift_od - old->ift_od, 1);
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
show_stat("LSlu", 5, "dropped-packets",
|
||||
new->ift_od - old->ift_od, 1);
|
||||
xo_close_instance("stats");
|
||||
xo_emit("\n");
|
||||
xo_flush();
|
||||
|
||||
if (new == &ift[0]) {
|
||||
new = &ift[1];
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -65,9 +65,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
struct socket sockb;
|
||||
@ -372,153 +374,246 @@ ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len,
|
||||
zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: net.inet6.ip6.stats");
|
||||
xo_warn("sysctl: net.inet6.ip6.stats");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread_counters(off, &ip6stat, len);
|
||||
|
||||
printf("%s:\n", name);
|
||||
xo_open_container(name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
|
||||
#define p(f, m) if (ip6stat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
|
||||
xo_emit(m, (uintmax_t)ip6stat.f, plural(ip6stat.f))
|
||||
#define p1a(f, m) if (ip6stat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)ip6stat.f)
|
||||
xo_emit(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");
|
||||
p(ip6s_total, "\t{:received-packets/%ju} "
|
||||
"{N:/total packet%s received}\n");
|
||||
p1a(ip6s_toosmall, "\t{:dropped-below-minimum-size/%ju} "
|
||||
"{N:/with size smaller than minimum}\n");
|
||||
p1a(ip6s_tooshort, "\t{:dropped-short-packets/%ju} "
|
||||
"{N:/with data size < data length}\n");
|
||||
p1a(ip6s_badoptions, "\t{:dropped-bad-options/%ju} "
|
||||
"{N:/with bad options}\n");
|
||||
p1a(ip6s_badvers, "\t{:dropped-bad-version/%ju} "
|
||||
"{N:/with incorrect version number}\n");
|
||||
p(ip6s_fragments, "\t{:received-fragments/%ju} "
|
||||
"{N:/fragment%s received}\n");
|
||||
p(ip6s_fragdropped, "\t{:dropped-fragment/%ju} "
|
||||
"{N:/fragment%s dropped (dup or out of space)}\n");
|
||||
p(ip6s_fragtimeout, "\t{:dropped-fragment-after-timeout/%ju} "
|
||||
"{N:/fragment%s dropped after timeout}\n");
|
||||
p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
|
||||
"{N:/fragment%s that exceeded limit}\n");
|
||||
p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
|
||||
"{N:/packet%s reassembled ok}\n");
|
||||
p(ip6s_delivered, "\t{:received-local-packets/%ju} "
|
||||
"{N:/packet%s for this host}\n");
|
||||
p(ip6s_forward, "\t{:forwarded-packets/%ju} "
|
||||
"{N:/packet%s forwarded}\n");
|
||||
p(ip6s_cantforward, "\t{:packets-not-forwardable/%ju} "
|
||||
"{N:/packet%s not forwardable}\n");
|
||||
p(ip6s_redirectsent, "\t{:sent-redirects/%ju} "
|
||||
"{N:/redirect%s sent}\n");
|
||||
p(ip6s_localout, "\t{:sent-packets/%ju} "
|
||||
"{N:/packet%s sent from this host}\n");
|
||||
p(ip6s_rawout, "\t{:send-packets-fabricated-header/%ju} "
|
||||
"{N:/packet%s sent with fabricated ip header}\n");
|
||||
p(ip6s_odropped, "\t{:discard-no-mbufs/%ju} "
|
||||
"{N:/output packet%s dropped due to no bufs, etc.}\n");
|
||||
p(ip6s_noroute, "\t{:discard-no-route/%ju} "
|
||||
"{N:/output packet%s discarded due to no route}\n");
|
||||
p(ip6s_fragmented, "\t{:sent-fragments/%ju} "
|
||||
"{N:/output datagram%s fragmented}\n");
|
||||
p(ip6s_ofragments, "\t{:fragments-created/%ju} "
|
||||
"{N:/fragment%s created}\n");
|
||||
p(ip6s_cantfrag, "\t{:discard-cannot-fragment/%ju} "
|
||||
"{N:/datagram%s that can't be fragmented}\n");
|
||||
p(ip6s_badscope, "\t{:discard-scope-violations/%ju} "
|
||||
"{N:/packet%s that violated scope rules}\n");
|
||||
p(ip6s_notmember, "\t{:multicast-no-join-packets/%ju} "
|
||||
"{N:/multicast packet%s which we don't join}\n");
|
||||
for (first = 1, i = 0; i < IP6S_HDRCNT; i++)
|
||||
if (ip6stat.ip6s_nxthist[i] != 0) {
|
||||
if (first) {
|
||||
printf("\tInput histogram:\n");
|
||||
xo_emit("\t{T:Input histogram}:\n");
|
||||
xo_open_list("input-histogram");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t%s: %ju\n", ip6nh[i],
|
||||
xo_open_instance("input-histogram");
|
||||
xo_emit("\t\t{k:name/%s}: {:count/%ju}\n", ip6nh[i],
|
||||
(uintmax_t)ip6stat.ip6s_nxthist[i]);
|
||||
xo_close_instance("input-histogram");
|
||||
}
|
||||
printf("\tMbuf statistics:\n");
|
||||
printf("\t\t%ju one mbuf\n", (uintmax_t)ip6stat.ip6s_m1);
|
||||
if (!first)
|
||||
xo_close_list("input-histogram");
|
||||
|
||||
xo_open_container("mbuf-statistics");
|
||||
xo_emit("\t{T:Mbuf statistics}:\n");
|
||||
xo_emit("\t\t{:one-mbuf/%ju} {N:/one mbuf}\n",
|
||||
(uintmax_t)ip6stat.ip6s_m1);
|
||||
for (first = 1, i = 0; i < IP6S_M2MMAX; i++) {
|
||||
char ifbuf[IFNAMSIZ];
|
||||
if (ip6stat.ip6s_m2m[i] != 0) {
|
||||
if (first) {
|
||||
printf("\t\ttwo or more mbuf:\n");
|
||||
xo_emit("\t\t{N:two or more mbuf}:\n");
|
||||
xo_open_list("mbuf-data");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t\t%s= %ju\n",
|
||||
xo_open_instance("mbuf-data");
|
||||
xo_emit("\t\t\t{k:name/%s}= {:count/%ju}\n",
|
||||
if_indextoname(i, ifbuf),
|
||||
(uintmax_t)ip6stat.ip6s_m2m[i]);
|
||||
xo_close_instance("mbuf-data");
|
||||
}
|
||||
}
|
||||
printf("\t\t%ju one ext mbuf\n",
|
||||
if (!first)
|
||||
xo_close_list("mbuf-data");
|
||||
xo_emit("\t\t{:one-extra-mbuf/%ju} {N:one ext mbuf}\n",
|
||||
(uintmax_t)ip6stat.ip6s_mext1);
|
||||
printf("\t\t%ju two or more ext mbuf\n",
|
||||
(uintmax_t)ip6stat.ip6s_mext2m);
|
||||
p(ip6s_exthdrtoolong,
|
||||
"\t%ju packet%s whose headers are not contiguous\n");
|
||||
p(ip6s_nogif, "\t%ju tunneling packet%s that can't find gif\n");
|
||||
p(ip6s_toomanyhdr,
|
||||
"\t%ju packet%s discarded because of too many headers\n");
|
||||
xo_emit("\t\t{:two-or-more-extra-mbufs/%ju} "
|
||||
"{N:/two or more ext mbuf}\n", (uintmax_t)ip6stat.ip6s_mext2m);
|
||||
xo_close_container("mbuf-statistics");
|
||||
|
||||
p(ip6s_exthdrtoolong, "\t{:dropped-header-too-long/%ju} "
|
||||
"{N:/packet%s whose headers are not contiguous}\n");
|
||||
p(ip6s_nogif, "\t{:discard-tunnel-no-gif/%ju} "
|
||||
"{N:/tunneling packet%s that can't find gif}\n");
|
||||
p(ip6s_toomanyhdr, "\t{:dropped-too-many-headers/%ju} "
|
||||
"{N:/packet%s discarded because of too many headers}\n");
|
||||
|
||||
/* for debugging source address selection */
|
||||
#define PRINT_SCOPESTAT(s,i) do {\
|
||||
switch(i) { /* XXX hardcoding in each case */\
|
||||
case 1:\
|
||||
p(s, "\t\t%ju interface-local%s\n");\
|
||||
p(s, "\t\t{ke:name/interface-locals}{:count/%ju} " \
|
||||
"{N:/interface-local%s}\n"); \
|
||||
break;\
|
||||
case 2:\
|
||||
p(s,"\t\t%ju link-local%s\n");\
|
||||
p(s,"\t\t{ke:name/link-locals}{:count/%ju} " \
|
||||
"{N:/link-local%s}\n"); \
|
||||
break;\
|
||||
case 5:\
|
||||
p(s,"\t\t%ju site-local%s\n");\
|
||||
p(s,"\t\t{ke:name/site-locals}{:count/%ju} " \
|
||||
"{N:/site-local%s}\n");\
|
||||
break;\
|
||||
case 14:\
|
||||
p(s,"\t\t%ju global%s\n");\
|
||||
p(s,"\t\t{ke:name/globals}{:count/%ju} " \
|
||||
"{N:/global%s}\n");\
|
||||
break;\
|
||||
default:\
|
||||
printf("\t\t%ju addresses scope=%x\n",\
|
||||
(uintmax_t)ip6stat.s, i);\
|
||||
xo_emit("\t\t{qke:name/%x}{:count/%ju} " \
|
||||
"addresses scope=%x\n",\
|
||||
i, (uintmax_t)ip6stat.s, i); \
|
||||
}\
|
||||
} while (0);
|
||||
|
||||
p(ip6s_sources_none,
|
||||
"\t%ju failure%s of source address selection\n");
|
||||
xo_open_container("source-address-selection");
|
||||
p(ip6s_sources_none, "\t{:address-selection-failures/%ju} "
|
||||
"{N:/failure%s of source address selection}\n");
|
||||
|
||||
for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
|
||||
if (ip6stat.ip6s_sources_sameif[i]) {
|
||||
if (first) {
|
||||
printf("\tsource addresses on an outgoing I/F\n");
|
||||
xo_open_list("outgoing-interface");
|
||||
xo_emit("\tsource addresses on an outgoing "
|
||||
"I/F\n");
|
||||
first = 0;
|
||||
}
|
||||
xo_open_instance("outgoing-interface");
|
||||
PRINT_SCOPESTAT(ip6s_sources_sameif[i], i);
|
||||
xo_close_instance("outgoing-interface");
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("outgoing-interface");
|
||||
|
||||
for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
|
||||
if (ip6stat.ip6s_sources_otherif[i]) {
|
||||
if (first) {
|
||||
printf("\tsource addresses on a non-outgoing I/F\n");
|
||||
xo_open_list("non-outgoing-interface");
|
||||
xo_emit("\tsource addresses on a non-outgoing "
|
||||
"I/F\n");
|
||||
first = 0;
|
||||
}
|
||||
xo_open_instance("non-outgoing-interface");
|
||||
PRINT_SCOPESTAT(ip6s_sources_otherif[i], i);
|
||||
xo_close_instance("non-outgoing-interface");
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("non-outgoing-interface");
|
||||
|
||||
for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
|
||||
if (ip6stat.ip6s_sources_samescope[i]) {
|
||||
if (first) {
|
||||
printf("\tsource addresses of same scope\n");
|
||||
xo_open_list("same-source");
|
||||
xo_emit("\tsource addresses of same scope\n");
|
||||
first = 0;
|
||||
}
|
||||
xo_open_instance("same-source");
|
||||
PRINT_SCOPESTAT(ip6s_sources_samescope[i], i);
|
||||
xo_close_instance("same-source");
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("same-source");
|
||||
|
||||
for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
|
||||
if (ip6stat.ip6s_sources_otherscope[i]) {
|
||||
if (first) {
|
||||
printf("\tsource addresses of a different scope\n");
|
||||
xo_open_list("different-scope");
|
||||
xo_emit("\tsource addresses of a different "
|
||||
"scope\n");
|
||||
first = 0;
|
||||
}
|
||||
xo_open_instance("different-scope");
|
||||
PRINT_SCOPESTAT(ip6s_sources_otherscope[i], i);
|
||||
xo_close_instance("different-scope");
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("different-scope");
|
||||
|
||||
for (first = 1, i = 0; i < IP6S_SCOPECNT; i++) {
|
||||
if (ip6stat.ip6s_sources_deprecated[i]) {
|
||||
if (first) {
|
||||
printf("\tdeprecated source addresses\n");
|
||||
xo_open_list("deprecated-source");
|
||||
xo_emit("\tdeprecated source addresses\n");
|
||||
first = 0;
|
||||
}
|
||||
xo_open_instance("deprecated-source");
|
||||
PRINT_SCOPESTAT(ip6s_sources_deprecated[i], i);
|
||||
xo_close_instance("deprecated-source");
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("deprecated-source");
|
||||
|
||||
printf("\tSource addresses selection rule applied:\n");
|
||||
for (i = 0; i < IP6S_RULESMAX; i++) {
|
||||
if (ip6stat.ip6s_sources_rule[i])
|
||||
printf("\t\t%ju %s\n",
|
||||
(uintmax_t)ip6stat.ip6s_sources_rule[i],
|
||||
srcrule_str[i]);
|
||||
for (first = 1, i = 0; i < IP6S_RULESMAX; i++) {
|
||||
if (ip6stat.ip6s_sources_rule[i]) {
|
||||
if (first) {
|
||||
xo_open_list("rules-applied");
|
||||
xo_emit("\t{T:Source addresses selection "
|
||||
"rule applied}:\n");
|
||||
first = 0;
|
||||
}
|
||||
xo_open_instance("rules-applied");
|
||||
xo_emit("\t\t{ke:name/%s}{:count/%ju} {d:name/%s}\n",
|
||||
srcrule_str[i],
|
||||
(uintmax_t)ip6stat.ip6s_sources_rule[i],
|
||||
srcrule_str[i]);
|
||||
xo_close_instance("rules-applied");
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("rules-applied");
|
||||
|
||||
xo_close_container("source-address-selection");
|
||||
|
||||
#undef p
|
||||
#undef p1a
|
||||
xo_close_container(name);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -529,52 +624,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");
|
||||
xo_emit("{T:/ip6 on %s}:\n", ifr.ifr_name);
|
||||
|
||||
end:
|
||||
close(s);
|
||||
xo_open_instance("ip6-interface-statistics");
|
||||
xo_emit("{ke:name/%s}", ifr.ifr_name);
|
||||
|
||||
p(ifs6_in_receive, "\t{:received-packets/%ju} "
|
||||
"{N:/total input datagram%s}\n");
|
||||
p(ifs6_in_hdrerr, "\t{:dropped-invalid-header/%ju} "
|
||||
"{N:/datagram%s with invalid header received}\n");
|
||||
p(ifs6_in_toobig, "\t{:dropped-mtu-exceeded/%ju} "
|
||||
"{N:/datagram%s exceeded MTU received}\n");
|
||||
p(ifs6_in_noroute, "\t{:dropped-no-route/%ju} "
|
||||
"{N:/datagram%s with no route received}\n");
|
||||
p(ifs6_in_addrerr, "\t{:dropped-invalid-destination/%ju} "
|
||||
"{N:/datagram%s with invalid dst received}\n");
|
||||
p(ifs6_in_protounknown, "\t{:dropped-unknown-protocol/%ju} "
|
||||
"{N:/datagram%s with unknown proto received}\n");
|
||||
p(ifs6_in_truncated, "\t{:dropped-truncated/%ju} "
|
||||
"{N:/truncated datagram%s received}\n");
|
||||
p(ifs6_in_discard, "\t{:dropped-discarded/%ju} "
|
||||
"{N:/input datagram%s discarded}\n");
|
||||
p(ifs6_in_deliver, "\t{:received-valid-packets/%ju} "
|
||||
"{N:/datagram%s delivered to an upper layer protocol}\n");
|
||||
p(ifs6_out_forward, "\t{:sent-forwarded/%ju} "
|
||||
"{N:/datagram%s forwarded to this interface}\n");
|
||||
p(ifs6_out_request, "\t{:sent-packets/%ju} "
|
||||
"{N:/datagram%s sent from an upper layer protocol}\n");
|
||||
p(ifs6_out_discard, "\t{:discard-packets/%ju} "
|
||||
"{N:/total discarded output datagram%s}\n");
|
||||
p(ifs6_out_fragok, "\t{:discard-fragments/%ju} "
|
||||
"{N:/output datagram%s fragmented}\n");
|
||||
p(ifs6_out_fragfail, "\t{:fragments-failed/%ju} "
|
||||
"{N:/output datagram%s failed on fragment}\n");
|
||||
p(ifs6_out_fragcreat, "\t{:fragments-created/%ju} "
|
||||
"{N:/output datagram%s succeeded on fragment}\n");
|
||||
p(ifs6_reass_reqd, "\t{:reassembly-required/%ju} "
|
||||
"{N:/incoming datagram%s fragmented}\n");
|
||||
p(ifs6_reass_ok, "\t{:reassembled-packets/%ju} "
|
||||
"{N:/datagram%s reassembled}\n");
|
||||
p(ifs6_reass_fail, "\t{:reassembly-failed/%ju} "
|
||||
"{N:/datagram%s failed on reassembly}\n");
|
||||
p(ifs6_in_mcast, "\t{:received-multicast/%ju} "
|
||||
"{N:/multicast datagram%s received}\n");
|
||||
p(ifs6_out_mcast, "\t{:sent-multicast/%ju} "
|
||||
"{N:/multicast datagram%s sent}\n");
|
||||
|
||||
end:
|
||||
xo_close_instance("ip6-interface-statistics");
|
||||
close(s);
|
||||
|
||||
#undef p
|
||||
#undef p_5
|
||||
}
|
||||
|
||||
static const char *icmp6names[] = {
|
||||
@ -854,76 +971,118 @@ icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len,
|
||||
zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: net.inet6.icmp6.stats");
|
||||
xo_warn("sysctl: net.inet6.icmp6.stats");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread_counters(off, &icmp6stat, len);
|
||||
|
||||
printf("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
xo_open_container(name);
|
||||
|
||||
#define p(f, m) if (icmp6stat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
|
||||
xo_emit(m, (uintmax_t)icmp6stat.f, plural(icmp6stat.f))
|
||||
#define p_5(f, m) if (icmp6stat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)icmp6stat.f)
|
||||
xo_emit(m, (uintmax_t)icmp6stat.f)
|
||||
|
||||
p(icp6s_error, "\t%ju call%s to icmp6_error\n");
|
||||
p(icp6s_canterror,
|
||||
"\t%ju error%s not generated in response to an icmp6 message\n");
|
||||
p(icp6s_toofreq,
|
||||
"\t%ju error%s not generated because of rate limitation\n");
|
||||
p(icp6s_error, "\t{:icmp6-calls/%ju} "
|
||||
"{N:/call%s to icmp6_error}\n");
|
||||
p(icp6s_canterror, "\t{:errors-not-generated-from-message/%ju} "
|
||||
"{N:/error%s not generated in response to an icmp6 message}\n");
|
||||
p(icp6s_toofreq, "\t{:errors-discarded-by-rate-limitation/%ju} "
|
||||
"{N:/error%s not generated because of rate limitation}\n");
|
||||
#define NELEM (int)(sizeof(icmp6stat.icp6s_outhist)/sizeof(icmp6stat.icp6s_outhist[0]))
|
||||
for (first = 1, i = 0; i < NELEM; i++)
|
||||
if (icmp6stat.icp6s_outhist[i] != 0) {
|
||||
if (first) {
|
||||
printf("\tOutput histogram:\n");
|
||||
xo_open_list("output-histogram");
|
||||
xo_emit("\t{T:Output histogram}:\n");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t%s: %ju\n", icmp6names[i],
|
||||
xo_open_instance("output-histogram");
|
||||
xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
|
||||
icmp6names[i],
|
||||
(uintmax_t)icmp6stat.icp6s_outhist[i]);
|
||||
xo_close_instance("output-histogram");
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("output-histogram");
|
||||
#undef NELEM
|
||||
p(icp6s_badcode, "\t%ju message%s with bad code fields\n");
|
||||
p(icp6s_tooshort, "\t%ju message%s < minimum length\n");
|
||||
p(icp6s_checksum, "\t%ju bad checksum%s\n");
|
||||
p(icp6s_badlen, "\t%ju message%s with bad length\n");
|
||||
|
||||
p(icp6s_badcode, "\t{:dropped-bad-code/%ju} "
|
||||
"{N:/message%s with bad code fields}\n");
|
||||
p(icp6s_tooshort, "\t{:dropped-too-short/%ju} "
|
||||
"{N:/message%s < minimum length}\n");
|
||||
p(icp6s_checksum, "\t{:dropped-bad-checksum/%ju} "
|
||||
"{N:/bad checksum%s}\n");
|
||||
p(icp6s_badlen, "\t{:dropped-bad-length/%ju} "
|
||||
"{N:/message%s with bad length}\n");
|
||||
#define NELEM (int)(sizeof(icmp6stat.icp6s_inhist)/sizeof(icmp6stat.icp6s_inhist[0]))
|
||||
for (first = 1, i = 0; i < NELEM; i++)
|
||||
if (icmp6stat.icp6s_inhist[i] != 0) {
|
||||
if (first) {
|
||||
printf("\tInput histogram:\n");
|
||||
xo_open_list("input-histogram");
|
||||
xo_emit("\t{T:Input histogram}:\n");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t%s: %ju\n", icmp6names[i],
|
||||
xo_open_instance("input-histogram");
|
||||
xo_emit("\t\t{k:name/%s}: {:count/%ju}\n",
|
||||
icmp6names[i],
|
||||
(uintmax_t)icmp6stat.icp6s_inhist[i]);
|
||||
xo_close_instance("input-histogram");
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list("input-histogram");
|
||||
#undef NELEM
|
||||
printf("\tHistogram of error messages to be generated:\n");
|
||||
p_5(icp6s_odst_unreach_noroute, "\t\t%ju no route\n");
|
||||
p_5(icp6s_odst_unreach_admin, "\t\t%ju administratively prohibited\n");
|
||||
p_5(icp6s_odst_unreach_beyondscope, "\t\t%ju beyond scope\n");
|
||||
p_5(icp6s_odst_unreach_addr, "\t\t%ju address unreachable\n");
|
||||
p_5(icp6s_odst_unreach_noport, "\t\t%ju port unreachable\n");
|
||||
p_5(icp6s_opacket_too_big, "\t\t%ju packet too big\n");
|
||||
p_5(icp6s_otime_exceed_transit, "\t\t%ju time exceed transit\n");
|
||||
p_5(icp6s_otime_exceed_reassembly, "\t\t%ju time exceed reassembly\n");
|
||||
p_5(icp6s_oparamprob_header, "\t\t%ju erroneous header field\n");
|
||||
p_5(icp6s_oparamprob_nextheader, "\t\t%ju unrecognized next header\n");
|
||||
p_5(icp6s_oparamprob_option, "\t\t%ju unrecognized option\n");
|
||||
p_5(icp6s_oredirect, "\t\t%ju redirect\n");
|
||||
p_5(icp6s_ounknown, "\t\t%ju unknown\n");
|
||||
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%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");
|
||||
p(icp6s_reflect, "\t{:reflect/%ju} "
|
||||
"{N:/message response%s generated}\n");
|
||||
p(icp6s_nd_toomanyopt, "\t{:too-many-nd-options/%ju} "
|
||||
"{N:/message%s with too many ND options}\n");
|
||||
p(icp6s_nd_badopt, "\t{:bad-nd-options/%ju} "
|
||||
"{N:/message%s with bad ND options}\n");
|
||||
p(icp6s_badns, "\t{:bad-neighbor-solicitation/%ju} "
|
||||
"{N:/bad neighbor solicitation message%s}\n");
|
||||
p(icp6s_badna, "\t{:bad-neighbor-advertisement/%ju} "
|
||||
"{N:/bad neighbor advertisement message%s}\n");
|
||||
p(icp6s_badrs, "\t{:bad-router-solicitation/%ju} "
|
||||
"{N:/bad router solicitation message%s}\n");
|
||||
p(icp6s_badra, "\t{:bad-router-advertisement/%ju} "
|
||||
"{N:/bad router advertisement message%s}\n");
|
||||
p(icp6s_badredirect, "\t{:bad-redirect/%ju} "
|
||||
"{N:/bad redirect message%s}\n");
|
||||
xo_close_container("errors");
|
||||
p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n");
|
||||
#undef p
|
||||
#undef p_5
|
||||
xo_close_container(name);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -934,61 +1093,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");
|
||||
xo_emit("{T:/icmp6 on %s}:\n", ifr.ifr_name);
|
||||
|
||||
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");
|
||||
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");
|
||||
|
||||
end:
|
||||
p(ifs6_out_msg, "\t{:sent-packets/%ju} "
|
||||
"{N:/total output message%s}\n");
|
||||
p(ifs6_out_error, "\t{:sent-errors/%ju} "
|
||||
"{N:/total output error message%s}\n");
|
||||
p(ifs6_out_dstunreach, "\t{:sent-destination-unreachable/%ju} "
|
||||
"{N:/output destination unreachable error%s}\n");
|
||||
p(ifs6_out_adminprohib, "\t{:sent-admin-prohibited/%ju} "
|
||||
"{N:/output administratively prohibited error%s}\n");
|
||||
p(ifs6_out_timeexceed, "\t{:sent-time-exceeded/%ju} "
|
||||
"{N:/output time exceeded error%s}\n");
|
||||
p(ifs6_out_paramprob, "\t{:sent-bad-parameter/%ju} "
|
||||
"{N:/output parameter problem error%s}\n");
|
||||
p(ifs6_out_pkttoobig, "\t{:sent-packet-too-big/%ju} "
|
||||
"{N:/output packet too big error%s}\n");
|
||||
p(ifs6_out_echo, "\t{:sent-echo-requests/%ju} "
|
||||
"{N:/output echo request%s}\n");
|
||||
p2(ifs6_out_echoreply, "\t{:sent-echo-replies/%ju} "
|
||||
"{N:/output echo repl%s}\n");
|
||||
p(ifs6_out_routersolicit, "\t{:sent-router-solicitation/%ju} "
|
||||
"{N:/output router solicitation%s}\n");
|
||||
p(ifs6_out_routeradvert, "\t{:sent-router-advertisement/%ju} "
|
||||
"{N:/output router advertisement%s}\n");
|
||||
p(ifs6_out_neighborsolicit, "\t{:sent-neighbor-solicitation/%ju} "
|
||||
"{N:/output neighbor solicitation%s}\n");
|
||||
p(ifs6_out_neighboradvert, "\t{:sent-neighbor-advertisement/%ju} "
|
||||
"{N:/output neighbor advertisement%s}\n");
|
||||
p(ifs6_out_redirect, "\t{:sent-redirects/%ju} "
|
||||
"{N:/output redirect%s}\n");
|
||||
p2(ifs6_out_mldquery, "\t{:sent-mld-queries/%ju} "
|
||||
"{N:/output MLD quer%s}\n");
|
||||
p(ifs6_out_mldreport, "\t{:sent-mld-reports/%ju} "
|
||||
"{N:/output MLD report%s}\n");
|
||||
p(ifs6_out_mlddone, "\t{:sent-mld-dones/%ju} "
|
||||
"{N:/output MLD done%s}\n");
|
||||
|
||||
end:
|
||||
xo_close_instance("icmp6-interface-statistics");
|
||||
close(s);
|
||||
#undef p
|
||||
}
|
||||
@ -1008,7 +1208,7 @@ pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len,
|
||||
zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: net.inet6.pim.stats");
|
||||
xo_warn("sysctl: net.inet6.pim.stats");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@ -1017,18 +1217,28 @@ pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
kread(off, &pim6stat, len);
|
||||
}
|
||||
|
||||
printf("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
xo_open_container(name);
|
||||
|
||||
#define p(f, m) if (pim6stat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
|
||||
p(pim6s_rcv_total, "\t%ju message%s received\n");
|
||||
p(pim6s_rcv_tooshort, "\t%ju message%s received with too few bytes\n");
|
||||
p(pim6s_rcv_badsum, "\t%ju message%s received with bad checksum\n");
|
||||
p(pim6s_rcv_badversion, "\t%ju message%s received with bad version\n");
|
||||
p(pim6s_rcv_registers, "\t%ju register%s received\n");
|
||||
p(pim6s_rcv_badregisters, "\t%ju bad register%s received\n");
|
||||
p(pim6s_snd_registers, "\t%ju register%s sent\n");
|
||||
xo_emit(m, (uintmax_t)pim6stat.f, plural(pim6stat.f))
|
||||
|
||||
p(pim6s_rcv_total, "\t{:received-packets/%ju} "
|
||||
"{N:/message%s received}\n");
|
||||
p(pim6s_rcv_tooshort, "\t{:dropped-too-short/%ju} "
|
||||
"{N:/message%s received with too few bytes}\n");
|
||||
p(pim6s_rcv_badsum, "\t{:dropped-bad-checksum/%ju} "
|
||||
"{N:/message%s received with bad checksum}\n");
|
||||
p(pim6s_rcv_badversion, "\t{:dropped-bad-version/%ju} "
|
||||
"{N:/message%s received with bad version}\n");
|
||||
p(pim6s_rcv_registers, "\t{:received-registers/%ju} "
|
||||
"{N:/register%s received}\n");
|
||||
p(pim6s_rcv_badregisters, "\t{:received-bad-registers/%ju} "
|
||||
"{N:/bad register%s received}\n");
|
||||
p(pim6s_snd_registers, "\t{:sent-registers/%ju} "
|
||||
"{N:/register%s sent}\n");
|
||||
#undef p
|
||||
xo_close_container(name);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1048,33 +1258,42 @@ rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len,
|
||||
zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: net.inet6.ip6.rip6stats");
|
||||
xo_warn("sysctl: net.inet6.ip6.rip6stats");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread_counters(off, &rip6stat, len);
|
||||
|
||||
printf("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
xo_open_container(name);
|
||||
|
||||
#define p(f, m) if (rip6stat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
|
||||
p(rip6s_ipackets, "\t%ju message%s received\n");
|
||||
p(rip6s_isum, "\t%ju checksum calculation%s on inbound\n");
|
||||
p(rip6s_badsum, "\t%ju message%s with bad checksum\n");
|
||||
p(rip6s_nosock, "\t%ju message%s dropped due to no socket\n");
|
||||
p(rip6s_nosockmcast,
|
||||
"\t%ju multicast message%s dropped due to no socket\n");
|
||||
p(rip6s_fullsock,
|
||||
"\t%ju message%s dropped due to full socket buffers\n");
|
||||
xo_emit(m, (uintmax_t)rip6stat.f, plural(rip6stat.f))
|
||||
|
||||
p(rip6s_ipackets, "\t{:received-packets/%ju} "
|
||||
"{N:/message%s received}\n");
|
||||
p(rip6s_isum, "\t{:input-checksum-computation/%ju} "
|
||||
"{N:/checksum calculation%s on inbound}\n");
|
||||
p(rip6s_badsum, "\t{:received-bad-checksum/%ju} "
|
||||
"{N:/message%s with bad checksum}\n");
|
||||
p(rip6s_nosock, "\t{:dropped-no-socket/%ju} "
|
||||
"{N:/message%s dropped due to no socket}\n");
|
||||
p(rip6s_nosockmcast, "\t{:dropped-multicast-no-socket/%ju} "
|
||||
"{N:/multicast message%s dropped due to no socket}\n");
|
||||
p(rip6s_fullsock, "\t{:dropped-full-socket-buffer/%ju} "
|
||||
"{N:/message%s dropped due to full socket buffers}\n");
|
||||
delivered = rip6stat.rip6s_ipackets -
|
||||
rip6stat.rip6s_badsum -
|
||||
rip6stat.rip6s_nosock -
|
||||
rip6stat.rip6s_nosockmcast -
|
||||
rip6stat.rip6s_fullsock;
|
||||
if (delivered || sflag <= 1)
|
||||
printf("\t%ju delivered\n", (uintmax_t)delivered);
|
||||
p(rip6s_opackets, "\t%ju datagram%s output\n");
|
||||
xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n",
|
||||
(uintmax_t)delivered);
|
||||
p(rip6s_opackets, "\t{:sent-packets/%ju} "
|
||||
"{N:/datagram%s output}\n");
|
||||
#undef p
|
||||
xo_close_container(name);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1092,14 +1311,18 @@ rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
};
|
||||
|
||||
void
|
||||
inet6print(struct in6_addr *in6, int port, const char *proto, int numeric)
|
||||
inet6print(const char *container, struct in6_addr *in6, int port,
|
||||
const char *proto, int numeric)
|
||||
{
|
||||
struct servent *sp = 0;
|
||||
char line[80], *cp;
|
||||
int width;
|
||||
|
||||
sprintf(line, "%.*s.", Wflag ? 39 :
|
||||
(Aflag && !numeric) ? 12 : 16, inet6name(in6));
|
||||
if (container)
|
||||
xo_open_container(container);
|
||||
|
||||
sprintf(line, "%.*s.", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
|
||||
inet6name(in6));
|
||||
cp = strchr(line, '\0');
|
||||
if (!numeric && port)
|
||||
GETSERVBYPORT6(port, proto, sp);
|
||||
@ -1108,7 +1331,15 @@ inet6print(struct in6_addr *in6, int port, const char *proto, int numeric)
|
||||
else
|
||||
sprintf(cp, "%d", ntohs((u_short)port));
|
||||
width = Wflag ? 45 : Aflag ? 18 : 22;
|
||||
printf("%-*.*s ", width, width, line);
|
||||
|
||||
xo_emit("{d:target/%-*.*s} ", width, width, line);
|
||||
|
||||
int alen = cp - line - 1, plen = strlen(cp) - 1;
|
||||
xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
|
||||
plen, cp);
|
||||
|
||||
if (container)
|
||||
xo_close_container(container);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1142,7 +1373,7 @@ inet6name(struct in6_addr *in6p)
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
/* XXX: in6p.s6_addr[2] can contain scopeid. */
|
||||
/* XXX: in6p.s6_addr[2] can contain scopeid. */
|
||||
in6_fillscopeid(&sin6);
|
||||
flags = (numeric_addr) ? NI_NUMERICHOST : 0;
|
||||
error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
|
||||
|
@ -107,8 +107,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
#ifdef IPSEC
|
||||
@ -171,27 +173,39 @@ static void print_ipsecstats(const struct ipsecstat *ipsecstat);
|
||||
static void
|
||||
print_ipsecstats(const struct ipsecstat *ipsecstat)
|
||||
{
|
||||
xo_open_container("ipsec-statistics");
|
||||
|
||||
#define p(f, m) if (ipsecstat->f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f))
|
||||
p(ips_in_polvio, "\t%ju inbound packet%s violated process "
|
||||
"security policy\n");
|
||||
p(ips_in_nomem, "\t%ju inbound packet%s failed due to "
|
||||
"insufficient memory\n");
|
||||
p(ips_in_inval, "\t%ju invalid inbound packet%s\n");
|
||||
p(ips_out_polvio, "\t%ju outbound packet%s violated process "
|
||||
"security policy\n");
|
||||
p(ips_out_nosa, "\t%ju outbound packet%s with no SA available\n");
|
||||
p(ips_out_nomem, "\t%ju outbound packet%s failed due to "
|
||||
"insufficient memory\n");
|
||||
p(ips_out_noroute, "\t%ju outbound packet%s with no route "
|
||||
"available\n");
|
||||
p(ips_out_inval, "\t%ju invalid outbound packet%s\n");
|
||||
p(ips_out_bundlesa, "\t%ju outbound packet%s with bundled SAs\n");
|
||||
p(ips_mbcoalesced, "\t%ju mbuf%s coalesced during clone\n");
|
||||
p(ips_clcoalesced, "\t%ju cluster%s coalesced during clone\n");
|
||||
p(ips_clcopied, "\t%ju cluster%s copied during clone\n");
|
||||
p(ips_mbinserted, "\t%ju mbuf%s inserted during makespace\n");
|
||||
xo_emit(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f))
|
||||
|
||||
p(ips_in_polvio, "\t{:dropped-policy-violation/%ju} "
|
||||
"{N:/inbound packet%s violated process security policy}\n");
|
||||
p(ips_in_nomem, "\t{:dropped-no-memory/%ju} "
|
||||
"{N:/inbound packet%s failed due to insufficient memory}\n");
|
||||
p(ips_in_inval, "\t{:dropped-invalid/%ju} "
|
||||
"{N:/invalid inbound packet%s}\n");
|
||||
p(ips_out_polvio, "\t{:discarded-policy-violation/%ju} "
|
||||
"{N:/outbound packet%s violated process security policy}\n");
|
||||
p(ips_out_nosa, "\t{:discarded-no-sa/%ju} "
|
||||
"{N:/outbound packet%s with no SA available}\n");
|
||||
p(ips_out_nomem, "\t{:discarded-no-memory/%ju} "
|
||||
"{N:/outbound packet%s failed due to insufficient memory}\n");
|
||||
p(ips_out_noroute, "\t{:discarded-no-route/%ju} "
|
||||
"{N:/outbound packet%s with no route available}\n");
|
||||
p(ips_out_inval, "\t{:discarded-invalid/%ju} "
|
||||
"{N:/invalid outbound packet%s}\n");
|
||||
p(ips_out_bundlesa, "\t{:send-bundled-sa/%ju} "
|
||||
"{N:/outbound packet%s with bundled SAs}\n");
|
||||
p(ips_mbcoalesced, "\t{:mbufs-coalesced-during-clone/%ju} "
|
||||
"{N:/mbuf%s coalesced during clone}\n");
|
||||
p(ips_clcoalesced, "\t{:clusters-coalesced-during-clone/%ju} "
|
||||
"{N:/cluster%s coalesced during clone}\n");
|
||||
p(ips_clcopied, "\t{:clusters-copied-during-clone/%ju} "
|
||||
"{N:/cluster%s copied during clone}\n");
|
||||
p(ips_mbinserted, "\t{:mbufs-inserted/%ju} "
|
||||
"{N:/mbuf%s inserted during makespace}\n");
|
||||
#undef p
|
||||
xo_close_container("ipsec-statistics");
|
||||
}
|
||||
|
||||
void
|
||||
@ -201,15 +215,13 @@ ipsec_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
kread_counters(off, (char *)&ipsecstat, sizeof(ipsecstat));
|
||||
|
||||
print_ipsecstats(&ipsecstat);
|
||||
}
|
||||
|
||||
|
||||
static void ipsec_hist_new(const uint64_t *hist, size_t histmax,
|
||||
const struct val2str *name, const char *title);
|
||||
static void print_ahstats(const struct ahstat *ahstat);
|
||||
static void print_espstats(const struct espstat *espstat);
|
||||
static void print_ipcompstats(const struct ipcompstat *ipcompstat);
|
||||
@ -219,7 +231,7 @@ static void print_ipcompstats(const struct ipcompstat *ipcompstat);
|
||||
*/
|
||||
static void
|
||||
ipsec_hist_new(const uint64_t *hist, size_t histmax,
|
||||
const struct val2str *name, const char *title)
|
||||
const struct val2str *name, const char *title, const char *cname)
|
||||
{
|
||||
int first;
|
||||
size_t proto;
|
||||
@ -230,54 +242,72 @@ ipsec_hist_new(const uint64_t *hist, size_t histmax,
|
||||
if (hist[proto] <= 0)
|
||||
continue;
|
||||
if (first) {
|
||||
printf("\t%s histogram:\n", title);
|
||||
xo_open_list(cname);
|
||||
xo_emit("\t{T:/%s histogram}:\n", title);
|
||||
first = 0;
|
||||
}
|
||||
xo_open_instance(cname);
|
||||
for (p = name; p && p->str; p++) {
|
||||
if (p->val == (int)proto)
|
||||
break;
|
||||
}
|
||||
if (p && p->str) {
|
||||
printf("\t\t%s: %ju\n", p->str,
|
||||
xo_emit("\t\t{k:name}: {:count/%ju}\n", p->str,
|
||||
(uintmax_t)hist[proto]);
|
||||
} else {
|
||||
printf("\t\t#%lu: %ju\n", (unsigned long)proto,
|
||||
(uintmax_t)hist[proto]);
|
||||
xo_emit("\t\t#{k:name/%lu}: {:count/%ju}\n",
|
||||
(unsigned long)proto, (uintmax_t)hist[proto]);
|
||||
}
|
||||
xo_close_instance(cname);
|
||||
}
|
||||
if (!first)
|
||||
xo_close_list(cname);
|
||||
}
|
||||
|
||||
static void
|
||||
print_ahstats(const struct ahstat *ahstat)
|
||||
{
|
||||
#define p(f, m) if (ahstat->f || sflag <= 1) \
|
||||
printf("\t%ju" m, (uintmax_t)ahstat->f, plural(ahstat->f))
|
||||
#define hist(f, n, t) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
|
||||
xo_open_container("ah-statictics");
|
||||
|
||||
p(ahs_hdrops, " packet%s shorter than header shows\n");
|
||||
p(ahs_nopf, " packet%s dropped; protocol family not supported\n");
|
||||
p(ahs_notdb, " packet%s dropped; no TDB\n");
|
||||
p(ahs_badkcr, " packet%s dropped; bad KCR\n");
|
||||
p(ahs_qfull, " packet%s dropped; queue full\n");
|
||||
p(ahs_noxform, " packet%s dropped; no transform\n");
|
||||
p(ahs_wrap, " replay counter wrap%s\n");
|
||||
p(ahs_badauth, " packet%s dropped; bad authentication detected\n");
|
||||
p(ahs_badauthl, " packet%s dropped; bad authentication length\n");
|
||||
p(ahs_replay, " possible replay packet%s detected\n");
|
||||
p(ahs_input, " packet%s in\n");
|
||||
p(ahs_output, " packet%s out\n");
|
||||
p(ahs_invalid, " packet%s dropped; invalid TDB\n");
|
||||
p(ahs_ibytes, " byte%s in\n");
|
||||
p(ahs_obytes, " byte%s out\n");
|
||||
p(ahs_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
|
||||
p(ahs_pdrops, " packet%s blocked due to policy\n");
|
||||
p(ahs_crypto, " crypto processing failure%s\n");
|
||||
p(ahs_tunnel, " tunnel sanity check failure%s\n");
|
||||
hist(ahstat->ahs_hist, ipsec_ahnames, "AH output");
|
||||
#define p(f, n, m) if (ahstat->f || sflag <= 1) \
|
||||
xo_emit("\t{:" n "/%ju} {N:/" m "}\n", \
|
||||
(uintmax_t)ahstat->f, plural(ahstat->f))
|
||||
#define hist(f, n, t, c) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t), (c))
|
||||
|
||||
p(ahs_hdrops, "dropped-short-header",
|
||||
"packet%s shorter than header shows");
|
||||
p(ahs_nopf, "dropped-bad-protocol",
|
||||
"packet%s dropped; protocol family not supported");
|
||||
p(ahs_notdb, "dropped-no-tdb", "packet%s dropped; no TDB");
|
||||
p(ahs_badkcr, "dropped-bad-kcr", "packet%s dropped; bad KCR");
|
||||
p(ahs_qfull, "dropped-queue-full", "packet%s dropped; queue full");
|
||||
p(ahs_noxform, "dropped-no-transform",
|
||||
"packet%s dropped; no transform");
|
||||
p(ahs_wrap, "replay-counter-wraps", "replay counter wrap%s");
|
||||
p(ahs_badauth, "dropped-bad-auth",
|
||||
"packet%s dropped; bad authentication detected");
|
||||
p(ahs_badauthl, "dropped-bad-auth-level",
|
||||
"packet%s dropped; bad authentication length");
|
||||
p(ahs_replay, "possile-replay-detected",
|
||||
"possible replay packet%s detected");
|
||||
p(ahs_input, "received-packets", "packet%s in");
|
||||
p(ahs_output, "send-packets", "packet%s out");
|
||||
p(ahs_invalid, "dropped-bad-tdb", "packet%s dropped; invalid TDB");
|
||||
p(ahs_ibytes, "received-bytes", "byte%s in");
|
||||
p(ahs_obytes, "send-bytes", "byte%s out");
|
||||
p(ahs_toobig, "dropped-too-large",
|
||||
"packet%s dropped; larger than IP_MAXPACKET");
|
||||
p(ahs_pdrops, "dropped-policy-violation",
|
||||
"packet%s blocked due to policy");
|
||||
p(ahs_crypto, "crypto-failures", "crypto processing failure%s");
|
||||
p(ahs_tunnel, "tunnel-failures", "tunnel sanity check failure%s");
|
||||
hist(ahstat->ahs_hist, ipsec_ahnames,
|
||||
"AH output", "ah-output-histogram");
|
||||
|
||||
#undef p
|
||||
#undef hist
|
||||
xo_close_container("ah-statictics");
|
||||
}
|
||||
|
||||
void
|
||||
@ -287,7 +317,7 @@ ah_stats(u_long off, const char *name, int family __unused, int proto __unused)
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
kread_counters(off, (char *)&ahstat, sizeof(ahstat));
|
||||
|
||||
print_ahstats(&ahstat);
|
||||
@ -296,35 +326,47 @@ ah_stats(u_long off, const char *name, int family __unused, int proto __unused)
|
||||
static void
|
||||
print_espstats(const struct espstat *espstat)
|
||||
{
|
||||
#define p(f, m) if (espstat->f || sflag <= 1) \
|
||||
printf("\t%ju" m, (uintmax_t)espstat->f, plural(espstat->f))
|
||||
#define hist(f, n, t) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
|
||||
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, " packet%s shorter than header shows\n");
|
||||
p(esps_nopf, " packet%s dropped; protocol family not supported\n");
|
||||
p(esps_notdb, " packet%s dropped; no TDB\n");
|
||||
p(esps_badkcr, " packet%s dropped; bad KCR\n");
|
||||
p(esps_qfull, " packet%s dropped; queue full\n");
|
||||
p(esps_noxform, " packet%s dropped; no transform\n");
|
||||
p(esps_badilen, " packet%s dropped; bad ilen\n");
|
||||
p(esps_wrap, " replay counter wrap%s\n");
|
||||
p(esps_badenc, " packet%s dropped; bad encryption detected\n");
|
||||
p(esps_badauth, " packet%s dropped; bad authentication detected\n");
|
||||
p(esps_replay, " possible replay packet%s detected\n");
|
||||
p(esps_input, " packet%s in\n");
|
||||
p(esps_output, " packet%s out\n");
|
||||
p(esps_invalid, " packet%s dropped; invalid TDB\n");
|
||||
p(esps_ibytes, " byte%s in\n");
|
||||
p(esps_obytes, " byte%s out\n");
|
||||
p(esps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
|
||||
p(esps_pdrops, " packet%s blocked due to policy\n");
|
||||
p(esps_crypto, " crypto processing failure%s\n");
|
||||
p(esps_tunnel, " tunnel sanity check failure%s\n");
|
||||
hist(espstat->esps_hist, ipsec_espnames, "ESP output");
|
||||
p(esps_hdrops, "dropped-short-header",
|
||||
"packet%s shorter than header shows");
|
||||
p(esps_nopf, "dropped-bad-protocol",
|
||||
"packet%s dropped; protocol family not supported");
|
||||
p(esps_notdb, "dropped-no-tdb", "packet%s dropped; no TDB");
|
||||
p(esps_badkcr, "dropped-bad-kcr", "packet%s dropped; bad KCR");
|
||||
p(esps_qfull, "dropped-queue-full", "packet%s dropped; queue full");
|
||||
p(esps_noxform, "dropped-no-transform",
|
||||
"packet%s dropped; no transform");
|
||||
p(esps_badilen, "dropped-bad-length", "packet%s dropped; bad ilen");
|
||||
p(esps_wrap, "replay-counter-wraps", "replay counter wrap%s");
|
||||
p(esps_badenc, "dropped-bad-crypto",
|
||||
"packet%s dropped; bad encryption detected");
|
||||
p(esps_badauth, "dropped-bad-auth",
|
||||
"packet%s dropped; bad authentication detected");
|
||||
p(esps_replay, "possible-replay-detected",
|
||||
"possible replay packet%s detected");
|
||||
p(esps_input, "received-packets", "packet%s in");
|
||||
p(esps_output, "sent-packets", "packet%s out");
|
||||
p(esps_invalid, "dropped-bad-tdb", "packet%s dropped; invalid TDB");
|
||||
p(esps_ibytes, "receieve-bytes", "byte%s in");
|
||||
p(esps_obytes, "sent-bytes", "byte%s out");
|
||||
p(esps_toobig, "dropped-too-large",
|
||||
"packet%s dropped; larger than IP_MAXPACKET");
|
||||
p(esps_pdrops, "dropped-policy-violation",
|
||||
"packet%s blocked due to policy");
|
||||
p(esps_crypto, "crypto-failures", "crypto processing failure%s");
|
||||
p(esps_tunnel, "tunnel-failures", "tunnel sanity check failure%s");
|
||||
hist(espstat->esps_hist, ipsec_espnames,
|
||||
"ESP output", "esp-output-histogram");
|
||||
|
||||
#undef p
|
||||
#undef hist
|
||||
xo_close_container("esp-statictics");
|
||||
}
|
||||
|
||||
void
|
||||
@ -334,7 +376,7 @@ esp_stats(u_long off, const char *name, int family __unused, int proto __unused)
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
kread_counters(off, (char *)&espstat, sizeof(espstat));
|
||||
|
||||
print_espstats(&espstat);
|
||||
@ -343,32 +385,44 @@ esp_stats(u_long off, const char *name, int family __unused, int proto __unused)
|
||||
static void
|
||||
print_ipcompstats(const struct ipcompstat *ipcompstat)
|
||||
{
|
||||
#define p(f, m) if (ipcompstat->f || sflag <= 1) \
|
||||
printf("\t%ju" m, (uintmax_t)ipcompstat->f, plural(ipcompstat->f))
|
||||
#define hist(f, n, t) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
|
||||
xo_open_container("ipcomp-statictics");
|
||||
|
||||
p(ipcomps_hdrops, " packet%s shorter than header shows\n");
|
||||
p(ipcomps_nopf, " packet%s dropped; protocol family not supported\n");
|
||||
p(ipcomps_notdb, " packet%s dropped; no TDB\n");
|
||||
p(ipcomps_badkcr, " packet%s dropped; bad KCR\n");
|
||||
p(ipcomps_qfull, " packet%s dropped; queue full\n");
|
||||
p(ipcomps_noxform, " packet%s dropped; no transform\n");
|
||||
p(ipcomps_wrap, " replay counter wrap%s\n");
|
||||
p(ipcomps_input, " packet%s in\n");
|
||||
p(ipcomps_output, " packet%s out\n");
|
||||
p(ipcomps_invalid, " packet%s dropped; invalid TDB\n");
|
||||
p(ipcomps_ibytes, " byte%s in\n");
|
||||
p(ipcomps_obytes, " byte%s out\n");
|
||||
p(ipcomps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
|
||||
p(ipcomps_pdrops, " packet%s blocked due to policy\n");
|
||||
p(ipcomps_crypto, " crypto processing failure%s\n");
|
||||
hist(ipcompstat->ipcomps_hist, ipsec_compnames, "COMP output");
|
||||
p(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n");
|
||||
p(ipcomps_uncompr, " packet%s sent uncompressed; compression was useless\n");
|
||||
#define p(f, n, m) if (ipcompstat->f || sflag <= 1) \
|
||||
xo_emit("\t{:" n "/%ju} {N:/" m "}\n", \
|
||||
(uintmax_t)ipcompstat->f, plural(ipcompstat->f))
|
||||
#define hist(f, n, t, c) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t), (c));
|
||||
|
||||
p(ipcomps_hdrops, "dropped-short-header",
|
||||
"packet%s shorter than header shows");
|
||||
p(ipcomps_nopf, "dropped-bad-protocol",
|
||||
"packet%s dropped; protocol family not supported");
|
||||
p(ipcomps_notdb, "dropped-no-tdb", "packet%s dropped; no TDB");
|
||||
p(ipcomps_badkcr, "dropped-bad-kcr", "packet%s dropped; bad KCR");
|
||||
p(ipcomps_qfull, "dropped-queue-full", "packet%s dropped; queue full");
|
||||
p(ipcomps_noxform, "dropped-no-transform",
|
||||
"packet%s dropped; no transform");
|
||||
p(ipcomps_wrap, "replay-counter-wraps", "replay counter wrap%s");
|
||||
p(ipcomps_input, "receieve-packets", "packet%s in");
|
||||
p(ipcomps_output, "sent-packets", "packet%s out");
|
||||
p(ipcomps_invalid, "dropped-bad-tdb", "packet%s dropped; invalid TDB");
|
||||
p(ipcomps_ibytes, "receieved-bytes", "byte%s in");
|
||||
p(ipcomps_obytes, "sent-bytes", "byte%s out");
|
||||
p(ipcomps_toobig, "dropped-too-large",
|
||||
"packet%s dropped; larger than IP_MAXPACKET");
|
||||
p(ipcomps_pdrops, "dropped-policy-violation",
|
||||
"packet%s blocked due to policy");
|
||||
p(ipcomps_crypto, "crypto-failure", "crypto processing failure%s");
|
||||
hist(ipcompstat->ipcomps_hist, ipsec_compnames,
|
||||
"COMP output", "comp-output-histogram");
|
||||
p(ipcomps_threshold, "sent-uncompressed-small-packets",
|
||||
"packet%s sent uncompressed; size < compr. algo. threshold");
|
||||
p(ipcomps_uncompr, "sent-uncompressed-useless-packets",
|
||||
"packet%s sent uncompressed; compression was useless");
|
||||
|
||||
#undef p
|
||||
#undef hist
|
||||
xo_close_container("ipcomp-statictics");
|
||||
}
|
||||
|
||||
void
|
||||
@ -379,7 +433,7 @@ ipcomp_stats(u_long off, const char *name, int family __unused,
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
kread_counters(off, (char *)&ipcompstat, sizeof(ipcompstat));
|
||||
|
||||
print_ipcompstats(&ipcompstat);
|
||||
|
@ -65,9 +65,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "netstat.h"
|
||||
#include <libxo/xo.h>
|
||||
|
||||
static struct nlist nl[] = {
|
||||
#define N_RTSTAT 0
|
||||
@ -146,7 +148,7 @@ static struct nlist nl[] = {
|
||||
{ .n_name = "_sctpstat" },
|
||||
#define N_MFCTABLESIZE 37
|
||||
{ .n_name = "_mfctablesize" },
|
||||
#define N_ARPSTAT 38
|
||||
#define N_ARPSTAT 38
|
||||
{ .n_name = "_arpstat" },
|
||||
#define N_UNP_SPHEAD 39
|
||||
{ .n_name = "unp_sphead" },
|
||||
@ -271,7 +273,7 @@ struct protox *protoprotox[] = {
|
||||
#endif
|
||||
NULL };
|
||||
|
||||
static void printproto(struct protox *, const char *);
|
||||
static void printproto(struct protox *, const char *, bool *);
|
||||
static void usage(void);
|
||||
static struct protox *name2protox(const char *);
|
||||
static struct protox *knownname(const char *);
|
||||
@ -317,9 +319,12 @@ main(int argc, char *argv[])
|
||||
int ch;
|
||||
int fib = -1;
|
||||
char *endptr;
|
||||
bool first = true;
|
||||
|
||||
af = AF_UNSPEC;
|
||||
|
||||
argc = xo_parse_args(argc, argv);
|
||||
|
||||
while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz"))
|
||||
!= -1)
|
||||
switch(ch) {
|
||||
@ -356,7 +361,7 @@ main(int argc, char *argv[])
|
||||
fib = strtol(optarg, &endptr, 0);
|
||||
if (*endptr != '\0' ||
|
||||
(fib == 0 && (errno == EINVAL || errno == ERANGE)))
|
||||
errx(1, "%s: invalid fib", optarg);
|
||||
xo_errx(1, "%s: invalid fib", optarg);
|
||||
break;
|
||||
case 'f':
|
||||
if (strcmp(optarg, "inet") == 0)
|
||||
@ -379,7 +384,8 @@ main(int argc, char *argv[])
|
||||
else if (strcmp(optarg, "link") == 0)
|
||||
af = AF_LINK;
|
||||
else {
|
||||
errx(1, "%s: unknown address family", optarg);
|
||||
xo_errx(1, "%s: unknown address family",
|
||||
optarg);
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
@ -417,9 +423,8 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
case 'p':
|
||||
if ((tp = name2protox(optarg)) == NULL) {
|
||||
errx(1,
|
||||
"%s: unknown or uninstrumented protocol",
|
||||
optarg);
|
||||
xo_errx(1, "%s: unknown or uninstrumented "
|
||||
"protocol", optarg);
|
||||
}
|
||||
pflag = 1;
|
||||
break;
|
||||
@ -496,13 +501,14 @@ main(int argc, char *argv[])
|
||||
if (!live)
|
||||
setgid(getgid());
|
||||
|
||||
if (xflag && Tflag)
|
||||
errx(1, "-x and -T are incompatible, pick one.");
|
||||
if (xflag && Tflag)
|
||||
xo_errx(1, "-x and -T are incompatible, pick one.");
|
||||
|
||||
if (Bflag) {
|
||||
if (!live)
|
||||
usage();
|
||||
bpf_stats(interface);
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
if (mflag) {
|
||||
@ -511,6 +517,7 @@ main(int argc, char *argv[])
|
||||
mbpr(kvmd, nl[N_SFSTAT].n_value);
|
||||
} else
|
||||
mbpr(NULL, 0);
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
if (Qflag) {
|
||||
@ -519,6 +526,7 @@ main(int argc, char *argv[])
|
||||
netisr_stats(kvmd);
|
||||
} else
|
||||
netisr_stats(NULL);
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
#if 0
|
||||
@ -536,19 +544,26 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
#endif
|
||||
if (iflag && !sflag) {
|
||||
xo_open_container("statistics");
|
||||
intpr(interval, NULL, af);
|
||||
xo_close_container("statistics");
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
if (rflag) {
|
||||
xo_open_container("statistics");
|
||||
if (sflag) {
|
||||
rt_stats();
|
||||
flowtable_stats();
|
||||
} else
|
||||
routepr(fib, af);
|
||||
xo_close_container("statistics");
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (gflag) {
|
||||
xo_open_container("statistics");
|
||||
if (sflag) {
|
||||
if (af == AF_INET || af == AF_UNSPEC)
|
||||
mrt_stats();
|
||||
@ -564,6 +579,8 @@ main(int argc, char *argv[])
|
||||
mroute6pr();
|
||||
#endif
|
||||
}
|
||||
xo_close_container("statistics");
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -571,31 +588,43 @@ main(int argc, char *argv[])
|
||||
kresolve_list(nl);
|
||||
|
||||
if (tp) {
|
||||
printproto(tp, tp->pr_name);
|
||||
xo_open_container("statistics");
|
||||
printproto(tp, tp->pr_name, &first);
|
||||
if (!first)
|
||||
xo_close_list("socket");
|
||||
xo_close_container("statistics");
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
xo_open_container("statistics");
|
||||
if (af == AF_INET || af == AF_UNSPEC)
|
||||
for (tp = protox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
printproto(tp, tp->pr_name, &first);
|
||||
#ifdef INET6
|
||||
if (af == AF_INET6 || af == AF_UNSPEC)
|
||||
for (tp = ip6protox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
printproto(tp, tp->pr_name, &first);
|
||||
#endif /*INET6*/
|
||||
#ifdef IPSEC
|
||||
if (af == PF_KEY || af == AF_UNSPEC)
|
||||
for (tp = pfkeyprotox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
printproto(tp, tp->pr_name, &first);
|
||||
#endif /*IPSEC*/
|
||||
#ifdef NETGRAPH
|
||||
if (af == AF_NETGRAPH || af == AF_UNSPEC)
|
||||
for (tp = netgraphprotox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
printproto(tp, tp->pr_name, &first);
|
||||
#endif /* NETGRAPH */
|
||||
if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
|
||||
unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value,
|
||||
nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value,
|
||||
nl[N_UNP_SPHEAD].n_value);
|
||||
nl[N_UNP_SPHEAD].n_value, &first);
|
||||
|
||||
if (!first)
|
||||
xo_close_list("socket");
|
||||
xo_close_container("statistics");
|
||||
xo_finish();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -605,24 +634,25 @@ main(int argc, char *argv[])
|
||||
* is not in the namelist, ignore this one.
|
||||
*/
|
||||
static void
|
||||
printproto(struct protox *tp, const char *name)
|
||||
printproto(struct protox *tp, const char *name, bool *first)
|
||||
{
|
||||
void (*pr)(u_long, const char *, int, int);
|
||||
u_long off;
|
||||
bool doingdblocks = false;
|
||||
|
||||
if (sflag) {
|
||||
if (iflag) {
|
||||
if (tp->pr_istats)
|
||||
intpr(interval, tp->pr_istats, af);
|
||||
else if (pflag)
|
||||
printf("%s: no per-interface stats routine\n",
|
||||
xo_message("%s: no per-interface stats routine",
|
||||
tp->pr_name);
|
||||
return;
|
||||
} else {
|
||||
pr = tp->pr_stats;
|
||||
if (!pr) {
|
||||
if (pflag)
|
||||
printf("%s: no stats routine\n",
|
||||
xo_message("%s: no stats routine",
|
||||
tp->pr_name);
|
||||
return;
|
||||
}
|
||||
@ -630,34 +660,39 @@ printproto(struct protox *tp, const char *name)
|
||||
off = 0;
|
||||
else if (tp->pr_sindex < 0) {
|
||||
if (pflag)
|
||||
printf(
|
||||
"%s: stats routine doesn't work on cores\n",
|
||||
tp->pr_name);
|
||||
xo_message("%s: stats routine doesn't "
|
||||
"work on cores", tp->pr_name);
|
||||
return;
|
||||
} else
|
||||
off = nl[tp->pr_sindex].n_value;
|
||||
}
|
||||
} else {
|
||||
doingdblocks = true;
|
||||
pr = tp->pr_cblocks;
|
||||
if (!pr) {
|
||||
if (pflag)
|
||||
printf("%s: no PCB routine\n", tp->pr_name);
|
||||
xo_message("%s: no PCB routine", tp->pr_name);
|
||||
return;
|
||||
}
|
||||
if (tp->pr_usesysctl && live)
|
||||
off = 0;
|
||||
else if (tp->pr_index < 0) {
|
||||
if (pflag)
|
||||
printf(
|
||||
"%s: PCB routine doesn't work on cores\n",
|
||||
tp->pr_name);
|
||||
xo_message("%s: PCB routine doesn't work on "
|
||||
"cores", tp->pr_name);
|
||||
return;
|
||||
} else
|
||||
off = nl[tp->pr_index].n_value;
|
||||
}
|
||||
if (pr != NULL && (off || (live && tp->pr_usesysctl) ||
|
||||
af != AF_UNSPEC))
|
||||
af != AF_UNSPEC)) {
|
||||
if (doingdblocks && *first) {
|
||||
xo_open_list("socket");
|
||||
*first = false;
|
||||
}
|
||||
|
||||
(*pr)(off, name, af, tp->pr_protocol);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -672,7 +707,7 @@ kvmd_init(void)
|
||||
setgid(getgid());
|
||||
|
||||
if (kvmd == NULL) {
|
||||
warnx("kvm not available: %s", errbuf);
|
||||
xo_warnx("kvm not available: %s", errbuf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -694,10 +729,10 @@ kresolve_list(struct nlist *_nl)
|
||||
|
||||
if (kvm_nlist(kvmd, _nl) < 0) {
|
||||
if (nlistf)
|
||||
errx(1, "%s: kvm_nlist: %s", nlistf,
|
||||
kvm_geterr(kvmd));
|
||||
xo_errx(1, "%s: kvm_nlist: %s", nlistf,
|
||||
kvm_geterr(kvmd));
|
||||
else
|
||||
errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
|
||||
xo_errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -716,7 +751,7 @@ kread(u_long addr, void *buf, size_t size)
|
||||
if (!buf)
|
||||
return (0);
|
||||
if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) {
|
||||
warnx("%s", kvm_geterr(kvmd));
|
||||
xo_warnx("%s", kvm_geterr(kvmd));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
@ -823,7 +858,7 @@ name2protox(const char *name)
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
(void)xo_error("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: netstat [-46AaLnRSTWx] [-f protocol_family | -p protocol]\n"
|
||||
" [-M core] [-N system]",
|
||||
" netstat -i | -I interface [-46abdhnW] [-f address_family]\n"
|
||||
@ -842,5 +877,6 @@ usage(void)
|
||||
" netstat -g [-46W] [-f address_family] [-M core] [-N system]",
|
||||
" netstat -gs [-46s] [-f address_family] [-M core] [-N system]",
|
||||
" netstat -Q");
|
||||
xo_finish();
|
||||
exit(1);
|
||||
}
|
||||
|
@ -56,7 +56,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
/*
|
||||
@ -88,7 +90,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtlp = memstat_mtl_alloc();
|
||||
if (mtlp == NULL) {
|
||||
warn("memstat_mtl_alloc");
|
||||
xo_warn("memstat_mtl_alloc");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,7 +100,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
*/
|
||||
if (live) {
|
||||
if (memstat_sysctl_all(mtlp, 0) < 0) {
|
||||
warnx("memstat_sysctl_all: %s",
|
||||
xo_warnx("memstat_sysctl_all: %s",
|
||||
memstat_strerror(memstat_mtl_geterror(mtlp)));
|
||||
goto out;
|
||||
}
|
||||
@ -106,10 +108,10 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
if (memstat_kvm_all(mtlp, kvmd) < 0) {
|
||||
error = memstat_mtl_geterror(mtlp);
|
||||
if (error == MEMSTAT_ERROR_KVM)
|
||||
warnx("memstat_kvm_all: %s",
|
||||
xo_warnx("memstat_kvm_all: %s",
|
||||
kvm_geterr(kvmd));
|
||||
else
|
||||
warnx("memstat_kvm_all: %s",
|
||||
xo_warnx("memstat_kvm_all: %s",
|
||||
memstat_strerror(error));
|
||||
goto out;
|
||||
}
|
||||
@ -117,7 +119,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found", MBUF_MEM_NAME);
|
||||
xo_warnx("memstat_mtl_find: zone %s not found", MBUF_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
mbuf_count = memstat_get_count(mtp);
|
||||
@ -129,7 +131,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_PACKET_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
xo_warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_PACKET_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
@ -141,7 +143,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_CLUSTER_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
xo_warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_CLUSTER_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
@ -154,7 +156,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_MALLOC, MBUF_TAG_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: malloc type %s not found",
|
||||
xo_warnx("memstat_mtl_find: malloc type %s not found",
|
||||
MBUF_TAG_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
@ -162,7 +164,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBOP_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
xo_warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_JUMBOP_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
@ -175,7 +177,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO9_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
xo_warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_JUMBO9_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
@ -188,7 +190,7 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO16_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
xo_warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_JUMBO16_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
@ -199,36 +201,44 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
jumbo16_sleeps = memstat_get_sleeps(mtp);
|
||||
jumbo16_size = memstat_get_size(mtp);
|
||||
|
||||
printf("%ju/%ju/%ju mbufs in use (current/cache/total)\n",
|
||||
xo_open_container("mbuf-statistics");
|
||||
|
||||
xo_emit("{:mbuf-current/%ju}/{:mbuf-cache/%ju}/{:mbuf-total/%ju} "
|
||||
"{N:mbufs in use (current\\/cache\\/total)}\n",
|
||||
mbuf_count + packet_count, mbuf_free + packet_free,
|
||||
mbuf_count + packet_count + mbuf_free + packet_free);
|
||||
|
||||
printf("%ju/%ju/%ju/%ju mbuf clusters in use "
|
||||
"(current/cache/total/max)\n",
|
||||
xo_emit("{:cluster-current/%ju}/{:cluster-cache/%ju}/"
|
||||
"{:cluster-total/%ju}/{:cluster-max/%ju} "
|
||||
"{N:mbuf clusters in use (current\\/cache\\/total\\/max)}\n",
|
||||
cluster_count - packet_free, cluster_free + packet_free,
|
||||
cluster_count + cluster_free, cluster_limit);
|
||||
|
||||
printf("%ju/%ju mbuf+clusters out of packet secondary zone in use "
|
||||
"(current/cache)\n",
|
||||
xo_emit("{:packet-count/%ju}/{:packet-free/%ju} "
|
||||
"{N:mbuf+clusters out of packet secondary zone in use "
|
||||
"(current\\/cache)}\n",
|
||||
packet_count, packet_free);
|
||||
|
||||
printf("%ju/%ju/%ju/%ju %juk (page size) jumbo clusters in use "
|
||||
"(current/cache/total/max)\n",
|
||||
xo_emit("{:jumbo-count/%ju}/{:jumbo-cache/%ju}/{:jumbo-total/%ju}/"
|
||||
"{:jumbo-max/%ju} {:jumbo-page-size/%ju}{U:k} {N:(page size)} "
|
||||
"{N:jumbo clusters in use (current\\/cache\\/total\\/max)}\n",
|
||||
jumbop_count, jumbop_free, jumbop_count + jumbop_free,
|
||||
jumbop_limit, jumbop_size / 1024);
|
||||
|
||||
printf("%ju/%ju/%ju/%ju 9k jumbo clusters in use "
|
||||
"(current/cache/total/max)\n",
|
||||
xo_emit("{:jumbo9-count/%ju}/{:jumbo9-cache/%ju}/"
|
||||
"{:jumbo9-total/%ju}/{:jumbo9-max/%ju} "
|
||||
"{N:9k jumbo clusters in use (current\\/cache\\/total\\/max)}\n",
|
||||
jumbo9_count, jumbo9_free, jumbo9_count + jumbo9_free,
|
||||
jumbo9_limit);
|
||||
|
||||
printf("%ju/%ju/%ju/%ju 16k jumbo clusters in use "
|
||||
"(current/cache/total/max)\n",
|
||||
xo_emit("{:jumbo16-count/%ju}/{:jumbo16-cache/%ju}/"
|
||||
"{:jumbo16-total/%ju}/{:jumbo16-limit/%ju} "
|
||||
"{N:16k jumbo clusters in use (current\\/cache\\/total\\/max)}\n",
|
||||
jumbo16_count, jumbo16_free, jumbo16_count + jumbo16_free,
|
||||
jumbo16_limit);
|
||||
|
||||
#if 0
|
||||
printf("%ju mbuf tags in use\n", tag_count);
|
||||
xo_emit("{:tag-count/%ju} {N:mbuf tags in use}\n", tag_count);
|
||||
#endif
|
||||
|
||||
/*-
|
||||
@ -276,23 +286,29 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
*/
|
||||
bytes_total = bytes_inuse + bytes_incache;
|
||||
|
||||
printf("%juK/%juK/%juK bytes allocated to network "
|
||||
"(current/cache/total)\n", bytes_inuse / 1024,
|
||||
bytes_incache / 1024, bytes_total / 1024);
|
||||
xo_emit("{:bytes-in-use/%ju}{U:K}/{:bytes-in-cache/%ju}{U:K}/"
|
||||
"{:bytes-total/%ju}{U:K} "
|
||||
"{N:bytes allocated to network (current\\/cache\\/total)}\n",
|
||||
bytes_inuse / 1024, bytes_incache / 1024, bytes_total / 1024);
|
||||
|
||||
printf("%ju/%ju/%ju requests for mbufs denied (mbufs/clusters/"
|
||||
"mbuf+clusters)\n", mbuf_failures, cluster_failures,
|
||||
packet_failures);
|
||||
printf("%ju/%ju/%ju requests for mbufs delayed (mbufs/clusters/"
|
||||
"mbuf+clusters)\n", mbuf_sleeps, cluster_sleeps,
|
||||
packet_sleeps);
|
||||
xo_emit("{:mbuf-failures/%ju}/{:cluster-failures/%ju}/"
|
||||
"{:packet-failures/%ju} {N:requests for mbufs denied "
|
||||
"(mbufs\\/clusters\\/mbuf+clusters)}\n",
|
||||
mbuf_failures, cluster_failures, packet_failures);
|
||||
xo_emit("{:mbuf-sleeps/%ju}/{:cluster-sleeps/%ju}/{:packet-sleeps/%ju} "
|
||||
"{N:requests for mbufs delayed "
|
||||
"(mbufs\\/clusters\\/mbuf+clusters)}\n",
|
||||
mbuf_sleeps, cluster_sleeps, packet_sleeps);
|
||||
|
||||
printf("%ju/%ju/%ju requests for jumbo clusters delayed "
|
||||
"(%juk/9k/16k)\n", jumbop_sleeps, jumbo9_sleeps,
|
||||
jumbo16_sleeps, jumbop_size / 1024);
|
||||
printf("%ju/%ju/%ju requests for jumbo clusters denied "
|
||||
"(%juk/9k/16k)\n", jumbop_failures, jumbo9_failures,
|
||||
jumbo16_failures, jumbop_size / 1024);
|
||||
xo_emit("{:jumbop-sleeps/%ju}/{:jumbo9-sleeps/%ju}/"
|
||||
"{:jumbo16-sleeps/%ju} {N:/requests for jumbo clusters delayed "
|
||||
"(%juk\\/9k\\/16k)}\n",
|
||||
jumbop_sleeps, jumbo9_sleeps, jumbo16_sleeps, jumbop_size / 1024);
|
||||
xo_emit("{:jumbop-failures/%ju}/{:jumbo9-failures/%ju}/"
|
||||
"{:jumbo16-failures/%ju} {N:/requests for jumbo clusters denied "
|
||||
"(%juk\\/9k\\/16k)}\n",
|
||||
jumbop_failures, jumbo9_failures, jumbo16_failures,
|
||||
jumbop_size / 1024);
|
||||
|
||||
if (live) {
|
||||
mlen = sizeof(nsfbufs);
|
||||
@ -302,23 +318,27 @@ mbpr(void *kvmd, u_long mbaddr)
|
||||
&mlen, NULL, 0) &&
|
||||
!sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak,
|
||||
&mlen, NULL, 0))
|
||||
printf("%d/%d/%d sfbufs in use (current/peak/max)\n",
|
||||
xo_emit("{:nsfbufs-current/%d}/{:nsfbufs-peak/%d}/"
|
||||
"{:nsfbufs/%d} "
|
||||
"{N:sfbufs in use (current\\/peak\\/max)}\n",
|
||||
nsfbufsused, nsfbufspeak, nsfbufs);
|
||||
mlen = sizeof(sfstat);
|
||||
if (sysctlbyname("kern.ipc.sfstat", &sfstat, &mlen, NULL, 0)) {
|
||||
warn("kern.ipc.sfstat");
|
||||
xo_warn("kern.ipc.sfstat");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (kread_counters(mbaddr, (char *)&sfstat, sizeof sfstat) != 0)
|
||||
goto out;
|
||||
}
|
||||
printf("%ju requests for sfbufs denied\n",
|
||||
xo_emit("{:sfbufs-alloc-failed/%ju} {N:requests for sfbufs denied}\n",
|
||||
(uintmax_t)sfstat.sf_allocfail);
|
||||
printf("%ju requests for sfbufs delayed\n",
|
||||
xo_emit("{:sfbufs-alloc-wait/%ju} {N:requests for sfbufs delayed}\n",
|
||||
(uintmax_t)sfstat.sf_allocwait);
|
||||
printf("%ju requests for I/O initiated by sendfile\n",
|
||||
xo_emit("{:sfbufs-io-count/%ju} "
|
||||
"{N:requests for I\\/O initiated by sendfile}\n",
|
||||
(uintmax_t)sfstat.sf_iocnt);
|
||||
out:
|
||||
xo_close_container("mbuf-statistics");
|
||||
memstat_mtl_free(mtlp);
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
/*
|
||||
@ -92,77 +94,85 @@ static void print_mfc(struct mfc *, int, int *);
|
||||
static void
|
||||
print_bw_meter(struct bw_meter *bw_meter, int *banner_printed)
|
||||
{
|
||||
char s0[256], s1[256], s2[256], s3[256];
|
||||
char s1[256], s2[256], s3[256];
|
||||
struct timeval now, end, delta;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
if (! *banner_printed) {
|
||||
printf(" Bandwidth Meters\n");
|
||||
printf(" %-30s", "Measured(Start|Packets|Bytes)");
|
||||
printf(" %s", "Type");
|
||||
printf(" %-30s", "Thresh(Interval|Packets|Bytes)");
|
||||
printf(" Remain");
|
||||
printf("\n");
|
||||
xo_open_list("bandwidth-meter");
|
||||
xo_emit(" {T:Bandwidth Meters}\n");
|
||||
xo_emit(" {T:/%-30s}", "Measured(Start|Packets|Bytes)");
|
||||
xo_emit(" {T:/%s}", "Type");
|
||||
xo_emit(" {T:/%-30s}", "Thresh(Interval|Packets|Bytes)");
|
||||
xo_emit(" {T:Remain}");
|
||||
xo_emit("\n");
|
||||
*banner_printed = 1;
|
||||
}
|
||||
|
||||
xo_open_instance("bandwidth-meter");
|
||||
|
||||
/* The measured values */
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS)
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) {
|
||||
sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_measured.b_packets);
|
||||
else
|
||||
xo_emit("{e:measured-packets/%ju}",
|
||||
(uintmax_t)bw_meter->bm_measured.b_packets);
|
||||
} else
|
||||
sprintf(s1, "?");
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES)
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) {
|
||||
sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_measured.b_bytes);
|
||||
else
|
||||
xo_emit("{e:measured-bytes/%ju}",
|
||||
(uintmax_t)bw_meter->bm_measured.b_bytes);
|
||||
} else
|
||||
sprintf(s2, "?");
|
||||
sprintf(s0, "%lu.%lu|%s|%s",
|
||||
(u_long)bw_meter->bm_start_time.tv_sec,
|
||||
(u_long)bw_meter->bm_start_time.tv_usec,
|
||||
s1, s2);
|
||||
printf(" %-30s", s0);
|
||||
xo_emit(" {[:-30}{:start-time/%lu.%06lu}|{q:measured-packets/%s}"
|
||||
"|{q:measured-bytes%s}{]:}",
|
||||
(u_long)bw_meter->bm_start_time.tv_sec,
|
||||
(u_long)bw_meter->bm_start_time.tv_usec, s1, s2);
|
||||
|
||||
/* The type of entry */
|
||||
sprintf(s0, "%s", "?");
|
||||
if (bw_meter->bm_flags & BW_METER_GEQ)
|
||||
sprintf(s0, "%s", ">=");
|
||||
else if (bw_meter->bm_flags & BW_METER_LEQ)
|
||||
sprintf(s0, "%s", "<=");
|
||||
printf(" %-3s", s0);
|
||||
xo_emit(" {t:type/%-3s}", (bw_meter->bm_flags & BW_METER_GEQ) ? ">=" :
|
||||
(bw_meter->bm_flags & BW_METER_LEQ) ? "<=" : "?");
|
||||
|
||||
/* The threshold values */
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS)
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) {
|
||||
sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_threshold.b_packets);
|
||||
else
|
||||
xo_emit("{e:threshold-packets/%ju}",
|
||||
(uintmax_t)bw_meter->bm_threshold.b_packets);
|
||||
} else
|
||||
sprintf(s1, "?");
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES)
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) {
|
||||
sprintf(s2, "%ju", (uintmax_t)bw_meter->bm_threshold.b_bytes);
|
||||
else
|
||||
xo_emit("{e:threshold-bytes/%ju}",
|
||||
(uintmax_t)bw_meter->bm_threshold.b_bytes);
|
||||
} else
|
||||
sprintf(s2, "?");
|
||||
sprintf(s0, "%lu.%lu|%s|%s",
|
||||
(u_long)bw_meter->bm_threshold.b_time.tv_sec,
|
||||
(u_long)bw_meter->bm_threshold.b_time.tv_usec,
|
||||
s1, s2);
|
||||
printf(" %-30s", s0);
|
||||
|
||||
xo_emit(" {[:-30}{:threshold-time/%lu.%06lu}|{q:threshold-packets/%s}"
|
||||
"|{q:threshold-bytes%s}{]:}",
|
||||
(u_long)bw_meter->bm_threshold.b_time.tv_sec,
|
||||
(u_long)bw_meter->bm_threshold.b_time.tv_usec, s1, s2);
|
||||
|
||||
/* Remaining time */
|
||||
timeradd(&bw_meter->bm_start_time,
|
||||
&bw_meter->bm_threshold.b_time, &end);
|
||||
if (timercmp(&now, &end, <=)) {
|
||||
timersub(&end, &now, &delta);
|
||||
sprintf(s3, "%lu.%lu",
|
||||
sprintf(s3, "%lu.%06lu",
|
||||
(u_long)delta.tv_sec,
|
||||
(u_long)delta.tv_usec);
|
||||
} else {
|
||||
/* Negative time */
|
||||
timersub(&now, &end, &delta);
|
||||
sprintf(s3, "-%lu.%lu",
|
||||
sprintf(s3, "-%lu.06%lu",
|
||||
(u_long)delta.tv_sec,
|
||||
(u_long)delta.tv_usec);
|
||||
}
|
||||
printf(" %s", s3);
|
||||
xo_emit(" {:remaining-time/%s}", s3);
|
||||
|
||||
printf("\n");
|
||||
xo_open_instance("bandwidth-meter");
|
||||
|
||||
xo_emit("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -176,21 +186,29 @@ print_mfc(struct mfc *m, int maxvif, int *banner_printed)
|
||||
bw_banner_printed = 0;
|
||||
|
||||
if (! *banner_printed) {
|
||||
printf("\nIPv4 Multicast Forwarding Table\n"
|
||||
" Origin Group "
|
||||
" Packets In-Vif Out-Vifs:Ttls\n");
|
||||
xo_open_list("multicast-forwarding-entry");
|
||||
xo_emit("\n{T:IPv4 Multicast Forwarding Table}\n"
|
||||
" {T:Origin} {T:Group} "
|
||||
" {T:Packets In-Vif} {T:Out-Vifs:Ttls}\n");
|
||||
*banner_printed = 1;
|
||||
}
|
||||
|
||||
printf(" %-15.15s", routename(m->mfc_origin.s_addr));
|
||||
printf(" %-15.15s", routename(m->mfc_mcastgrp.s_addr));
|
||||
printf(" %9lu", m->mfc_pkt_cnt);
|
||||
printf(" %3d ", m->mfc_parent);
|
||||
xo_emit(" {:origin-address/%-15.15s}", routename(m->mfc_origin.s_addr));
|
||||
xo_emit(" {:group-address/%-15.15s}",
|
||||
routename(m->mfc_mcastgrp.s_addr));
|
||||
xo_emit(" {:sent-packets/%9lu}", m->mfc_pkt_cnt);
|
||||
xo_emit(" {:parent/%3d} ", m->mfc_parent);
|
||||
xo_open_list("vif-ttl");
|
||||
for (vifi = 0; vifi <= maxvif; vifi++) {
|
||||
if (m->mfc_ttls[vifi] > 0)
|
||||
printf(" %u:%u", vifi, m->mfc_ttls[vifi]);
|
||||
if (m->mfc_ttls[vifi] > 0) {
|
||||
xo_open_instance("vif-ttl");
|
||||
xo_emit(" {k:vif/%u}:{:ttl/%u}", vifi,
|
||||
m->mfc_ttls[vifi]);
|
||||
xo_close_instance("vif-ttl");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
xo_close_list("vif-ttl");
|
||||
xo_emit("\n");
|
||||
|
||||
/*
|
||||
* XXX We break the rules and try to use KVM to read the
|
||||
@ -205,6 +223,8 @@ print_mfc(struct mfc *m, int maxvif, int *banner_printed)
|
||||
print_bw_meter(&bw_meter, &bw_banner_printed);
|
||||
bwm = bw_meter.bm_mfc_next;
|
||||
}
|
||||
if (banner_printed)
|
||||
xo_close_list("bandwidth-meter");
|
||||
}
|
||||
|
||||
void
|
||||
@ -242,7 +262,7 @@ mroutepr()
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet.ip.viftable", viftable, &len, NULL,
|
||||
0) < 0) {
|
||||
warn("sysctl: net.inet.ip.viftable");
|
||||
xo_warn("sysctl: net.inet.ip.viftable");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@ -252,7 +272,7 @@ mroutepr()
|
||||
pviftbl = mrl[N_VIFTABLE].n_value;
|
||||
|
||||
if (pmfchashtbl == 0 || pmfctablesize == 0 || pviftbl == 0) {
|
||||
fprintf(stderr, "No IPv4 MROUTING kernel support.\n");
|
||||
xo_warnx("No IPv4 MROUTING kernel support.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -266,23 +286,29 @@ mroutepr()
|
||||
|
||||
maxvif = vifi;
|
||||
if (!banner_printed) {
|
||||
printf("\nIPv4 Virtual Interface Table\n"
|
||||
" Vif Thresh Local-Address "
|
||||
"Remote-Address Pkts-In Pkts-Out\n");
|
||||
xo_emit("\n{T:IPv4 Virtual Interface Table\n"
|
||||
" Vif Thresh Local-Address "
|
||||
"Remote-Address Pkts-In Pkts-Out}\n");
|
||||
banner_printed = 1;
|
||||
xo_open_list("vif");
|
||||
}
|
||||
|
||||
printf(" %2u %6u %-15.15s",
|
||||
xo_open_instance("vif");
|
||||
xo_emit(" {:vif/%2u} {:threshold/%6u} {:route/%-15.15s}",
|
||||
/* opposite math of add_vif() */
|
||||
vifi, v->v_threshold,
|
||||
routename(v->v_lcl_addr.s_addr));
|
||||
printf(" %-15.15s", (v->v_flags & VIFF_TUNNEL) ?
|
||||
xo_emit(" {:source/%-15.15s}", (v->v_flags & VIFF_TUNNEL) ?
|
||||
routename(v->v_rmt_addr.s_addr) : "");
|
||||
|
||||
printf(" %9lu %9lu\n", v->v_pkt_in, v->v_pkt_out);
|
||||
xo_emit(" {:received-packets/%9lu} {:sent-packets/%9lu}\n",
|
||||
v->v_pkt_in, v->v_pkt_out);
|
||||
xo_close_instance("vif");
|
||||
}
|
||||
if (!banner_printed)
|
||||
printf("\nIPv4 Virtual Interface Table is empty\n");
|
||||
if (banner_printed)
|
||||
xo_close_list("vif");
|
||||
else
|
||||
xo_emit("\n{T:IPv4 Virtual Interface Table is empty}\n");
|
||||
|
||||
banner_printed = 0;
|
||||
|
||||
@ -302,19 +328,19 @@ mroutepr()
|
||||
len = 0;
|
||||
if (sysctlbyname("net.inet.ip.mfctable", NULL, &len, NULL,
|
||||
0) < 0) {
|
||||
warn("sysctl: net.inet.ip.mfctable");
|
||||
xo_warn("sysctl: net.inet.ip.mfctable");
|
||||
return;
|
||||
}
|
||||
|
||||
mfctable = malloc(len);
|
||||
if (mfctable == NULL) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
xo_warnx("malloc %lu bytes", (u_long)len);
|
||||
return;
|
||||
}
|
||||
if (sysctlbyname("net.inet.ip.mfctable", mfctable, &len, NULL,
|
||||
0) < 0) {
|
||||
free(mfctable);
|
||||
warn("sysctl: net.inet.ip.mfctable");
|
||||
xo_warn("sysctl: net.inet.ip.mfctable");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -323,8 +349,10 @@ mroutepr()
|
||||
print_mfc(m++, maxvif, &banner_printed);
|
||||
len -= sizeof(*m);
|
||||
}
|
||||
if (banner_printed)
|
||||
xo_close_list("multicast-forwarding-entry");
|
||||
if (len != 0)
|
||||
warnx("print_mfc: %lu trailing bytes", (u_long)len);
|
||||
xo_warnx("print_mfc: %lu trailing bytes", (u_long)len);
|
||||
|
||||
free(mfctable);
|
||||
} else {
|
||||
@ -336,14 +364,14 @@ mroutepr()
|
||||
error = kread(pmfctablesize, (char *)&mfctablesize,
|
||||
sizeof(u_long));
|
||||
if (error) {
|
||||
warn("kread: mfctablesize");
|
||||
xo_warn("kread: mfctablesize");
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(*mfchashtbl) * mfctablesize;
|
||||
mfchashtbl = malloc(len);
|
||||
if (mfchashtbl == NULL) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
xo_warnx("malloc %lu bytes", (u_long)len);
|
||||
return;
|
||||
}
|
||||
kread(pmfchashtbl, (char *)&mfchashtbl, len);
|
||||
@ -354,14 +382,16 @@ mroutepr()
|
||||
print_mfc(m, maxvif, &banner_printed);
|
||||
}
|
||||
}
|
||||
if (banner_printed)
|
||||
xo_close_list("multicast-forwarding-entry");
|
||||
|
||||
free(mfchashtbl);
|
||||
}
|
||||
|
||||
if (!banner_printed)
|
||||
printf("\nIPv4 Multicast Forwarding Table is empty\n");
|
||||
xo_emit("\n{T:IPv4 Multicast Forwarding Table is empty}\n");
|
||||
|
||||
printf("\n");
|
||||
xo_emit("\n");
|
||||
numeric_addr = saved_numeric_addr;
|
||||
}
|
||||
|
||||
@ -383,33 +413,48 @@ mrt_stats()
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet.ip.mrtstat", &mrtstat, &len, NULL,
|
||||
0) < 0) {
|
||||
warn("sysctl: net.inet.ip.mrtstat failed.");
|
||||
xo_warn("sysctl: net.inet.ip.mrtstat failed.");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread_counters(mstaddr, &mrtstat, len);
|
||||
|
||||
printf("IPv4 multicast forwarding:\n");
|
||||
xo_emit("{T:IPv4 multicast forwarding}:\n");
|
||||
|
||||
#define p(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)mrtstat.f, plural(mrtstat.f))
|
||||
xo_emit(m, (uintmax_t)mrtstat.f, plural(mrtstat.f))
|
||||
#define p2(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f))
|
||||
xo_emit(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f))
|
||||
|
||||
p(mrts_mfc_lookups, "\t%ju multicast forwarding cache lookup%s\n");
|
||||
p2(mrts_mfc_misses, "\t%ju multicast forwarding cache miss%s\n");
|
||||
p(mrts_upcalls, "\t%ju upcall%s to multicast routing daemon\n");
|
||||
p(mrts_upq_ovflw, "\t%ju upcall queue overflow%s\n");
|
||||
xo_open_container("multicast-statistics");
|
||||
|
||||
p(mrts_mfc_lookups, "\t{:cache-lookups/%ju} "
|
||||
"{N:/multicast forwarding cache lookup%s}\n");
|
||||
p2(mrts_mfc_misses, "\t{:cache-misses/%ju} "
|
||||
"{N:/multicast forwarding cache miss%s}\n");
|
||||
p(mrts_upcalls, "\t{:upcalls-total/%ju} "
|
||||
"{N:/upcall%s to multicast routing daemon}\n");
|
||||
p(mrts_upq_ovflw, "\t{:upcall-overflows/%ju} "
|
||||
"{N:/upcall queue overflow%s}\n");
|
||||
p(mrts_upq_sockfull,
|
||||
"\t%ju upcall%s dropped due to full socket buffer\n");
|
||||
p(mrts_cache_cleanups, "\t%ju cache cleanup%s\n");
|
||||
p(mrts_no_route, "\t%ju datagram%s with no route for origin\n");
|
||||
p(mrts_bad_tunnel, "\t%ju datagram%s arrived with bad tunneling\n");
|
||||
p(mrts_cant_tunnel, "\t%ju datagram%s could not be tunneled\n");
|
||||
p(mrts_wrong_if, "\t%ju datagram%s arrived on wrong interface\n");
|
||||
p(mrts_drop_sel, "\t%ju datagram%s selectively dropped\n");
|
||||
p(mrts_q_overflow, "\t%ju datagram%s dropped due to queue overflow\n");
|
||||
p(mrts_pkt2large, "\t%ju datagram%s dropped for being too large\n");
|
||||
"\t{:upcalls-dropped-full-buffer/%ju} "
|
||||
"{N:/upcall%s dropped due to full socket buffer}\n");
|
||||
p(mrts_cache_cleanups, "\t{:cache-cleanups/%ju} "
|
||||
"{N:/cache cleanup%s}\n");
|
||||
p(mrts_no_route, "\t{:dropped-no-origin/%ju} "
|
||||
"{N:/datagram%s with no route for origin}\n");
|
||||
p(mrts_bad_tunnel, "\t{:dropped-bad-tunnel/%ju} "
|
||||
"{N:/datagram%s arrived with bad tunneling}\n");
|
||||
p(mrts_cant_tunnel, "\t{:dropped-could-not-tunnel/%ju} "
|
||||
"{N:/datagram%s could not be tunneled}\n");
|
||||
p(mrts_wrong_if, "\t{:dropped-wrong-incoming-interface/%ju} "
|
||||
"{N:/datagram%s arrived on wrong interface}\n");
|
||||
p(mrts_drop_sel, "\t{:dropped-selectively/%ju} "
|
||||
"{N:/datagram%s selectively dropped}\n");
|
||||
p(mrts_q_overflow, "\t{:dropped-queue-overflow/%ju} "
|
||||
"{N:/datagram%s dropped due to queue overflow}\n");
|
||||
p(mrts_pkt2large, "\t{:dropped-too-large/%ju} "
|
||||
"{N:/datagram%s dropped for being too large}\n");
|
||||
|
||||
#undef p2
|
||||
#undef p
|
||||
|
@ -89,6 +89,8 @@ __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>
|
||||
@ -143,7 +145,7 @@ mroute6pr()
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len,
|
||||
NULL, 0) < 0) {
|
||||
warn("sysctl: net.inet6.ip6.mif6table");
|
||||
xo_warn("sysctl: net.inet6.ip6.mif6table");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
@ -165,28 +167,33 @@ mroute6pr()
|
||||
|
||||
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(ifnet.if_index, 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");
|
||||
xo_warn("sysctl: net.inet6.ip6.mf6ctable");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
@ -199,19 +206,24 @@ mroute6pr()
|
||||
while(mfcp) {
|
||||
kread((u_long)mfcp, (char *)&mfc, sizeof(mfc));
|
||||
if (!banner_printed) {
|
||||
printf ("\nIPv6 Multicast Forwarding Cache\n");
|
||||
printf(" %-*.*s %-*.*s %s",
|
||||
WID_ORG, WID_ORG, "Origin",
|
||||
WID_GRP, WID_GRP, "Group",
|
||||
" Packets Waits In-Mif Out-Mifs\n");
|
||||
xo_open_list("multicast-forwarding-cache");
|
||||
xo_emit("\n"
|
||||
"{T:IPv6 Multicast Forwarding Cache}\n");
|
||||
xo_emit(" {T:%-*.*s} {T:%-*.*s} {T:%s}",
|
||||
WID_ORG, WID_ORG, "Origin",
|
||||
WID_GRP, WID_GRP, "Group",
|
||||
" Packets Waits In-Mif Out-Mifs\n");
|
||||
banner_printed = 1;
|
||||
}
|
||||
|
||||
printf(" %-*.*s", WID_ORG, WID_ORG,
|
||||
routename6(&mfc.mf6c_origin));
|
||||
printf(" %-*.*s", WID_GRP, WID_GRP,
|
||||
routename6(&mfc.mf6c_mcastgrp));
|
||||
printf(" %9ju", (uintmax_t)mfc.mf6c_pkt_cnt);
|
||||
xo_open_instance("multicast-forwarding-cache");
|
||||
|
||||
xo_emit(" {:origin/%-*.*s}", WID_ORG, WID_ORG,
|
||||
routename6(&mfc.mf6c_origin));
|
||||
xo_emit(" {:group/%-*.*s}", WID_GRP, WID_GRP,
|
||||
routename6(&mfc.mf6c_mcastgrp));
|
||||
xo_emit(" {:total-packets/%9ju}",
|
||||
(uintmax_t)mfc.mf6c_pkt_cnt);
|
||||
|
||||
for (waitings = 0, rtep = mfc.mf6c_stall; rtep; ) {
|
||||
waitings++;
|
||||
@ -219,25 +231,30 @@ mroute6pr()
|
||||
kread((u_long)rtep, (char *)&rte, sizeof(rte));
|
||||
rtep = rte.next;
|
||||
}
|
||||
printf(" %3ld", waitings);
|
||||
xo_emit(" {:waitings/%3ld}", waitings);
|
||||
|
||||
if (mfc.mf6c_parent == MF6C_INCOMPLETE_PARENT)
|
||||
printf(" --- ");
|
||||
xo_emit(" --- ");
|
||||
else
|
||||
printf(" %3d ", mfc.mf6c_parent);
|
||||
xo_emit(" {:parent/%3d} ", mfc.mf6c_parent);
|
||||
xo_open_list("mif");
|
||||
for (mifi = 0; mifi <= maxmif; mifi++) {
|
||||
if (IF_ISSET(mifi, &mfc.mf6c_ifset))
|
||||
printf(" %u", mifi);
|
||||
xo_emit(" {l:%u}", mifi);
|
||||
}
|
||||
printf("\n");
|
||||
xo_close_list("mif");
|
||||
xo_emit("\n");
|
||||
|
||||
mfcp = mfc.mf6c_next;
|
||||
xo_close_instance("multicast-forwarding-cache");
|
||||
}
|
||||
}
|
||||
if (!banner_printed)
|
||||
printf("\nIPv6 Multicast Forwarding Table is empty\n");
|
||||
if (banner_printed)
|
||||
xo_close_list("multicast-forwarding-cache");
|
||||
else
|
||||
xo_emit("\n{T:IPv6 Multicast Forwarding Table is empty}\n");
|
||||
|
||||
printf("\n");
|
||||
xo_emit("\n");
|
||||
numeric_addr = saved_numeric_addr;
|
||||
}
|
||||
|
||||
@ -259,36 +276,49 @@ mrt6_stats()
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len,
|
||||
NULL, 0) < 0) {
|
||||
warn("sysctl: net.inet6.ip6.mrt6stat");
|
||||
xo_warn("sysctl: net.inet6.ip6.mrt6stat");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
|
||||
|
||||
printf("IPv6 multicast forwarding:\n");
|
||||
xo_open_container("multicast-statistics");
|
||||
xo_emit("{T:IPv6 multicast forwarding}:\n");
|
||||
|
||||
#define p(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)mrtstat.f, plural(mrtstat.f))
|
||||
xo_emit(m, (uintmax_t)mrtstat.f, plural(mrtstat.f))
|
||||
#define p2(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f))
|
||||
xo_emit(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");
|
||||
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*/
|
||||
|
@ -53,9 +53,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
static int first = 1;
|
||||
@ -73,8 +75,7 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused,
|
||||
/* If symbol not found, try looking in the KLD module */
|
||||
if (off == 0) {
|
||||
if (debug)
|
||||
fprintf(stderr,
|
||||
"Error reading symbols from ng_socket.ko");
|
||||
xo_warnx("Error reading symbols from ng_socket.ko");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -106,19 +107,21 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused,
|
||||
|
||||
/* Do headline */
|
||||
if (first) {
|
||||
printf("Netgraph sockets\n");
|
||||
xo_emit("{T:Netgraph sockets}\n");
|
||||
if (Aflag)
|
||||
printf("%-8.8s ", "PCB");
|
||||
printf("%-5.5s %-6.6s %-6.6s %-14.14s %s\n",
|
||||
"Type", "Recv-Q", "Send-Q",
|
||||
"Node Address", "#Hooks");
|
||||
xo_emit("{T:/%-8.8s} ", "PCB");
|
||||
xo_emit("{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} "
|
||||
"{T:/%-14.14s} {T:/%s}\n",
|
||||
"Type", "Recv-Q", "Send-Q", "Node Address",
|
||||
"#Hooks");
|
||||
first = 0;
|
||||
}
|
||||
|
||||
/* Show socket */
|
||||
if (Aflag)
|
||||
printf("%8lx ", (u_long) this);
|
||||
printf("%-5.5s %6u %6u ",
|
||||
xo_emit("{:address/%8lx} ", (u_long) this);
|
||||
xo_emit("{t:name/%-5.5s} {:receive-bytes-waiting/%6u} "
|
||||
"{:send-byte-waiting/%6u} ",
|
||||
name, sockb.so_rcv.sb_ccc, sockb.so_snd.sb_ccc);
|
||||
|
||||
/* Get info on associated node */
|
||||
@ -134,9 +137,9 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused,
|
||||
/* Display associated node info */
|
||||
if (*ni->name != '\0')
|
||||
snprintf(path, sizeof(path), "%s:", ni->name);
|
||||
printf("%-14.14s %4d", path, ni->hooks);
|
||||
xo_emit("{t:path/%-14.14s} {:hooks/%4d}", path, ni->hooks);
|
||||
finish:
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
/*
|
||||
@ -112,13 +113,13 @@ netisr_load_kvm_uint(kvm_t *kd, const char *name, u_int *p)
|
||||
|
||||
ret = kvm_nlist(kd, nl);
|
||||
if (ret < 0)
|
||||
errx(-1, "%s: kvm_nlist(%s): %s", __func__, name,
|
||||
xo_errx(-1, "%s: kvm_nlist(%s): %s", __func__, name,
|
||||
kvm_geterr(kd));
|
||||
if (ret != 0)
|
||||
errx(-1, "%s: kvm_nlist(%s): unresolved symbol", __func__,
|
||||
xo_errx(-1, "%s: kvm_nlist(%s): unresolved symbol", __func__,
|
||||
name);
|
||||
if (kvm_read(kd, nl[0].n_value, p, sizeof(*p)) != sizeof(*p))
|
||||
errx(-1, "%s: kvm_read(%s): %s", __func__, name,
|
||||
xo_errx(-1, "%s: kvm_read(%s): %s", __func__, name,
|
||||
kvm_geterr(kd));
|
||||
}
|
||||
|
||||
@ -134,7 +135,7 @@ netisr_load_kvm_string(kvm_t *kd, uintptr_t addr, char *dest, u_int limit)
|
||||
for (i = 0; i < limit; i++) {
|
||||
if (kvm_read(kd, addr + i, &dest[i], sizeof(dest[i])) !=
|
||||
sizeof(dest[i]))
|
||||
err(-1, "%s: kvm_read: %s", __func__,
|
||||
xo_err(-1, "%s: kvm_read: %s", __func__,
|
||||
kvm_geterr(kd));
|
||||
if (dest[i] == '\0')
|
||||
break;
|
||||
@ -190,9 +191,9 @@ netisr_load_sysctl_uint(const char *name, u_int *p)
|
||||
|
||||
retlen = sizeof(u_int);
|
||||
if (sysctlbyname(name, p, &retlen, NULL, 0) < 0)
|
||||
err(-1, "%s", name);
|
||||
xo_err(-1, "%s", name);
|
||||
if (retlen != sizeof(u_int))
|
||||
errx(-1, "%s: invalid len %ju", name, (uintmax_t)retlen);
|
||||
xo_errx(-1, "%s: invalid len %ju", name, (uintmax_t)retlen);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -202,7 +203,7 @@ netisr_load_sysctl_string(const char *name, char *p, size_t len)
|
||||
|
||||
retlen = len;
|
||||
if (sysctlbyname(name, p, &retlen, NULL, 0) < 0)
|
||||
err(-1, "%s", name);
|
||||
xo_err(-1, "%s", name);
|
||||
p[len - 1] = '\0';
|
||||
}
|
||||
|
||||
@ -241,21 +242,21 @@ netisr_load_kvm_proto(kvm_t *kd)
|
||||
*/
|
||||
netisr_load_kvm_uint(kd, "_netisr_maxprot", &maxprot);
|
||||
if (maxprot != NETISR_MAXPROT)
|
||||
errx(-1, "%s: NETISR_MAXPROT mismatch", __func__);
|
||||
xo_errx(-1, "%s: NETISR_MAXPROT mismatch", __func__);
|
||||
len = maxprot * sizeof(*np_array);
|
||||
np_array = malloc(len);
|
||||
if (np_array == NULL)
|
||||
err(-1, "%s: malloc", __func__);
|
||||
xo_err(-1, "%s: malloc", __func__);
|
||||
ret = kvm_nlist(kd, nl);
|
||||
if (ret < 0)
|
||||
errx(-1, "%s: kvm_nlist(_netisr_proto): %s", __func__,
|
||||
xo_errx(-1, "%s: kvm_nlist(_netisr_proto): %s", __func__,
|
||||
kvm_geterr(kd));
|
||||
if (ret != 0)
|
||||
errx(-1, "%s: kvm_nlist(_netisr_proto): unresolved symbol",
|
||||
xo_errx(-1, "%s: kvm_nlist(_netisr_proto): unresolved symbol",
|
||||
__func__);
|
||||
if (kvm_read(kd, nl[NLIST_NETISR_PROTO].n_value, np_array, len) !=
|
||||
(ssize_t)len)
|
||||
errx(-1, "%s: kvm_read(_netisr_proto): %s", __func__,
|
||||
xo_errx(-1, "%s: kvm_read(_netisr_proto): %s", __func__,
|
||||
kvm_geterr(kd));
|
||||
|
||||
/*
|
||||
@ -301,21 +302,21 @@ netisr_load_sysctl_proto(void)
|
||||
size_t len;
|
||||
|
||||
if (sysctlbyname("net.isr.proto", NULL, &len, NULL, 0) < 0)
|
||||
err(-1, "net.isr.proto: query len");
|
||||
xo_err(-1, "net.isr.proto: query len");
|
||||
if (len % sizeof(*proto_array) != 0)
|
||||
errx(-1, "net.isr.proto: invalid len");
|
||||
xo_errx(-1, "net.isr.proto: invalid len");
|
||||
proto_array = malloc(len);
|
||||
if (proto_array == NULL)
|
||||
err(-1, "malloc");
|
||||
xo_err(-1, "malloc");
|
||||
if (sysctlbyname("net.isr.proto", proto_array, &len, NULL, 0) < 0)
|
||||
err(-1, "net.isr.proto: query data");
|
||||
xo_err(-1, "net.isr.proto: query data");
|
||||
if (len % sizeof(*proto_array) != 0)
|
||||
errx(-1, "net.isr.proto: invalid len");
|
||||
xo_errx(-1, "net.isr.proto: invalid len");
|
||||
proto_array_len = len / sizeof(*proto_array);
|
||||
if (proto_array_len < 1)
|
||||
errx(-1, "net.isr.proto: no data");
|
||||
xo_errx(-1, "net.isr.proto: no data");
|
||||
if (proto_array[0].snp_version != sizeof(proto_array[0]))
|
||||
errx(-1, "net.isr.proto: invalid version");
|
||||
xo_errx(-1, "net.isr.proto: invalid version");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -338,41 +339,41 @@ netisr_load_kvm_workstream(kvm_t *kd)
|
||||
len = numthreads * sizeof(*nws_array);
|
||||
nws_array = malloc(len);
|
||||
if (nws_array == NULL)
|
||||
err(-1, "malloc");
|
||||
xo_err(-1, "malloc");
|
||||
ret = kvm_nlist(kd, nl);
|
||||
if (ret < 0)
|
||||
errx(-1, "%s: kvm_nlist: %s", __func__, kvm_geterr(kd));
|
||||
xo_errx(-1, "%s: kvm_nlist: %s", __func__, kvm_geterr(kd));
|
||||
if (ret != 0)
|
||||
errx(-1, "%s: kvm_nlist: unresolved symbol", __func__);
|
||||
xo_errx(-1, "%s: kvm_nlist: unresolved symbol", __func__);
|
||||
if (kvm_read(kd, nl[NLIST_NWS_ARRAY].n_value, nws_array, len) !=
|
||||
(ssize_t)len)
|
||||
errx(-1, "%s: kvm_read(_nws_array): %s", __func__,
|
||||
xo_errx(-1, "%s: kvm_read(_nws_array): %s", __func__,
|
||||
kvm_geterr(kd));
|
||||
workstream_array = calloc(numthreads, sizeof(*workstream_array));
|
||||
if (workstream_array == NULL)
|
||||
err(-1, "calloc");
|
||||
xo_err(-1, "calloc");
|
||||
workstream_array_len = numthreads;
|
||||
work_array = calloc(numthreads * proto_array_len, sizeof(*work_array));
|
||||
if (work_array == NULL)
|
||||
err(-1, "calloc");
|
||||
xo_err(-1, "calloc");
|
||||
counter = 0;
|
||||
for (wsid = 0; wsid < numthreads; wsid++) {
|
||||
cpuid = nws_array[wsid];
|
||||
if (kvm_dpcpu_setcpu(kd, cpuid) < 0)
|
||||
errx(-1, "%s: kvm_dpcpu_setcpu(%u): %s", __func__,
|
||||
xo_errx(-1, "%s: kvm_dpcpu_setcpu(%u): %s", __func__,
|
||||
cpuid, kvm_geterr(kd));
|
||||
bzero(nl_nws, sizeof(nl_nws));
|
||||
nl_nws[0].n_name = "_nws";
|
||||
ret = kvm_nlist(kd, nl_nws);
|
||||
if (ret < 0)
|
||||
errx(-1, "%s: kvm_nlist looking up nws on CPU %u: %s",
|
||||
__func__, cpuid, kvm_geterr(kd));
|
||||
xo_errx(-1, "%s: kvm_nlist looking up nws on CPU "
|
||||
"%u: %s", __func__, cpuid, kvm_geterr(kd));
|
||||
if (ret != 0)
|
||||
errx(-1, "%s: kvm_nlist(nws): unresolved symbol on "
|
||||
xo_errx(-1, "%s: kvm_nlist(nws): unresolved symbol on "
|
||||
"CPU %u", __func__, cpuid);
|
||||
if (kvm_read(kd, nl_nws[0].n_value, &nws, sizeof(nws)) !=
|
||||
sizeof(nws))
|
||||
errx(-1, "%s: kvm_read(nw): %s", __func__,
|
||||
xo_errx(-1, "%s: kvm_read(nw): %s", __func__,
|
||||
kvm_geterr(kd));
|
||||
snwsp = &workstream_array[wsid];
|
||||
snwsp->snws_version = sizeof(*snwsp);
|
||||
@ -384,7 +385,7 @@ netisr_load_kvm_workstream(kvm_t *kd)
|
||||
/*
|
||||
* Extract the CPU's per-protocol work information.
|
||||
*/
|
||||
printf("counting to maxprot: %u\n", maxprot);
|
||||
xo_emit("counting to maxprot: {:maxprot/%u}\n", maxprot);
|
||||
for (proto = 0; proto < maxprot; proto++) {
|
||||
if (!netisr_protoispresent(proto))
|
||||
continue;
|
||||
@ -413,22 +414,22 @@ netisr_load_sysctl_workstream(void)
|
||||
size_t len;
|
||||
|
||||
if (sysctlbyname("net.isr.workstream", NULL, &len, NULL, 0) < 0)
|
||||
err(-1, "net.isr.workstream: query len");
|
||||
xo_err(-1, "net.isr.workstream: query len");
|
||||
if (len % sizeof(*workstream_array) != 0)
|
||||
errx(-1, "net.isr.workstream: invalid len");
|
||||
xo_errx(-1, "net.isr.workstream: invalid len");
|
||||
workstream_array = malloc(len);
|
||||
if (workstream_array == NULL)
|
||||
err(-1, "malloc");
|
||||
xo_err(-1, "malloc");
|
||||
if (sysctlbyname("net.isr.workstream", workstream_array, &len, NULL,
|
||||
0) < 0)
|
||||
err(-1, "net.isr.workstream: query data");
|
||||
xo_err(-1, "net.isr.workstream: query data");
|
||||
if (len % sizeof(*workstream_array) != 0)
|
||||
errx(-1, "net.isr.workstream: invalid len");
|
||||
xo_errx(-1, "net.isr.workstream: invalid len");
|
||||
workstream_array_len = len / sizeof(*workstream_array);
|
||||
if (workstream_array_len < 1)
|
||||
errx(-1, "net.isr.workstream: no data");
|
||||
xo_errx(-1, "net.isr.workstream: no data");
|
||||
if (workstream_array[0].snws_version != sizeof(workstream_array[0]))
|
||||
errx(-1, "net.isr.workstream: invalid version");
|
||||
xo_errx(-1, "net.isr.workstream: invalid version");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -437,21 +438,21 @@ netisr_load_sysctl_work(void)
|
||||
size_t len;
|
||||
|
||||
if (sysctlbyname("net.isr.work", NULL, &len, NULL, 0) < 0)
|
||||
err(-1, "net.isr.work: query len");
|
||||
xo_err(-1, "net.isr.work: query len");
|
||||
if (len % sizeof(*work_array) != 0)
|
||||
errx(-1, "net.isr.work: invalid len");
|
||||
xo_errx(-1, "net.isr.work: invalid len");
|
||||
work_array = malloc(len);
|
||||
if (work_array == NULL)
|
||||
err(-1, "malloc");
|
||||
xo_err(-1, "malloc");
|
||||
if (sysctlbyname("net.isr.work", work_array, &len, NULL, 0) < 0)
|
||||
err(-1, "net.isr.work: query data");
|
||||
xo_err(-1, "net.isr.work: query data");
|
||||
if (len % sizeof(*work_array) != 0)
|
||||
errx(-1, "net.isr.work: invalid len");
|
||||
xo_errx(-1, "net.isr.work: invalid len");
|
||||
work_array_len = len / sizeof(*work_array);
|
||||
if (work_array_len < 1)
|
||||
errx(-1, "net.isr.work: no data");
|
||||
xo_errx(-1, "net.isr.work: no data");
|
||||
if (work_array[0].snw_version != sizeof(work_array[0]))
|
||||
errx(-1, "net.isr.work: invalid version");
|
||||
xo_errx(-1, "net.isr.work: invalid version");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -459,17 +460,17 @@ netisr_print_proto(struct sysctl_netisr_proto *snpp)
|
||||
{
|
||||
char tmp[20];
|
||||
|
||||
printf("%-6s", snpp->snp_name);
|
||||
printf(" %5u", snpp->snp_proto);
|
||||
printf(" %6u", snpp->snp_qlimit);
|
||||
printf(" %6s",
|
||||
xo_emit("{[:-6}{k:name/%s}{]:}", snpp->snp_name);
|
||||
xo_emit(" {:protocol/%5u}", snpp->snp_proto);
|
||||
xo_emit(" {:queue-limit/%6u}", snpp->snp_qlimit);
|
||||
xo_emit(" {:policy-type/%6s}",
|
||||
(snpp->snp_policy == NETISR_POLICY_SOURCE) ? "source" :
|
||||
(snpp->snp_policy == NETISR_POLICY_FLOW) ? "flow" :
|
||||
(snpp->snp_policy == NETISR_POLICY_CPU) ? "cpu" : "-");
|
||||
netisr_dispatch_policy_to_string(snpp->snp_dispatch, tmp,
|
||||
sizeof(tmp));
|
||||
printf(" %8s", tmp);
|
||||
printf(" %s%s%s\n",
|
||||
xo_emit(" {:policy/%8s}", tmp);
|
||||
xo_emit(" {:flags/%s%s%s}\n",
|
||||
(snpp->snp_flags & NETISR_SNP_FLAGS_M2CPUID) ? "C" : "-",
|
||||
(snpp->snp_flags & NETISR_SNP_FLAGS_DRAINEDCPU) ? "D" : "-",
|
||||
(snpp->snp_flags & NETISR_SNP_FLAGS_M2FLOW) ? "F" : "-");
|
||||
@ -481,23 +482,28 @@ netisr_print_workstream(struct sysctl_netisr_workstream *snwsp)
|
||||
struct sysctl_netisr_work *snwp;
|
||||
u_int i;
|
||||
|
||||
xo_open_list("work");
|
||||
for (i = 0; i < work_array_len; i++) {
|
||||
snwp = &work_array[i];
|
||||
if (snwp->snw_wsid != snwsp->snws_wsid)
|
||||
continue;
|
||||
printf("%4u ", snwsp->snws_wsid);
|
||||
printf("%3u ", snwsp->snws_cpu);
|
||||
printf("%2s", "");
|
||||
printf("%-6s", netisr_proto2name(snwp->snw_proto));
|
||||
printf(" %5u", snwp->snw_len);
|
||||
printf(" %5u", snwp->snw_watermark);
|
||||
printf(" %8ju", snwp->snw_dispatched);
|
||||
printf(" %8ju", snwp->snw_hybrid_dispatched);
|
||||
printf(" %8ju", snwp->snw_qdrops);
|
||||
printf(" %8ju", snwp->snw_queued);
|
||||
printf(" %8ju", snwp->snw_handled);
|
||||
printf("\n");
|
||||
xo_open_instance("work");
|
||||
xo_emit("{t:workstream/%4u} ", snwsp->snws_wsid);
|
||||
xo_emit("{t:cpu/%3u} ", snwsp->snws_cpu);
|
||||
xo_emit("{P: }");
|
||||
xo_emit("{t:name/%-6s}", netisr_proto2name(snwp->snw_proto));
|
||||
xo_emit(" {t:length/%5u}", snwp->snw_len);
|
||||
xo_emit(" {t:watermark/%5u}", snwp->snw_watermark);
|
||||
xo_emit(" {t:dispatched/%8ju}", snwp->snw_dispatched);
|
||||
xo_emit(" {t:hybrid-dispatched/%8ju}",
|
||||
snwp->snw_hybrid_dispatched);
|
||||
xo_emit(" {t:queue-drops/%8ju}", snwp->snw_qdrops);
|
||||
xo_emit(" {t:queued/%8ju}", snwp->snw_queued);
|
||||
xo_emit(" {t:handled/%8ju}", snwp->snw_handled);
|
||||
xo_emit("\n");
|
||||
xo_close_instance("work");
|
||||
}
|
||||
xo_close_list("work");
|
||||
}
|
||||
|
||||
void
|
||||
@ -515,39 +521,55 @@ netisr_stats(void *kvmd)
|
||||
netisr_load_sysctl_work();
|
||||
} else {
|
||||
if (kd == NULL)
|
||||
errx(-1, "netisr_stats: !live but !kd");
|
||||
xo_errx(-1, "netisr_stats: !live but !kd");
|
||||
netisr_load_kvm_config(kd);
|
||||
netisr_load_kvm_proto(kd);
|
||||
netisr_load_kvm_workstream(kd); /* Also does work. */
|
||||
}
|
||||
|
||||
printf("Configuration:\n");
|
||||
printf("%-25s %12s %12s\n", "Setting", "Current", "Limit");
|
||||
printf("%-25s %12u %12u\n", "Thread count", numthreads, maxthreads);
|
||||
printf("%-25s %12u %12u\n", "Default queue limit", defaultqlimit,
|
||||
maxqlimit);
|
||||
printf("%-25s %12s %12s\n", "Dispatch policy", dispatch_policy,
|
||||
"n/a");
|
||||
printf("%-25s %12s %12s\n", "Threads bound to CPUs",
|
||||
bindthreads ? "enabled" : "disabled", "n/a");
|
||||
printf("\n");
|
||||
xo_open_container("netisr");
|
||||
|
||||
printf("Protocols:\n");
|
||||
printf("%-6s %5s %6s %-6s %-8s %-5s\n", "Name", "Proto", "QLimit",
|
||||
"Policy", "Dispatch", "Flags");
|
||||
xo_emit("{T:Configuration}:\n");
|
||||
xo_emit("{T:/%-25s} {T:/%12s} {T:/%12s}\n",
|
||||
"Setting", "Current", "Limit");
|
||||
xo_emit("{T:/%-25s} {T:/%12u} {T:/%12u}\n",
|
||||
"Thread count", numthreads, maxthreads);
|
||||
xo_emit("{T:/%-25s} {T:/%12u} {T:/%12u}\n",
|
||||
"Default queue limit", defaultqlimit, maxqlimit);
|
||||
xo_emit("{T:/%-25s} {T:/%12s} {T:/%12s}\n",
|
||||
"Dispatch policy", dispatch_policy, "n/a");
|
||||
xo_emit("{T:/%-25s} {T:/%12s} {T:/%12s}\n",
|
||||
"Threads bound to CPUs", bindthreads ? "enabled" : "disabled",
|
||||
"n/a");
|
||||
xo_emit("\n");
|
||||
|
||||
xo_emit("{T:Protocols}:\n");
|
||||
xo_emit("{T:/%-6s} {T:/%5s} {T:/%6s} {T:/%-6s} {T:/%-8s} {T:/%-5s}\n",
|
||||
"Name", "Proto", "QLimit", "Policy", "Dispatch", "Flags");
|
||||
xo_open_list("protocol");
|
||||
for (i = 0; i < proto_array_len; i++) {
|
||||
xo_open_instance("protocol");
|
||||
snpp = &proto_array[i];
|
||||
netisr_print_proto(snpp);
|
||||
xo_close_instance("protocol");
|
||||
}
|
||||
printf("\n");
|
||||
xo_close_list("protocol");
|
||||
xo_emit("\n");
|
||||
|
||||
printf("Workstreams:\n");
|
||||
printf("%4s %3s ", "WSID", "CPU");
|
||||
printf("%2s", "");
|
||||
printf("%-6s %5s %5s %8s %8s %8s %8s %8s\n", "Name", "Len", "WMark",
|
||||
"Disp'd", "HDisp'd", "QDrops", "Queued", "Handled");
|
||||
xo_emit("{T:Workstreams}:\n");
|
||||
xo_emit("{T:/%4s} {T:/%3s} ", "WSID", "CPU");
|
||||
xo_emit("{P:/%2s}", "");
|
||||
xo_emit("{T:/%-6s} {T:/%5s} {T:/%5s} {T:/%8s} {T:/%8s} {T:/%8s} "
|
||||
"{T:/%8s} {T:/%8s}\n",
|
||||
"Name", "Len", "WMark", "Disp'd", "HDisp'd", "QDrops", "Queued",
|
||||
"Handled");
|
||||
xo_open_list("workstream");
|
||||
for (i = 0; i < workstream_array_len; i++) {
|
||||
xo_open_instance("workstream");
|
||||
snwsp = &workstream_array[i];
|
||||
netisr_print_workstream(snwsp);
|
||||
xo_close_instance("workstream");
|
||||
}
|
||||
xo_close_list("workstream");
|
||||
xo_close_container("netisr");
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ struct in6_addr;
|
||||
void in6_fillscopeid(struct sockaddr_in6 *);
|
||||
char *routename6(struct sockaddr_in6 *);
|
||||
const char *netname6(struct sockaddr_in6 *, struct in6_addr *);
|
||||
void inet6print(struct in6_addr *, int, const char *, int);
|
||||
void inet6print(const char *, struct in6_addr *, int, const char *, int);
|
||||
#endif /*INET6*/
|
||||
|
||||
#ifdef IPSEC
|
||||
@ -143,7 +143,7 @@ void nserr_stats(u_long, const char *, int, int);
|
||||
void netgraphprotopr(u_long, const char *, int, int);
|
||||
#endif
|
||||
|
||||
void unixpr(u_long, u_long, u_long, u_long, u_long);
|
||||
void unixpr(u_long, u_long, u_long, u_long, u_long, bool *);
|
||||
|
||||
void esis_stats(u_long, const char *, int, int);
|
||||
void clnp_stats(u_long, const char *, int, int);
|
||||
|
@ -81,6 +81,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
#ifdef IPSEC
|
||||
@ -118,59 +120,89 @@ pfkey_stats(u_long off, const char *name, int family __unused,
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
xo_open_container(name);
|
||||
kread_counters(off, (char *)&pfkeystat, sizeof(pfkeystat));
|
||||
|
||||
#define p(f, m) if (pfkeystat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)pfkeystat.f, plural(pfkeystat.f))
|
||||
xo_emit(m, (uintmax_t)pfkeystat.f, plural(pfkeystat.f))
|
||||
|
||||
/* userland -> kernel */
|
||||
p(out_total, "\t%ju request%s sent from userland\n");
|
||||
p(out_bytes, "\t%ju byte%s sent from userland\n");
|
||||
p(out_total, "\t{:sent-requests//%ju} "
|
||||
"{N:/request%s sent from userland}\n");
|
||||
p(out_bytes, "\t{:sent-bytes/%ju} "
|
||||
"{N:/byte%s sent from userland}\n");
|
||||
for (first = 1, type = 0;
|
||||
type < sizeof(pfkeystat.out_msgtype)/sizeof(pfkeystat.out_msgtype[0]);
|
||||
type++) {
|
||||
type<sizeof(pfkeystat.out_msgtype)/sizeof(pfkeystat.out_msgtype[0]);
|
||||
type++) {
|
||||
if (pfkeystat.out_msgtype[type] <= 0)
|
||||
continue;
|
||||
if (first) {
|
||||
printf("\thistogram by message type:\n");
|
||||
xo_open_list("output-histogram");
|
||||
xo_emit("\t{T:histogram by message type}:\n");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t%s: %ju\n", pfkey_msgtype_names(type),
|
||||
(uintmax_t)pfkeystat.out_msgtype[type]);
|
||||
xo_open_instance("output-histogram");
|
||||
xo_emit("\t\t{k::type/%s}: {:count/%ju}\n",
|
||||
pfkey_msgtype_names(type),
|
||||
(uintmax_t)pfkeystat.out_msgtype[type]);
|
||||
xo_close_instance("output-histogram");
|
||||
}
|
||||
p(out_invlen, "\t%ju message%s with invalid length field\n");
|
||||
p(out_invver, "\t%ju message%s with invalid version field\n");
|
||||
p(out_invmsgtype, "\t%ju message%s with invalid message type field\n");
|
||||
p(out_tooshort, "\t%ju message%s too short\n");
|
||||
p(out_nomem, "\t%ju message%s with memory allocation failure\n");
|
||||
p(out_dupext, "\t%ju message%s with duplicate extension\n");
|
||||
p(out_invexttype, "\t%ju message%s with invalid extension type\n");
|
||||
p(out_invsatype, "\t%ju message%s with invalid sa type\n");
|
||||
p(out_invaddr, "\t%ju message%s with invalid address extension\n");
|
||||
if (!first)
|
||||
xo_close_list("output-histogram");
|
||||
|
||||
p(out_invlen, "\t{:dropped-bad-length/%ju} "
|
||||
"{N:/message%s with invalid length field}\n");
|
||||
p(out_invver, "\t{:dropped-bad-version/%ju} "
|
||||
"{N:/message%s with invalid version field}\n");
|
||||
p(out_invmsgtype, "\t{:dropped-bad-type/%ju} "
|
||||
"{N:/message%s with invalid message type field}\n");
|
||||
p(out_tooshort, "\t{:dropped-too-short/%ju} "
|
||||
"{N:/message%s too short}\n");
|
||||
p(out_nomem, "\t{:dropped-no-memory/%ju} "
|
||||
"{N:/message%s with memory allocation failure}\n");
|
||||
p(out_dupext, "\t{:dropped-duplicate-extension/%ju} "
|
||||
"{N:/message%s with duplicate extension}\n");
|
||||
p(out_invexttype, "\t{:dropped-bad-extension/%ju} "
|
||||
"{N:/message%s with invalid extension type}\n");
|
||||
p(out_invsatype, "\t:dropped-bad-sa-type/%ju} "
|
||||
"{N:/message%s with invalid sa type}\n");
|
||||
p(out_invaddr, "\t{:dropped-bad-address-extension/%ju} "
|
||||
"{N:/message%s with invalid address extension}\n");
|
||||
|
||||
/* kernel -> userland */
|
||||
p(in_total, "\t%ju request%s sent to userland\n");
|
||||
p(in_bytes, "\t%ju byte%s sent to userland\n");
|
||||
p(in_total, "\t{:received-requests/%ju} "
|
||||
"{N:/request%s sent to userland}\n");
|
||||
p(in_bytes, "\t{:received-bytes/%ju} "
|
||||
"{N:/byte%s sent to userland}\n");
|
||||
for (first = 1, type = 0;
|
||||
type < sizeof(pfkeystat.in_msgtype)/sizeof(pfkeystat.in_msgtype[0]);
|
||||
type++) {
|
||||
type < sizeof(pfkeystat.in_msgtype)/sizeof(pfkeystat.in_msgtype[0]);
|
||||
type++) {
|
||||
if (pfkeystat.in_msgtype[type] <= 0)
|
||||
continue;
|
||||
if (first) {
|
||||
printf("\thistogram by message type:\n");
|
||||
xo_open_list("input-histogram");
|
||||
xo_emit("\t{T:histogram by message type}:\n");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t%s: %ju\n", pfkey_msgtype_names(type),
|
||||
(uintmax_t)pfkeystat.in_msgtype[type]);
|
||||
xo_open_instance("input-histogram");
|
||||
xo_emit("\t\t{k:type/%s}: {:count/%ju}\n",
|
||||
pfkey_msgtype_names(type),
|
||||
(uintmax_t)pfkeystat.in_msgtype[type]);
|
||||
xo_close_instance("input-histogram");
|
||||
}
|
||||
p(in_msgtarget[KEY_SENDUP_ONE],
|
||||
"\t%ju message%s toward single socket\n");
|
||||
p(in_msgtarget[KEY_SENDUP_ALL],
|
||||
"\t%ju message%s toward all sockets\n");
|
||||
if (!first)
|
||||
xo_close_list("input-histogram");
|
||||
p(in_msgtarget[KEY_SENDUP_ONE], "\t{:received-one-socket/%ju} "
|
||||
"{N:/message%s toward single socket}\n");
|
||||
p(in_msgtarget[KEY_SENDUP_ALL], "\t{:received-all-sockets/%ju} "
|
||||
"{N:/message%s toward all sockets}\n");
|
||||
p(in_msgtarget[KEY_SENDUP_REGISTERED],
|
||||
"\t%ju message%s toward registered sockets\n");
|
||||
p(in_nomem, "\t%ju message%s with memory allocation failure\n");
|
||||
"\t{:received-registered-sockets/%ju} "
|
||||
"{N:/message%s toward registered sockets}\n");
|
||||
p(in_nomem, "\t{:discarded-no-memory/%ju} "
|
||||
"{N:/message%s with memory allocation failure}\n");
|
||||
#undef p
|
||||
xo_close_container(name);
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
|
@ -64,10 +64,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d)))
|
||||
@ -78,25 +80,26 @@ __FBSDID("$FreeBSD$");
|
||||
struct bits {
|
||||
u_long b_mask;
|
||||
char b_val;
|
||||
const char *b_name;
|
||||
} bits[] = {
|
||||
{ RTF_UP, 'U' },
|
||||
{ RTF_GATEWAY, 'G' },
|
||||
{ RTF_HOST, 'H' },
|
||||
{ RTF_REJECT, 'R' },
|
||||
{ RTF_DYNAMIC, 'D' },
|
||||
{ RTF_MODIFIED, 'M' },
|
||||
{ RTF_DONE, 'd' }, /* Completed -- for routing messages only */
|
||||
{ RTF_XRESOLVE, 'X' },
|
||||
{ RTF_STATIC, 'S' },
|
||||
{ RTF_PROTO1, '1' },
|
||||
{ RTF_PROTO2, '2' },
|
||||
{ RTF_PROTO3, '3' },
|
||||
{ RTF_BLACKHOLE,'B' },
|
||||
{ RTF_BROADCAST,'b' },
|
||||
{ RTF_UP, 'U', "up" },
|
||||
{ RTF_GATEWAY, 'G', "gateway" },
|
||||
{ RTF_HOST, 'H', "host" },
|
||||
{ RTF_REJECT, 'R', "reject" },
|
||||
{ RTF_DYNAMIC, 'D', "dynamic" },
|
||||
{ RTF_MODIFIED, 'M', "modified" },
|
||||
{ RTF_DONE, 'd', "done" }, /* Completed -- for routing msgs only */
|
||||
{ RTF_XRESOLVE, 'X', "xresolve" },
|
||||
{ RTF_STATIC, 'S', "static" },
|
||||
{ RTF_PROTO1, '1', "proto1" },
|
||||
{ RTF_PROTO2, '2', "proto2" },
|
||||
{ RTF_PROTO3, '3', "proto3" },
|
||||
{ RTF_BLACKHOLE,'B', "blackhole" },
|
||||
{ RTF_BROADCAST,'b', "broadcast" },
|
||||
#ifdef RTF_LLINFO
|
||||
{ RTF_LLINFO, 'L' },
|
||||
{ RTF_LLINFO, 'L', "llinfo" },
|
||||
#endif
|
||||
{ 0 , 0 }
|
||||
{ 0 , 0, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -143,14 +146,15 @@ static void size_cols_rtentry(struct rtentry *rt);
|
||||
static void p_rtnode_kvm(void);
|
||||
static void p_rtable_sysctl(int, int);
|
||||
static void p_rtable_kvm(int, int );
|
||||
static void p_rtree_kvm(struct radix_node *);
|
||||
static void p_rtentry_sysctl(struct rt_msghdr *);
|
||||
static void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int);
|
||||
static void p_rtree_kvm(const char *name, struct radix_node *);
|
||||
static void p_rtentry_kvm(const char *name, struct rtentry *);
|
||||
static void p_rtentry_sysctl(const char *name, struct rt_msghdr *);
|
||||
static void p_sockaddr(const char *name, struct sockaddr *, struct sockaddr *,
|
||||
int, int);
|
||||
static const char *fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask,
|
||||
int flags);
|
||||
static void p_flags(int, const char *);
|
||||
static const char *fmt_flags(int f);
|
||||
static void p_rtentry_kvm(struct rtentry *);
|
||||
static void domask(char *, in_addr_t, u_long);
|
||||
|
||||
/*
|
||||
@ -178,15 +182,17 @@ routepr(int fibnum, int af)
|
||||
if (clock_gettime(CLOCK_UPTIME, &uptime) < 0)
|
||||
err(EX_OSERR, "clock_gettime() failed");
|
||||
|
||||
printf("Routing tables");
|
||||
xo_open_container("route-information");
|
||||
xo_emit("{T:Routing tables}");
|
||||
if (fibnum)
|
||||
printf(" (fib: %d)", fibnum);
|
||||
printf("\n");
|
||||
xo_emit(" ({L:fib}: {:fib/%d})", fibnum);
|
||||
xo_emit("\n");
|
||||
|
||||
if (Aflag == 0 && live != 0 && NewTree)
|
||||
p_rtable_sysctl(fibnum, af);
|
||||
else
|
||||
p_rtable_kvm(fibnum, af);
|
||||
xo_close_container("route-information");
|
||||
}
|
||||
|
||||
|
||||
@ -221,9 +227,9 @@ pr_family(int af1)
|
||||
break;
|
||||
}
|
||||
if (afname)
|
||||
printf("\n%s:\n", afname);
|
||||
xo_emit("\n{k:address-family/%s}:\n", afname);
|
||||
else
|
||||
printf("\nProtocol Family %d:\n", af1);
|
||||
xo_emit("\n{L:Protocol Family} {k:address-family/%d}:\n", af1);
|
||||
}
|
||||
|
||||
/* column widths; each followed by one space */
|
||||
@ -320,7 +326,7 @@ size_cols_rtentry(struct rtentry *rt)
|
||||
}
|
||||
if (rt->rt_ifp) {
|
||||
if (rt->rt_ifp != lastif) {
|
||||
if (kget(rt->rt_ifp, ifnet) == 0)
|
||||
if (kget(rt->rt_ifp, ifnet) == 0)
|
||||
len = strlen(ifnet.if_xname);
|
||||
else
|
||||
len = strlen("---");
|
||||
@ -333,7 +339,7 @@ size_cols_rtentry(struct rtentry *rt)
|
||||
if ((expire_time =
|
||||
rt->rt_expire - uptime.tv_sec) > 0) {
|
||||
len = snprintf(buffer, sizeof(buffer), "%d",
|
||||
(int)expire_time);
|
||||
(int)expire_time);
|
||||
wid_expire = MAX(len, wid_expire);
|
||||
}
|
||||
}
|
||||
@ -349,9 +355,10 @@ pr_rthdr(int af1)
|
||||
{
|
||||
|
||||
if (Aflag)
|
||||
printf("%-8.8s ","Address");
|
||||
xo_emit("{T:/%-8.8s} ","Address");
|
||||
if (Wflag) {
|
||||
printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n",
|
||||
xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} "
|
||||
"{T:/%*.*s} {T:/%*.*s} {T:/%*.*s} {T:/%*s}\n",
|
||||
wid_dst, wid_dst, "Destination",
|
||||
wid_gw, wid_gw, "Gateway",
|
||||
wid_flags, wid_flags, "Flags",
|
||||
@ -360,7 +367,8 @@ pr_rthdr(int af1)
|
||||
wid_if, wid_if, "Netif",
|
||||
wid_expire, "Expire");
|
||||
} else {
|
||||
printf("%-*.*s %-*.*s %-*.*s %*.*s %*s\n",
|
||||
xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} "
|
||||
"{T:/%*s}\n",
|
||||
wid_dst, wid_dst, "Destination",
|
||||
wid_gw, wid_gw, "Gateway",
|
||||
wid_flags, wid_flags, "Flags",
|
||||
@ -391,10 +399,11 @@ p_rtable_kvm(int fibnum, int af)
|
||||
struct radix_node_head **rt_tables;
|
||||
u_long rtree;
|
||||
int fam, af_size;
|
||||
bool did_rt_family = false;
|
||||
|
||||
kresolve_list(rl);
|
||||
if ((rtree = rl[N_RTREE].n_value) == 0) {
|
||||
printf("rt_tables: symbol not in namelist\n");
|
||||
xo_emit("rt_tables: symbol not in namelist\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -406,6 +415,7 @@ p_rtable_kvm(int fibnum, int af)
|
||||
if (kread((u_long)(rtree), (char *)(rt_tables) + fibnum * af_size,
|
||||
af_size) != 0)
|
||||
err(EX_OSERR, "error retrieving radix pointers");
|
||||
xo_open_container("route-table");
|
||||
for (fam = 0; fam <= AF_MAX; fam++) {
|
||||
int tmpfib;
|
||||
|
||||
@ -430,17 +440,30 @@ p_rtable_kvm(int fibnum, int af)
|
||||
continue;
|
||||
if (fam == AF_UNSPEC) {
|
||||
if (Aflag && af == 0) {
|
||||
printf("Netmasks:\n");
|
||||
p_rtree_kvm(head.rnh_treetop);
|
||||
xo_emit("{T:Netmasks}:\n");
|
||||
xo_open_list("netmasks");
|
||||
p_rtree_kvm("netmasks", head.rnh_treetop);
|
||||
xo_close_list("netmasks");
|
||||
}
|
||||
} else if (af == AF_UNSPEC || af == fam) {
|
||||
if (!did_rt_family) {
|
||||
xo_open_list("rt-family");
|
||||
did_rt_family = true;
|
||||
}
|
||||
size_cols(fam, head.rnh_treetop);
|
||||
xo_open_instance("rt-family");
|
||||
pr_family(fam);
|
||||
do_rtent = 1;
|
||||
xo_open_list("rt-entry");
|
||||
pr_rthdr(fam);
|
||||
p_rtree_kvm(head.rnh_treetop);
|
||||
p_rtree_kvm("rt-entry", head.rnh_treetop);
|
||||
xo_close_list("rt-entry");
|
||||
xo_close_instance("rt-family");
|
||||
}
|
||||
}
|
||||
if (did_rt_family)
|
||||
xo_close_list("rt-family");
|
||||
xo_close_container("route-table");
|
||||
|
||||
free(rt_tables);
|
||||
}
|
||||
@ -450,8 +473,18 @@ p_rtable_kvm(int fibnum, int af)
|
||||
* debugging kvm(3) interface.
|
||||
*/
|
||||
static void
|
||||
p_rtree_kvm(struct radix_node *rn)
|
||||
p_rtree_kvm(const char *name, struct radix_node *rn)
|
||||
{
|
||||
bool opened;
|
||||
|
||||
opened = false;
|
||||
|
||||
#define DOOPEN() do { \
|
||||
if (!opened) { xo_open_instance(name); opened = true; } \
|
||||
} while (0)
|
||||
#define DOCLOSE() do { \
|
||||
if (opened) { opened = false; xo_close_instance(name); } \
|
||||
} while(0)
|
||||
|
||||
again:
|
||||
if (kget(rn, rnode) != 0)
|
||||
@ -459,33 +492,46 @@ p_rtree_kvm(struct radix_node *rn)
|
||||
if (!(rnode.rn_flags & RNF_ACTIVE))
|
||||
return;
|
||||
if (rnode.rn_bit < 0) {
|
||||
if (Aflag)
|
||||
printf("%-8.8lx ", (u_long)rn);
|
||||
if (Aflag) {
|
||||
DOOPEN();
|
||||
xo_emit("{q:radix-node/%-8.8lx} ", (u_long)rn);
|
||||
}
|
||||
if (rnode.rn_flags & RNF_ROOT) {
|
||||
if (Aflag)
|
||||
printf("(root node)%s",
|
||||
if (Aflag) {
|
||||
DOOPEN();
|
||||
xo_emit("({:root/root} node){L:/%s}",
|
||||
rnode.rn_dupedkey ? " =>\n" : "\n");
|
||||
}
|
||||
} else if (do_rtent) {
|
||||
if (kget(rn, rtentry) == 0) {
|
||||
p_rtentry_kvm(&rtentry);
|
||||
if (Aflag)
|
||||
DOOPEN();
|
||||
p_rtentry_kvm(name, &rtentry);
|
||||
if (Aflag) {
|
||||
DOOPEN();
|
||||
p_rtnode_kvm();
|
||||
DOCLOSE();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),
|
||||
NULL, 0, 44);
|
||||
putchar('\n');
|
||||
DOOPEN();
|
||||
p_sockaddr("address",
|
||||
kgetsa((struct sockaddr *)rnode.rn_key),
|
||||
NULL, 0, 44);
|
||||
xo_emit("\n");
|
||||
}
|
||||
DOCLOSE();
|
||||
if ((rn = rnode.rn_dupedkey))
|
||||
goto again;
|
||||
} else {
|
||||
if (Aflag && do_rtent) {
|
||||
printf("%-8.8lx ", (u_long)rn);
|
||||
DOOPEN();
|
||||
xo_emit("{q:radix-node/%-8.8lx} ", (u_long)rn);
|
||||
p_rtnode_kvm();
|
||||
DOCLOSE();
|
||||
}
|
||||
rn = rnode.rn_right;
|
||||
p_rtree_kvm(rnode.rn_left);
|
||||
p_rtree_kvm(rn);
|
||||
p_rtree_kvm(name, rnode.rn_left);
|
||||
p_rtree_kvm(name, rn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,37 +544,41 @@ p_rtnode_kvm(void)
|
||||
|
||||
if (rnode.rn_bit < 0) {
|
||||
if (rnode.rn_mask) {
|
||||
printf("\t mask ");
|
||||
p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask),
|
||||
NULL, 0, -1);
|
||||
xo_emit("\t {L:mask} ");
|
||||
p_sockaddr("netmask",
|
||||
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);
|
||||
xo_emit("{[:6}{:bit/(%d)}{]:} {q:left-node/%8.8lx} "
|
||||
": {q:right-node/%8.8lx}", rnode.rn_bit,
|
||||
(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 : " ");
|
||||
xo_emit(" mk = {q:node/%8.8lx} \\{({:bit/%d}),{nbufs/%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>, ");
|
||||
xo_emit(" <{:mode/normal}>, ");
|
||||
if (kget(rmask.rm_leaf, rnode_aux) == 0)
|
||||
p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask),
|
||||
p_sockaddr("netmask",
|
||||
kgetsa(/*XXX*/(void *)rnode_aux.rn_mask),
|
||||
NULL, 0, -1);
|
||||
else
|
||||
p_sockaddr(NULL, NULL, 0, -1);
|
||||
p_sockaddr(NULL, NULL, NULL, 0, -1);
|
||||
} else
|
||||
p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask),
|
||||
NULL, 0, -1);
|
||||
putchar('}');
|
||||
p_sockaddr("netmask",
|
||||
kgetsa((struct sockaddr *)rmask.rm_mask),
|
||||
NULL, 0, -1);
|
||||
xo_emit("\\}");
|
||||
if ((rm = rmask.rm_mklist))
|
||||
printf(" ->");
|
||||
xo_emit(" {D:->}");
|
||||
}
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -539,7 +589,8 @@ p_rtable_sysctl(int fibnum, int af)
|
||||
char *buf, *next, *lim;
|
||||
struct rt_msghdr *rtm;
|
||||
struct sockaddr *sa;
|
||||
int fam = 0, ifindex = 0, size;
|
||||
int fam = AF_UNSPEC, ifindex = 0, size;
|
||||
int need_table_close = false;
|
||||
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
@ -566,7 +617,7 @@ p_rtable_sysctl(int fibnum, int af)
|
||||
errx(2, "realloc(%d) failed", size);
|
||||
memset(&ifmap[ifmap_size], 0,
|
||||
size - ifmap_size *
|
||||
sizeof(struct ifmap_entry));
|
||||
sizeof(struct ifmap_entry));
|
||||
|
||||
ifmap_size = roundup(ifindex + 1, 32);
|
||||
}
|
||||
@ -594,6 +645,8 @@ p_rtable_sysctl(int fibnum, int af)
|
||||
if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0)
|
||||
err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum);
|
||||
lim = buf + needed;
|
||||
xo_open_container("route-table");
|
||||
xo_open_list("rt-family");
|
||||
for (next = buf; next < lim; next += rtm->rtm_msglen) {
|
||||
rtm = (struct rt_msghdr *)next;
|
||||
if (rtm->rtm_version != RTM_VERSION)
|
||||
@ -602,19 +655,35 @@ p_rtable_sysctl(int fibnum, int af)
|
||||
* Peek inside header to determine AF
|
||||
*/
|
||||
sa = (struct sockaddr *)(rtm + 1);
|
||||
/* Only print family first time. */
|
||||
if (fam != sa->sa_family) {
|
||||
if (need_table_close) {
|
||||
xo_close_list("rt-entry");
|
||||
xo_close_instance("rt-family");
|
||||
}
|
||||
need_table_close = true;
|
||||
|
||||
fam = sa->sa_family;
|
||||
size_cols(fam, NULL);
|
||||
xo_open_instance("rt-family");
|
||||
pr_family(fam);
|
||||
xo_open_list("rt-entry");
|
||||
|
||||
pr_rthdr(fam);
|
||||
}
|
||||
p_rtentry_sysctl(rtm);
|
||||
p_rtentry_sysctl("rt-entry", rtm);
|
||||
}
|
||||
if (need_table_close) {
|
||||
xo_close_list("rt-entry");
|
||||
xo_close_instance("rt-family");
|
||||
}
|
||||
xo_close_list("rt-family");
|
||||
xo_close_container("route-table");
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
p_rtentry_sysctl(struct rt_msghdr *rtm)
|
||||
p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm)
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
|
||||
char buffer[128];
|
||||
@ -622,6 +691,8 @@ p_rtentry_sysctl(struct rt_msghdr *rtm)
|
||||
sa_u addr, mask, gw;
|
||||
unsigned int l;
|
||||
|
||||
xo_open_instance(name);
|
||||
|
||||
#define GETSA(_s, _f) { \
|
||||
bzero(&(_s), sizeof(_s)); \
|
||||
if (rtm->rtm_addrs & _f) { \
|
||||
@ -634,18 +705,20 @@ p_rtentry_sysctl(struct rt_msghdr *rtm)
|
||||
GETSA(addr, RTA_DST);
|
||||
GETSA(gw, RTA_GATEWAY);
|
||||
GETSA(mask, RTA_NETMASK);
|
||||
p_sockaddr(&addr.u_sa, &mask.u_sa, rtm->rtm_flags, wid_dst);
|
||||
p_sockaddr(&gw.u_sa, NULL, RTF_HOST, wid_gw);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags);
|
||||
p_sockaddr("destination", &addr.u_sa, &mask.u_sa, rtm->rtm_flags,
|
||||
wid_dst);
|
||||
p_sockaddr("gateway", &gw.u_sa, NULL, RTF_HOST, wid_gw);
|
||||
snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:}",
|
||||
wid_flags);
|
||||
p_flags(rtm->rtm_flags, buffer);
|
||||
if (Wflag) {
|
||||
printf("%*lu ", wid_pksent, rtm->rtm_rmx.rmx_pksent);
|
||||
xo_emit("{t:use/%*lu} ", wid_pksent, rtm->rtm_rmx.rmx_pksent);
|
||||
|
||||
if (rtm->rtm_rmx.rmx_mtu != 0)
|
||||
printf("%*lu ", wid_mtu, rtm->rtm_rmx.rmx_mtu);
|
||||
xo_emit("{t:mtu/%*lu} ", wid_mtu, rtm->rtm_rmx.rmx_mtu);
|
||||
else
|
||||
printf("%*s ", wid_mtu, "");
|
||||
xo_emit("{P:/%*s} ", wid_mtu, "");
|
||||
}
|
||||
|
||||
memset(prettyname, 0, sizeof(prettyname));
|
||||
@ -656,32 +729,41 @@ p_rtentry_sysctl(struct rt_msghdr *rtm)
|
||||
strlcpy(prettyname, "---", sizeof(prettyname));
|
||||
}
|
||||
|
||||
printf("%*.*s", wid_if, wid_if, prettyname);
|
||||
xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if, prettyname);
|
||||
if (rtm->rtm_rmx.rmx_expire) {
|
||||
time_t expire_time;
|
||||
|
||||
if ((expire_time =
|
||||
rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0)
|
||||
printf(" %*d", wid_expire, (int)expire_time);
|
||||
if ((expire_time = rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0)
|
||||
xo_emit(" {:expire-time/%*d}", wid_expire,
|
||||
(int)expire_time);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
xo_close_instance(name);
|
||||
}
|
||||
|
||||
static void
|
||||
p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width)
|
||||
p_sockaddr(const char *name, struct sockaddr *sa, struct sockaddr *mask,
|
||||
int flags, int width)
|
||||
{
|
||||
const char *cp;
|
||||
char buf[128];
|
||||
|
||||
cp = fmt_sockaddr(sa, mask, flags);
|
||||
|
||||
if (width < 0 )
|
||||
printf("%s ", cp);
|
||||
else {
|
||||
if (numeric_addr)
|
||||
printf("%-*s ", width, cp);
|
||||
else
|
||||
printf("%-*.*s ", width, width, cp);
|
||||
if (width < 0) {
|
||||
snprintf(buf, sizeof(buf), "{:%s/%%s} ", name);
|
||||
xo_emit(buf, cp);
|
||||
} else {
|
||||
if (numeric_addr) {
|
||||
snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%s}{]:} ",
|
||||
-width, name);
|
||||
xo_emit(buf, cp);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "{[:%d}{:%s/%%-.*s}{]:} ",
|
||||
-width, name);
|
||||
xo_emit(buf, width, cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -742,7 +824,7 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags)
|
||||
case AF_NETGRAPH:
|
||||
{
|
||||
strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data,
|
||||
sizeof(workbuf));
|
||||
sizeof(workbuf));
|
||||
cp = workbuf;
|
||||
break;
|
||||
}
|
||||
@ -798,7 +880,15 @@ fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags)
|
||||
static void
|
||||
p_flags(int f, const char *format)
|
||||
{
|
||||
printf(format, fmt_flags(f));
|
||||
struct bits *p;
|
||||
|
||||
xo_emit(format, fmt_flags(f));
|
||||
|
||||
xo_open_list("flags_pretty");
|
||||
for (p = bits; p->b_mask; p++)
|
||||
if (p->b_mask & f)
|
||||
xo_emit("{le:flags_pretty/%s}", p->b_name);
|
||||
xo_close_list("flags_pretty");
|
||||
}
|
||||
|
||||
static const char *
|
||||
@ -816,7 +906,7 @@ fmt_flags(int f)
|
||||
}
|
||||
|
||||
static void
|
||||
p_rtentry_kvm(struct rtentry *rt)
|
||||
p_rtentry_kvm(const char *name, struct rtentry *rt)
|
||||
{
|
||||
static struct ifnet ifnet, *lastif;
|
||||
static char buffer[128];
|
||||
@ -830,18 +920,21 @@ p_rtentry_kvm(struct rtentry *rt)
|
||||
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_sockaddr("destination", &addr.u_sa, &mask.u_sa, rt->rt_flags,
|
||||
wid_dst);
|
||||
p_sockaddr("gateway", kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw);
|
||||
snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:}",
|
||||
wid_flags);
|
||||
p_flags(rt->rt_flags, buffer);
|
||||
if (Wflag) {
|
||||
printf("%*ju ", wid_pksent,
|
||||
xo_emit("{[:%d}{t:use/%ju}{]:} ", -wid_pksent,
|
||||
(uintmax_t )kread_counter((u_long )rt->rt_pksent));
|
||||
|
||||
if (rt->rt_mtu != 0)
|
||||
printf("%*lu ", wid_mtu, rt->rt_mtu);
|
||||
xo_emit("{t:mtu/%*lu} ", wid_mtu, rt->rt_mtu);
|
||||
else
|
||||
printf("%*s ", wid_mtu, "");
|
||||
xo_emit("{P:/%*s} ", wid_mtu, "");
|
||||
}
|
||||
if (rt->rt_ifp) {
|
||||
if (rt->rt_ifp != lastif) {
|
||||
@ -852,18 +945,19 @@ p_rtentry_kvm(struct rtentry *rt)
|
||||
strlcpy(prettyname, "---", sizeof(prettyname));
|
||||
lastif = rt->rt_ifp;
|
||||
}
|
||||
printf("%*.*s", wid_if, wid_if, prettyname);
|
||||
xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if, prettyname);
|
||||
if (rt->rt_expire) {
|
||||
time_t expire_time;
|
||||
|
||||
if ((expire_time =
|
||||
rt->rt_expire - uptime.tv_sec) > 0)
|
||||
printf(" %*d", wid_expire, (int)expire_time);
|
||||
xo_emit(" {:expire-time/%*d}",
|
||||
wid_expire, (int)expire_time);
|
||||
}
|
||||
if (rt->rt_nodes[0].rn_dupedkey)
|
||||
printf(" =>");
|
||||
xo_emit(" =>");
|
||||
}
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
}
|
||||
|
||||
char *
|
||||
@ -1022,7 +1116,7 @@ netname6(struct sockaddr_in6 *sa6, struct in6_addr *mask)
|
||||
}
|
||||
}
|
||||
if (illegal)
|
||||
fprintf(stderr, "illegal prefixlen\n");
|
||||
xo_error("illegal prefixlen\n");
|
||||
}
|
||||
else
|
||||
masklen = 128;
|
||||
@ -1077,28 +1171,34 @@ rt_stats(void)
|
||||
kresolve_list(rl);
|
||||
|
||||
if ((rtsaddr = rl[N_RTSTAT].n_value) == 0) {
|
||||
printf("rtstat: symbol not in namelist\n");
|
||||
xo_emit("{W:rtstat: symbol not in namelist}\n");
|
||||
return;
|
||||
}
|
||||
if ((rttaddr = rl[N_RTTRASH].n_value) == 0) {
|
||||
printf("rttrash: symbol not in namelist\n");
|
||||
xo_emit("{W:rttrash: symbol not in namelist}\n");
|
||||
return;
|
||||
}
|
||||
kread(rtsaddr, (char *)&rtstat, sizeof (rtstat));
|
||||
kread(rttaddr, (char *)&rttrash, sizeof (rttrash));
|
||||
printf("routing:\n");
|
||||
xo_emit("{T:routing}:\n");
|
||||
|
||||
#define p(f, m) if (rtstat.f || sflag <= 1) \
|
||||
printf(m, rtstat.f, plural(rtstat.f))
|
||||
xo_emit(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");
|
||||
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));
|
||||
}
|
||||
|
@ -58,9 +58,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "netstat.h"
|
||||
#include <libxo/xo.h>
|
||||
|
||||
#ifdef SCTP
|
||||
|
||||
@ -98,8 +100,8 @@ struct xladdr_entry {
|
||||
|
||||
LIST_HEAD(xraddr_list, xraddr_entry) xraddr_head;
|
||||
struct xraddr_entry {
|
||||
struct xsctp_raddr *xraddr;
|
||||
LIST_ENTRY(xraddr_entry) xraddr_entries;
|
||||
struct xsctp_raddr *xraddr;
|
||||
LIST_ENTRY(xraddr_entry) xraddr_entries;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -192,12 +194,16 @@ inet6name(struct in6_addr *in6p)
|
||||
#endif
|
||||
|
||||
static void
|
||||
sctp_print_address(union sctp_sockstore *address, int port, int num_port)
|
||||
sctp_print_address(const char *container, union sctp_sockstore *address,
|
||||
int port, int num_port)
|
||||
{
|
||||
struct servent *sp = 0;
|
||||
char line[80], *cp;
|
||||
int width;
|
||||
|
||||
if (container)
|
||||
xo_open_container(container);
|
||||
|
||||
switch (address->sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
@ -221,7 +227,14 @@ sctp_print_address(union sctp_sockstore *address, int port, int num_port)
|
||||
else
|
||||
sprintf(cp, "%d ", ntohs((u_short)port));
|
||||
width = Wflag ? 45 : 22;
|
||||
printf("%-*.*s ", width, width, line);
|
||||
xo_emit("{d:target/%-*.*s} ", width, width, line);
|
||||
|
||||
int alen = cp - line - 1, plen = strlen(cp) - 1;
|
||||
xo_emit("{e:address/%*.*s}{e:port/%*.*s}", alen, alen, line, plen,
|
||||
plen, cp);
|
||||
|
||||
if (container)
|
||||
xo_close_container(container);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -297,7 +310,7 @@ sctp_process_tcb(struct xsctp_tcb *xstcb,
|
||||
prev_xl = xl;
|
||||
xl = malloc(sizeof(struct xladdr_entry));
|
||||
if (xl == NULL) {
|
||||
warnx("malloc %lu bytes",
|
||||
xo_warnx("malloc %lu bytes",
|
||||
(u_long)sizeof(struct xladdr_entry));
|
||||
goto out;
|
||||
}
|
||||
@ -318,7 +331,7 @@ sctp_process_tcb(struct xsctp_tcb *xstcb,
|
||||
prev_xr = xr;
|
||||
xr = malloc(sizeof(struct xraddr_entry));
|
||||
if (xr == NULL) {
|
||||
warnx("malloc %lu bytes",
|
||||
xo_warnx("malloc %lu bytes",
|
||||
(u_long)sizeof(struct xraddr_entry));
|
||||
goto out;
|
||||
}
|
||||
@ -333,26 +346,29 @@ sctp_process_tcb(struct xsctp_tcb *xstcb,
|
||||
/*
|
||||
* Let's print the address infos.
|
||||
*/
|
||||
xo_open_list("address");
|
||||
xl = LIST_FIRST(&xladdr_head);
|
||||
xr = LIST_FIRST(&xraddr_head);
|
||||
x_max = (xl_total > xr_total) ? xl_total : xr_total;
|
||||
for (i = 0; i < x_max; i++) {
|
||||
xo_open_instance("address");
|
||||
|
||||
if (((*indent == 0) && i > 0) || *indent > 0)
|
||||
printf("%-12s ", " ");
|
||||
xo_emit("{P:/%-12s} ", " ");
|
||||
|
||||
if (xl != NULL) {
|
||||
sctp_print_address(&(xl->xladdr->address),
|
||||
sctp_print_address("local", &(xl->xladdr->address),
|
||||
htons(xstcb->local_port), numeric_port);
|
||||
} else {
|
||||
if (Wflag) {
|
||||
printf("%-45s ", " ");
|
||||
xo_emit("{P:/%-45s} ", " ");
|
||||
} else {
|
||||
printf("%-22s ", " ");
|
||||
xo_emit("{P:/%-22s} ", " ");
|
||||
}
|
||||
}
|
||||
|
||||
if (xr != NULL && !Lflag) {
|
||||
sctp_print_address(&(xr->xraddr->address),
|
||||
sctp_print_address("remote", &(xr->xraddr->address),
|
||||
htons(xstcb->remote_port), numeric_port);
|
||||
}
|
||||
|
||||
@ -365,7 +381,8 @@ sctp_process_tcb(struct xsctp_tcb *xstcb,
|
||||
sctp_statesprint(xstcb->state);
|
||||
|
||||
if (i < x_max)
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
xo_close_instance("address");
|
||||
}
|
||||
|
||||
out:
|
||||
@ -404,23 +421,26 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb,
|
||||
|
||||
if (first) {
|
||||
if (!Lflag) {
|
||||
printf("Active SCTP associations");
|
||||
xo_emit("Active SCTP associations");
|
||||
if (aflag)
|
||||
printf(" (including servers)");
|
||||
xo_emit(" (including servers)");
|
||||
} else
|
||||
printf("Current listen queue sizes (qlen/maxqlen)");
|
||||
putchar('\n');
|
||||
xo_emit("Current listen queue sizes (qlen/maxqlen)");
|
||||
xo_emit("\n");
|
||||
if (Lflag)
|
||||
printf("%-6.6s %-5.5s %-8.8s %-22.22s\n",
|
||||
xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-8.8s} "
|
||||
"{T:/%-22.22s}\n",
|
||||
"Proto", "Type", "Listen", "Local Address");
|
||||
else
|
||||
if (Wflag)
|
||||
printf("%-6.6s %-5.5s %-45.45s %-45.45s %s\n",
|
||||
xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-45.45s} "
|
||||
"{T:/%-45.45s} {T:/%s}\n",
|
||||
"Proto", "Type",
|
||||
"Local Address", "Foreign Address",
|
||||
"(state)");
|
||||
else
|
||||
printf("%-6.6s %-5.5s %-22.22s %-22.22s %s\n",
|
||||
xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-22.22s} "
|
||||
"{T:/%-22.22s} {T:/%s}\n",
|
||||
"Proto", "Type",
|
||||
"Local Address", "Foreign Address",
|
||||
"(state)");
|
||||
@ -450,27 +470,38 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb,
|
||||
char buf1[9];
|
||||
|
||||
snprintf(buf1, 9, "%hu/%hu", xinpcb->qlen, xinpcb->maxqlen);
|
||||
printf("%-6.6s %-5.5s ", pname, tname);
|
||||
printf("%-8.8s ", buf1);
|
||||
xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ",
|
||||
pname, tname);
|
||||
xo_emit("{d:queues/%-8.8s}{e:queue-len/%hu}"
|
||||
"{e:max-queue-len/%hu} ",
|
||||
buf1, xinpcb->qlen, xinpcb->maxqlen);
|
||||
}
|
||||
|
||||
offset_laddr = *offset;
|
||||
process_closed = 0;
|
||||
|
||||
xo_open_list("local-address");
|
||||
retry:
|
||||
while (*offset < buflen) {
|
||||
xladdr = (struct xsctp_laddr *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_laddr);
|
||||
if (xladdr->last) {
|
||||
if (aflag && !Lflag && (xladdr_total == 0) && process_closed) {
|
||||
printf("%-6.6s %-5.5s ", pname, tname);
|
||||
xo_open_instance("local-address");
|
||||
|
||||
xo_emit("{:protocol/%-6.6s/%s} "
|
||||
"{:type/%-5.5s/%s} ", pname, tname);
|
||||
if (Wflag) {
|
||||
printf("%-91.91s CLOSED", " ");
|
||||
xo_emit("{P:/%-91.91s/%s} "
|
||||
"{:state/CLOSED}", " ");
|
||||
} else {
|
||||
printf("%-45.45s CLOSED", " ");
|
||||
xo_emit("{P:/%-45.45s/%s} "
|
||||
"{:state/CLOSED}", " ");
|
||||
}
|
||||
xo_close_instance("local-address");
|
||||
}
|
||||
if (process_closed || is_listening) {
|
||||
putchar('\n');
|
||||
xo_emit("\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -478,31 +509,39 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb,
|
||||
if (!Lflag && !is_listening && !process_closed)
|
||||
continue;
|
||||
|
||||
xo_open_instance("local-address");
|
||||
|
||||
if (xladdr_total == 0) {
|
||||
printf("%-6.6s %-5.5s ", pname, tname);
|
||||
xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ",
|
||||
pname, tname);
|
||||
} else {
|
||||
putchar('\n');
|
||||
printf((Lflag) ?
|
||||
"%-21.21s " : "%-12.12s ", " ");
|
||||
xo_emit("\n");
|
||||
xo_emit(Lflag ? "{P:/%-21.21s} " : "{P:/%-12.12s} ",
|
||||
" ");
|
||||
}
|
||||
sctp_print_address(&(xladdr->address),
|
||||
sctp_print_address("local", &(xladdr->address),
|
||||
htons(xinpcb->local_port), numeric_port);
|
||||
if (aflag && !Lflag && xladdr_total == 0) {
|
||||
if (Wflag) {
|
||||
if (process_closed) {
|
||||
printf("%-45.45s CLOSED", " ");
|
||||
xo_emit("{P:/%-45.45s} "
|
||||
"{:state/CLOSED}", " ");
|
||||
} else {
|
||||
printf("%-45.45s LISTEN", " ");
|
||||
xo_emit("{P:/%-45.45s} "
|
||||
"{:state:LISTEN}", " ");
|
||||
}
|
||||
} else {
|
||||
if (process_closed) {
|
||||
printf("%-22.22s CLOSED", " ");
|
||||
xo_emit("{P:/%-22.22s} "
|
||||
"{:state/CLOSED}", " ");
|
||||
} else {
|
||||
printf("%-22.22s LISTEN", " ");
|
||||
xo_emit("{P:/%-22.22s} "
|
||||
"{:state/LISTEN}", " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
xladdr_total++;
|
||||
xo_close_instance("local-address");
|
||||
}
|
||||
|
||||
xstcb = (struct xsctp_tcb *)(buf + *offset);
|
||||
@ -513,12 +552,15 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb,
|
||||
goto retry;
|
||||
}
|
||||
while (xstcb->last == 0 && *offset < buflen) {
|
||||
printf("%-6.6s %-5.5s ", pname, tname);
|
||||
xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ",
|
||||
pname, tname);
|
||||
sctp_process_tcb(xstcb, buf, buflen, offset, &indent);
|
||||
indent++;
|
||||
xstcb = (struct xsctp_tcb *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_tcb);
|
||||
}
|
||||
|
||||
xo_close_list("local-address");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -540,15 +582,15 @@ sctp_protopr(u_long off __unused,
|
||||
|
||||
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: %s", mibvar);
|
||||
xo_warn("sysctl: %s", mibvar);
|
||||
return;
|
||||
}
|
||||
if ((buf = malloc(len)) == 0) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
xo_warnx("malloc %lu bytes", (u_long)len);
|
||||
return;
|
||||
}
|
||||
if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
|
||||
warn("sysctl: %s", mibvar);
|
||||
xo_warn("sysctl: %s", mibvar);
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
@ -594,11 +636,11 @@ sctp_statesprint(uint32_t state)
|
||||
idx = NETSTAT_SCTP_STATES_SHUTDOWN_PENDING;
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN 0x%08x", state);
|
||||
xo_emit("UNKNOWN {:state/0x%08x}", state);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s", sctpstates[idx]);
|
||||
xo_emit("{:state/%s}", sctpstates[idx]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -616,96 +658,160 @@ sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
if (sysctlbyname("net.inet.sctp.stats", &sctpstat, &len,
|
||||
zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: net.inet.sctp.stats");
|
||||
xo_warn("sysctl: net.inet.sctp.stats");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(off, &sctpstat, len);
|
||||
|
||||
printf ("%s:\n", name);
|
||||
xo_open_container(name);
|
||||
xo_emit("{T:/%s}:\n", name);
|
||||
|
||||
#define p(f, m) if (sctpstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)sctpstat.f, plural(sctpstat.f))
|
||||
xo_emit(m, (uintmax_t)sctpstat.f, plural(sctpstat.f))
|
||||
#define p1a(f, m) if (sctpstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)sctpstat.f)
|
||||
xo_emit(m, (uintmax_t)sctpstat.f)
|
||||
|
||||
/*
|
||||
* input statistics
|
||||
*/
|
||||
p(sctps_recvpackets, "\t%ju input packet%s\n");
|
||||
p(sctps_recvdatagrams, "\t\t%ju datagram%s\n");
|
||||
p(sctps_recvpktwithdata, "\t\t%ju packet%s that had data\n");
|
||||
p(sctps_recvsacks, "\t\t%ju input SACK chunk%s\n");
|
||||
p(sctps_recvdata, "\t\t%ju input DATA chunk%s\n");
|
||||
p(sctps_recvdupdata, "\t\t%ju duplicate DATA chunk%s\n");
|
||||
p(sctps_recvheartbeat, "\t\t%ju input HB chunk%s\n");
|
||||
p(sctps_recvheartbeatack, "\t\t%ju HB-ACK chunk%s\n");
|
||||
p(sctps_recvecne, "\t\t%ju input ECNE chunk%s\n");
|
||||
p(sctps_recvauth, "\t\t%ju input AUTH chunk%s\n");
|
||||
p(sctps_recvauthmissing, "\t\t%ju chunk%s missing AUTH\n");
|
||||
p(sctps_recvivalhmacid, "\t\t%ju invalid HMAC id%s received\n");
|
||||
p(sctps_recvivalkeyid, "\t\t%ju invalid secret id%s received\n");
|
||||
p1a(sctps_recvauthfailed, "\t\t%ju auth failed\n");
|
||||
p1a(sctps_recvexpress, "\t\t%ju fast path receives all one chunk\n");
|
||||
p1a(sctps_recvexpressm, "\t\t%ju fast path multi-part data\n");
|
||||
p(sctps_recvpackets, "\t{:received-packets/%ju} "
|
||||
"{N:/input packet%s}\n");
|
||||
p(sctps_recvdatagrams, "\t\t{:received-datagrams/%ju} "
|
||||
"{N:/datagram%s}\n");
|
||||
p(sctps_recvpktwithdata, "\t\t{:received-with-data/%ju} "
|
||||
"{N:/packet%s that had data}\n");
|
||||
p(sctps_recvsacks, "\t\t{:received-sack-chunks/%ju} "
|
||||
"{N:/input SACK chunk%s}\n");
|
||||
p(sctps_recvdata, "\t\t{:received-data-chunks/%ju} "
|
||||
"{N:/input DATA chunk%s}\n");
|
||||
p(sctps_recvdupdata, "\t\t{:received-duplicate-data-chunks/%ju} "
|
||||
"{N:/duplicate DATA chunk%s}\n");
|
||||
p(sctps_recvheartbeat, "\t\t{:received-hb-chunks/%ju} "
|
||||
"{N:/input HB chunk%s}\n");
|
||||
p(sctps_recvheartbeatack, "\t\t{:received-hb-ack-chunks/%ju} "
|
||||
"{N:/HB-ACK chunk%s}\n");
|
||||
p(sctps_recvecne, "\t\t{:received-ecne-chunks/%ju} "
|
||||
"{N:/input ECNE chunk%s}\n");
|
||||
p(sctps_recvauth, "\t\t{:received-auth-chunks/%ju} "
|
||||
"{N:/input AUTH chunk%s}\n");
|
||||
p(sctps_recvauthmissing, "\t\t{:dropped-missing-auth/%ju} "
|
||||
"{N:/chunk%s missing AUTH}\n");
|
||||
p(sctps_recvivalhmacid, "\t\t{:dropped-invalid-hmac/%ju} "
|
||||
"{N:/invalid HMAC id%s received}\n");
|
||||
p(sctps_recvivalkeyid, "\t\t{:dropped-invalid-secret/%ju} "
|
||||
"{N:/invalid secret id%s received}\n");
|
||||
p1a(sctps_recvauthfailed, "\t\t{:dropped-auth-failed/%ju} "
|
||||
"{N:/auth failed}\n");
|
||||
p1a(sctps_recvexpress, "\t\t{:received-fast-path/%ju} "
|
||||
"{N:/fast path receives all one chunk}\n");
|
||||
p1a(sctps_recvexpressm, "\t\t{:receives-fast-path-multipart/%ju} "
|
||||
"{N:/fast path multi-part data}\n");
|
||||
|
||||
/*
|
||||
* output statistics
|
||||
*/
|
||||
p(sctps_sendpackets, "\t%ju output packet%s\n");
|
||||
p(sctps_sendsacks, "\t\t%ju output SACK%s\n");
|
||||
p(sctps_senddata, "\t\t%ju output DATA chunk%s\n");
|
||||
p(sctps_sendretransdata, "\t\t%ju retransmitted DATA chunk%s\n");
|
||||
p(sctps_sendfastretrans, "\t\t%ju fast retransmitted DATA chunk%s\n");
|
||||
p(sctps_sendmultfastretrans, "\t\t%ju FR'%s that happened more "
|
||||
"than once to same chunk\n");
|
||||
p(sctps_sendheartbeat, "\t\t%ju output HB chunk%s\n");
|
||||
p(sctps_sendecne, "\t\t%ju output ECNE chunk%s\n");
|
||||
p(sctps_sendauth, "\t\t%ju output AUTH chunk%s\n");
|
||||
p1a(sctps_senderrors, "\t\t%ju ip_output error counter\n");
|
||||
p(sctps_sendpackets, "\t{:sent-packets/%ju} "
|
||||
"{N:/output packet%s}\n");
|
||||
p(sctps_sendsacks, "\t\t{:sent-sacks/%ju} "
|
||||
"{N:/output SACK%s}\n");
|
||||
p(sctps_senddata, "\t\t{:sent-data-chunks/%ju} "
|
||||
"{N:/output DATA chunk%s}\n");
|
||||
p(sctps_sendretransdata, "\t\t{:sent-retransmitted-data-chunks/%ju} "
|
||||
"{N:/retransmitted DATA chunk%s}\n");
|
||||
p(sctps_sendfastretrans, "\t\t"
|
||||
"{:sent-fast-retransmitted-data-chunks/%ju} "
|
||||
"{N:/fast retransmitted DATA chunk%s}\n");
|
||||
p(sctps_sendmultfastretrans, "\t\t"
|
||||
"{:sent-fast-retransmitted-data-chunk-multiple-times/%ju} "
|
||||
"{N:/FR'%s that happened more than once to same chunk}\n");
|
||||
p(sctps_sendheartbeat, "\t\t{:sent-hb-chunks/%ju} "
|
||||
"{N:/output HB chunk%s}\n");
|
||||
p(sctps_sendecne, "\t\t{:sent-ecne-chunks/%ju} "
|
||||
"{N:/output ECNE chunk%s}\n");
|
||||
p(sctps_sendauth, "\t\t{:sent-auth-chunks/%ju} "
|
||||
"{N:/output AUTH chunk%s}\n");
|
||||
p1a(sctps_senderrors, "\t\t{:send-errors/%ju} "
|
||||
"{N:/ip_output error counter}\n");
|
||||
|
||||
/*
|
||||
* PCKDROPREP statistics
|
||||
*/
|
||||
printf("\tPacket drop statistics:\n");
|
||||
p1a(sctps_pdrpfmbox, "\t\t%ju from middle box\n");
|
||||
p1a(sctps_pdrpfehos, "\t\t%ju from end host\n");
|
||||
p1a(sctps_pdrpmbda, "\t\t%ju with data\n");
|
||||
p1a(sctps_pdrpmbct, "\t\t%ju non-data, non-endhost\n");
|
||||
p1a(sctps_pdrpbwrpt, "\t\t%ju non-endhost, bandwidth rep only\n");
|
||||
p1a(sctps_pdrpcrupt, "\t\t%ju not enough for chunk header\n");
|
||||
p1a(sctps_pdrpnedat, "\t\t%ju not enough data to confirm\n");
|
||||
p1a(sctps_pdrppdbrk, "\t\t%ju where process_chunk_drop said break\n");
|
||||
p1a(sctps_pdrptsnnf, "\t\t%ju failed to find TSN\n");
|
||||
p1a(sctps_pdrpdnfnd, "\t\t%ju attempt reverse TSN lookup\n");
|
||||
p1a(sctps_pdrpdiwnp, "\t\t%ju e-host confirms zero-rwnd\n");
|
||||
p1a(sctps_pdrpdizrw, "\t\t%ju midbox confirms no space\n");
|
||||
p1a(sctps_pdrpbadd, "\t\t%ju data did not match TSN\n");
|
||||
p(sctps_pdrpmark, "\t\t%ju TSN'%s marked for Fast Retran\n");
|
||||
xo_emit("\t{T:Packet drop statistics}:\n");
|
||||
xo_open_container("drop-statistics");
|
||||
p1a(sctps_pdrpfmbox, "\t\t{:middle-box/%ju} "
|
||||
"{N:/from middle box}\n");
|
||||
p1a(sctps_pdrpfehos, "\t\t{:end-host/%ju} "
|
||||
"{N:/from end host}\n");
|
||||
p1a(sctps_pdrpmbda, "\t\t{:with-data/%ju} "
|
||||
"{N:/with data}\n");
|
||||
p1a(sctps_pdrpmbct, "\t\t{:non-data/%ju} "
|
||||
"{N:/non-data, non-endhost}\n");
|
||||
p1a(sctps_pdrpbwrpt, "\t\t{:non-endhost/%ju} "
|
||||
"{N:/non-endhost, bandwidth rep only}\n");
|
||||
p1a(sctps_pdrpcrupt, "\t\t{:short-header/%ju} "
|
||||
"{N:/not enough for chunk header}\n");
|
||||
p1a(sctps_pdrpnedat, "\t\t{:short-data/%ju} "
|
||||
"{N:/not enough data to confirm}\n");
|
||||
p1a(sctps_pdrppdbrk, "\t\t{:chunk-break/%ju} "
|
||||
"{N:/where process_chunk_drop said break}\n");
|
||||
p1a(sctps_pdrptsnnf, "\t\t{:tsn-not-found/%ju} "
|
||||
"{N:/failed to find TSN}\n");
|
||||
p1a(sctps_pdrpdnfnd, "\t\t{:reverse-tsn/%ju} "
|
||||
"{N:/attempt reverse TSN lookup}\n");
|
||||
p1a(sctps_pdrpdiwnp, "\t\t{:confirmed-zero-window/%ju} "
|
||||
"{N:/e-host confirms zero-rwnd}\n");
|
||||
p1a(sctps_pdrpdizrw, "\t\t{:middle-box-no-space/%ju} "
|
||||
"{N:/midbox confirms no space}\n");
|
||||
p1a(sctps_pdrpbadd, "\t\t{:bad-data/%ju} "
|
||||
"{N:/data did not match TSN}\n");
|
||||
p(sctps_pdrpmark, "\t\t{:tsn-marked-fast-retransmission/%ju} "
|
||||
"{N:/TSN'%s marked for Fast Retran}\n");
|
||||
xo_close_container("drop-statistics");
|
||||
|
||||
/*
|
||||
* Timeouts
|
||||
*/
|
||||
printf("\tTimeouts:\n");
|
||||
p(sctps_timoiterator, "\t\t%ju iterator timer%s fired\n");
|
||||
p(sctps_timodata, "\t\t%ju T3 data time out%s\n");
|
||||
p(sctps_timowindowprobe, "\t\t%ju window probe (T3) timer%s fired\n");
|
||||
p(sctps_timoinit, "\t\t%ju INIT timer%s fired\n");
|
||||
p(sctps_timosack, "\t\t%ju sack timer%s fired\n");
|
||||
p(sctps_timoshutdown, "\t\t%ju shutdown timer%s fired\n");
|
||||
p(sctps_timoheartbeat, "\t\t%ju heartbeat timer%s fired\n");
|
||||
p1a(sctps_timocookie, "\t\t%ju a cookie timeout fired\n");
|
||||
p1a(sctps_timosecret, "\t\t%ju an endpoint changed its cookie"
|
||||
xo_emit("\t{T:Timeouts}:\n");
|
||||
xo_open_container("timeouts");
|
||||
p(sctps_timoiterator, "\t\t{:iterator/%ju} "
|
||||
"{N:/iterator timer%s fired}\n");
|
||||
p(sctps_timodata, "\t\t{:t3-data/%ju} "
|
||||
"{N:/T3 data time out%s}\n");
|
||||
p(sctps_timowindowprobe, "\t\t{:window-probe/%ju} "
|
||||
"{N:/window probe (T3) timer%s fired}\n");
|
||||
p(sctps_timoinit, "\t\t{:init-timer/%ju} "
|
||||
"{N:/INIT timer%s fired}\n");
|
||||
p(sctps_timosack, "\t\t{:sack-timer/%ju} "
|
||||
"{N:/sack timer%s fired}\n");
|
||||
p(sctps_timoshutdown, "\t\t{:shutdown-timer/%ju} "
|
||||
"{N:/shutdown timer%s fired}\n");
|
||||
p(sctps_timoheartbeat, "\t\t{:heartbeat-timer/%ju} "
|
||||
"{N:/heartbeat timer%s fired}\n");
|
||||
p1a(sctps_timocookie, "\t\t{:cookie-timer/%ju} "
|
||||
"{N:/a cookie timeout fired}\n");
|
||||
p1a(sctps_timosecret, "\t\t{:endpoint-changed-cookie/%ju} "
|
||||
"{N:/an endpoint changed its cook}ie"
|
||||
"secret\n");
|
||||
p(sctps_timopathmtu, "\t\t%ju PMTU timer%s fired\n");
|
||||
p(sctps_timoshutdownack, "\t\t%ju shutdown ack timer%s fired\n");
|
||||
p(sctps_timoshutdownguard, "\t\t%ju shutdown guard timer%s fired\n");
|
||||
p(sctps_timostrmrst, "\t\t%ju stream reset timer%s fired\n");
|
||||
p(sctps_timoearlyfr, "\t\t%ju early FR timer%s fired\n");
|
||||
p1a(sctps_timoasconf, "\t\t%ju an asconf timer fired\n");
|
||||
p1a(sctps_timoautoclose, "\t\t%ju auto close timer fired\n");
|
||||
p(sctps_timoassockill, "\t\t%ju asoc free timer%s expired\n");
|
||||
p(sctps_timoinpkill, "\t\t%ju inp free timer%s expired\n");
|
||||
p(sctps_timopathmtu, "\t\t{:pmtu-timer/%ju} "
|
||||
"{N:/PMTU timer%s fired}\n");
|
||||
p(sctps_timoshutdownack, "\t\t{:shutdown-timer/%ju} "
|
||||
"{N:/shutdown ack timer%s fired}\n");
|
||||
p(sctps_timoshutdownguard, "\t\t{:shutdown-guard-timer/%ju} "
|
||||
"{N:/shutdown guard timer%s fired}\n");
|
||||
p(sctps_timostrmrst, "\t\t{:stream-reset-timer/%ju} "
|
||||
"{N:/stream reset timer%s fired}\n");
|
||||
p(sctps_timoearlyfr, "\t\t{:early-fast-retransmission-timer/%ju} "
|
||||
"{N:/early FR timer%s fired}\n");
|
||||
p1a(sctps_timoasconf, "\t\t{:asconf-timer/%ju} "
|
||||
"{N:/an asconf timer fired}\n");
|
||||
p1a(sctps_timoautoclose, "\t\t{:auto-close-timer/%ju} "
|
||||
"{N:/auto close timer fired}\n");
|
||||
p(sctps_timoassockill, "\t\t{:asoc-free-timer/%ju} "
|
||||
"{N:/asoc free timer%s expired}\n");
|
||||
p(sctps_timoinpkill, "\t\t{:input-free-timer/%ju} "
|
||||
"{N:/inp free timer%s expired}\n");
|
||||
xo_close_container("timeouts");
|
||||
|
||||
#if 0
|
||||
/*
|
||||
@ -727,60 +833,86 @@ sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
/*
|
||||
* Others
|
||||
*/
|
||||
p1a(sctps_hdrops, "\t%ju packet shorter than header\n");
|
||||
p1a(sctps_badsum, "\t%ju checksum error\n");
|
||||
p1a(sctps_noport, "\t%ju no endpoint for port\n");
|
||||
p1a(sctps_badvtag, "\t%ju bad v-tag\n");
|
||||
p1a(sctps_badsid, "\t%ju bad SID\n");
|
||||
p1a(sctps_nomem, "\t%ju no memory\n");
|
||||
p1a(sctps_fastretransinrtt, "\t%ju number of multiple FR in a RTT "
|
||||
"window\n");
|
||||
p1a(sctps_hdrops, "\t{:dropped-too-short/%ju} "
|
||||
"{N:/packet shorter than header}\n");
|
||||
p1a(sctps_badsum, "\t{:dropped-bad-checksum/%ju} "
|
||||
"{N:/checksum error}\n");
|
||||
p1a(sctps_noport, "\t{:dropped-no-endpoint/%ju} "
|
||||
"{N:/no endpoint for port}\n");
|
||||
p1a(sctps_badvtag, "\t{:dropped-bad-v-tag/%ju} "
|
||||
"{N:/bad v-tag}\n");
|
||||
p1a(sctps_badsid, "\t{:dropped-bad-sid/%ju} "
|
||||
"{N:/bad SID}\n");
|
||||
p1a(sctps_nomem, "\t{:dropped-no-memory/%ju} "
|
||||
"{N:/no memory}\n");
|
||||
p1a(sctps_fastretransinrtt, "\t{:multiple-fast-retransmits-in-rtt/%ju} "
|
||||
"{N:/number of multiple FR in a RT}T window\n");
|
||||
#if 0
|
||||
p(sctps_markedretrans, "\t%ju TODO:sctps_markedretrans\n");
|
||||
#endif
|
||||
p1a(sctps_naglesent, "\t%ju RFC813 allowed sending\n");
|
||||
p1a(sctps_naglequeued, "\t%ju RFC813 does not allow sending\n");
|
||||
p1a(sctps_maxburstqueued, "\t%ju times max burst prohibited sending\n");
|
||||
p1a(sctps_ifnomemqueued, "\t%ju look ahead tells us no memory in "
|
||||
"interface\n");
|
||||
p(sctps_windowprobed, "\t%ju number%s of window probes sent\n");
|
||||
p(sctps_lowlevelerr, "\t%ju time%s an output error to clamp "
|
||||
"down on next user send\n");
|
||||
p(sctps_lowlevelerrusr, "\t%ju time%s sctp_senderrors were "
|
||||
"caused from a user\n");
|
||||
p(sctps_datadropchklmt, "\t%ju number of in data drop%s due to "
|
||||
"chunk limit reached\n");
|
||||
p(sctps_datadroprwnd, "\t%ju number of in data drop%s due to rwnd "
|
||||
"limit reached\n");
|
||||
p(sctps_ecnereducedcwnd, "\t%ju time%s a ECN reduced "
|
||||
"the cwnd\n");
|
||||
p1a(sctps_vtagexpress, "\t%ju used express lookup via vtag\n");
|
||||
p1a(sctps_vtagbogus, "\t%ju collision in express lookup\n");
|
||||
p(sctps_primary_randry, "\t%ju time%s the sender ran dry "
|
||||
"of user data on primary\n");
|
||||
p1a(sctps_cmt_randry, "\t%ju same for above\n");
|
||||
p(sctps_slowpath_sack, "\t%ju sack%s the slow way\n");
|
||||
p(sctps_wu_sacks_sent, "\t%ju window update only sack%s sent\n");
|
||||
p(sctps_sends_with_flags, "\t%ju send%s with sinfo_flags !=0\n");
|
||||
p(sctps_sends_with_unord, "\t%ju unordered send%s\n");
|
||||
p(sctps_sends_with_eof, "\t%ju send%s with EOF flag set\n");
|
||||
p(sctps_sends_with_abort, "\t%ju send%s with ABORT flag set\n");
|
||||
p(sctps_protocol_drain_calls, "\t%ju time%s protocol drain called\n");
|
||||
p(sctps_protocol_drains_done, "\t%ju time%s we did a protocol "
|
||||
"drain\n");
|
||||
p(sctps_read_peeks, "\t%ju time%s recv was called with peek\n");
|
||||
p(sctps_cached_chk, "\t%ju cached chunk%s used\n");
|
||||
p1a(sctps_cached_strmoq, "\t%ju cached stream oq's used\n");
|
||||
p(sctps_left_abandon, "\t%ju unread message%s abandonded by close\n");
|
||||
p1a(sctps_send_burst_avoid, "\t%ju send burst avoidance, already "
|
||||
"max burst inflight to net\n");
|
||||
p1a(sctps_send_cwnd_avoid, "\t%ju send cwnd full avoidance, already "
|
||||
"max burst inflight to net\n");
|
||||
p(sctps_fwdtsn_map_over, "\t%ju number of map array over-run%s via "
|
||||
"fwd-tsn's\n");
|
||||
p1a(sctps_naglesent, "\t{:rfc813-sent/%ju} "
|
||||
"{N:/RFC813 allowed sending}\n");
|
||||
p1a(sctps_naglequeued, "\t{:rfc813-queued/%ju} "
|
||||
"{N:/RFC813 does not allow sending}\n");
|
||||
p1a(sctps_maxburstqueued, "\t{:max-burst-queued/%ju} "
|
||||
"{N:/times max burst prohibited sending}\n");
|
||||
p1a(sctps_ifnomemqueued, "\t{:no-memory-in-interface/%ju} "
|
||||
"{N:/look ahead tells us no memory in interface}\n");
|
||||
p(sctps_windowprobed, "\t{:sent-window-probes/%ju} "
|
||||
"{N:/number%s of window probes sent}\n");
|
||||
p(sctps_lowlevelerr, "\t{:low-level-err/%ju} "
|
||||
"{N:/time%s an output error to clamp down on next user send}\n");
|
||||
p(sctps_lowlevelerrusr, "\t{:low-level-user-error/%ju} "
|
||||
"{N:/time%s sctp_senderrors were caused from a user}\n");
|
||||
p(sctps_datadropchklmt, "\t{:dropped-chunk-limit/%ju} "
|
||||
"{N:/number of in data drop%s due to chunk limit reached}\n");
|
||||
p(sctps_datadroprwnd, "\t{:dropped-rwnd-limit/%ju} "
|
||||
"{N:/number of in data drop%s due to rwnd limit reached}\n");
|
||||
p(sctps_ecnereducedcwnd, "\t{:ecn-reduced-cwnd/%ju} "
|
||||
"{N:/time%s a ECN reduced the cwnd}\n");
|
||||
p1a(sctps_vtagexpress, "\t{:v-tag-express-lookup/%ju} "
|
||||
"{N:/used express lookup via vtag}\n");
|
||||
p1a(sctps_vtagbogus, "\t{:v-tag-collision/%ju} "
|
||||
"{N:/collision in express lookup}\n");
|
||||
p(sctps_primary_randry, "\t{:sender-ran-dry/%ju} "
|
||||
"{N:/time%s the sender ran dry of user data on primary}\n");
|
||||
p1a(sctps_cmt_randry, "\t{:cmt-ran-dry/%ju} "
|
||||
"{N:/same for above}\n");
|
||||
p(sctps_slowpath_sack, "\t{:slow-path-sack/%ju} "
|
||||
"{N:/sack%s the slow way}\n");
|
||||
p(sctps_wu_sacks_sent, "\t{:sent-window-update-only-sack/%ju} "
|
||||
"{N:/window update only sack%s sent}\n");
|
||||
p(sctps_sends_with_flags, "\t{:sent-with-sinfo/%ju} "
|
||||
"{N:/send%s with sinfo_flags !=0}\n");
|
||||
p(sctps_sends_with_unord, "\t{:sent-with-unordered/%ju} "
|
||||
"{N:/unordered send%s}\n");
|
||||
p(sctps_sends_with_eof, "\t{:sent-with-eof/%ju} "
|
||||
"{N:/send%s with EOF flag set}\n");
|
||||
p(sctps_sends_with_abort, "\t{:sent-with-abort/%ju} "
|
||||
"{N:/send%s with ABORT flag set}\n");
|
||||
p(sctps_protocol_drain_calls, "\t{:protocol-drain-called/%ju} "
|
||||
"{N:/time%s protocol drain called}\n");
|
||||
p(sctps_protocol_drains_done, "\t{:protocol-drain/%ju} "
|
||||
"{N:/time%s we did a protocol drain}\n");
|
||||
p(sctps_read_peeks, "\t{:read-with-peek/%ju} "
|
||||
"{N:/time%s recv was called with peek}\n");
|
||||
p(sctps_cached_chk, "\t{:cached-chunks/%ju} "
|
||||
"{N:/cached chunk%s used}\n");
|
||||
p1a(sctps_cached_strmoq, "\t{:cached-output-queue-used/%ju} "
|
||||
"{N:/cached stream oq's used}\n");
|
||||
p(sctps_left_abandon, "\t{:messages-abandoned/%ju} "
|
||||
"{N:/unread message%s abandonded by close}\n");
|
||||
p1a(sctps_send_burst_avoid, "\t{:send-burst-avoidance/%ju} "
|
||||
"{N:/send burst avoidance, already max burst inflight to net}\n");
|
||||
p1a(sctps_send_cwnd_avoid, "\t{:send-cwnd-avoidance/%ju} "
|
||||
"{N:/send cwnd full avoidance, already max burst inflight "
|
||||
"to net}\n");
|
||||
p(sctps_fwdtsn_map_over, "\t{:tsn-map-overruns/%ju} "
|
||||
"{N:/number of map array over-run%s via fwd-tsn's}\n");
|
||||
|
||||
#undef p
|
||||
#undef p1a
|
||||
xo_close_container(name);
|
||||
}
|
||||
|
||||
#endif /* SCTP */
|
||||
|
@ -57,8 +57,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <strings.h>
|
||||
#include <kvm.h>
|
||||
#include <libxo/xo.h>
|
||||
#include "netstat.h"
|
||||
|
||||
static void unixdomainpr(struct xunpcb *, struct xsocket *);
|
||||
@ -78,15 +80,15 @@ pcblist_sysctl(int type, char **bufp)
|
||||
len = 0;
|
||||
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: %s", mibvar);
|
||||
xo_warn("sysctl: %s", mibvar);
|
||||
return (-1);
|
||||
}
|
||||
if ((buf = malloc(len)) == 0) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
xo_warnx("malloc %lu bytes", (u_long)len);
|
||||
return (-2);
|
||||
}
|
||||
if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
|
||||
warn("sysctl: %s", mibvar);
|
||||
xo_warn("sysctl: %s", mibvar);
|
||||
free(buf);
|
||||
return (-2);
|
||||
}
|
||||
@ -115,14 +117,14 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp)
|
||||
kread(count_off, &unp_count, sizeof(unp_count));
|
||||
len = 2 * sizeof(xug) + (unp_count + unp_count / 8) * sizeof(xu);
|
||||
if ((buf = malloc(len)) == 0) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
xo_warnx("malloc %lu bytes", (u_long)len);
|
||||
return (-2);
|
||||
}
|
||||
p = buf;
|
||||
|
||||
#define COPYOUT(obj, size) do { \
|
||||
if (len < (size)) { \
|
||||
warnx("buffer size exceeded"); \
|
||||
xo_warnx("buffer size exceeded"); \
|
||||
goto fail; \
|
||||
} \
|
||||
bcopy((obj), p, (size)); \
|
||||
@ -190,7 +192,7 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp)
|
||||
|
||||
void
|
||||
unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off,
|
||||
u_long sphead_off)
|
||||
u_long sphead_off, bool *first)
|
||||
{
|
||||
char *buf;
|
||||
int ret, type;
|
||||
@ -228,26 +230,35 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off,
|
||||
|
||||
oxug = xug = (struct xunpgen *)buf;
|
||||
for (xug = (struct xunpgen *)((char *)xug + xug->xug_len);
|
||||
xug->xug_len > sizeof(struct xunpgen);
|
||||
xug = (struct xunpgen *)((char *)xug + xug->xug_len)) {
|
||||
xug->xug_len > sizeof(struct xunpgen);
|
||||
xug = (struct xunpgen *)((char *)xug + xug->xug_len)) {
|
||||
xunp = (struct xunpcb *)xug;
|
||||
so = &xunp->xu_socket;
|
||||
|
||||
/* Ignore PCBs which were freed during copyout. */
|
||||
if (xunp->xu_unp.unp_gencnt > oxug->xug_gen)
|
||||
continue;
|
||||
if (*first) {
|
||||
xo_open_list("socket");
|
||||
*first = false;
|
||||
}
|
||||
xo_open_instance("socket");
|
||||
unixdomainpr(xunp, so);
|
||||
xo_close_instance("socket");
|
||||
}
|
||||
if (xug != oxug && xug->xug_gen != oxug->xug_gen) {
|
||||
if (oxug->xug_count > xug->xug_count) {
|
||||
printf("Some %s sockets may have been deleted.\n",
|
||||
socktype[type]);
|
||||
xo_emit("Some {:type/%s} sockets may have "
|
||||
"been {:action/deleted}.\n",
|
||||
socktype[type]);
|
||||
} else if (oxug->xug_count < xug->xug_count) {
|
||||
printf("Some %s sockets may have been created.\n",
|
||||
socktype[type]);
|
||||
xo_emit("Some {:type/%s} sockets may have "
|
||||
"been {:action/created}.\n",
|
||||
socktype[type]);
|
||||
} else {
|
||||
printf("Some %s sockets may have been created or deleted",
|
||||
socktype[type]);
|
||||
xo_emit("Some {:type/%s} sockets may have "
|
||||
"been {:action/created or deleted}",
|
||||
socktype[type]);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
@ -261,6 +272,25 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
|
||||
struct sockaddr_un *sa;
|
||||
static int first = 1;
|
||||
char buf1[15];
|
||||
static const char *titles[2] = {
|
||||
"{T:/%-8.8s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%8.8s} "
|
||||
"{T:/%8.8s} {T:/%8.8s} {T:/%8.8s} {T:Addr}\n",
|
||||
"{T:/%-16.16s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%16.16s} "
|
||||
"{T:/%16.16s} {T:/%16.16s} {T:/%16.16s} {T:Addr}\n"
|
||||
};
|
||||
static const char *format[2] = {
|
||||
"{q:address/%8lx} {t:type/%-6.6s} "
|
||||
"{:receive-bytes-waiting/%6u} "
|
||||
"{:send-bytes-waiting/%6u} "
|
||||
"{q:vnode/%8lx} {q:connection/%8lx} "
|
||||
"{q:first-reference/%8lx} {q:next-reference/%8lx}",
|
||||
"{q:address/%16lx} {t:type/%-6.6s} "
|
||||
"{:receive-bytes-waiting/%6u} "
|
||||
"{:send-bytes-waiting/%6u} "
|
||||
"{q:vnode/%16lx} {q:connection/%16lx} "
|
||||
"{q:first-reference/%16lx} {q:next-reference/%16lx}"
|
||||
};
|
||||
int fmt = (sizeof(void *) == 8) ? 1 : 0;
|
||||
|
||||
unp = &xunp->xu_unp;
|
||||
if (unp->unp_addr)
|
||||
@ -269,9 +299,8 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
|
||||
sa = (struct sockaddr_un *)0;
|
||||
|
||||
if (first && !Lflag) {
|
||||
printf("Active UNIX domain sockets\n");
|
||||
printf(
|
||||
"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
|
||||
xo_emit("{T:Active UNIX domain sockets}\n");
|
||||
xo_emit(titles[fmt],
|
||||
"Address", "Type", "Recv-Q", "Send-Q",
|
||||
"Inode", "Conn", "Refs", "Nextref");
|
||||
first = 0;
|
||||
@ -283,9 +312,11 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
|
||||
if (Lflag) {
|
||||
snprintf(buf1, 15, "%d/%d/%d", so->so_qlen,
|
||||
so->so_incqlen, so->so_qlimit);
|
||||
printf("unix %-14.14s", buf1);
|
||||
xo_emit("unix {d:socket/%-14.14s}{e:queue-length/%d}"
|
||||
"{e:incomplete-queue-length/%d}{e:queue-limit/%d}",
|
||||
buf1, so->so_qlen, so->so_incqlen, so->so_qlimit);
|
||||
} else {
|
||||
printf("%8lx %-6.6s %6u %6u %8lx %8lx %8lx %8lx",
|
||||
xo_emit(format[fmt],
|
||||
(long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
|
||||
so->so_snd.sb_cc, (long)unp->unp_vnode,
|
||||
(long)unp->unp_conn,
|
||||
@ -293,8 +324,8 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
|
||||
(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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user