mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-17 04:41:59 +08:00
netstat: New command - Almost completely compiles
Currently disable in Makefile until all builds. Adding it so others can assist in debugging issues.
This commit is contained in:
parent
db068df3c4
commit
f1710b69d4
293
freebsd-userspace/commands/usr.bin/netstat/atalk.c
Normal file
293
freebsd-userspace/commands/usr.bin/netstat/atalk.c
Normal file
@ -0,0 +1,293 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)atalk.c 1.1 (Whistle) 6/6/96";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netatalk/at.h>
|
||||
#include <netatalk/ddp_var.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <nlist.h>
|
||||
#include <netdb.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "netstat.h"
|
||||
|
||||
struct ddpcb ddpcb;
|
||||
struct socket sockb;
|
||||
|
||||
static int first = 1;
|
||||
|
||||
/*
|
||||
* Print a summary of connections related to a Network Systems
|
||||
* protocol. For XXX, also give state of connection.
|
||||
* Listening processes (aflag) are suppressed unless the
|
||||
* -a (all) flag is specified.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
at_pr_net(struct sockaddr_at *sat, int numeric)
|
||||
{
|
||||
static char mybuf[50];
|
||||
|
||||
if (!numeric) {
|
||||
switch(sat->sat_addr.s_net) {
|
||||
case 0xffff:
|
||||
return "????";
|
||||
case ATADDR_ANYNET:
|
||||
return("*");
|
||||
}
|
||||
}
|
||||
sprintf(mybuf,"%hu",ntohs(sat->sat_addr.s_net));
|
||||
return mybuf;
|
||||
}
|
||||
|
||||
static const char *
|
||||
at_pr_host(struct sockaddr_at *sat, int numeric)
|
||||
{
|
||||
static char mybuf[50];
|
||||
|
||||
if (!numeric) {
|
||||
switch(sat->sat_addr.s_node) {
|
||||
case ATADDR_BCAST:
|
||||
return "bcast";
|
||||
case ATADDR_ANYNODE:
|
||||
return("*");
|
||||
}
|
||||
}
|
||||
sprintf(mybuf,"%d",(unsigned int)sat->sat_addr.s_node);
|
||||
return mybuf;
|
||||
}
|
||||
|
||||
static const char *
|
||||
at_pr_port(struct sockaddr_at *sat)
|
||||
{
|
||||
static char mybuf[50];
|
||||
struct servent *serv;
|
||||
|
||||
switch(sat->sat_port) {
|
||||
case ATADDR_ANYPORT:
|
||||
return("*");
|
||||
case 0xff:
|
||||
return "????";
|
||||
default:
|
||||
if (numeric_port) {
|
||||
(void)snprintf(mybuf, sizeof(mybuf), "%d",
|
||||
(unsigned int)sat->sat_port);
|
||||
} else {
|
||||
serv = getservbyport(sat->sat_port, "ddp");
|
||||
if (serv == NULL)
|
||||
(void)snprintf(mybuf, sizeof(mybuf), "%d",
|
||||
(unsigned int) sat->sat_port);
|
||||
else
|
||||
(void) snprintf(mybuf, sizeof(mybuf), "%s",
|
||||
serv->s_name);
|
||||
}
|
||||
}
|
||||
return mybuf;
|
||||
}
|
||||
|
||||
static char *
|
||||
at_pr_range(struct sockaddr_at *sat)
|
||||
{
|
||||
static char mybuf[50];
|
||||
|
||||
if(sat->sat_range.r_netrange.nr_firstnet
|
||||
!= sat->sat_range.r_netrange.nr_lastnet) {
|
||||
sprintf(mybuf,"%d-%d",
|
||||
ntohs(sat->sat_range.r_netrange.nr_firstnet),
|
||||
ntohs(sat->sat_range.r_netrange.nr_lastnet));
|
||||
} else {
|
||||
sprintf(mybuf,"%d",
|
||||
ntohs(sat->sat_range.r_netrange.nr_firstnet));
|
||||
}
|
||||
return mybuf;
|
||||
}
|
||||
|
||||
|
||||
/* what == 0 for addr only == 3 */
|
||||
/* 1 for net */
|
||||
/* 2 for host */
|
||||
/* 4 for port */
|
||||
/* 8 for numeric only */
|
||||
char *
|
||||
atalk_print(struct sockaddr *sa, int what)
|
||||
{
|
||||
struct sockaddr_at *sat = (struct sockaddr_at *)sa;
|
||||
static char mybuf[50];
|
||||
int numeric = (what & 0x08);
|
||||
|
||||
mybuf[0] = 0;
|
||||
switch (what & 0x13) {
|
||||
case 0:
|
||||
mybuf[0] = 0;
|
||||
break;
|
||||
case 1:
|
||||
sprintf(mybuf,"%s",at_pr_net(sat, numeric));
|
||||
break;
|
||||
case 2:
|
||||
sprintf(mybuf,"%s",at_pr_host(sat, numeric));
|
||||
break;
|
||||
case 3:
|
||||
sprintf(mybuf,"%s.%s",
|
||||
at_pr_net(sat, numeric),
|
||||
at_pr_host(sat, numeric));
|
||||
break;
|
||||
case 0x10:
|
||||
sprintf(mybuf,"%s", at_pr_range(sat));
|
||||
}
|
||||
if (what & 4) {
|
||||
sprintf(mybuf+strlen(mybuf),".%s",at_pr_port(sat));
|
||||
}
|
||||
return mybuf;
|
||||
}
|
||||
|
||||
char *
|
||||
atalk_print2(struct sockaddr *sa, struct sockaddr *mask, int what)
|
||||
{
|
||||
int n;
|
||||
static char buf[100];
|
||||
struct sockaddr_at *sat1, *sat2;
|
||||
struct sockaddr_at thesockaddr;
|
||||
struct sockaddr *sa2;
|
||||
|
||||
sat1 = (struct sockaddr_at *)sa;
|
||||
sat2 = (struct sockaddr_at *)mask;
|
||||
sa2 = (struct sockaddr *)&thesockaddr;
|
||||
|
||||
thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net & sat2->sat_addr.s_net;
|
||||
snprintf(buf, sizeof(buf), "%s", atalk_print(sa2, 1 |(what & 8)));
|
||||
if(sat2->sat_addr.s_net != 0xFFFF) {
|
||||
thesockaddr.sat_addr.s_net = sat1->sat_addr.s_net | ~sat2->sat_addr.s_net;
|
||||
n = strlen(buf);
|
||||
snprintf(buf + n, sizeof(buf) - n, "-%s", atalk_print(sa2, 1 |(what & 8)));
|
||||
}
|
||||
if(what & 2) {
|
||||
n = strlen(buf);
|
||||
snprintf(buf + n, sizeof(buf) - n, ".%s", atalk_print(sa, what & (~1)));
|
||||
}
|
||||
return(buf);
|
||||
}
|
||||
|
||||
void
|
||||
atalkprotopr(u_long off __unused, const char *name, int af1 __unused,
|
||||
int proto __unused)
|
||||
{
|
||||
struct ddpcb *this, *next;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
kread(off, (char *)&this, sizeof (struct ddpcb *));
|
||||
for ( ; this != NULL; this = next) {
|
||||
kread((u_long)this, (char *)&ddpcb, sizeof (ddpcb));
|
||||
next = ddpcb.ddp_next;
|
||||
#if 0
|
||||
if (!aflag && atalk_nullhost(ddpcb.ddp_lsat) ) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
kread((u_long)ddpcb.ddp_socket, (char *)&sockb, sizeof (sockb));
|
||||
if (first) {
|
||||
printf("Active ATALK connections");
|
||||
if (aflag)
|
||||
printf(" (including servers)");
|
||||
putchar('\n');
|
||||
if (Aflag)
|
||||
printf("%-8.8s ", "PCB");
|
||||
printf(Aflag ?
|
||||
"%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
|
||||
"%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
|
||||
"Proto", "Recv-Q", "Send-Q",
|
||||
"Local Address", "Foreign Address", "(state)");
|
||||
first = 0;
|
||||
}
|
||||
if (Aflag)
|
||||
printf("%8lx ", (u_long) this);
|
||||
printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc,
|
||||
sockb.so_snd.sb_cc);
|
||||
printf(Aflag?" %-18.18s":" %-22.22s", atalk_print(
|
||||
(struct sockaddr *)&ddpcb.ddp_lsat,7));
|
||||
printf(Aflag?" %-18.18s":" %-22.22s", atalk_print(
|
||||
(struct sockaddr *)&ddpcb.ddp_fsat,7));
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
#define ANY(x,y,z) if (x || sflag <= 1) \
|
||||
printf("\t%lu %s%s%s\n",x,y,plural(x),z)
|
||||
|
||||
/*
|
||||
* Dump DDP statistics structure.
|
||||
*/
|
||||
void
|
||||
ddp_stats(u_long off __unused, const char *name, int af1 __unused,
|
||||
int proto __unused)
|
||||
{
|
||||
struct ddpstat ddpstat;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
kread(off, (char *)&ddpstat, sizeof (ddpstat));
|
||||
printf("%s:\n", name);
|
||||
ANY(ddpstat.ddps_short, "packet", " with short headers ");
|
||||
ANY(ddpstat.ddps_long, "packet", " with long headers ");
|
||||
ANY(ddpstat.ddps_nosum, "packet", " with no checksum ");
|
||||
ANY(ddpstat.ddps_tooshort, "packet", " too short ");
|
||||
ANY(ddpstat.ddps_badsum, "packet", " with bad checksum ");
|
||||
ANY(ddpstat.ddps_toosmall, "packet", " with not enough data ");
|
||||
ANY(ddpstat.ddps_forward, "packet", " forwarded ");
|
||||
ANY(ddpstat.ddps_encap, "packet", " encapsulated ");
|
||||
ANY(ddpstat.ddps_cantforward, "packet", " rcvd for unreachable dest ");
|
||||
ANY(ddpstat.ddps_nosockspace, "packet", " dropped due to no socket space ");
|
||||
}
|
158
freebsd-userspace/commands/usr.bin/netstat/bpf.c
Normal file
158
freebsd-userspace/commands/usr.bin/netstat/bpf.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Christian S.J. Peron
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/param.h>
|
||||
#ifndef __rtems__
|
||||
#include <sys/user.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/net/if_var.h>
|
||||
#include <freebsd/net/bpf.h>
|
||||
#include <freebsd/net/bpfdesc.h>
|
||||
#else
|
||||
#include <net/if_var.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/bpfdesc.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "netstat.h"
|
||||
|
||||
/* print bpf stats */
|
||||
|
||||
static char *
|
||||
bpf_pidname(pid_t pid)
|
||||
{
|
||||
#ifdef __rtems__
|
||||
return "rtems";
|
||||
#else
|
||||
struct kinfo_proc newkp;
|
||||
int error, mib[4];
|
||||
size_t size;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = pid;
|
||||
size = sizeof(newkp);
|
||||
error = sysctl(mib, 4, &newkp, &size, NULL, 0);
|
||||
if (error < 0) {
|
||||
warn("kern.proc.pid failed");
|
||||
return (strdup("??????"));
|
||||
}
|
||||
return (strdup(newkp.ki_comm));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
bpf_flags(struct xbpf_d *bd, char *flagbuf)
|
||||
{
|
||||
|
||||
*flagbuf++ = bd->bd_promisc ? 'p' : '-';
|
||||
*flagbuf++ = bd->bd_immediate ? 'i' : '-';
|
||||
*flagbuf++ = bd->bd_hdrcmplt ? '-' : 'f';
|
||||
*flagbuf++ = (bd->bd_direction == BPF_D_IN) ? '-' :
|
||||
((bd->bd_direction == BPF_D_OUT) ? 'o' : 's');
|
||||
*flagbuf++ = bd->bd_feedback ? 'b' : '-';
|
||||
*flagbuf++ = bd->bd_async ? 'a' : '-';
|
||||
*flagbuf++ = bd->bd_locked ? 'l' : '-';
|
||||
*flagbuf++ = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
bpf_stats(char *ifname)
|
||||
{
|
||||
struct xbpf_d *d, *bd, zerostat;
|
||||
char *pname, flagbuf[12];
|
||||
size_t size;
|
||||
|
||||
if (zflag) {
|
||||
bzero(&zerostat, sizeof(zerostat));
|
||||
if (sysctlbyname("net.bpf.stats", NULL, NULL,
|
||||
&zerostat, sizeof(zerostat)) < 0)
|
||||
warn("failed to zero bpf counters");
|
||||
return;
|
||||
}
|
||||
if (sysctlbyname("net.bpf.stats", NULL, &size,
|
||||
NULL, 0) < 0) {
|
||||
warn("net.bpf.stats");
|
||||
return;
|
||||
}
|
||||
if (size == 0)
|
||||
return;
|
||||
bd = malloc(size);
|
||||
if (bd == NULL) {
|
||||
warn("malloc failed");
|
||||
return;
|
||||
}
|
||||
if (sysctlbyname("net.bpf.stats", bd, &size,
|
||||
NULL, 0) < 0) {
|
||||
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");
|
||||
for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) {
|
||||
if (d->bd_structsize != sizeof(*d)) {
|
||||
warnx("bpf_stats_extended: version mismatch");
|
||||
return;
|
||||
}
|
||||
if (ifname && strcmp(ifname, d->bd_ifname) != 0)
|
||||
continue;
|
||||
bpf_flags(d, flagbuf);
|
||||
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);
|
||||
free(pname);
|
||||
}
|
||||
free(bd);
|
||||
}
|
735
freebsd-userspace/commands/usr.bin/netstat/if.c
Normal file
735
freebsd-userspace/commands/usr.bin/netstat/if.c
Normal file
@ -0,0 +1,735 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/net/if_var.h>
|
||||
#else
|
||||
#include <net/if_var.h>
|
||||
#endif
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/ethernet.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/net/pfvar.h>
|
||||
#include <freebsd/net/if_pfsync.h>
|
||||
#include <netinet/in.h>
|
||||
#include <freebsd/netinet/in_var.h>
|
||||
/* IPX not on RTEMS */
|
||||
/* #include <netipx/ipx.h> */
|
||||
/* #include <netipx/ipx_if.h> */
|
||||
#else
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pfsync.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netipx/ipx.h>
|
||||
#include <netipx/ipx_if.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#ifdef __rtems__
|
||||
/* apparently libutil.h is not needed */
|
||||
#else
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "netstat.h"
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
static void sidewaysintpr(int, u_long);
|
||||
static void catchalarm(int);
|
||||
|
||||
#ifdef INET6
|
||||
static char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dump pfsync statistics structure.
|
||||
*/
|
||||
void
|
||||
pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
{
|
||||
struct pfsyncstats pfsyncstat, zerostat;
|
||||
size_t len = sizeof(struct pfsyncstats);
|
||||
|
||||
if (live) {
|
||||
if (zflag)
|
||||
memset(&zerostat, 0, len);
|
||||
if (sysctlbyname("net.inet.pfsync.stats", &pfsyncstat, &len,
|
||||
zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: net.inet.pfsync.stats");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(off, &pfsyncstat, len);
|
||||
|
||||
printf("%s:\n", name);
|
||||
|
||||
#define p(f, m) if (pfsyncstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f))
|
||||
#define p2(f, m) if (pfsyncstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)pfsyncstat.f)
|
||||
|
||||
p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n");
|
||||
p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n");
|
||||
p(pfsyncs_badif, "\t\t%ju packet%s discarded for bad interface\n");
|
||||
p(pfsyncs_badttl, "\t\t%ju packet%s discarded for bad ttl\n");
|
||||
p(pfsyncs_hdrops, "\t\t%ju packet%s shorter than header\n");
|
||||
p(pfsyncs_badver, "\t\t%ju packet%s discarded for bad version\n");
|
||||
p(pfsyncs_badauth, "\t\t%ju packet%s discarded for bad HMAC\n");
|
||||
p(pfsyncs_badact,"\t\t%ju packet%s discarded for bad action\n");
|
||||
p(pfsyncs_badlen, "\t\t%ju packet%s discarded for short packet\n");
|
||||
p(pfsyncs_badval, "\t\t%ju state%s discarded for bad values\n");
|
||||
p(pfsyncs_stale, "\t\t%ju stale state%s\n");
|
||||
p(pfsyncs_badstate, "\t\t%ju failed state lookup/insert%s\n");
|
||||
p(pfsyncs_opackets, "\t%ju packet%s sent (IPv4)\n");
|
||||
p(pfsyncs_opackets6, "\t%ju packet%s sent (IPv6)\n");
|
||||
p2(pfsyncs_onomem, "\t\t%ju send failed due to mbuf memory error\n");
|
||||
p2(pfsyncs_oerrors, "\t\t%ju send error\n");
|
||||
#undef p
|
||||
#undef p2
|
||||
}
|
||||
|
||||
/*
|
||||
* Display a formatted value, or a '-' in the same space.
|
||||
*/
|
||||
static void
|
||||
show_stat(const char *fmt, int width, u_long value, short showvalue)
|
||||
{
|
||||
const char *lsep, *rsep;
|
||||
char newfmt[32];
|
||||
|
||||
lsep = "";
|
||||
if (strncmp(fmt, "LS", 2) == 0) {
|
||||
lsep = " ";
|
||||
fmt += 2;
|
||||
}
|
||||
rsep = " ";
|
||||
if (strncmp(fmt, "NRS", 3) == 0) {
|
||||
rsep = "";
|
||||
fmt += 3;
|
||||
}
|
||||
if (showvalue == 0) {
|
||||
/* Print just dash. */
|
||||
sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep);
|
||||
printf(newfmt, "-");
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
/* Construct the format string. */
|
||||
sprintf(newfmt, "%s%%%d%s%s", lsep, width, fmt, rsep);
|
||||
printf(newfmt, value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a description of the network interfaces.
|
||||
*/
|
||||
void
|
||||
intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *))
|
||||
{
|
||||
struct ifnet ifnet;
|
||||
struct ifnethead ifnethead;
|
||||
union {
|
||||
struct ifaddr ifa;
|
||||
struct in_ifaddr in;
|
||||
#ifdef INET6
|
||||
struct in6_ifaddr in6;
|
||||
#endif
|
||||
struct ipx_ifaddr ipx;
|
||||
} ifaddr;
|
||||
u_long ifaddraddr;
|
||||
u_long ifaddrfound;
|
||||
u_long ifnetfound;
|
||||
u_long opackets;
|
||||
u_long ipackets;
|
||||
u_long obytes;
|
||||
u_long ibytes;
|
||||
u_long omcasts;
|
||||
u_long imcasts;
|
||||
u_long oerrors;
|
||||
u_long ierrors;
|
||||
u_long idrops;
|
||||
u_long collisions;
|
||||
short timer;
|
||||
int drops;
|
||||
struct sockaddr *sa = NULL;
|
||||
char name[IFNAMSIZ];
|
||||
short network_layer;
|
||||
short link_layer;
|
||||
|
||||
if (ifnetaddr == 0) {
|
||||
printf("ifnet: symbol not defined\n");
|
||||
return;
|
||||
}
|
||||
if (interval1) {
|
||||
sidewaysintpr(interval1, ifnetaddr);
|
||||
return;
|
||||
}
|
||||
if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead) != 0)
|
||||
return;
|
||||
ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead);
|
||||
if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0)
|
||||
return;
|
||||
|
||||
if (!pfunc) {
|
||||
if (Wflag)
|
||||
printf("%-7.7s", "Name");
|
||||
else
|
||||
printf("%-5.5s", "Name");
|
||||
printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s",
|
||||
"Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop");
|
||||
if (bflag)
|
||||
printf(" %10.10s","Ibytes");
|
||||
printf(" %8.8s %5.5s", "Opkts", "Oerrs");
|
||||
if (bflag)
|
||||
printf(" %10.10s","Obytes");
|
||||
printf(" %5s", "Coll");
|
||||
if (tflag)
|
||||
printf(" %s", "Time");
|
||||
if (dflag)
|
||||
printf(" %s", "Drop");
|
||||
putchar('\n');
|
||||
}
|
||||
ifaddraddr = 0;
|
||||
while (ifnetaddr || ifaddraddr) {
|
||||
struct sockaddr_in *sockin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sockin6;
|
||||
#endif
|
||||
char *cp;
|
||||
int n, m;
|
||||
|
||||
network_layer = 0;
|
||||
link_layer = 0;
|
||||
|
||||
if (ifaddraddr == 0) {
|
||||
ifnetfound = ifnetaddr;
|
||||
if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0)
|
||||
return;
|
||||
strlcpy(name, ifnet.if_xname, sizeof(name));
|
||||
ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link);
|
||||
if (interface != 0 && strcmp(name, interface) != 0)
|
||||
continue;
|
||||
cp = index(name, '\0');
|
||||
|
||||
if (pfunc) {
|
||||
(*pfunc)(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ifnet.if_flags&IFF_UP) == 0)
|
||||
*cp++ = '*';
|
||||
*cp = '\0';
|
||||
ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead);
|
||||
}
|
||||
ifaddrfound = ifaddraddr;
|
||||
|
||||
/*
|
||||
* Get the interface stats. These may get
|
||||
* overriden below on a per-interface basis.
|
||||
*/
|
||||
opackets = ifnet.if_opackets;
|
||||
ipackets = ifnet.if_ipackets;
|
||||
obytes = ifnet.if_obytes;
|
||||
ibytes = ifnet.if_ibytes;
|
||||
omcasts = ifnet.if_omcasts;
|
||||
imcasts = ifnet.if_imcasts;
|
||||
oerrors = ifnet.if_oerrors;
|
||||
ierrors = ifnet.if_ierrors;
|
||||
idrops = ifnet.if_iqdrops;
|
||||
collisions = ifnet.if_collisions;
|
||||
timer = ifnet.if_timer;
|
||||
drops = ifnet.if_snd.ifq_drops;
|
||||
|
||||
if (ifaddraddr == 0) {
|
||||
if (Wflag)
|
||||
printf("%-7.7s", name);
|
||||
else
|
||||
printf("%-5.5s", name);
|
||||
printf(" %5lu ", ifnet.if_mtu);
|
||||
printf("%-13.13s ", "none");
|
||||
printf("%-17.17s ", "none");
|
||||
} else {
|
||||
if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)
|
||||
!= 0) {
|
||||
ifaddraddr = 0;
|
||||
continue;
|
||||
}
|
||||
#define CP(x) ((char *)(x))
|
||||
cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
|
||||
CP(&ifaddr);
|
||||
sa = (struct sockaddr *)cp;
|
||||
if (af != AF_UNSPEC && sa->sa_family != af) {
|
||||
ifaddraddr =
|
||||
(u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
|
||||
continue;
|
||||
}
|
||||
if (Wflag)
|
||||
printf("%-7.7s", name);
|
||||
else
|
||||
printf("%-5.5s", name);
|
||||
printf(" %5lu ", ifnet.if_mtu);
|
||||
switch (sa->sa_family) {
|
||||
case AF_UNSPEC:
|
||||
printf("%-13.13s ", "none");
|
||||
printf("%-15.15s ", "none");
|
||||
break;
|
||||
case AF_INET:
|
||||
sockin = (struct sockaddr_in *)sa;
|
||||
#ifdef notdef
|
||||
/* can't use inet_makeaddr because kernel
|
||||
* keeps nets unshifted.
|
||||
*/
|
||||
in = inet_makeaddr(ifaddr.in.ia_subnet,
|
||||
INADDR_ANY);
|
||||
printf("%-13.13s ", netname(in.s_addr,
|
||||
ifaddr.in.ia_subnetmask));
|
||||
#else
|
||||
printf("%-13.13s ",
|
||||
netname(htonl(ifaddr.in.ia_subnet),
|
||||
ifaddr.in.ia_subnetmask));
|
||||
#endif
|
||||
printf("%-17.17s ",
|
||||
routename(sockin->sin_addr.s_addr));
|
||||
|
||||
network_layer = 1;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sockin6 = (struct sockaddr_in6 *)sa;
|
||||
printf("%-13.13s ",
|
||||
netname6(&ifaddr.in6.ia_addr,
|
||||
&ifaddr.in6.ia_prefixmask.sin6_addr));
|
||||
printf("%-17.17s ",
|
||||
inet_ntop(AF_INET6,
|
||||
&sockin6->sin6_addr,
|
||||
ntop_buf, sizeof(ntop_buf)));
|
||||
|
||||
network_layer = 1;
|
||||
break;
|
||||
#endif /*INET6*/
|
||||
case AF_IPX:
|
||||
{
|
||||
struct sockaddr_ipx *sipx =
|
||||
(struct sockaddr_ipx *)sa;
|
||||
u_long net;
|
||||
char netnum[10];
|
||||
|
||||
*(union ipx_net *) &net = sipx->sipx_addr.x_net;
|
||||
sprintf(netnum, "%lx", (u_long)ntohl(net));
|
||||
printf("ipx:%-8s ", netnum);
|
||||
/* printf("ipx:%-8s ", netname(net, 0L)); */
|
||||
printf("%-17s ",
|
||||
ipx_phost((struct sockaddr *)sipx));
|
||||
}
|
||||
|
||||
network_layer = 1;
|
||||
break;
|
||||
|
||||
case AF_APPLETALK:
|
||||
printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
|
||||
printf("%-11.11s ",atalk_print(sa,0x0b) );
|
||||
break;
|
||||
case AF_LINK:
|
||||
{
|
||||
struct sockaddr_dl *sdl =
|
||||
(struct sockaddr_dl *)sa;
|
||||
char linknum[10];
|
||||
cp = (char *)LLADDR(sdl);
|
||||
n = sdl->sdl_alen;
|
||||
sprintf(linknum, "<Link#%d>", sdl->sdl_index);
|
||||
m = printf("%-13.13s ", linknum);
|
||||
}
|
||||
goto hexprint;
|
||||
default:
|
||||
m = printf("(%d)", sa->sa_family);
|
||||
for (cp = sa->sa_len + (char *)sa;
|
||||
--cp > sa->sa_data && (*cp == 0);) {}
|
||||
n = cp - sa->sa_data + 1;
|
||||
cp = sa->sa_data;
|
||||
hexprint:
|
||||
while (--n >= 0)
|
||||
m += printf("%02x%c", *cp++ & 0xff,
|
||||
n > 0 ? ':' : ' ');
|
||||
m = 32 - m;
|
||||
while (m-- > 0)
|
||||
putchar(' ');
|
||||
|
||||
link_layer = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixup the statistics for interfaces that
|
||||
* update stats for their network addresses
|
||||
*/
|
||||
if (network_layer) {
|
||||
opackets = ifaddr.in.ia_ifa.if_opackets;
|
||||
ipackets = ifaddr.in.ia_ifa.if_ipackets;
|
||||
obytes = ifaddr.in.ia_ifa.if_obytes;
|
||||
ibytes = ifaddr.in.ia_ifa.if_ibytes;
|
||||
}
|
||||
|
||||
ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
|
||||
}
|
||||
|
||||
show_stat("lu", 8, ipackets, link_layer|network_layer);
|
||||
show_stat("lu", 5, ierrors, link_layer);
|
||||
show_stat("lu", 5, idrops, link_layer);
|
||||
if (bflag)
|
||||
show_stat("lu", 10, ibytes, link_layer|network_layer);
|
||||
|
||||
show_stat("lu", 8, opackets, link_layer|network_layer);
|
||||
show_stat("lu", 5, oerrors, link_layer);
|
||||
if (bflag)
|
||||
show_stat("lu", 10, obytes, link_layer|network_layer);
|
||||
|
||||
show_stat("NRSlu", 5, collisions, link_layer);
|
||||
if (tflag)
|
||||
show_stat("LSd", 4, timer, link_layer);
|
||||
if (dflag)
|
||||
show_stat("LSd", 4, drops, link_layer);
|
||||
putchar('\n');
|
||||
|
||||
if (aflag && ifaddrfound) {
|
||||
/*
|
||||
* Print family's multicast addresses
|
||||
*/
|
||||
struct ifmultiaddr *multiaddr;
|
||||
struct ifmultiaddr ifma;
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in in;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif /* INET6 */
|
||||
struct sockaddr_dl dl;
|
||||
} msa;
|
||||
const char *fmt;
|
||||
|
||||
TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) {
|
||||
if (kread((u_long)multiaddr, (char *)&ifma,
|
||||
sizeof ifma) != 0)
|
||||
break;
|
||||
multiaddr = &ifma;
|
||||
if (kread((u_long)ifma.ifma_addr, (char *)&msa,
|
||||
sizeof msa) != 0)
|
||||
break;
|
||||
if (msa.sa.sa_family != sa->sa_family)
|
||||
continue;
|
||||
|
||||
fmt = 0;
|
||||
switch (msa.sa.sa_family) {
|
||||
case AF_INET:
|
||||
fmt = routename(msa.in.sin_addr.s_addr);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
printf("%*s %-19.19s(refs: %d)\n",
|
||||
Wflag ? 27 : 25, "",
|
||||
inet_ntop(AF_INET6,
|
||||
&msa.in6.sin6_addr,
|
||||
ntop_buf,
|
||||
sizeof(ntop_buf)),
|
||||
ifma.ifma_refcount);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
case AF_LINK:
|
||||
switch (msa.dl.sdl_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
fmt = ether_ntoa(
|
||||
(struct ether_addr *)
|
||||
LLADDR(&msa.dl));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (fmt) {
|
||||
printf("%*s %-17.17s",
|
||||
Wflag ? 27 : 25, "", fmt);
|
||||
if (msa.sa.sa_family == AF_LINK) {
|
||||
printf(" %8lu", imcasts);
|
||||
printf("%*s",
|
||||
bflag ? 17 : 6, "");
|
||||
printf(" %8lu", omcasts);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct iftot {
|
||||
SLIST_ENTRY(iftot) chain;
|
||||
char ift_name[IFNAMSIZ]; /* interface name */
|
||||
u_long ift_ip; /* input packets */
|
||||
u_long ift_ie; /* input errors */
|
||||
u_long ift_id; /* input drops */
|
||||
u_long ift_op; /* output packets */
|
||||
u_long ift_oe; /* output errors */
|
||||
u_long ift_co; /* collisions */
|
||||
u_int ift_dr; /* drops */
|
||||
u_long ift_ib; /* input bytes */
|
||||
u_long ift_ob; /* output bytes */
|
||||
};
|
||||
|
||||
u_char signalled; /* set if alarm goes off "early" */
|
||||
|
||||
/*
|
||||
* Print a running summary of interface statistics.
|
||||
* Repeat display every interval1 seconds, showing statistics
|
||||
* collected over that interval. Assumes that interval1 is non-zero.
|
||||
* First line printed at top of screen is always cumulative.
|
||||
* XXX - should be rewritten to use ifmib(4).
|
||||
*/
|
||||
static void
|
||||
sidewaysintpr(int interval1, u_long off)
|
||||
{
|
||||
struct ifnet ifnet;
|
||||
u_long firstifnet;
|
||||
struct ifnethead ifnethead;
|
||||
struct itimerval interval_it;
|
||||
struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting;
|
||||
int line;
|
||||
int oldmask, first;
|
||||
u_long interesting_off;
|
||||
|
||||
if (kread(off, (char *)&ifnethead, sizeof ifnethead) != 0)
|
||||
return;
|
||||
firstifnet = (u_long)TAILQ_FIRST(&ifnethead);
|
||||
|
||||
if ((iftot = malloc(sizeof(struct iftot))) == NULL) {
|
||||
printf("malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
memset(iftot, 0, sizeof(struct iftot));
|
||||
|
||||
interesting = NULL;
|
||||
interesting_off = 0;
|
||||
for (off = firstifnet, ip = iftot; off;) {
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
if (kread(off, (char *)&ifnet, sizeof ifnet) != 0)
|
||||
break;
|
||||
strlcpy(name, ifnet.if_xname, sizeof(name));
|
||||
if (interface && strcmp(name, interface) == 0) {
|
||||
interesting = ip;
|
||||
interesting_off = off;
|
||||
}
|
||||
snprintf(ip->ift_name, sizeof(ip->ift_name), "(%s)", name);;
|
||||
if ((ipn = malloc(sizeof(struct iftot))) == NULL) {
|
||||
printf("malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
memset(ipn, 0, sizeof(struct iftot));
|
||||
SLIST_NEXT(ip, chain) = ipn;
|
||||
ip = ipn;
|
||||
off = (u_long)TAILQ_NEXT(&ifnet, if_link);
|
||||
}
|
||||
if (interface && interesting == NULL)
|
||||
errx(1, "%s: unknown interface", interface);
|
||||
if ((total = malloc(sizeof(struct iftot))) == NULL) {
|
||||
printf("malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
memset(total, 0, sizeof(struct iftot));
|
||||
if ((sum = malloc(sizeof(struct iftot))) == NULL) {
|
||||
printf("malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
memset(sum, 0, sizeof(struct iftot));
|
||||
|
||||
(void)signal(SIGALRM, catchalarm);
|
||||
signalled = NO;
|
||||
interval_it.it_interval.tv_sec = interval1;
|
||||
interval_it.it_interval.tv_usec = 0;
|
||||
interval_it.it_value = interval_it.it_interval;
|
||||
setitimer(ITIMER_REAL, &interval_it, NULL);
|
||||
first = 1;
|
||||
banner:
|
||||
printf("%17s %14s %16s", "input",
|
||||
interesting ? interesting->ift_name : "(Total)", "output");
|
||||
putchar('\n');
|
||||
printf("%10s %5s %5s %10s %10s %5s %10s %5s",
|
||||
"packets", "errs", "idrops", "bytes", "packets", "errs", "bytes",
|
||||
"colls");
|
||||
if (dflag)
|
||||
printf(" %5.5s", "drops");
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
line = 0;
|
||||
loop:
|
||||
if (interesting != NULL) {
|
||||
ip = interesting;
|
||||
if (kread(interesting_off, (char *)&ifnet, sizeof ifnet) != 0) {
|
||||
printf("???\n");
|
||||
exit(1);
|
||||
};
|
||||
if (!first) {
|
||||
show_stat("lu", 10, ifnet.if_ipackets - ip->ift_ip, 1);
|
||||
show_stat("lu", 5, ifnet.if_ierrors - ip->ift_ie, 1);
|
||||
show_stat("lu", 5, ifnet.if_iqdrops - ip->ift_id, 1);
|
||||
show_stat("lu", 10, ifnet.if_ibytes - ip->ift_ib, 1);
|
||||
show_stat("lu", 10, ifnet.if_opackets - ip->ift_op, 1);
|
||||
show_stat("lu", 5, ifnet.if_oerrors - ip->ift_oe, 1);
|
||||
show_stat("lu", 10, ifnet.if_obytes - ip->ift_ob, 1);
|
||||
show_stat("NRSlu", 5,
|
||||
ifnet.if_collisions - ip->ift_co, 1);
|
||||
if (dflag)
|
||||
show_stat("LSu", 5,
|
||||
ifnet.if_snd.ifq_drops - ip->ift_dr, 1);
|
||||
}
|
||||
ip->ift_ip = ifnet.if_ipackets;
|
||||
ip->ift_ie = ifnet.if_ierrors;
|
||||
ip->ift_id = ifnet.if_iqdrops;
|
||||
ip->ift_ib = ifnet.if_ibytes;
|
||||
ip->ift_op = ifnet.if_opackets;
|
||||
ip->ift_oe = ifnet.if_oerrors;
|
||||
ip->ift_ob = ifnet.if_obytes;
|
||||
ip->ift_co = ifnet.if_collisions;
|
||||
ip->ift_dr = ifnet.if_snd.ifq_drops;
|
||||
} else {
|
||||
sum->ift_ip = 0;
|
||||
sum->ift_ie = 0;
|
||||
sum->ift_id = 0;
|
||||
sum->ift_ib = 0;
|
||||
sum->ift_op = 0;
|
||||
sum->ift_oe = 0;
|
||||
sum->ift_ob = 0;
|
||||
sum->ift_co = 0;
|
||||
sum->ift_dr = 0;
|
||||
for (off = firstifnet, ip = iftot;
|
||||
off && SLIST_NEXT(ip, chain) != NULL;
|
||||
ip = SLIST_NEXT(ip, chain)) {
|
||||
if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) {
|
||||
off = 0;
|
||||
continue;
|
||||
}
|
||||
sum->ift_ip += ifnet.if_ipackets;
|
||||
sum->ift_ie += ifnet.if_ierrors;
|
||||
sum->ift_id += ifnet.if_iqdrops;
|
||||
sum->ift_ib += ifnet.if_ibytes;
|
||||
sum->ift_op += ifnet.if_opackets;
|
||||
sum->ift_oe += ifnet.if_oerrors;
|
||||
sum->ift_ob += ifnet.if_obytes;
|
||||
sum->ift_co += ifnet.if_collisions;
|
||||
sum->ift_dr += ifnet.if_snd.ifq_drops;
|
||||
off = (u_long)TAILQ_NEXT(&ifnet, if_link);
|
||||
}
|
||||
if (!first) {
|
||||
show_stat("lu", 10, sum->ift_ip - total->ift_ip, 1);
|
||||
show_stat("lu", 5, sum->ift_ie - total->ift_ie, 1);
|
||||
show_stat("lu", 5, sum->ift_id - total->ift_id, 1);
|
||||
show_stat("lu", 10, sum->ift_ib - total->ift_ib, 1);
|
||||
show_stat("lu", 10, sum->ift_op - total->ift_op, 1);
|
||||
show_stat("lu", 5, sum->ift_oe - total->ift_oe, 1);
|
||||
show_stat("lu", 10, sum->ift_ob - total->ift_ob, 1);
|
||||
show_stat("NRSlu", 5, sum->ift_co - total->ift_co, 1);
|
||||
if (dflag)
|
||||
show_stat("LSu", 5,
|
||||
sum->ift_dr - total->ift_dr, 1);
|
||||
}
|
||||
*total = *sum;
|
||||
}
|
||||
if (!first)
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
if ((noutputs != 0) && (--noutputs == 0))
|
||||
exit(0);
|
||||
oldmask = sigblock(sigmask(SIGALRM));
|
||||
while (!signalled)
|
||||
sigpause(0);
|
||||
signalled = NO;
|
||||
sigsetmask(oldmask);
|
||||
line++;
|
||||
first = 0;
|
||||
if (line == 21)
|
||||
goto banner;
|
||||
else
|
||||
goto loop;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a flag to indicate that a signal from the periodic itimer has been
|
||||
* caught.
|
||||
*/
|
||||
static void
|
||||
catchalarm(int signo __unused)
|
||||
{
|
||||
signalled = YES;
|
||||
}
|
1291
freebsd-userspace/commands/usr.bin/netstat/inet.c
Normal file
1291
freebsd-userspace/commands/usr.bin/netstat/inet.c
Normal file
File diff suppressed because it is too large
Load Diff
1159
freebsd-userspace/commands/usr.bin/netstat/inet6.c
Normal file
1159
freebsd-userspace/commands/usr.bin/netstat/inet6.c
Normal file
File diff suppressed because it is too large
Load Diff
481
freebsd-userspace/commands/usr.bin/netstat/ipsec.c
Normal file
481
freebsd-userspace/commands/usr.bin/netstat/ipsec.c
Normal file
@ -0,0 +1,481 @@
|
||||
/* $KAME: ipsec.c,v 1.33 2003/07/25 09:54:32 itojun Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 NTT Multimedia Communications Laboratories, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef IPSEC
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/netipsec/ipsec.h>
|
||||
#include <freebsd/netipsec/ah_var.h>
|
||||
#include <freebsd/netipsec/esp_var.h>
|
||||
#include <freebsd/netipsec/ipcomp_var.h>
|
||||
#else
|
||||
#include <netipsec/ipsec.h>
|
||||
#include <netipsec/ah_var.h>
|
||||
#include <netipsec/esp_var.h>
|
||||
#include <netipsec/ipcomp_var.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "netstat.h"
|
||||
|
||||
#ifdef IPSEC
|
||||
struct val2str {
|
||||
int val;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
static struct val2str ipsec_ahnames[] = {
|
||||
{ SADB_AALG_NONE, "none", },
|
||||
{ SADB_AALG_MD5HMAC, "hmac-md5", },
|
||||
{ SADB_AALG_SHA1HMAC, "hmac-sha1", },
|
||||
{ SADB_X_AALG_MD5, "md5", },
|
||||
{ SADB_X_AALG_SHA, "sha", },
|
||||
{ SADB_X_AALG_NULL, "null", },
|
||||
#ifdef SADB_X_AALG_SHA2_256
|
||||
{ SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
|
||||
#endif
|
||||
#ifdef SADB_X_AALG_SHA2_384
|
||||
{ SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
|
||||
#endif
|
||||
#ifdef SADB_X_AALG_SHA2_512
|
||||
{ SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
|
||||
#endif
|
||||
#ifdef SADB_X_AALG_RIPEMD160HMAC
|
||||
{ SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", },
|
||||
#endif
|
||||
#ifdef SADB_X_AALG_AES_XCBC_MAC
|
||||
{ SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", },
|
||||
#endif
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
static struct val2str ipsec_espnames[] = {
|
||||
{ SADB_EALG_NONE, "none", },
|
||||
{ SADB_EALG_DESCBC, "des-cbc", },
|
||||
{ SADB_EALG_3DESCBC, "3des-cbc", },
|
||||
{ SADB_EALG_NULL, "null", },
|
||||
{ SADB_X_EALG_CAST128CBC, "cast128-cbc", },
|
||||
{ SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
|
||||
#ifdef SADB_X_EALG_RIJNDAELCBC
|
||||
{ SADB_X_EALG_RIJNDAELCBC, "rijndael-cbc", },
|
||||
#endif
|
||||
#ifdef SADB_X_EALG_AESCTR
|
||||
{ SADB_X_EALG_AESCTR, "aes-ctr", },
|
||||
#endif
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
static struct val2str ipsec_compnames[] = {
|
||||
{ SADB_X_CALG_NONE, "none", },
|
||||
{ SADB_X_CALG_OUI, "oui", },
|
||||
{ SADB_X_CALG_DEFLATE, "deflate", },
|
||||
{ SADB_X_CALG_LZS, "lzs", },
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
static void ipsec_hist(const u_quad_t *hist, size_t histmax,
|
||||
const struct val2str *name, const char *title);
|
||||
static void print_ipsecstats(const struct ipsecstat *ipsecstat);
|
||||
|
||||
|
||||
/*
|
||||
* Dump IPSEC statistics structure.
|
||||
*/
|
||||
static void
|
||||
ipsec_hist(const u_quad_t *hist, size_t histmax, const struct val2str *name,
|
||||
const char *title)
|
||||
{
|
||||
int first;
|
||||
size_t proto;
|
||||
const struct val2str *p;
|
||||
|
||||
first = 1;
|
||||
for (proto = 0; proto < histmax; proto++) {
|
||||
if (hist[proto] <= 0)
|
||||
continue;
|
||||
if (first) {
|
||||
printf("\t%s histogram:\n", title);
|
||||
first = 0;
|
||||
}
|
||||
for (p = name; p && p->str; p++) {
|
||||
if (p->val == (int)proto)
|
||||
break;
|
||||
}
|
||||
if (p && p->str) {
|
||||
printf("\t\t%s: %ju\n", p->str, (uintmax_t)hist[proto]);
|
||||
} else {
|
||||
printf("\t\t#%ld: %ju\n", (long)proto,
|
||||
(uintmax_t)hist[proto]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_ipsecstats(const struct ipsecstat *ipsecstat)
|
||||
{
|
||||
#define p(f, m) if (ipsecstat->f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f))
|
||||
#define pes(f, m) if (ipsecstat->f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)ipsecstat->f, plurales(ipsecstat->f))
|
||||
#define hist(f, n, t) \
|
||||
ipsec_hist((f), sizeof(f)/sizeof(f[0]), (n), (t));
|
||||
|
||||
p(in_success, "\t%ju inbound packet%s processed successfully\n");
|
||||
p(in_polvio, "\t%ju inbound packet%s violated process security "
|
||||
"policy\n");
|
||||
p(in_nosa, "\t%ju inbound packet%s with no SA available\n");
|
||||
p(in_inval, "\t%ju invalid inbound packet%s\n");
|
||||
p(in_nomem, "\t%ju inbound packet%s failed due to insufficient memory\n");
|
||||
p(in_badspi, "\t%ju inbound packet%s failed getting SPI\n");
|
||||
p(in_ahreplay, "\t%ju inbound packet%s failed on AH replay check\n");
|
||||
p(in_espreplay, "\t%ju inbound packet%s failed on ESP replay check\n");
|
||||
p(in_ahauthsucc, "\t%ju inbound packet%s considered authentic\n");
|
||||
p(in_ahauthfail, "\t%ju inbound packet%s failed on authentication\n");
|
||||
hist(ipsecstat->in_ahhist, ipsec_ahnames, "AH input");
|
||||
hist(ipsecstat->in_esphist, ipsec_espnames, "ESP input");
|
||||
hist(ipsecstat->in_comphist, ipsec_compnames, "IPComp input");
|
||||
|
||||
p(out_success, "\t%ju outbound packet%s processed successfully\n");
|
||||
p(out_polvio, "\t%ju outbound packet%s violated process security "
|
||||
"policy\n");
|
||||
p(out_nosa, "\t%ju outbound packet%s with no SA available\n");
|
||||
p(out_inval, "\t%ju invalid outbound packet%s\n");
|
||||
p(out_nomem, "\t%ju outbound packet%s failed due to insufficient memory\n");
|
||||
p(out_noroute, "\t%ju outbound packet%s with no route\n");
|
||||
hist(ipsecstat->out_ahhist, ipsec_ahnames, "AH output");
|
||||
hist(ipsecstat->out_esphist, ipsec_espnames, "ESP output");
|
||||
hist(ipsecstat->out_comphist, ipsec_compnames, "IPComp output");
|
||||
p(spdcachelookup, "\t%ju SPD cache lookup%s\n");
|
||||
pes(spdcachemiss, "\t%ju SPD cache miss%s\n");
|
||||
#undef pes
|
||||
#undef hist
|
||||
p(ips_in_polvio, "\t%ju inbound packet%s violated process "
|
||||
"security policy\n");
|
||||
p(ips_out_polvio, "\t%ju outbound packet%s violated process "
|
||||
"security policy\n");
|
||||
p(ips_out_nosa, "\t%ju outbound packet%s with no SA available\n");
|
||||
p(ips_out_nomem, "\t%ju outbound packet%s failed due to "
|
||||
"insufficient memory\n");
|
||||
p(ips_out_noroute, "\t%ju outbound packet%s with no route "
|
||||
"available\n");
|
||||
p(ips_out_inval, "\t%ju invalid outbound packet%s\n");
|
||||
p(ips_out_bundlesa, "\t%ju outbound packet%s with bundled SAs\n");
|
||||
p(ips_mbcoalesced, "\t%ju mbuf%s coalesced during clone\n");
|
||||
p(ips_clcoalesced, "\t%ju cluster%s coalesced during clone\n");
|
||||
p(ips_clcopied, "\t%ju cluster%s copied during clone\n");
|
||||
p(ips_mbinserted, "\t%ju mbuf%s inserted during makespace\n");
|
||||
#undef p
|
||||
}
|
||||
|
||||
void
|
||||
ipsec_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
{
|
||||
struct ipsecstat ipsecstat;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
kread(off, (char *)&ipsecstat, sizeof(ipsecstat));
|
||||
|
||||
print_ipsecstats(&ipsecstat);
|
||||
}
|
||||
|
||||
|
||||
static void ipsec_hist_new(const u_int32_t *hist, size_t histmax,
|
||||
const struct val2str *name, const char *title);
|
||||
static void print_ahstats(const struct ahstat *ahstat);
|
||||
static void print_espstats(const struct espstat *espstat);
|
||||
static void print_ipcompstats(const struct ipcompstat *ipcompstat);
|
||||
|
||||
/*
|
||||
* Dump IPSEC statistics structure.
|
||||
*/
|
||||
static void
|
||||
ipsec_hist_new(const u_int32_t *hist, size_t histmax,
|
||||
const struct val2str *name, const char *title)
|
||||
{
|
||||
int first;
|
||||
size_t proto;
|
||||
const struct val2str *p;
|
||||
|
||||
first = 1;
|
||||
for (proto = 0; proto < histmax; proto++) {
|
||||
if (hist[proto] <= 0)
|
||||
continue;
|
||||
if (first) {
|
||||
printf("\t%s histogram:\n", title);
|
||||
first = 0;
|
||||
}
|
||||
for (p = name; p && p->str; p++) {
|
||||
if (p->val == (int)proto)
|
||||
break;
|
||||
}
|
||||
if (p && p->str) {
|
||||
printf("\t\t%s: %u\n", p->str, hist[proto]);
|
||||
} else {
|
||||
printf("\t\t#%lu: %u\n", (unsigned long)proto,
|
||||
hist[proto]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_ahstats(const struct ahstat *ahstat)
|
||||
{
|
||||
#define p32(f, m) if (ahstat->f || sflag <= 1) \
|
||||
printf("\t%u" m, (unsigned int)ahstat->f, plural(ahstat->f))
|
||||
#define p64(f, m) if (ahstat->f || sflag <= 1) \
|
||||
printf("\t%ju" m, (uintmax_t)ahstat->f, plural(ahstat->f))
|
||||
#define hist(f, n, t) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
|
||||
|
||||
p32(ahs_hdrops, " packet%s shorter than header shows\n");
|
||||
p32(ahs_nopf, " packet%s dropped; protocol family not supported\n");
|
||||
p32(ahs_notdb, " packet%s dropped; no TDB\n");
|
||||
p32(ahs_badkcr, " packet%s dropped; bad KCR\n");
|
||||
p32(ahs_qfull, " packet%s dropped; queue full\n");
|
||||
p32(ahs_noxform, " packet%s dropped; no transform\n");
|
||||
p32(ahs_wrap, " replay counter wrap%s\n");
|
||||
p32(ahs_badauth, " packet%s dropped; bad authentication detected\n");
|
||||
p32(ahs_badauthl, " packet%s dropped; bad authentication length\n");
|
||||
p32(ahs_replay, " possible replay packet%s detected\n");
|
||||
p32(ahs_input, " packet%s in\n");
|
||||
p32(ahs_output, " packet%s out\n");
|
||||
p32(ahs_invalid, " packet%s dropped; invalid TDB\n");
|
||||
p64(ahs_ibytes, " byte%s in\n");
|
||||
p64(ahs_obytes, " byte%s out\n");
|
||||
p32(ahs_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
|
||||
p32(ahs_pdrops, " packet%s blocked due to policy\n");
|
||||
p32(ahs_crypto, " crypto processing failure%s\n");
|
||||
p32(ahs_tunnel, " tunnel sanity check failure%s\n");
|
||||
hist(ahstat->ahs_hist, ipsec_ahnames, "AH output");
|
||||
|
||||
#undef p32
|
||||
#undef p64
|
||||
#undef hist
|
||||
}
|
||||
|
||||
void
|
||||
ah_stats(u_long off, const char *name, int family __unused, int proto __unused)
|
||||
{
|
||||
struct ahstat ahstat;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
kread(off, (char *)&ahstat, sizeof(ahstat));
|
||||
|
||||
print_ahstats(&ahstat);
|
||||
}
|
||||
|
||||
static void
|
||||
print_espstats(const struct espstat *espstat)
|
||||
{
|
||||
#define p32(f, m) if (espstat->f || sflag <= 1) \
|
||||
printf("\t%u" m, (unsigned int)espstat->f, plural(espstat->f))
|
||||
#define p64(f, m) if (espstat->f || sflag <= 1) \
|
||||
printf("\t%ju" m, (uintmax_t)espstat->f, plural(espstat->f))
|
||||
#define hist(f, n, t) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
|
||||
|
||||
p32(esps_hdrops, " packet%s shorter than header shows\n");
|
||||
p32(esps_nopf, " packet%s dropped; protocol family not supported\n");
|
||||
p32(esps_notdb, " packet%s dropped; no TDB\n");
|
||||
p32(esps_badkcr, " packet%s dropped; bad KCR\n");
|
||||
p32(esps_qfull, " packet%s dropped; queue full\n");
|
||||
p32(esps_noxform, " packet%s dropped; no transform\n");
|
||||
p32(esps_badilen, " packet%s dropped; bad ilen\n");
|
||||
p32(esps_wrap, " replay counter wrap%s\n");
|
||||
p32(esps_badenc, " packet%s dropped; bad encryption detected\n");
|
||||
p32(esps_badauth, " packet%s dropped; bad authentication detected\n");
|
||||
p32(esps_replay, " possible replay packet%s detected\n");
|
||||
p32(esps_input, " packet%s in\n");
|
||||
p32(esps_output, " packet%s out\n");
|
||||
p32(esps_invalid, " packet%s dropped; invalid TDB\n");
|
||||
p64(esps_ibytes, " byte%s in\n");
|
||||
p64(esps_obytes, " byte%s out\n");
|
||||
p32(esps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
|
||||
p32(esps_pdrops, " packet%s blocked due to policy\n");
|
||||
p32(esps_crypto, " crypto processing failure%s\n");
|
||||
p32(esps_tunnel, " tunnel sanity check failure%s\n");
|
||||
hist(espstat->esps_hist, ipsec_espnames, "ESP output");
|
||||
|
||||
#undef p32
|
||||
#undef p64
|
||||
#undef hist
|
||||
}
|
||||
|
||||
void
|
||||
esp_stats(u_long off, const char *name, int family __unused, int proto __unused)
|
||||
{
|
||||
struct espstat espstat;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
kread(off, (char *)&espstat, sizeof(espstat));
|
||||
|
||||
print_espstats(&espstat);
|
||||
}
|
||||
|
||||
static void
|
||||
print_ipcompstats(const struct ipcompstat *ipcompstat)
|
||||
{
|
||||
uint32_t version;
|
||||
#define p32(f, m) if (ipcompstat->f || sflag <= 1) \
|
||||
printf("\t%u" m, (unsigned int)ipcompstat->f, plural(ipcompstat->f))
|
||||
#define p64(f, m) if (ipcompstat->f || sflag <= 1) \
|
||||
printf("\t%ju" m, (uintmax_t)ipcompstat->f, plural(ipcompstat->f))
|
||||
#define hist(f, n, t) \
|
||||
ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
|
||||
|
||||
#ifndef IPCOMPSTAT_VERSION
|
||||
version = 0;
|
||||
#else
|
||||
version = ipcompstat->version;
|
||||
#endif
|
||||
p32(ipcomps_hdrops, " packet%s shorter than header shows\n");
|
||||
p32(ipcomps_nopf, " packet%s dropped; protocol family not supported\n");
|
||||
p32(ipcomps_notdb, " packet%s dropped; no TDB\n");
|
||||
p32(ipcomps_badkcr, " packet%s dropped; bad KCR\n");
|
||||
p32(ipcomps_qfull, " packet%s dropped; queue full\n");
|
||||
p32(ipcomps_noxform, " packet%s dropped; no transform\n");
|
||||
p32(ipcomps_wrap, " replay counter wrap%s\n");
|
||||
p32(ipcomps_input, " packet%s in\n");
|
||||
p32(ipcomps_output, " packet%s out\n");
|
||||
p32(ipcomps_invalid, " packet%s dropped; invalid TDB\n");
|
||||
p64(ipcomps_ibytes, " byte%s in\n");
|
||||
p64(ipcomps_obytes, " byte%s out\n");
|
||||
p32(ipcomps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
|
||||
p32(ipcomps_pdrops, " packet%s blocked due to policy\n");
|
||||
p32(ipcomps_crypto, " crypto processing failure%s\n");
|
||||
hist(ipcompstat->ipcomps_hist, ipsec_compnames, "COMP output");
|
||||
if (version >= 1) {
|
||||
p32(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n");
|
||||
p32(ipcomps_uncompr, " packet%s sent uncompressed; compression was useless\n");
|
||||
}
|
||||
|
||||
#undef p32
|
||||
#undef p64
|
||||
#undef hist
|
||||
}
|
||||
|
||||
void
|
||||
ipcomp_stats(u_long off, const char *name, int family __unused,
|
||||
int proto __unused)
|
||||
{
|
||||
struct ipcompstat ipcompstat;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
kread(off, (char *)&ipcompstat, sizeof(ipcompstat));
|
||||
|
||||
print_ipcompstats(&ipcompstat);
|
||||
}
|
||||
|
||||
#endif /*IPSEC*/
|
354
freebsd-userspace/commands/usr.bin/netstat/ipx.c
Normal file
354
freebsd-userspace/commands/usr.bin/netstat/ipx.c
Normal file
@ -0,0 +1,354 @@
|
||||
/*-
|
||||
* Copyright (c) 2004, Robert N. M. Watson
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ns.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
|
||||
#include <net/route.h>
|
||||
|
||||
#define TCPSTATES
|
||||
#include <netinet/tcp_fsm.h>
|
||||
|
||||
#include <netipx/ipx.h>
|
||||
#include <netipx/ipx_pcb.h>
|
||||
#include <netipx/ipx_var.h>
|
||||
#ifdef IPXERRORMSGS
|
||||
#include <netipx/ipx_error.h>
|
||||
#endif
|
||||
#include <netipx/spx.h>
|
||||
#include <netipx/spx_timer.h>
|
||||
#include <netipx/spx_var.h>
|
||||
#define SANAMES
|
||||
#include <netipx/spx_debug.h>
|
||||
|
||||
#include <nlist.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "netstat.h"
|
||||
|
||||
static char *ipx_prpr(struct ipx_addr *);
|
||||
|
||||
/*
|
||||
* Print a summary of connections related to a Network Systems
|
||||
* protocol. For SPX, also give state of connection.
|
||||
* Listening processes (aflag) are suppressed unless the
|
||||
* -a (all) flag is specified.
|
||||
*/
|
||||
|
||||
void
|
||||
ipxprotopr(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
{
|
||||
struct ipxpcbhead cb;
|
||||
struct ipxpcb *ipxp;
|
||||
struct ipxpcb ipxpcb;
|
||||
struct spxpcb spxpcb;
|
||||
struct socket sockb;
|
||||
static int first = 1;
|
||||
int isspx;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
|
||||
isspx = strcmp(name, "spx") == 0;
|
||||
kread(off, (char *)&cb, sizeof (struct ipxpcbhead));
|
||||
ipxp = LIST_FIRST(&cb);
|
||||
while (ipxp != NULL) {
|
||||
u_long ppcb;
|
||||
|
||||
kread((u_long)ipxp, (char *)&ipxpcb, sizeof (ipxpcb));
|
||||
ipxp = LIST_NEXT(&ipxpcb, ipxp_list);
|
||||
|
||||
if (!aflag && ipx_nullhost(ipxpcb.ipxp_faddr) ) {
|
||||
continue;
|
||||
}
|
||||
kread((u_long)ipxpcb.ipxp_socket,
|
||||
(char *)&sockb, sizeof (sockb));
|
||||
ppcb = (u_long) ipxpcb.ipxp_pcb;
|
||||
if (ppcb) {
|
||||
if (isspx) {
|
||||
kread(ppcb, (char *)&spxpcb, sizeof (spxpcb));
|
||||
} else continue;
|
||||
} else
|
||||
if (isspx) continue;
|
||||
if (first) {
|
||||
printf("Active IPX connections");
|
||||
if (aflag)
|
||||
printf(" (including servers)");
|
||||
putchar('\n');
|
||||
if (Aflag)
|
||||
printf("%-8.8s ", "PCB");
|
||||
printf(Aflag ?
|
||||
"%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" :
|
||||
"%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n",
|
||||
"Proto", "Recv-Q", "Send-Q",
|
||||
"Local Address", "Foreign Address", "(state)");
|
||||
first = 0;
|
||||
}
|
||||
if (Aflag)
|
||||
printf("%8lx ", ppcb);
|
||||
printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc,
|
||||
sockb.so_snd.sb_cc);
|
||||
printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_laddr));
|
||||
printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_faddr));
|
||||
if (isspx) {
|
||||
if (spxpcb.s_state >= TCP_NSTATES)
|
||||
printf(" %d", spxpcb.s_state);
|
||||
else
|
||||
printf(" %s", tcpstates[spxpcb.s_state]);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
#define ANY(x,y,z) \
|
||||
if (x || sflag <= 1) printf("\t%u %s%s%s\n", x, y, plural(x), z)
|
||||
#define ANYl(x,y,z) \
|
||||
if (x || sflag <= 1) printf("\t%lu %s%s%s\n", x, y, plural(x), z)
|
||||
|
||||
/*
|
||||
* Dump SPX statistics structure.
|
||||
*/
|
||||
void
|
||||
spx_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
{
|
||||
struct spx_istat spx_istat;
|
||||
#define spxstat spx_istat.newstats
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
kread(off, (char *)&spx_istat, sizeof (spx_istat));
|
||||
printf("%s:\n", name);
|
||||
ANY(spx_istat.nonucn, "connection", " dropped due to no new sockets ");
|
||||
ANY(spx_istat.gonawy, "connection", " terminated due to our end dying");
|
||||
ANY(spx_istat.nonucn, "connection",
|
||||
" dropped due to inability to connect");
|
||||
ANY(spx_istat.noconn, "connection",
|
||||
" dropped due to inability to connect");
|
||||
ANY(spx_istat.notme, "connection",
|
||||
" incompleted due to mismatched id's");
|
||||
ANY(spx_istat.wrncon, "connection", " dropped due to mismatched id's");
|
||||
ANY(spx_istat.bdreas, "packet", " dropped out of sequence");
|
||||
ANY(spx_istat.lstdup, "packet", " duplicating the highest packet");
|
||||
ANY(spx_istat.notyet, "packet", " refused as exceeding allocation");
|
||||
ANYl(spxstat.spxs_connattempt, "connection", " initiated");
|
||||
ANYl(spxstat.spxs_accepts, "connection", " accepted");
|
||||
ANYl(spxstat.spxs_connects, "connection", " established");
|
||||
ANYl(spxstat.spxs_drops, "connection", " dropped");
|
||||
ANYl(spxstat.spxs_conndrops, "embryonic connection", " dropped");
|
||||
ANYl(spxstat.spxs_closed, "connection", " closed (includes drops)");
|
||||
ANYl(spxstat.spxs_segstimed, "packet", " where we tried to get rtt");
|
||||
ANYl(spxstat.spxs_rttupdated, "time", " we got rtt");
|
||||
ANYl(spxstat.spxs_delack, "delayed ack", " sent");
|
||||
ANYl(spxstat.spxs_timeoutdrop, "connection",
|
||||
" dropped in rxmt timeout");
|
||||
ANYl(spxstat.spxs_rexmttimeo, "retransmit timeout", "");
|
||||
ANYl(spxstat.spxs_persisttimeo, "persist timeout", "");
|
||||
ANYl(spxstat.spxs_keeptimeo, "keepalive timeout", "");
|
||||
ANYl(spxstat.spxs_keepprobe, "keepalive probe", " sent");
|
||||
ANYl(spxstat.spxs_keepdrops, "connection", " dropped in keepalive");
|
||||
ANYl(spxstat.spxs_sndtotal, "total packet", " sent");
|
||||
ANYl(spxstat.spxs_sndpack, "data packet", " sent");
|
||||
ANYl(spxstat.spxs_sndbyte, "data byte", " sent");
|
||||
ANYl(spxstat.spxs_sndrexmitpack, "data packet", " retransmitted");
|
||||
ANYl(spxstat.spxs_sndrexmitbyte, "data byte", " retransmitted");
|
||||
ANYl(spxstat.spxs_sndacks, "ack-only packet", " sent");
|
||||
ANYl(spxstat.spxs_sndprobe, "window probe", " sent");
|
||||
ANYl(spxstat.spxs_sndurg, "packet", " sent with URG only");
|
||||
ANYl(spxstat.spxs_sndwinup, "window update-only packet", " sent");
|
||||
ANYl(spxstat.spxs_sndctrl, "control (SYN|FIN|RST) packet", " sent");
|
||||
ANYl(spxstat.spxs_sndvoid, "request", " to send a non-existant packet");
|
||||
ANYl(spxstat.spxs_rcvtotal, "total packet", " received");
|
||||
ANYl(spxstat.spxs_rcvpack, "packet", " received in sequence");
|
||||
ANYl(spxstat.spxs_rcvbyte, "byte", " received in sequence");
|
||||
ANYl(spxstat.spxs_rcvbadsum, "packet", " received with ccksum errs");
|
||||
ANYl(spxstat.spxs_rcvbadoff, "packet", " received with bad offset");
|
||||
ANYl(spxstat.spxs_rcvshort, "packet", " received too short");
|
||||
ANYl(spxstat.spxs_rcvduppack, "duplicate-only packet", " received");
|
||||
ANYl(spxstat.spxs_rcvdupbyte, "duplicate-only byte", " received");
|
||||
ANYl(spxstat.spxs_rcvpartduppack, "packet",
|
||||
" with some duplicate data");
|
||||
ANYl(spxstat.spxs_rcvpartdupbyte, "dup. byte", " in part-dup. packet");
|
||||
ANYl(spxstat.spxs_rcvoopack, "out-of-order packet", " received");
|
||||
ANYl(spxstat.spxs_rcvoobyte, "out-of-order byte", " received");
|
||||
ANYl(spxstat.spxs_rcvpackafterwin, "packet", " with data after window");
|
||||
ANYl(spxstat.spxs_rcvbyteafterwin, "byte", " rcvd after window");
|
||||
ANYl(spxstat.spxs_rcvafterclose, "packet", " rcvd after 'close'");
|
||||
ANYl(spxstat.spxs_rcvwinprobe, "rcvd window probe packet", "");
|
||||
ANYl(spxstat.spxs_rcvdupack, "rcvd duplicate ack", "");
|
||||
ANYl(spxstat.spxs_rcvacktoomuch, "rcvd ack", " for unsent data");
|
||||
ANYl(spxstat.spxs_rcvackpack, "rcvd ack packet", "");
|
||||
ANYl(spxstat.spxs_rcvackbyte, "byte", " acked by rcvd acks");
|
||||
ANYl(spxstat.spxs_rcvwinupd, "rcvd window update packet", "");
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump IPX statistics structure.
|
||||
*/
|
||||
void
|
||||
ipx_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
{
|
||||
struct ipxstat ipxstat;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
kread(off, (char *)&ipxstat, sizeof (ipxstat));
|
||||
printf("%s:\n", name);
|
||||
ANYl(ipxstat.ipxs_total, "total packet", " received");
|
||||
ANYl(ipxstat.ipxs_badsum, "packet", " with bad checksums");
|
||||
ANYl(ipxstat.ipxs_tooshort, "packet", " smaller than advertised");
|
||||
ANYl(ipxstat.ipxs_toosmall, "packet", " smaller than a header");
|
||||
ANYl(ipxstat.ipxs_forward, "packet", " forwarded");
|
||||
ANYl(ipxstat.ipxs_cantforward, "packet", " not forwardable");
|
||||
ANYl(ipxstat.ipxs_delivered, "packet", " for this host");
|
||||
ANYl(ipxstat.ipxs_localout, "packet", " sent from this host");
|
||||
ANYl(ipxstat.ipxs_odropped, "packet", " dropped due to no bufs, etc.");
|
||||
ANYl(ipxstat.ipxs_noroute, "packet", " discarded due to no route");
|
||||
ANYl(ipxstat.ipxs_mtutoosmall, "packet", " too big");
|
||||
}
|
||||
|
||||
#ifdef IPXERRORMSGS
|
||||
static struct {
|
||||
u_short code;
|
||||
char *name;
|
||||
char *where;
|
||||
} ipx_errnames[] = {
|
||||
{0, "Unspecified Error", " at Destination"},
|
||||
{1, "Bad Checksum", " at Destination"},
|
||||
{2, "No Listener", " at Socket"},
|
||||
{3, "Packet", " Refused due to lack of space at Destination"},
|
||||
{01000, "Unspecified Error", " while gatewayed"},
|
||||
{01001, "Bad Checksum", " while gatewayed"},
|
||||
{01002, "Packet", " forwarded too many times"},
|
||||
{01003, "Packet", " too large to be forwarded"},
|
||||
{-1, 0, 0},
|
||||
};
|
||||
|
||||
/*
|
||||
* Dump IPX Error statistics structure.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ipxerr_stats(u_long off, const char *name, int af __unused, int proto __unused)
|
||||
{
|
||||
struct ipx_errstat ipx_errstat;
|
||||
int j;
|
||||
int histoprint = 1;
|
||||
int z;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
kread(off, (char *)&ipx_errstat, sizeof (ipx_errstat));
|
||||
printf("IPX error statistics:\n");
|
||||
ANY(ipx_errstat.ipx_es_error, "call", " to ipx_error");
|
||||
ANY(ipx_errstat.ipx_es_oldshort, "error",
|
||||
" ignored due to insufficient addressing");
|
||||
ANY(ipx_errstat.ipx_es_oldipx_err, "error request",
|
||||
" in response to error packets");
|
||||
ANY(ipx_errstat.ipx_es_tooshort, "error packet",
|
||||
" received incomplete");
|
||||
ANY(ipx_errstat.ipx_es_badcode, "error packet",
|
||||
" received of unknown type");
|
||||
for(j = 0; j < IPX_ERR_MAX; j ++) {
|
||||
z = ipx_errstat.ipx_es_outhist[j];
|
||||
if (z && histoprint) {
|
||||
printf("Output Error Histogram:\n");
|
||||
histoprint = 0;
|
||||
}
|
||||
ipx_erputil(z, ipx_errstat.ipx_es_codes[j]);
|
||||
}
|
||||
histoprint = 1;
|
||||
for(j = 0; j < IPX_ERR_MAX; j ++) {
|
||||
z = ipx_errstat.ipx_es_inhist[j];
|
||||
if (z && histoprint) {
|
||||
printf("Input Error Histogram:\n");
|
||||
histoprint = 0;
|
||||
}
|
||||
ipx_erputil(z, ipx_errstat.ipx_es_codes[j]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipx_erputil(int z, int c)
|
||||
{
|
||||
int j;
|
||||
char codebuf[30];
|
||||
char *name, *where;
|
||||
|
||||
for(j = 0;; j ++) {
|
||||
if ((name = ipx_errnames[j].name) == 0)
|
||||
break;
|
||||
if (ipx_errnames[j].code == c)
|
||||
break;
|
||||
}
|
||||
if (name == 0) {
|
||||
if (c > 01000)
|
||||
where = "in transit";
|
||||
else
|
||||
where = "at destination";
|
||||
sprintf(codebuf, "Unknown IPX error code 0%o", c);
|
||||
name = codebuf;
|
||||
} else
|
||||
where = ipx_errnames[j].where;
|
||||
ANY(z, name, where);
|
||||
}
|
||||
#endif /* IPXERRORMSGS */
|
||||
|
||||
static struct sockaddr_ipx ssipx = { .sipx_family = AF_IPX };
|
||||
|
||||
static
|
||||
char *ipx_prpr(struct ipx_addr *x)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = &ssipx;
|
||||
|
||||
sipx->sipx_addr = *x;
|
||||
return(ipx_print((struct sockaddr *)sipx));
|
||||
}
|
805
freebsd-userspace/commands/usr.bin/netstat/main.c
Normal file
805
freebsd-userspace/commands/usr.bin/netstat/main.c
Normal file
@ -0,0 +1,805 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char const copyright[] =
|
||||
"@(#) Copyright (c) 1983, 1988, 1993\n\
|
||||
Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef NETGRAPH
|
||||
#include <netgraph/ng_socket.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <kvm.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <nlist.h>
|
||||
#include <paths.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "netstat.h"
|
||||
|
||||
static struct nlist nl[] = {
|
||||
#define N_IFNET 0
|
||||
{ .n_name = "_ifnet" },
|
||||
#define N_RTSTAT 1
|
||||
{ .n_name = "_rtstat" },
|
||||
#define N_RTREE 2
|
||||
{ .n_name = "_rt_tables"},
|
||||
#define N_MRTSTAT 3
|
||||
{ .n_name = "_mrtstat" },
|
||||
#define N_MFCHASHTBL 4
|
||||
{ .n_name = "_mfchashtbl" },
|
||||
#define N_VIFTABLE 5
|
||||
{ .n_name = "_viftable" },
|
||||
#define N_IPX 6
|
||||
{ .n_name = "_ipxpcb_list"},
|
||||
#define N_IPXSTAT 7
|
||||
{ .n_name = "_ipxstat"},
|
||||
#define N_SPXSTAT 8
|
||||
{ .n_name = "_spx_istat"},
|
||||
#define N_DDPSTAT 9
|
||||
{ .n_name = "_ddpstat"},
|
||||
#define N_DDPCB 10
|
||||
{ .n_name = "_ddpcb"},
|
||||
#define N_NGSOCKS 11
|
||||
{ .n_name = "_ngsocklist"},
|
||||
#define N_IP6STAT 12
|
||||
{ .n_name = "_ip6stat" },
|
||||
#define N_ICMP6STAT 13
|
||||
{ .n_name = "_icmp6stat" },
|
||||
#define N_IPSECSTAT 14
|
||||
{ .n_name = "_ipsec4stat" },
|
||||
#define N_IPSEC6STAT 15
|
||||
{ .n_name = "_ipsec6stat" },
|
||||
#define N_PIM6STAT 16
|
||||
{ .n_name = "_pim6stat" },
|
||||
#define N_MRT6STAT 17
|
||||
{ .n_name = "_mrt6stat" },
|
||||
#define N_MF6CTABLE 18
|
||||
{ .n_name = "_mf6ctable" },
|
||||
#define N_MIF6TABLE 19
|
||||
{ .n_name = "_mif6table" },
|
||||
#define N_PFKEYSTAT 20
|
||||
{ .n_name = "_pfkeystat" },
|
||||
#define N_MBSTAT 21
|
||||
{ .n_name = "_mbstat" },
|
||||
#define N_MBTYPES 22
|
||||
{ .n_name = "_mbtypes" },
|
||||
#define N_NMBCLUSTERS 23
|
||||
{ .n_name = "_nmbclusters" },
|
||||
#define N_NMBUFS 24
|
||||
{ .n_name = "_nmbufs" },
|
||||
#define N_MBHI 25
|
||||
{ .n_name = "_mbuf_hiwm" },
|
||||
#define N_CLHI 26
|
||||
{ .n_name = "_clust_hiwm" },
|
||||
#define N_NCPUS 27
|
||||
{ .n_name = "_smp_cpus" },
|
||||
#define N_PAGESZ 28
|
||||
{ .n_name = "_pagesize" },
|
||||
#define N_MBPSTAT 29
|
||||
{ .n_name = "_mb_statpcpu" },
|
||||
#define N_RTTRASH 30
|
||||
{ .n_name = "_rttrash" },
|
||||
#define N_MBLO 31
|
||||
{ .n_name = "_mbuf_lowm" },
|
||||
#define N_CLLO 32
|
||||
{ .n_name = "_clust_lowm" },
|
||||
#define N_CARPSTAT 33
|
||||
{ .n_name = "_carpstats" },
|
||||
#define N_PFSYNCSTAT 34
|
||||
{ .n_name = "_pfsyncstats" },
|
||||
#define N_AHSTAT 35
|
||||
{ .n_name = "_ahstat" },
|
||||
#define N_ESPSTAT 36
|
||||
{ .n_name = "_espstat" },
|
||||
#define N_IPCOMPSTAT 37
|
||||
{ .n_name = "_ipcompstat" },
|
||||
#define N_TCPSTAT 38
|
||||
{ .n_name = "_tcpstat" },
|
||||
#define N_UDPSTAT 39
|
||||
{ .n_name = "_udpstat" },
|
||||
#define N_IPSTAT 40
|
||||
{ .n_name = "_ipstat" },
|
||||
#define N_ICMPSTAT 41
|
||||
{ .n_name = "_icmpstat" },
|
||||
#define N_IGMPSTAT 42
|
||||
{ .n_name = "_igmpstat" },
|
||||
#define N_PIMSTAT 43
|
||||
{ .n_name = "_pimstat" },
|
||||
#define N_TCBINFO 44
|
||||
{ .n_name = "_tcbinfo" },
|
||||
#define N_UDBINFO 45
|
||||
{ .n_name = "_udbinfo" },
|
||||
#define N_DIVCBINFO 46
|
||||
{ .n_name = "_divcbinfo" },
|
||||
#define N_RIPCBINFO 47
|
||||
{ .n_name = "_ripcbinfo" },
|
||||
#define N_UNP_COUNT 48
|
||||
{ .n_name = "_unp_count" },
|
||||
#define N_UNP_GENCNT 49
|
||||
{ .n_name = "_unp_gencnt" },
|
||||
#define N_UNP_DHEAD 50
|
||||
{ .n_name = "_unp_dhead" },
|
||||
#define N_UNP_SHEAD 51
|
||||
{ .n_name = "_unp_shead" },
|
||||
#define N_RIP6STAT 52
|
||||
{ .n_name = "_rip6stat" },
|
||||
#define N_SCTPSTAT 53
|
||||
{ .n_name = "_sctpstat" },
|
||||
#define N_MFCTABLESIZE 54
|
||||
{ .n_name = "_mfctablesize" },
|
||||
#define N_ARPSTAT 55
|
||||
{ .n_name = "_arpstat" },
|
||||
{ .n_name = NULL },
|
||||
};
|
||||
|
||||
struct protox {
|
||||
int pr_index; /* index into nlist of cb head */
|
||||
int pr_sindex; /* index into nlist of stat block */
|
||||
u_char pr_wanted; /* 1 if wanted, 0 otherwise */
|
||||
void (*pr_cblocks)(u_long, const char *, int, int);
|
||||
/* control blocks printing routine */
|
||||
void (*pr_stats)(u_long, const char *, int, int);
|
||||
/* statistics printing routine */
|
||||
void (*pr_istats)(char *); /* per/if statistics printing routine */
|
||||
const char *pr_name; /* well-known name */
|
||||
int pr_usesysctl; /* non-zero if we use sysctl, not kvm */
|
||||
int pr_protocol;
|
||||
} protox[] = {
|
||||
{ N_TCBINFO, N_TCPSTAT, 1, protopr,
|
||||
tcp_stats, NULL, "tcp", 1, IPPROTO_TCP },
|
||||
{ N_UDBINFO, N_UDPSTAT, 1, protopr,
|
||||
udp_stats, NULL, "udp", 1, IPPROTO_UDP },
|
||||
#ifdef SCTP
|
||||
{ -1, N_SCTPSTAT, 1, sctp_protopr,
|
||||
sctp_stats, NULL, "sctp", 1, IPPROTO_SCTP },
|
||||
#endif
|
||||
{ N_DIVCBINFO, -1, 1, protopr,
|
||||
NULL, NULL, "divert", 1, IPPROTO_DIVERT },
|
||||
{ N_RIPCBINFO, N_IPSTAT, 1, protopr,
|
||||
ip_stats, NULL, "ip", 1, IPPROTO_RAW },
|
||||
{ N_RIPCBINFO, N_ICMPSTAT, 1, protopr,
|
||||
icmp_stats, NULL, "icmp", 1, IPPROTO_ICMP },
|
||||
{ N_RIPCBINFO, N_IGMPSTAT, 1, protopr,
|
||||
igmp_stats, NULL, "igmp", 1, IPPROTO_IGMP },
|
||||
#ifdef IPSEC
|
||||
{ -1, N_IPSECSTAT, 1, NULL, /* keep as compat */
|
||||
ipsec_stats, NULL, "ipsec", 0, 0},
|
||||
{ -1, N_AHSTAT, 1, NULL,
|
||||
ah_stats, NULL, "ah", 0, 0},
|
||||
{ -1, N_ESPSTAT, 1, NULL,
|
||||
esp_stats, NULL, "esp", 0, 0},
|
||||
{ -1, N_IPCOMPSTAT, 1, NULL,
|
||||
ipcomp_stats, NULL, "ipcomp", 0, 0},
|
||||
#endif
|
||||
{ N_RIPCBINFO, N_PIMSTAT, 1, protopr,
|
||||
pim_stats, NULL, "pim", 1, IPPROTO_PIM },
|
||||
{ -1, N_CARPSTAT, 1, NULL,
|
||||
carp_stats, NULL, "carp", 1, 0 },
|
||||
{ -1, N_PFSYNCSTAT, 1, NULL,
|
||||
pfsync_stats, NULL, "pfsync", 1, 0 },
|
||||
{ -1, N_ARPSTAT, 1, NULL,
|
||||
arp_stats, NULL, "arp", 1, 0 },
|
||||
{ -1, -1, 0, NULL,
|
||||
NULL, NULL, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
#ifdef INET6
|
||||
struct protox ip6protox[] = {
|
||||
{ N_TCBINFO, N_TCPSTAT, 1, protopr,
|
||||
tcp_stats, NULL, "tcp", 1, IPPROTO_TCP },
|
||||
{ N_UDBINFO, N_UDPSTAT, 1, protopr,
|
||||
udp_stats, NULL, "udp", 1, IPPROTO_UDP },
|
||||
{ N_RIPCBINFO, N_IP6STAT, 1, protopr,
|
||||
ip6_stats, ip6_ifstats, "ip6", 1, IPPROTO_RAW },
|
||||
{ N_RIPCBINFO, N_ICMP6STAT, 1, protopr,
|
||||
icmp6_stats, icmp6_ifstats, "icmp6", 1, IPPROTO_ICMPV6 },
|
||||
#ifdef IPSEC
|
||||
{ -1, N_IPSEC6STAT, 1, NULL,
|
||||
ipsec_stats, NULL, "ipsec6", 0, 0 },
|
||||
#endif
|
||||
#ifdef notyet
|
||||
{ -1, N_PIM6STAT, 1, NULL,
|
||||
pim6_stats, NULL, "pim6", 1, 0 },
|
||||
#endif
|
||||
{ -1, N_RIP6STAT, 1, NULL,
|
||||
rip6_stats, NULL, "rip6", 1, 0 },
|
||||
{ -1, -1, 0, NULL,
|
||||
NULL, NULL, NULL, 0, 0 }
|
||||
};
|
||||
#endif /*INET6*/
|
||||
|
||||
#ifdef IPSEC
|
||||
struct protox pfkeyprotox[] = {
|
||||
{ -1, N_PFKEYSTAT, 1, NULL,
|
||||
pfkey_stats, NULL, "pfkey", 0, 0 },
|
||||
{ -1, -1, 0, NULL,
|
||||
NULL, NULL, NULL, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
struct protox atalkprotox[] = {
|
||||
{ N_DDPCB, N_DDPSTAT, 1, atalkprotopr,
|
||||
ddp_stats, NULL, "ddp", 0, 0 },
|
||||
{ -1, -1, 0, NULL,
|
||||
NULL, NULL, NULL, 0, 0 }
|
||||
};
|
||||
#ifdef NETGRAPH
|
||||
struct protox netgraphprotox[] = {
|
||||
{ N_NGSOCKS, -1, 1, netgraphprotopr,
|
||||
NULL, NULL, "ctrl", 0, 0 },
|
||||
{ N_NGSOCKS, -1, 1, netgraphprotopr,
|
||||
NULL, NULL, "data", 0, 0 },
|
||||
{ -1, -1, 0, NULL,
|
||||
NULL, NULL, NULL, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
#ifdef IPX
|
||||
struct protox ipxprotox[] = {
|
||||
{ N_IPX, N_IPXSTAT, 1, ipxprotopr,
|
||||
ipx_stats, NULL, "ipx", 0, 0 },
|
||||
{ N_IPX, N_SPXSTAT, 1, ipxprotopr,
|
||||
spx_stats, NULL, "spx", 0, 0 },
|
||||
{ -1, -1, 0, NULL,
|
||||
NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
struct protox *protoprotox[] = {
|
||||
protox,
|
||||
#ifdef INET6
|
||||
ip6protox,
|
||||
#endif
|
||||
#ifdef IPSEC
|
||||
pfkeyprotox,
|
||||
#endif
|
||||
#ifdef IPX
|
||||
ipxprotox,
|
||||
#endif
|
||||
atalkprotox, NULL };
|
||||
|
||||
static void printproto(struct protox *, const char *);
|
||||
static void usage(void);
|
||||
static struct protox *name2protox(const char *);
|
||||
static struct protox *knownname(const char *);
|
||||
|
||||
static kvm_t *kvmd;
|
||||
static char *nlistf = NULL, *memf = NULL;
|
||||
|
||||
int Aflag; /* show addresses of protocol control block */
|
||||
int aflag; /* show all sockets (including servers) */
|
||||
int Bflag; /* show information about bpf consumers */
|
||||
int bflag; /* show i/f total bytes in/out */
|
||||
int dflag; /* show i/f dropped packets */
|
||||
int gflag; /* show group (multicast) routing or stats */
|
||||
int hflag; /* show counters in human readable format */
|
||||
int iflag; /* show interfaces */
|
||||
int Lflag; /* show size of listen queues */
|
||||
int mflag; /* show memory stats */
|
||||
int noutputs = 0; /* how much outputs before we exit */
|
||||
int numeric_addr; /* show addresses numerically */
|
||||
int numeric_port; /* show ports numerically */
|
||||
static int pflag; /* show given protocol */
|
||||
int rflag; /* show routing tables (or routing stats) */
|
||||
int sflag; /* show protocol statistics */
|
||||
int tflag; /* show i/f watchdog timers */
|
||||
int Wflag; /* wide display */
|
||||
int xflag; /* extra information, includes all socket buffer info */
|
||||
int zflag; /* zero stats */
|
||||
|
||||
int interval; /* repeat interval for i/f stats */
|
||||
|
||||
char *interface; /* desired i/f for stats, or NULL for all i/fs */
|
||||
int unit; /* unit number for above */
|
||||
|
||||
int af; /* address family */
|
||||
int live; /* true if we are examining a live system */
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct protox *tp = NULL; /* for printing cblocks & stats */
|
||||
int ch;
|
||||
|
||||
af = AF_UNSPEC;
|
||||
|
||||
while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:q:rSstuWw:xz")) != -1)
|
||||
switch(ch) {
|
||||
case 'A':
|
||||
Aflag = 1;
|
||||
break;
|
||||
case 'a':
|
||||
aflag = 1;
|
||||
break;
|
||||
case 'B':
|
||||
Bflag = 1;
|
||||
break;
|
||||
case 'b':
|
||||
bflag = 1;
|
||||
break;
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
if (strcmp(optarg, "ipx") == 0)
|
||||
af = AF_IPX;
|
||||
else if (strcmp(optarg, "inet") == 0)
|
||||
af = AF_INET;
|
||||
#ifdef INET6
|
||||
else if (strcmp(optarg, "inet6") == 0)
|
||||
af = AF_INET6;
|
||||
#endif
|
||||
#ifdef IPSEC
|
||||
else if (strcmp(optarg, "pfkey") == 0)
|
||||
af = PF_KEY;
|
||||
#endif
|
||||
else if (strcmp(optarg, "unix") == 0)
|
||||
af = AF_UNIX;
|
||||
else if (strcmp(optarg, "atalk") == 0)
|
||||
af = AF_APPLETALK;
|
||||
#ifdef NETGRAPH
|
||||
else if (strcmp(optarg, "ng") == 0
|
||||
|| strcmp(optarg, "netgraph") == 0)
|
||||
af = AF_NETGRAPH;
|
||||
#endif
|
||||
else if (strcmp(optarg, "link") == 0)
|
||||
af = AF_LINK;
|
||||
else {
|
||||
errx(1, "%s: unknown address family", optarg);
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
gflag = 1;
|
||||
break;
|
||||
case 'h':
|
||||
hflag = 1;
|
||||
break;
|
||||
case 'I': {
|
||||
char *cp;
|
||||
|
||||
iflag = 1;
|
||||
for (cp = interface = optarg; isalpha(*cp); cp++)
|
||||
continue;
|
||||
unit = atoi(cp);
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
iflag = 1;
|
||||
break;
|
||||
case 'L':
|
||||
Lflag = 1;
|
||||
break;
|
||||
case 'M':
|
||||
memf = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
mflag = 1;
|
||||
break;
|
||||
case 'N':
|
||||
nlistf = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
numeric_addr = numeric_port = 1;
|
||||
break;
|
||||
case 'p':
|
||||
if ((tp = name2protox(optarg)) == NULL) {
|
||||
errx(1,
|
||||
"%s: unknown or uninstrumented protocol",
|
||||
optarg);
|
||||
}
|
||||
pflag = 1;
|
||||
break;
|
||||
case 'q':
|
||||
noutputs = atoi(optarg);
|
||||
if (noutputs != 0)
|
||||
noutputs++;
|
||||
break;
|
||||
case 'r':
|
||||
rflag = 1;
|
||||
break;
|
||||
case 's':
|
||||
++sflag;
|
||||
break;
|
||||
case 'S':
|
||||
numeric_addr = 1;
|
||||
break;
|
||||
case 't':
|
||||
tflag = 1;
|
||||
break;
|
||||
case 'u':
|
||||
af = AF_UNIX;
|
||||
break;
|
||||
case 'W':
|
||||
case 'l':
|
||||
Wflag = 1;
|
||||
break;
|
||||
case 'w':
|
||||
interval = atoi(optarg);
|
||||
iflag = 1;
|
||||
break;
|
||||
case 'x':
|
||||
xflag = 1;
|
||||
break;
|
||||
case 'z':
|
||||
zflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
#define BACKWARD_COMPATIBILITY
|
||||
#ifdef BACKWARD_COMPATIBILITY
|
||||
if (*argv) {
|
||||
if (isdigit(**argv)) {
|
||||
interval = atoi(*argv);
|
||||
if (interval <= 0)
|
||||
usage();
|
||||
++argv;
|
||||
iflag = 1;
|
||||
}
|
||||
if (*argv) {
|
||||
nlistf = *argv;
|
||||
if (*++argv)
|
||||
memf = *argv;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Discard setgid privileges if not the running kernel so that bad
|
||||
* guys can't print interesting stuff from kernel memory.
|
||||
*/
|
||||
live = (nlistf == NULL && memf == NULL);
|
||||
if (!live)
|
||||
setgid(getgid());
|
||||
|
||||
if (Bflag) {
|
||||
if (!live)
|
||||
usage();
|
||||
bpf_stats(interface);
|
||||
exit(0);
|
||||
}
|
||||
if (mflag) {
|
||||
if (!live) {
|
||||
if (kread(0, NULL, 0) == 0)
|
||||
mbpr(kvmd, nl[N_MBSTAT].n_value);
|
||||
} else
|
||||
mbpr(NULL, 0);
|
||||
exit(0);
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* Keep file descriptors open to avoid overhead
|
||||
* of open/close on each call to get* routines.
|
||||
*/
|
||||
sethostent(1);
|
||||
setnetent(1);
|
||||
#else
|
||||
/*
|
||||
* This does not make sense any more with DNS being default over
|
||||
* the files. Doing a setXXXXent(1) causes a tcp connection to be
|
||||
* used for the queries, which is slower.
|
||||
*/
|
||||
#endif
|
||||
kread(0, NULL, 0);
|
||||
if (iflag && !sflag) {
|
||||
intpr(interval, nl[N_IFNET].n_value, NULL);
|
||||
exit(0);
|
||||
}
|
||||
if (rflag) {
|
||||
if (sflag)
|
||||
rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value);
|
||||
else
|
||||
routepr(nl[N_RTREE].n_value);
|
||||
exit(0);
|
||||
}
|
||||
if (gflag) {
|
||||
if (sflag) {
|
||||
if (af == AF_INET || af == AF_UNSPEC)
|
||||
mrt_stats(nl[N_MRTSTAT].n_value);
|
||||
#ifdef INET6
|
||||
if (af == AF_INET6 || af == AF_UNSPEC)
|
||||
mrt6_stats(nl[N_MRT6STAT].n_value);
|
||||
#endif
|
||||
} else {
|
||||
if (af == AF_INET || af == AF_UNSPEC)
|
||||
mroutepr(nl[N_MFCHASHTBL].n_value,
|
||||
nl[N_MFCTABLESIZE].n_value,
|
||||
nl[N_VIFTABLE].n_value);
|
||||
#ifdef INET6
|
||||
if (af == AF_INET6 || af == AF_UNSPEC)
|
||||
mroute6pr(nl[N_MF6CTABLE].n_value,
|
||||
nl[N_MIF6TABLE].n_value);
|
||||
#endif
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (tp) {
|
||||
printproto(tp, tp->pr_name);
|
||||
exit(0);
|
||||
}
|
||||
if (af == AF_INET || af == AF_UNSPEC)
|
||||
for (tp = protox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
#ifdef INET6
|
||||
if (af == AF_INET6 || af == AF_UNSPEC)
|
||||
for (tp = ip6protox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
#endif /*INET6*/
|
||||
#ifdef IPSEC
|
||||
if (af == PF_KEY || af == AF_UNSPEC)
|
||||
for (tp = pfkeyprotox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
#endif /*IPSEC*/
|
||||
#ifdef IPX
|
||||
if (af == AF_IPX || af == AF_UNSPEC) {
|
||||
for (tp = ipxprotox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
}
|
||||
#endif /* IPX */
|
||||
if (af == AF_APPLETALK || af == AF_UNSPEC)
|
||||
for (tp = atalkprotox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
#ifdef NETGRAPH
|
||||
if (af == AF_NETGRAPH || af == AF_UNSPEC)
|
||||
for (tp = netgraphprotox; tp->pr_name; tp++)
|
||||
printproto(tp, tp->pr_name);
|
||||
#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);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out protocol statistics or control blocks (per sflag).
|
||||
* If the interface was not specifically requested, and the symbol
|
||||
* is not in the namelist, ignore this one.
|
||||
*/
|
||||
static void
|
||||
printproto(tp, name)
|
||||
struct protox *tp;
|
||||
const char *name;
|
||||
{
|
||||
void (*pr)(u_long, const char *, int, int);
|
||||
u_long off;
|
||||
|
||||
if (sflag) {
|
||||
if (iflag) {
|
||||
if (tp->pr_istats)
|
||||
intpr(interval, nl[N_IFNET].n_value,
|
||||
tp->pr_istats);
|
||||
else if (pflag)
|
||||
printf("%s: no per-interface stats routine\n",
|
||||
tp->pr_name);
|
||||
return;
|
||||
} else {
|
||||
pr = tp->pr_stats;
|
||||
if (!pr) {
|
||||
if (pflag)
|
||||
printf("%s: no stats routine\n",
|
||||
tp->pr_name);
|
||||
return;
|
||||
}
|
||||
if (tp->pr_usesysctl && live)
|
||||
off = 0;
|
||||
else if (tp->pr_sindex < 0) {
|
||||
if (pflag)
|
||||
printf(
|
||||
"%s: stats routine doesn't work on cores\n",
|
||||
tp->pr_name);
|
||||
return;
|
||||
} else
|
||||
off = nl[tp->pr_sindex].n_value;
|
||||
}
|
||||
} else {
|
||||
pr = tp->pr_cblocks;
|
||||
if (!pr) {
|
||||
if (pflag)
|
||||
printf("%s: no PCB routine\n", tp->pr_name);
|
||||
return;
|
||||
}
|
||||
if (tp->pr_usesysctl && live)
|
||||
off = 0;
|
||||
else if (tp->pr_index < 0) {
|
||||
if (pflag)
|
||||
printf(
|
||||
"%s: PCB routine doesn't work on cores\n",
|
||||
tp->pr_name);
|
||||
return;
|
||||
} else
|
||||
off = nl[tp->pr_index].n_value;
|
||||
}
|
||||
if (pr != NULL && (off || (live && tp->pr_usesysctl) ||
|
||||
af != AF_UNSPEC))
|
||||
(*pr)(off, name, af, tp->pr_protocol);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read kernel memory, return 0 on success.
|
||||
*/
|
||||
int
|
||||
kread(u_long addr, void *buf, size_t size)
|
||||
{
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
|
||||
if (kvmd == NULL) {
|
||||
kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
|
||||
setgid(getgid());
|
||||
if (kvmd != NULL) {
|
||||
if (kvm_nlist(kvmd, nl) < 0) {
|
||||
if (nlistf)
|
||||
errx(1, "%s: kvm_nlist: %s", nlistf,
|
||||
kvm_geterr(kvmd));
|
||||
else
|
||||
errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
|
||||
}
|
||||
|
||||
if (nl[0].n_type == 0) {
|
||||
if (nlistf)
|
||||
errx(1, "%s: no namelist", nlistf);
|
||||
else
|
||||
errx(1, "no namelist");
|
||||
}
|
||||
} else {
|
||||
warnx("kvm not available: %s", errbuf);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
if (!buf)
|
||||
return (0);
|
||||
if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) {
|
||||
warnx("%s", kvm_geterr(kvmd));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
const char *
|
||||
plural(uintmax_t n)
|
||||
{
|
||||
return (n != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
const char *
|
||||
plurales(uintmax_t n)
|
||||
{
|
||||
return (n != 1 ? "es" : "");
|
||||
}
|
||||
|
||||
const char *
|
||||
pluralies(uintmax_t n)
|
||||
{
|
||||
return (n != 1 ? "ies" : "y");
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the protox for the given "well-known" name.
|
||||
*/
|
||||
static struct protox *
|
||||
knownname(const char *name)
|
||||
{
|
||||
struct protox **tpp, *tp;
|
||||
|
||||
for (tpp = protoprotox; *tpp; tpp++)
|
||||
for (tp = *tpp; tp->pr_name; tp++)
|
||||
if (strcmp(tp->pr_name, name) == 0)
|
||||
return (tp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the protox corresponding to name.
|
||||
*/
|
||||
static struct protox *
|
||||
name2protox(const char *name)
|
||||
{
|
||||
struct protox *tp;
|
||||
char **alias; /* alias from p->aliases */
|
||||
struct protoent *p;
|
||||
|
||||
/*
|
||||
* Try to find the name in the list of "well-known" names. If that
|
||||
* fails, check if name is an alias for an Internet protocol.
|
||||
*/
|
||||
if ((tp = knownname(name)) != NULL)
|
||||
return (tp);
|
||||
|
||||
setprotoent(1); /* make protocol lookup cheaper */
|
||||
while ((p = getprotoent()) != NULL) {
|
||||
/* assert: name not same as p->name */
|
||||
for (alias = p->p_aliases; *alias; alias++)
|
||||
if (strcmp(name, *alias) == 0) {
|
||||
endprotoent();
|
||||
return (knownname(p->p_name));
|
||||
}
|
||||
}
|
||||
endprotoent();
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
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",
|
||||
"usage: netstat [-AaLnSWx] [-f protocol_family | -p protocol]\n"
|
||||
" [-M core] [-N system]",
|
||||
" netstat -i | -I interface [-abdhntW] [-f address_family]\n"
|
||||
" [-M core] [-N system]",
|
||||
" netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]",
|
||||
" netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n"
|
||||
" [-M core] [-N system]",
|
||||
" netstat -i | -I interface -s [-f protocol_family | -p protocol]\n"
|
||||
" [-M core] [-N system]",
|
||||
" netstat -m [-M core] [-N system]",
|
||||
" netstat -B [-I interface]",
|
||||
" netstat -r [-AanW] [-f address_family] [-M core] [-N system]",
|
||||
" netstat -rs [-s] [-M core] [-N system]",
|
||||
" netstat -g [-W] [-f address_family] [-M core] [-N system]",
|
||||
" netstat -gs [-s] [-f address_family] [-M core] [-N system]");
|
||||
exit(1);
|
||||
}
|
323
freebsd-userspace/commands/usr.bin/netstat/mbuf.c
Normal file
323
freebsd-userspace/commands/usr.bin/netstat/mbuf.c
Normal file
@ -0,0 +1,323 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* The Regents of the University of California.
|
||||
* Copyright (c) 2005 Robert N. M. Watson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)mbuf.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifdef __rtems__
|
||||
#include <stdint.h>
|
||||
#include <freebsd/sys/mbuf.h>
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <err.h>
|
||||
#ifdef __rtems__
|
||||
/* XXX what to do? */
|
||||
#else
|
||||
#include <kvm.h>
|
||||
#include <memstat.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "netstat.h"
|
||||
|
||||
/*
|
||||
* Print mbuf statistics.
|
||||
*/
|
||||
void
|
||||
mbpr(void *kvmd, u_long mbaddr)
|
||||
{
|
||||
struct memory_type_list *mtlp;
|
||||
struct memory_type *mtp;
|
||||
uintmax_t mbuf_count, mbuf_bytes, mbuf_free, mbuf_failures, mbuf_size;
|
||||
uintmax_t cluster_count, cluster_bytes, cluster_limit, cluster_free;
|
||||
uintmax_t cluster_failures, cluster_size;
|
||||
uintmax_t packet_count, packet_bytes, packet_free, packet_failures;
|
||||
uintmax_t tag_count, tag_bytes;
|
||||
uintmax_t jumbop_count, jumbop_bytes, jumbop_limit, jumbop_free;
|
||||
uintmax_t jumbop_failures, jumbop_size;
|
||||
uintmax_t jumbo9_count, jumbo9_bytes, jumbo9_limit, jumbo9_free;
|
||||
uintmax_t jumbo9_failures, jumbo9_size;
|
||||
uintmax_t jumbo16_count, jumbo16_bytes, jumbo16_limit, jumbo16_free;
|
||||
uintmax_t jumbo16_failures, jumbo16_size;
|
||||
uintmax_t bytes_inuse, bytes_incache, bytes_total;
|
||||
int nsfbufs, nsfbufspeak, nsfbufsused;
|
||||
struct mbstat mbstat;
|
||||
size_t mlen;
|
||||
int error;
|
||||
|
||||
mtlp = memstat_mtl_alloc();
|
||||
if (mtlp == NULL) {
|
||||
warn("memstat_mtl_alloc");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use memstat_*_all() because some mbuf-related memory is in uma(9),
|
||||
* and some malloc(9).
|
||||
*/
|
||||
if (live) {
|
||||
if (memstat_sysctl_all(mtlp, 0) < 0) {
|
||||
warnx("memstat_sysctl_all: %s",
|
||||
memstat_strerror(memstat_mtl_geterror(mtlp)));
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (memstat_kvm_all(mtlp, kvmd) < 0) {
|
||||
error = memstat_mtl_geterror(mtlp);
|
||||
if (error == MEMSTAT_ERROR_KVM)
|
||||
warnx("memstat_kvm_all: %s",
|
||||
kvm_geterr(kvmd));
|
||||
else
|
||||
warnx("memstat_kvm_all: %s",
|
||||
memstat_strerror(error));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found", MBUF_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
mbuf_count = memstat_get_count(mtp);
|
||||
mbuf_bytes = memstat_get_bytes(mtp);
|
||||
mbuf_free = memstat_get_free(mtp);
|
||||
mbuf_failures = memstat_get_failures(mtp);
|
||||
mbuf_size = memstat_get_size(mtp);
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_PACKET_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_PACKET_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
packet_count = memstat_get_count(mtp);
|
||||
packet_bytes = memstat_get_bytes(mtp);
|
||||
packet_free = memstat_get_free(mtp);
|
||||
packet_failures = memstat_get_failures(mtp);
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_CLUSTER_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_CLUSTER_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
cluster_count = memstat_get_count(mtp);
|
||||
cluster_bytes = memstat_get_bytes(mtp);
|
||||
cluster_limit = memstat_get_countlimit(mtp);
|
||||
cluster_free = memstat_get_free(mtp);
|
||||
cluster_failures = memstat_get_failures(mtp);
|
||||
cluster_size = memstat_get_size(mtp);
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_MALLOC, MBUF_TAG_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: malloc type %s not found",
|
||||
MBUF_TAG_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
tag_count = memstat_get_count(mtp);
|
||||
tag_bytes = memstat_get_bytes(mtp);
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBOP_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_JUMBOP_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
jumbop_count = memstat_get_count(mtp);
|
||||
jumbop_bytes = memstat_get_bytes(mtp);
|
||||
jumbop_limit = memstat_get_countlimit(mtp);
|
||||
jumbop_free = memstat_get_free(mtp);
|
||||
jumbop_failures = memstat_get_failures(mtp);
|
||||
jumbop_size = memstat_get_size(mtp);
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO9_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_JUMBO9_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
jumbo9_count = memstat_get_count(mtp);
|
||||
jumbo9_bytes = memstat_get_bytes(mtp);
|
||||
jumbo9_limit = memstat_get_countlimit(mtp);
|
||||
jumbo9_free = memstat_get_free(mtp);
|
||||
jumbo9_failures = memstat_get_failures(mtp);
|
||||
jumbo9_size = memstat_get_size(mtp);
|
||||
|
||||
mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO16_MEM_NAME);
|
||||
if (mtp == NULL) {
|
||||
warnx("memstat_mtl_find: zone %s not found",
|
||||
MBUF_JUMBO16_MEM_NAME);
|
||||
goto out;
|
||||
}
|
||||
jumbo16_count = memstat_get_count(mtp);
|
||||
jumbo16_bytes = memstat_get_bytes(mtp);
|
||||
jumbo16_limit = memstat_get_countlimit(mtp);
|
||||
jumbo16_free = memstat_get_free(mtp);
|
||||
jumbo16_failures = memstat_get_failures(mtp);
|
||||
jumbo16_size = memstat_get_size(mtp);
|
||||
|
||||
printf("%ju/%ju/%ju 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",
|
||||
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",
|
||||
packet_count, packet_free);
|
||||
|
||||
printf("%ju/%ju/%ju/%ju %juk (page size) 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",
|
||||
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",
|
||||
jumbo16_count, jumbo16_free, jumbo16_count + jumbo16_free,
|
||||
jumbo16_limit);
|
||||
|
||||
#if 0
|
||||
printf("%ju mbuf tags in use\n", tag_count);
|
||||
#endif
|
||||
|
||||
/*-
|
||||
* Calculate in-use bytes as:
|
||||
* - straight mbuf memory
|
||||
* - mbuf memory in packets
|
||||
* - the clusters attached to packets
|
||||
* - and the rest of the non-packet-attached clusters.
|
||||
* - m_tag memory
|
||||
* This avoids counting the clusters attached to packets in the cache.
|
||||
* This currently excludes sf_buf space.
|
||||
*/
|
||||
bytes_inuse =
|
||||
mbuf_bytes + /* straight mbuf memory */
|
||||
packet_bytes + /* mbufs in packets */
|
||||
(packet_count * cluster_size) + /* clusters in packets */
|
||||
/* other clusters */
|
||||
((cluster_count - packet_count - packet_free) * cluster_size) +
|
||||
tag_bytes +
|
||||
(jumbop_count * jumbop_size) + /* jumbo clusters */
|
||||
(jumbo9_count * jumbo9_size) +
|
||||
(jumbo16_count * jumbo16_size);
|
||||
|
||||
/*
|
||||
* Calculate in-cache bytes as:
|
||||
* - cached straught mbufs
|
||||
* - cached packet mbufs
|
||||
* - cached packet clusters
|
||||
* - cached straight clusters
|
||||
* This currently excludes sf_buf space.
|
||||
*/
|
||||
bytes_incache =
|
||||
(mbuf_free * mbuf_size) + /* straight free mbufs */
|
||||
(packet_free * mbuf_size) + /* mbufs in free packets */
|
||||
(packet_free * cluster_size) + /* clusters in free packets */
|
||||
(cluster_free * cluster_size) + /* free clusters */
|
||||
(jumbop_free * jumbop_size) + /* jumbo clusters */
|
||||
(jumbo9_free * jumbo9_size) +
|
||||
(jumbo16_free * jumbo16_size);
|
||||
|
||||
/*
|
||||
* Total is bytes in use + bytes in cache. This doesn't take into
|
||||
* account various other misc data structures, overhead, etc, but
|
||||
* gives the user something useful despite that.
|
||||
*/
|
||||
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);
|
||||
|
||||
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 jumbo clusters denied "
|
||||
"(%juk/9k/16k)\n", jumbop_failures, jumbo9_failures,
|
||||
jumbo16_failures, jumbop_size / 1024);
|
||||
|
||||
if (live) {
|
||||
mlen = sizeof(nsfbufs);
|
||||
if (!sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL,
|
||||
0) &&
|
||||
!sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused,
|
||||
&mlen, NULL, 0) &&
|
||||
!sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak,
|
||||
&mlen, NULL, 0))
|
||||
printf("%d/%d/%d sfbufs in use (current/peak/max)\n",
|
||||
nsfbufsused, nsfbufspeak, nsfbufs);
|
||||
mlen = sizeof(mbstat);
|
||||
if (sysctlbyname("kern.ipc.mbstat", &mbstat, &mlen, NULL, 0)) {
|
||||
warn("kern.ipc.mbstat");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (kread(mbaddr, (char *)&mbstat, sizeof mbstat) != 0)
|
||||
goto out;
|
||||
}
|
||||
printf("%lu requests for sfbufs denied\n", mbstat.sf_allocfail);
|
||||
printf("%lu requests for sfbufs delayed\n", mbstat.sf_allocwait);
|
||||
printf("%lu requests for I/O initiated by sendfile\n",
|
||||
mbstat.sf_iocnt);
|
||||
printf("%lu calls to protocol drain routines\n", mbstat.m_drain);
|
||||
out:
|
||||
memstat_mtl_free(mtlp);
|
||||
}
|
391
freebsd-userspace/commands/usr.bin/netstat/mroute.c
Normal file
391
freebsd-userspace/commands/usr.bin/netstat/mroute.c
Normal file
@ -0,0 +1,391 @@
|
||||
/*-
|
||||
* Copyright (c) 1989 Stephen Deering
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Stephen Deering of Stanford University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mroute.c 8.2 (Berkeley) 4/28/95
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Print multicast routing structures and statistics.
|
||||
*
|
||||
* MROUTING 1.0
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/mbuf.h>
|
||||
#else
|
||||
#include <sys/mbuf.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/igmp.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#define _KERNEL 1
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/netinet/ip_mroute.h>
|
||||
#else
|
||||
#include <netinet/ip_mroute.h>
|
||||
#endif
|
||||
#undef _KERNEL
|
||||
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "netstat.h"
|
||||
|
||||
|
||||
static void print_bw_meter(struct bw_meter *, int *);
|
||||
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];
|
||||
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");
|
||||
*banner_printed = 1;
|
||||
}
|
||||
|
||||
/* The measured values */
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS)
|
||||
sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_measured.b_packets);
|
||||
else
|
||||
sprintf(s1, "?");
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES)
|
||||
sprintf(s2, "%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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* The threshold values */
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS)
|
||||
sprintf(s1, "%ju", (uintmax_t)bw_meter->bm_threshold.b_packets);
|
||||
else
|
||||
sprintf(s1, "?");
|
||||
if (bw_meter->bm_flags & BW_METER_UNIT_BYTES)
|
||||
sprintf(s2, "%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);
|
||||
|
||||
/* 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",
|
||||
(u_long)delta.tv_sec,
|
||||
(u_long)delta.tv_usec);
|
||||
} else {
|
||||
/* Negative time */
|
||||
timersub(&now, &end, &delta);
|
||||
sprintf(s3, "-%lu.%lu",
|
||||
(u_long)delta.tv_sec,
|
||||
(u_long)delta.tv_usec);
|
||||
}
|
||||
printf(" %s", s3);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_mfc(struct mfc *m, int maxvif, int *banner_printed)
|
||||
{
|
||||
struct bw_meter bw_meter, *bwm;
|
||||
int bw_banner_printed;
|
||||
int error;
|
||||
vifi_t vifi;
|
||||
|
||||
bw_banner_printed = 0;
|
||||
|
||||
if (! *banner_printed) {
|
||||
printf("\nIPv4 Multicast Forwarding Table\n"
|
||||
" Origin Group "
|
||||
" Packets In-Vif 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);
|
||||
for (vifi = 0; vifi <= maxvif; vifi++) {
|
||||
if (m->mfc_ttls[vifi] > 0)
|
||||
printf(" %u:%u", vifi, m->mfc_ttls[vifi]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* XXX We break the rules and try to use KVM to read the
|
||||
* bandwidth meters, they are not retrievable via sysctl yet.
|
||||
*/
|
||||
bwm = m->mfc_bw_meter;
|
||||
while (bwm != NULL) {
|
||||
error = kread((u_long)bwm, (char *)&bw_meter,
|
||||
sizeof(bw_meter));
|
||||
if (error)
|
||||
break;
|
||||
print_bw_meter(&bw_meter, &bw_banner_printed);
|
||||
bwm = bw_meter.bm_mfc_next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl)
|
||||
{
|
||||
struct vif viftable[MAXVIFS];
|
||||
struct vif *v;
|
||||
struct mfc *m;
|
||||
int banner_printed;
|
||||
int saved_numeric_addr;
|
||||
size_t len;
|
||||
vifi_t vifi, maxvif;
|
||||
|
||||
saved_numeric_addr = numeric_addr;
|
||||
numeric_addr = 1;
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* The VIF table will move to hanging off the struct if_info for
|
||||
* each IPv4 configured interface. Currently it is statically
|
||||
* allocated, and retrieved either using KVM or an opaque SYSCTL.
|
||||
*
|
||||
* This can't happen until the API documented in multicast(4)
|
||||
* is itself refactored. The historical reason why VIFs use
|
||||
* a separate ifindex space is entirely due to the legacy
|
||||
* capability of the MROUTING code to create IPIP tunnels on
|
||||
* the fly to support DVMRP. When gif(4) became available, this
|
||||
* functionality was deprecated, as PIM does not use it.
|
||||
*/
|
||||
maxvif = 0;
|
||||
|
||||
len = sizeof(viftable);
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet.ip.viftable", viftable, &len, NULL,
|
||||
0) < 0) {
|
||||
warn("sysctl: net.inet.ip.viftable");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(pviftbl, (char *)viftable, sizeof(viftable));
|
||||
|
||||
banner_printed = 0;
|
||||
for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) {
|
||||
if (v->v_lcl_addr.s_addr == 0)
|
||||
continue;
|
||||
|
||||
maxvif = vifi;
|
||||
if (!banner_printed) {
|
||||
printf("\nIPv4 Virtual Interface Table\n"
|
||||
" Vif Thresh Local-Address "
|
||||
"Remote-Address Pkts-In Pkts-Out\n");
|
||||
banner_printed = 1;
|
||||
}
|
||||
|
||||
printf(" %2u %6u %-15.15s",
|
||||
/* opposite math of add_vif() */
|
||||
vifi, v->v_threshold,
|
||||
routename(v->v_lcl_addr.s_addr));
|
||||
printf(" %-15.15s", (v->v_flags & VIFF_TUNNEL) ?
|
||||
routename(v->v_rmt_addr.s_addr) : "");
|
||||
|
||||
printf(" %9lu %9lu\n", v->v_pkt_in, v->v_pkt_out);
|
||||
}
|
||||
if (!banner_printed)
|
||||
printf("\nIPv4 Virtual Interface Table is empty\n");
|
||||
|
||||
banner_printed = 0;
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* The MFC table will move into the AF_INET radix trie in future.
|
||||
* In 8.x, it becomes a dynamically allocated structure referenced
|
||||
* by a hashed LIST, allowing more than 256 entries w/o kernel tuning.
|
||||
*
|
||||
* If retrieved via opaque SYSCTL, the kernel will coalesce it into
|
||||
* a static table for us.
|
||||
* If retrieved via KVM, the hash list pointers must be followed.
|
||||
*/
|
||||
if (live) {
|
||||
struct mfc *mfctable;
|
||||
|
||||
len = 0;
|
||||
if (sysctlbyname("net.inet.ip.mfctable", NULL, &len, NULL,
|
||||
0) < 0) {
|
||||
warn("sysctl: net.inet.ip.mfctable");
|
||||
return;
|
||||
}
|
||||
|
||||
mfctable = malloc(len);
|
||||
if (mfctable == NULL) {
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
m = mfctable;
|
||||
while (len >= sizeof(*m)) {
|
||||
print_mfc(m++, maxvif, &banner_printed);
|
||||
len -= sizeof(*m);
|
||||
}
|
||||
if (len != 0)
|
||||
warnx("print_mfc: %lu trailing bytes", (u_long)len);
|
||||
|
||||
free(mfctable);
|
||||
} else {
|
||||
LIST_HEAD(, mfc) *mfchashtbl;
|
||||
u_long i, mfctablesize;
|
||||
struct mfc mfc;
|
||||
int error;
|
||||
|
||||
error = kread(pmfctablesize, (char *)&mfctablesize,
|
||||
sizeof(u_long));
|
||||
if (error) {
|
||||
warn("kread: mfctablesize");
|
||||
return;
|
||||
}
|
||||
|
||||
len = sizeof(*mfchashtbl) * mfctablesize;
|
||||
mfchashtbl = malloc(len);
|
||||
if (mfchashtbl == NULL) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
return;
|
||||
}
|
||||
kread(pmfchashtbl, (char *)&mfchashtbl, len);
|
||||
|
||||
for (i = 0; i < mfctablesize; i++) {
|
||||
LIST_FOREACH(m, &mfchashtbl[i], mfc_hash) {
|
||||
kread((u_long)m, (char *)&mfc, sizeof(mfc));
|
||||
print_mfc(m, maxvif, &banner_printed);
|
||||
}
|
||||
}
|
||||
|
||||
free(mfchashtbl);
|
||||
}
|
||||
|
||||
if (!banner_printed)
|
||||
printf("\nIPv4 Multicast Forwarding Table is empty\n");
|
||||
|
||||
printf("\n");
|
||||
numeric_addr = saved_numeric_addr;
|
||||
}
|
||||
|
||||
void
|
||||
mrt_stats(u_long mstaddr)
|
||||
{
|
||||
struct mrtstat mrtstat;
|
||||
size_t len = sizeof mrtstat;
|
||||
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet.ip.mrtstat", &mrtstat, &len, NULL,
|
||||
0) < 0) {
|
||||
warn("sysctl: net.inet.ip.mrtstat");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
|
||||
|
||||
printf("IPv4 multicast forwarding:\n");
|
||||
|
||||
#define p(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, mrtstat.f, plural(mrtstat.f))
|
||||
#define p2(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, mrtstat.f, plurales(mrtstat.f))
|
||||
|
||||
p(mrts_mfc_lookups, "\t%lu multicast forwarding cache lookup%s\n");
|
||||
p2(mrts_mfc_misses, "\t%lu multicast forwarding cache miss%s\n");
|
||||
p(mrts_upcalls, "\t%lu upcall%s to multicast routing daemon\n");
|
||||
p(mrts_upq_ovflw, "\t%lu upcall queue overflow%s\n");
|
||||
p(mrts_upq_sockfull,
|
||||
"\t%lu upcall%s dropped due to full socket buffer\n");
|
||||
p(mrts_cache_cleanups, "\t%lu cache cleanup%s\n");
|
||||
p(mrts_no_route, "\t%lu datagram%s with no route for origin\n");
|
||||
p(mrts_bad_tunnel, "\t%lu datagram%s arrived with bad tunneling\n");
|
||||
p(mrts_cant_tunnel, "\t%lu datagram%s could not be tunneled\n");
|
||||
p(mrts_wrong_if, "\t%lu datagram%s arrived on wrong interface\n");
|
||||
p(mrts_drop_sel, "\t%lu datagram%s selectively dropped\n");
|
||||
p(mrts_q_overflow, "\t%lu datagram%s dropped due to queue overflow\n");
|
||||
p(mrts_pkt2large, "\t%lu datagram%s dropped for being too large\n");
|
||||
|
||||
#undef p2
|
||||
#undef p
|
||||
}
|
268
freebsd-userspace/commands/usr.bin/netstat/mroute6.c
Normal file
268
freebsd-userspace/commands/usr.bin/netstat/mroute6.c
Normal file
@ -0,0 +1,268 @@
|
||||
/*-
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1989 Stephen Deering
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Stephen Deering of Stanford University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mroute.c 8.2 (Berkeley) 4/28/95
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef INET6
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/mbuf.h>
|
||||
#else
|
||||
#include <sys/mbuf.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define KERNEL 1
|
||||
#include <netinet6/ip6_mroute.h>
|
||||
#undef KERNEL
|
||||
|
||||
#include "netstat.h"
|
||||
|
||||
#define WID_ORG (Wflag ? 39 : (numeric_addr ? 29 : 18)) /* width of origin column */
|
||||
#define WID_GRP (Wflag ? 18 : (numeric_addr ? 16 : 18)) /* width of group column */
|
||||
|
||||
void
|
||||
mroute6pr(u_long mfcaddr, u_long mifaddr)
|
||||
{
|
||||
struct mf6c *mf6ctable[MF6CTBLSIZ], *mfcp;
|
||||
struct mif6 mif6table[MAXMIFS];
|
||||
struct mf6c mfc;
|
||||
struct rtdetq rte, *rtep;
|
||||
struct mif6 *mifp;
|
||||
mifi_t mifi;
|
||||
int i;
|
||||
int banner_printed;
|
||||
int saved_numeric_addr;
|
||||
mifi_t maxmif = 0;
|
||||
long int waitings;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(mif6table);
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len,
|
||||
NULL, 0) < 0) {
|
||||
warn("sysctl: net.inet6.ip6.mif6table");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(mifaddr, (char *)mif6table, sizeof(mif6table));
|
||||
|
||||
saved_numeric_addr = numeric_addr;
|
||||
numeric_addr = 1;
|
||||
banner_printed = 0;
|
||||
|
||||
for (mifi = 0, mifp = mif6table; mifi < MAXMIFS; ++mifi, ++mifp) {
|
||||
struct ifnet ifnet;
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
if (mifp->m6_ifp == NULL)
|
||||
continue;
|
||||
|
||||
/* XXX KVM */
|
||||
kread((u_long)mifp->m6_ifp, (char *)&ifnet, sizeof(ifnet));
|
||||
|
||||
maxmif = mifi;
|
||||
if (!banner_printed) {
|
||||
printf("\nIPv6 Multicast Interface Table\n"
|
||||
" Mif Rate PhyIF "
|
||||
"Pkts-In Pkts-Out\n");
|
||||
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));
|
||||
|
||||
printf(" %9ju %9ju\n", (uintmax_t)mifp->m6_pkt_in,
|
||||
(uintmax_t)mifp->m6_pkt_out);
|
||||
}
|
||||
if (!banner_printed)
|
||||
printf("\nIPv6 Multicast Interface Table is empty\n");
|
||||
|
||||
len = sizeof(mf6ctable);
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet6.ip6.mf6ctable", mf6ctable, &len,
|
||||
NULL, 0) < 0) {
|
||||
warn("sysctl: net.inet6.ip6.mf6ctable");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(mfcaddr, (char *)mf6ctable, sizeof(mf6ctable));
|
||||
|
||||
banner_printed = 0;
|
||||
|
||||
for (i = 0; i < MF6CTBLSIZ; ++i) {
|
||||
mfcp = mf6ctable[i];
|
||||
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");
|
||||
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);
|
||||
|
||||
for (waitings = 0, rtep = mfc.mf6c_stall; rtep; ) {
|
||||
waitings++;
|
||||
/* XXX KVM */
|
||||
kread((u_long)rtep, (char *)&rte, sizeof(rte));
|
||||
rtep = rte.next;
|
||||
}
|
||||
printf(" %3ld", waitings);
|
||||
|
||||
if (mfc.mf6c_parent == MF6C_INCOMPLETE_PARENT)
|
||||
printf(" --- ");
|
||||
else
|
||||
printf(" %3d ", mfc.mf6c_parent);
|
||||
for (mifi = 0; mifi <= maxmif; mifi++) {
|
||||
if (IF_ISSET(mifi, &mfc.mf6c_ifset))
|
||||
printf(" %u", mifi);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
mfcp = mfc.mf6c_next;
|
||||
}
|
||||
}
|
||||
if (!banner_printed)
|
||||
printf("\nIPv6 Multicast Forwarding Table is empty\n");
|
||||
|
||||
printf("\n");
|
||||
numeric_addr = saved_numeric_addr;
|
||||
}
|
||||
|
||||
void
|
||||
mrt6_stats(u_long mstaddr)
|
||||
{
|
||||
struct mrt6stat mrtstat;
|
||||
size_t len = sizeof mrtstat;
|
||||
|
||||
if (live) {
|
||||
if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len,
|
||||
NULL, 0) < 0) {
|
||||
warn("sysctl: net.inet6.ip6.mrt6stat");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
|
||||
|
||||
printf("IPv6 multicast forwarding:\n");
|
||||
|
||||
#define p(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)mrtstat.f, plural(mrtstat.f))
|
||||
#define p2(f, m) if (mrtstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f))
|
||||
|
||||
p(mrt6s_mfc_lookups, "\t%ju multicast forwarding cache lookup%s\n");
|
||||
p2(mrt6s_mfc_misses, "\t%ju multicast forwarding cache miss%s\n");
|
||||
p(mrt6s_upcalls, "\t%ju upcall%s to multicast routing daemon\n");
|
||||
p(mrt6s_upq_ovflw, "\t%ju upcall queue overflow%s\n");
|
||||
p(mrt6s_upq_sockfull,
|
||||
"\t%ju upcall%s dropped due to full socket buffer\n");
|
||||
p(mrt6s_cache_cleanups, "\t%ju cache cleanup%s\n");
|
||||
p(mrt6s_no_route, "\t%ju datagram%s with no route for origin\n");
|
||||
p(mrt6s_bad_tunnel, "\t%ju datagram%s arrived with bad tunneling\n");
|
||||
p(mrt6s_cant_tunnel, "\t%ju datagram%s could not be tunneled\n");
|
||||
p(mrt6s_wrong_if, "\t%ju datagram%s arrived on wrong interface\n");
|
||||
p(mrt6s_drop_sel, "\t%ju datagram%s selectively dropped\n");
|
||||
p(mrt6s_q_overflow,
|
||||
"\t%ju datagram%s dropped due to queue overflow\n");
|
||||
p(mrt6s_pkt2large, "\t%ju datagram%s dropped for being too large\n");
|
||||
|
||||
#undef p2
|
||||
#undef p
|
||||
}
|
||||
#endif /*INET6*/
|
196
freebsd-userspace/commands/usr.bin/netstat/netgraph.c
Normal file
196
freebsd-userspace/commands/usr.bin/netstat/netgraph.c
Normal file
@ -0,0 +1,196 @@
|
||||
/*-
|
||||
* Copyright (c) 1996-1999 Whistle Communications, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Subject to the following obligations and disclaimer of warranty, use and
|
||||
* redistribution of this software, in source or object code forms, with or
|
||||
* without modifications are expressly permitted by Whistle Communications;
|
||||
* provided, however, that:
|
||||
* 1. Any and all reproductions of the source or object code must include the
|
||||
* copyright notice above and the following disclaimer of warranties; and
|
||||
* 2. No rights are granted, in any manner or form, to use Whistle
|
||||
* Communications, Inc. trademarks, including the mark "WHISTLE
|
||||
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
|
||||
* such appears in the above copyright notice or in the software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
|
||||
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
|
||||
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
|
||||
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
|
||||
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
|
||||
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
|
||||
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#include <freebsd/sys/linker.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/linker.h>
|
||||
#endif
|
||||
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netgraph.h>
|
||||
#include <netgraph/ng_message.h>
|
||||
#include <netgraph/ng_socket.h>
|
||||
#include <netgraph/ng_socketvar.h>
|
||||
|
||||
#include <nlist.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include "netstat.h"
|
||||
|
||||
static int first = 1;
|
||||
static int csock = -1;
|
||||
|
||||
void
|
||||
netgraphprotopr(u_long off, const char *name, int af1 __unused,
|
||||
int proto __unused)
|
||||
{
|
||||
struct ngpcb *this, *next;
|
||||
struct ngpcb ngpcb;
|
||||
struct ngsock info;
|
||||
struct socket sockb;
|
||||
int debug = 1;
|
||||
|
||||
/* If symbol not found, try looking in the KLD module */
|
||||
if (off == 0) {
|
||||
const char *const modname = "ng_socket.ko";
|
||||
/* XXX We should get "mpath" from "sysctl kern.module_path" */
|
||||
const char *mpath[] = { "/", "/boot/", "/modules/", NULL };
|
||||
struct nlist sym[] = { { .n_name = "_ngsocklist" },
|
||||
{ .n_name = NULL } };
|
||||
const char **pre;
|
||||
struct kld_file_stat ks;
|
||||
int fileid;
|
||||
|
||||
/* Can't do this for core dumps. */
|
||||
if (!live)
|
||||
return;
|
||||
|
||||
/* See if module is loaded */
|
||||
if ((fileid = kldfind(modname)) < 0) {
|
||||
if (debug)
|
||||
warn("kldfind(%s)", modname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get module info */
|
||||
memset(&ks, 0, sizeof(ks));
|
||||
ks.version = sizeof(struct kld_file_stat);
|
||||
if (kldstat(fileid, &ks) < 0) {
|
||||
if (debug)
|
||||
warn("kldstat(%d)", fileid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get symbol table from module file */
|
||||
for (pre = mpath; *pre; pre++) {
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
snprintf(path, sizeof(path), "%s%s", *pre, modname);
|
||||
if (nlist(path, sym) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Did we find it? */
|
||||
if (sym[0].n_value == 0) {
|
||||
if (debug)
|
||||
warnx("%s not found", modname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Symbol found at load address plus symbol offset */
|
||||
off = (u_long) ks.address + sym[0].n_value;
|
||||
}
|
||||
|
||||
/* Get pointer to first socket */
|
||||
kread(off, (char *)&this, sizeof(this));
|
||||
|
||||
/* Get my own socket node */
|
||||
if (csock == -1)
|
||||
NgMkSockNode(NULL, &csock, NULL);
|
||||
|
||||
for (; this != NULL; this = next) {
|
||||
u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)];
|
||||
struct ng_mesg *resp = (struct ng_mesg *) rbuf;
|
||||
struct nodeinfo *ni = (struct nodeinfo *) resp->data;
|
||||
char path[64];
|
||||
|
||||
/* Read in ngpcb structure */
|
||||
kread((u_long)this, (char *)&ngpcb, sizeof(ngpcb));
|
||||
next = LIST_NEXT(&ngpcb, socks);
|
||||
|
||||
/* Read in socket structure */
|
||||
kread((u_long)ngpcb.ng_socket, (char *)&sockb, sizeof(sockb));
|
||||
|
||||
/* Check type of socket */
|
||||
if (strcmp(name, "ctrl") == 0 && ngpcb.type != NG_CONTROL)
|
||||
continue;
|
||||
if (strcmp(name, "data") == 0 && ngpcb.type != NG_DATA)
|
||||
continue;
|
||||
|
||||
/* Do headline */
|
||||
if (first) {
|
||||
printf("Netgraph sockets\n");
|
||||
if (Aflag)
|
||||
printf("%-8.8s ", "PCB");
|
||||
printf("%-5.5s %-6.6s %-6.6s %-14.14s %s\n",
|
||||
"Type", "Recv-Q", "Send-Q",
|
||||
"Node Address", "#Hooks");
|
||||
first = 0;
|
||||
}
|
||||
|
||||
/* Show socket */
|
||||
if (Aflag)
|
||||
printf("%8lx ", (u_long) this);
|
||||
printf("%-5.5s %6u %6u ",
|
||||
name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);
|
||||
|
||||
/* Get ngsock structure */
|
||||
if (ngpcb.sockdata == NULL) /* unconnected data socket */
|
||||
goto finish;
|
||||
kread((u_long)ngpcb.sockdata, (char *)&info, sizeof(info));
|
||||
|
||||
/* Get info on associated node */
|
||||
if (info.node_id == 0 || csock == -1)
|
||||
goto finish;
|
||||
snprintf(path, sizeof(path), "[%x]:", info.node_id);
|
||||
if (NgSendMsg(csock, path,
|
||||
NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0)
|
||||
goto finish;
|
||||
if (NgRecvMsg(csock, resp, sizeof(rbuf), NULL) < 0)
|
||||
goto finish;
|
||||
|
||||
/* Display associated node info */
|
||||
if (*ni->name != '\0')
|
||||
snprintf(path, sizeof(path), "%s:", ni->name);
|
||||
printf("%-14.14s %4d", path, ni->hooks);
|
||||
finish:
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
523
freebsd-userspace/commands/usr.bin/netstat/netstat.1
Normal file
523
freebsd-userspace/commands/usr.bin/netstat/netstat.1
Normal file
@ -0,0 +1,523 @@
|
||||
.\" Copyright (c) 1983, 1990, 1992, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)netstat.1 8.8 (Berkeley) 4/18/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 10, 2010
|
||||
.Dt NETSTAT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm netstat
|
||||
.Nd show network status
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
command symbolically displays the contents of various network-related
|
||||
data structures.
|
||||
There are a number of output formats,
|
||||
depending on the options for the information presented.
|
||||
.Bl -tag -width indent
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Op Fl AaLnSWx
|
||||
.Op Fl f Ar protocol_family | Fl p Ar protocol
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Display a list of active sockets
|
||||
(protocol control blocks)
|
||||
for each network protocol,
|
||||
for a particular
|
||||
.Ar protocol_family ,
|
||||
or for a single
|
||||
.Ar protocol .
|
||||
If
|
||||
.Fl A
|
||||
is also present,
|
||||
show the address of a protocol control block (PCB)
|
||||
associated with a socket; used for debugging.
|
||||
If
|
||||
.Fl a
|
||||
is also present,
|
||||
show the state of all sockets;
|
||||
normally sockets used by server processes are not shown.
|
||||
If
|
||||
.Fl L
|
||||
is also present,
|
||||
show the size of the various listen queues.
|
||||
The first count shows the number of unaccepted connections,
|
||||
the second count shows the amount of unaccepted incomplete connections,
|
||||
and the third count is the maximum number of queued connections.
|
||||
If
|
||||
.Fl S
|
||||
is also present,
|
||||
show network addresses as numbers (as with
|
||||
.Fl n )
|
||||
but show ports symbolically.
|
||||
If
|
||||
.Fl x
|
||||
is present display full socket buffer statistics for each internet socket.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl i | I Ar interface
|
||||
.Op Fl abdhntW
|
||||
.Op Fl f Ar address_family
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Show the state of all network interfaces or a single
|
||||
.Ar interface
|
||||
which have been auto-configured
|
||||
(interfaces statically configured into a system, but not
|
||||
located at boot time are not shown).
|
||||
An asterisk
|
||||
.Pq Dq Li *
|
||||
after an interface name indicates that the interface is
|
||||
.Dq down .
|
||||
If
|
||||
.Fl a
|
||||
is also present, multicast addresses currently in use are shown
|
||||
for each Ethernet interface and for each IP interface address.
|
||||
Multicast addresses are shown on separate lines following the interface
|
||||
address with which they are associated.
|
||||
If
|
||||
.Fl b
|
||||
is also present, show the number of bytes in and out.
|
||||
If
|
||||
.Fl d
|
||||
is also present, show the number of dropped packets.
|
||||
If
|
||||
.Fl h
|
||||
is also present, print all counters in human readable form.
|
||||
If
|
||||
.Fl t
|
||||
is also present, show the contents of watchdog timers.
|
||||
If
|
||||
.Fl W
|
||||
is also present, print interface names using a wider field size.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl w Ar wait
|
||||
.Op Fl I Ar interface
|
||||
.Op Fl d
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Op Fl q Ar howmany
|
||||
.Ek
|
||||
.Xc
|
||||
At intervals of
|
||||
.Ar wait
|
||||
seconds,
|
||||
display the information regarding packet
|
||||
traffic on all configured network interfaces
|
||||
or a single
|
||||
.Ar interface .
|
||||
If
|
||||
.Fl q
|
||||
is also present, exit after
|
||||
.Ar howmany
|
||||
outputs.
|
||||
If
|
||||
.Fl d
|
||||
is also present, show the number of dropped packets.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl s Op Fl s
|
||||
.Op Fl z
|
||||
.Op Fl f Ar protocol_family | Fl p Ar protocol
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Display system-wide statistics for each network protocol,
|
||||
for a particular
|
||||
.Ar protocol_family ,
|
||||
or for a single
|
||||
.Ar protocol .
|
||||
If
|
||||
.Fl s
|
||||
is repeated, counters with a value of zero are suppressed.
|
||||
If
|
||||
.Fl z
|
||||
is also present, reset statistic counters after displaying them.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl i | I Ar interface Fl s
|
||||
.Op Fl f Ar protocol_family | Fl p Ar protocol
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Display per-interface statistics for each network protocol,
|
||||
for a particular
|
||||
.Ar protocol_family ,
|
||||
or for a single
|
||||
.Ar protocol .
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl m
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Show statistics recorded by the memory management routines
|
||||
.Pq Xr mbuf 9 .
|
||||
The network manages a private pool of memory buffers.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl B
|
||||
.Op Fl z
|
||||
.Op Fl I Ar interface
|
||||
.Ek
|
||||
.Xc
|
||||
Show statistics about
|
||||
.Xr bpf 4
|
||||
peers.
|
||||
This includes information like
|
||||
how many packets have been matched, dropped and received by the
|
||||
bpf device, also information about current buffer sizes and device
|
||||
states.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl r
|
||||
.Op Fl AanW
|
||||
.Op Fl f Ar address_family
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Display the contents of all routing tables,
|
||||
or a routing table for a particular
|
||||
.Ar address_family .
|
||||
If
|
||||
.Fl A
|
||||
is also present,
|
||||
show the contents of the internal Patricia tree
|
||||
structures; used for debugging.
|
||||
If
|
||||
.Fl a
|
||||
is also present,
|
||||
show protocol-cloned routes
|
||||
(routes generated by an
|
||||
.Dv RTF_PRCLONING
|
||||
parent route);
|
||||
normally these routes are not shown.
|
||||
When
|
||||
.Fl W
|
||||
is also present,
|
||||
show the path MTU
|
||||
for each route,
|
||||
and print interface
|
||||
names with a wider
|
||||
field size.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl rs
|
||||
.Op Fl s
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Display routing statistics.
|
||||
If
|
||||
.Fl s
|
||||
is repeated, counters with a value of zero are suppressed.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl g
|
||||
.Op Fl W
|
||||
.Op Fl f Ar address_family
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Display the contents of the multicast virtual interface tables,
|
||||
and multicast forwarding caches.
|
||||
Entries in these tables will appear only when the kernel is
|
||||
actively forwarding multicast sessions.
|
||||
This option is applicable only to the
|
||||
.Cm inet
|
||||
and
|
||||
.Cm inet6
|
||||
address families.
|
||||
.It Xo
|
||||
.Bk -words
|
||||
.Nm
|
||||
.Fl gs
|
||||
.Op Fl s
|
||||
.Op Fl f Ar address_family
|
||||
.Op Fl M Ar core
|
||||
.Op Fl N Ar system
|
||||
.Ek
|
||||
.Xc
|
||||
Show multicast routing statistics.
|
||||
If
|
||||
.Fl s
|
||||
is repeated, counters with a value of zero are suppressed.
|
||||
.El
|
||||
.Pp
|
||||
Some options have the general meaning:
|
||||
.Bl -tag -width flag
|
||||
.It Fl f Ar address_family , Fl p Ar protocol
|
||||
Limit display to those records
|
||||
of the specified
|
||||
.Ar address_family
|
||||
or a single
|
||||
.Ar protocol .
|
||||
The following address families and protocols are recognized:
|
||||
.Pp
|
||||
.Bl -tag -width ".Cm netgraph , ng Pq Dv AF_NETGRAPH" -compact
|
||||
.It Em Family
|
||||
.Em Protocols
|
||||
.It Cm inet Pq Dv AF_INET
|
||||
.Cm divert , icmp , igmp , ip , ipsec , pim, sctp , tcp , udp
|
||||
.It Cm inet6 Pq Dv AF_INET6
|
||||
.Cm icmp6 , ip6 , ipsec6 , rip6 , tcp , udp
|
||||
.It Cm pfkey Pq Dv PF_KEY
|
||||
.Cm pfkey
|
||||
.It Cm atalk Pq Dv AF_APPLETALK
|
||||
.Cm ddp
|
||||
.It Cm netgraph , ng Pq Dv AF_NETGRAPH
|
||||
.Cm ctrl , data
|
||||
.It Cm ipx Pq Dv AF_IPX
|
||||
.Cm ipx , spx
|
||||
.\".It Cm ns Pq Dv AF_NS
|
||||
.\".Cm idp , ns_err , spp
|
||||
.\".It Cm iso Pq Dv AF_ISO
|
||||
.\".Cm clnp , cltp , esis , tp
|
||||
.It Cm unix Pq Dv AF_UNIX
|
||||
.It Cm link Pq Dv AF_LINK
|
||||
.El
|
||||
.Pp
|
||||
The program will complain if
|
||||
.Ar protocol
|
||||
is unknown or if there is no statistics routine for it.
|
||||
.It Fl M
|
||||
Extract values associated with the name list from the specified core
|
||||
instead of the default
|
||||
.Pa /dev/kmem .
|
||||
.It Fl N
|
||||
Extract the name list from the specified system instead of the default,
|
||||
which is the kernel image the system has booted from.
|
||||
.It Fl n
|
||||
Show network addresses and ports as numbers.
|
||||
Normally
|
||||
.Nm
|
||||
attempts to resolve addresses and ports,
|
||||
and display them symbolically.
|
||||
.It Fl W
|
||||
In certain displays, avoid truncating addresses even if this causes
|
||||
some fields to overflow.
|
||||
.El
|
||||
.Pp
|
||||
The default display, for active sockets, shows the local
|
||||
and remote addresses, send and receive queue sizes (in bytes), protocol,
|
||||
and the internal state of the protocol.
|
||||
Address formats are of the form
|
||||
.Dq host.port
|
||||
or
|
||||
.Dq network.port
|
||||
if a socket's address specifies a network but no specific host address.
|
||||
When known, the host and network addresses are displayed symbolically
|
||||
according to the databases
|
||||
.Xr hosts 5
|
||||
and
|
||||
.Xr networks 5 ,
|
||||
respectively.
|
||||
If a symbolic name for an address is unknown, or if
|
||||
the
|
||||
.Fl n
|
||||
option is specified, the address is printed numerically, according
|
||||
to the address family.
|
||||
For more information regarding
|
||||
the Internet IPv4
|
||||
.Dq dot format ,
|
||||
refer to
|
||||
.Xr inet 3 .
|
||||
Unspecified,
|
||||
or
|
||||
.Dq wildcard ,
|
||||
addresses and ports appear as
|
||||
.Dq Li * .
|
||||
.Pp
|
||||
The interface display provides a table of cumulative
|
||||
statistics regarding packets transferred, errors, and collisions.
|
||||
The network addresses of the interface
|
||||
and the maximum transmission unit
|
||||
.Pq Dq mtu
|
||||
are also displayed.
|
||||
.Pp
|
||||
The routing table display indicates the available routes and their status.
|
||||
Each route consists of a destination host or network, and a gateway to use
|
||||
in forwarding packets.
|
||||
The flags field shows a collection of information about the route stored
|
||||
as binary choices.
|
||||
The individual flags are discussed in more detail in the
|
||||
.Xr route 8
|
||||
and
|
||||
.Xr route 4
|
||||
manual pages.
|
||||
The mapping between letters and flags is:
|
||||
.Bl -column ".Li W" ".Dv RTF_WASCLONED"
|
||||
.It Li 1 Ta Dv RTF_PROTO1 Ta "Protocol specific routing flag #1"
|
||||
.It Li 2 Ta Dv RTF_PROTO2 Ta "Protocol specific routing flag #2"
|
||||
.It Li 3 Ta Dv RTF_PROTO3 Ta "Protocol specific routing flag #3"
|
||||
.It Li B Ta Dv RTF_BLACKHOLE Ta "Just discard pkts (during updates)"
|
||||
.It Li b Ta Dv RTF_BROADCAST Ta "The route represents a broadcast address"
|
||||
.It Li C Ta Dv RTF_CLONING Ta "Generate new routes on use"
|
||||
.It Li c Ta Dv RTF_PRCLONING Ta "Protocol-specified generate new routes on use"
|
||||
.It Li D Ta Dv RTF_DYNAMIC Ta "Created dynamically (by redirect)"
|
||||
.It Li G Ta Dv RTF_GATEWAY Ta "Destination requires forwarding by intermediary"
|
||||
.It Li H Ta Dv RTF_HOST Ta "Host entry (net otherwise)"
|
||||
.It Li L Ta Dv RTF_LLINFO Ta "Valid protocol to link address translation"
|
||||
.It Li M Ta Dv RTF_MODIFIED Ta "Modified dynamically (by redirect)"
|
||||
.It Li R Ta Dv RTF_REJECT Ta "Host or net unreachable"
|
||||
.It Li S Ta Dv RTF_STATIC Ta "Manually added"
|
||||
.It Li U Ta Dv RTF_UP Ta "Route usable"
|
||||
.It Li W Ta Dv RTF_WASCLONED Ta "Route was generated as a result of cloning"
|
||||
.It Li X Ta Dv RTF_XRESOLVE Ta "External daemon translates proto to link address"
|
||||
.El
|
||||
.Pp
|
||||
Direct routes are created for each
|
||||
interface attached to the local host;
|
||||
the gateway field for such entries shows the address of the outgoing interface.
|
||||
The refcnt field gives the
|
||||
current number of active uses of the route.
|
||||
Connection oriented
|
||||
protocols normally hold on to a single route for the duration of
|
||||
a connection while connectionless protocols obtain a route while sending
|
||||
to the same destination.
|
||||
The use field provides a count of the number of packets
|
||||
sent using that route.
|
||||
The interface entry indicates the network interface utilized for the route.
|
||||
.Pp
|
||||
When
|
||||
.Nm
|
||||
is invoked with the
|
||||
.Fl w
|
||||
option and a
|
||||
.Ar wait
|
||||
interval argument, it displays a running count of statistics related to
|
||||
network interfaces.
|
||||
An obsolescent version of this option used a numeric parameter
|
||||
with no option, and is currently supported for backward compatibility.
|
||||
By default, this display summarizes information for all interfaces.
|
||||
Information for a specific interface may be displayed with the
|
||||
.Fl I
|
||||
option.
|
||||
.Pp
|
||||
The
|
||||
.Xr bpf 4
|
||||
flags displayed when
|
||||
.Nm
|
||||
is invoked with the
|
||||
.Fl B
|
||||
option represent the underlying parameters of the bpf peer.
|
||||
Each flag is
|
||||
represented as a single lower case letter.
|
||||
The mapping between the letters and flags in order of appearance are:
|
||||
.Bl -column ".Li i"
|
||||
.It Li p Ta Set if listening promiscuously
|
||||
.It Li i Ta Dv BIOCIMMEDIATE No has been set on the device
|
||||
.It Li f Ta Dv BIOCGHDRCMPLT No status: source link addresses are being
|
||||
filled automatically
|
||||
.It Li s Ta Dv BIOCGSEESENT No status: see packets originating locally and
|
||||
remotely on the interface.
|
||||
.It Li a Ta Packet reception generates a signal
|
||||
.It Li l Ta Dv BIOCLOCK No status: descriptor has been locked
|
||||
.El
|
||||
.Pp
|
||||
For more information about these flags, please refer to
|
||||
.Xr bpf 4 .
|
||||
.Pp
|
||||
The
|
||||
.Fl x
|
||||
flag causes
|
||||
.Nm
|
||||
to output all the information recorded about data
|
||||
stored in the socket buffers.
|
||||
The fields are:
|
||||
.Bl -column ".Li R-MBUF"
|
||||
.It Li R-MBUF Ta Number of mbufs in the receive queue.
|
||||
.It Li S-MBUF Ta Number of mbufs in the send queue.
|
||||
.It Li R-CLUS Ta Number of clusters, of any type, in the receive
|
||||
queue.
|
||||
.It Li S-CLUS Ta Number of clusters, of any type, in the send queue.
|
||||
.It Li R-HIWA Ta Receive buffer high water mark, in bytes.
|
||||
.It Li S-HIWA Ta Send buffer high water mark, in bytes.
|
||||
.It Li R-LOWA Ta Receive buffer low water mark, in bytes.
|
||||
.It Li S-LOWA Ta Send buffer low water mark, in bytes.
|
||||
.It Li R-BCNT Ta Receive buffer byte count.
|
||||
.It Li S-BCNT Ta Send buffer byte count.
|
||||
.It Li R-BMAX Ta Maximum bytes that can be used in the receive buffer.
|
||||
.It Li S-BMAX Ta Maximum bytes that can be used in the send buffer.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr fstat 1 ,
|
||||
.Xr nfsstat 1 ,
|
||||
.Xr procstat 1 ,
|
||||
.Xr ps 1 ,
|
||||
.Xr sockstat 1 ,
|
||||
.Xr bpf 4 ,
|
||||
.Xr inet 4 ,
|
||||
.Xr route 4 ,
|
||||
.Xr unix 4 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr networks 5 ,
|
||||
.Xr protocols 5 ,
|
||||
.Xr services 5 ,
|
||||
.Xr iostat 8 ,
|
||||
.Xr route 8 ,
|
||||
.Xr trpt 8 ,
|
||||
.Xr vmstat 8 ,
|
||||
.Xr mbuf 9
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.2 .
|
||||
.Pp
|
||||
IPv6 support was added by WIDE/KAME project.
|
||||
.Sh BUGS
|
||||
The notion of errors is ill-defined.
|
167
freebsd-userspace/commands/usr.bin/netstat/netstat.h
Normal file
167
freebsd-userspace/commands/usr.bin/netstat/netstat.h
Normal file
@ -0,0 +1,167 @@
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
* Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)netstat.h 8.2 (Berkeley) 1/4/94
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
extern int Aflag; /* show addresses of protocol control block */
|
||||
extern int aflag; /* show all sockets (including servers) */
|
||||
extern int bflag; /* show i/f total bytes in/out */
|
||||
extern int dflag; /* show i/f dropped packets */
|
||||
extern int gflag; /* show group (multicast) routing or stats */
|
||||
extern int hflag; /* show counters in human readable format */
|
||||
extern int iflag; /* show interfaces */
|
||||
extern int Lflag; /* show size of listen queues */
|
||||
extern int mflag; /* show memory stats */
|
||||
extern int noutputs; /* how much outputs before we exit */
|
||||
extern int numeric_addr; /* show addresses numerically */
|
||||
extern int numeric_port; /* show ports numerically */
|
||||
extern int rflag; /* show routing tables (or routing stats) */
|
||||
extern int sflag; /* show protocol statistics */
|
||||
extern int tflag; /* show i/f watchdog timers */
|
||||
extern int Wflag; /* wide display */
|
||||
extern int xflag; /* extended display, includes all socket buffer info */
|
||||
extern int zflag; /* zero stats */
|
||||
|
||||
extern int interval; /* repeat interval for i/f stats */
|
||||
|
||||
extern char *interface; /* desired i/f for stats, or NULL for all i/fs */
|
||||
extern int unit; /* unit number for above */
|
||||
|
||||
extern int af; /* address family */
|
||||
extern int live; /* true if we are examining a live system */
|
||||
|
||||
int kread(u_long addr, void *buf, size_t size);
|
||||
const char *plural(uintmax_t);
|
||||
const char *plurales(uintmax_t);
|
||||
const char *pluralies(uintmax_t);
|
||||
|
||||
int sotoxsocket(struct socket *, struct xsocket *);
|
||||
void protopr(u_long, const char *, int, int);
|
||||
void tcp_stats(u_long, const char *, int, int);
|
||||
void udp_stats(u_long, const char *, int, int);
|
||||
#ifdef SCTP
|
||||
void sctp_protopr(u_long, const char *, int, int);
|
||||
void sctp_stats(u_long, const char *, int, int);
|
||||
#endif
|
||||
void arp_stats(u_long, const char *, int, int);
|
||||
void ip_stats(u_long, const char *, int, int);
|
||||
void icmp_stats(u_long, const char *, int, int);
|
||||
void igmp_stats(u_long, const char *, int, int);
|
||||
void pim_stats(u_long, const char *, int, int);
|
||||
void carp_stats(u_long, const char *, int, int);
|
||||
void pfsync_stats(u_long, const char *, int, int);
|
||||
#ifdef IPSEC
|
||||
void ipsec_stats(u_long, const char *, int, int);
|
||||
void esp_stats(u_long, const char *, int, int);
|
||||
void ah_stats(u_long, const char *, int, int);
|
||||
void ipcomp_stats(u_long, const char *, int, int);
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
void ip6_stats(u_long, const char *, int, int);
|
||||
void ip6_ifstats(char *);
|
||||
void icmp6_stats(u_long, const char *, int, int);
|
||||
void icmp6_ifstats(char *);
|
||||
void pim6_stats(u_long, const char *, int, int);
|
||||
void rip6_stats(u_long, const char *, int, int);
|
||||
void mroute6pr(u_long, u_long);
|
||||
void mrt6_stats(u_long);
|
||||
|
||||
struct sockaddr_in6;
|
||||
struct in6_addr;
|
||||
char *routename6(struct sockaddr_in6 *);
|
||||
const char *netname6(struct sockaddr_in6 *, struct in6_addr *);
|
||||
void inet6print(struct in6_addr *, int, const char *, int);
|
||||
#endif /*INET6*/
|
||||
|
||||
#ifdef IPSEC
|
||||
void pfkey_stats(u_long, const char *, int, int);
|
||||
#endif
|
||||
|
||||
void mbpr(void *, u_long);
|
||||
|
||||
void hostpr(u_long, u_long);
|
||||
void impstats(u_long, u_long);
|
||||
|
||||
void intpr(int, u_long, void (*)(char *));
|
||||
|
||||
void pr_rthdr(int);
|
||||
void pr_family(int);
|
||||
void rt_stats(u_long, u_long);
|
||||
char *ipx_pnet(struct sockaddr *);
|
||||
char *ipx_phost(struct sockaddr *);
|
||||
char *ns_phost(struct sockaddr *);
|
||||
void upHex(char *);
|
||||
|
||||
char *routename(in_addr_t);
|
||||
char *netname(in_addr_t, u_long);
|
||||
char *atalk_print(struct sockaddr *, int);
|
||||
char *atalk_print2(struct sockaddr *, struct sockaddr *, int);
|
||||
char *ipx_print(struct sockaddr *);
|
||||
char *ns_print(struct sockaddr *);
|
||||
void routepr(u_long);
|
||||
|
||||
void ipxprotopr(u_long, const char *, int, int);
|
||||
void spx_stats(u_long, const char *, int, int);
|
||||
void ipx_stats(u_long, const char *, int, int);
|
||||
void ipxerr_stats(u_long, const char *, int, int);
|
||||
|
||||
void nsprotopr(u_long, const char *, int, int);
|
||||
void spp_stats(u_long, const char *, int, int);
|
||||
void idp_stats(u_long, const char *, int, int);
|
||||
void nserr_stats(u_long, const char *, int, int);
|
||||
|
||||
void atalkprotopr(u_long, const char *, int, int);
|
||||
void ddp_stats(u_long, const char *, int, int);
|
||||
|
||||
#ifdef NETGRAPH
|
||||
void netgraphprotopr(u_long, const char *, int, int);
|
||||
#endif
|
||||
|
||||
void unixpr(u_long, u_long, u_long, u_long);
|
||||
|
||||
void esis_stats(u_long, const char *, int, int);
|
||||
void clnp_stats(u_long, const char *, int, int);
|
||||
void cltp_stats(u_long, const char *, int, int);
|
||||
void iso_protopr(u_long, const char *, int, int);
|
||||
void iso_protopr1(u_long, int);
|
||||
void tp_protopr(u_long, const char *, int, int);
|
||||
void tp_inproto(u_long);
|
||||
void tp_stats(caddr_t, caddr_t);
|
||||
|
||||
void mroutepr(u_long, u_long, u_long);
|
||||
void mrt_stats(u_long);
|
||||
void bpf_stats(char *);
|
184
freebsd-userspace/commands/usr.bin/netstat/pfkey.c
Normal file
184
freebsd-userspace/commands/usr.bin/netstat/pfkey.c
Normal file
@ -0,0 +1,184 @@
|
||||
/* $NetBSD: inet.c,v 1.35.2.1 1999/04/29 14:57:08 perry Exp $ */
|
||||
/* $KAME: ipsec.c,v 1.25 2001/03/12 09:04:39 itojun Exp $ */
|
||||
/*-
|
||||
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef IPSEC
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/netipsec/keysock.h>
|
||||
#else
|
||||
#include <netipsec/keysock.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "netstat.h"
|
||||
|
||||
#ifdef IPSEC
|
||||
|
||||
static const char *pfkey_msgtypenames[] = {
|
||||
"reserved", "getspi", "update", "add", "delete",
|
||||
"get", "acquire", "register", "expire", "flush",
|
||||
"dump", "x_promisc", "x_pchange", "x_spdupdate", "x_spdadd",
|
||||
"x_spddelete", "x_spdget", "x_spdacquire", "x_spddump", "x_spdflush",
|
||||
"x_spdsetidx", "x_spdexpire", "x_spddelete2"
|
||||
};
|
||||
|
||||
static const char *pfkey_msgtype_names (int);
|
||||
|
||||
|
||||
static const char *
|
||||
pfkey_msgtype_names(int x)
|
||||
{
|
||||
const int max =
|
||||
sizeof(pfkey_msgtypenames)/sizeof(pfkey_msgtypenames[0]);
|
||||
static char buf[20];
|
||||
|
||||
if (x < max && pfkey_msgtypenames[x])
|
||||
return pfkey_msgtypenames[x];
|
||||
snprintf(buf, sizeof(buf), "#%d", x);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
pfkey_stats(u_long off, const char *name, int family __unused,
|
||||
int proto __unused)
|
||||
{
|
||||
struct pfkeystat pfkeystat;
|
||||
unsigned first, type;
|
||||
|
||||
if (off == 0)
|
||||
return;
|
||||
printf ("%s:\n", name);
|
||||
kread(off, (char *)&pfkeystat, sizeof(pfkeystat));
|
||||
|
||||
#define p(f, m) if (pfkeystat.f || sflag <= 1) \
|
||||
printf(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");
|
||||
for (first = 1, type = 0;
|
||||
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");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t%s: %ju\n", pfkey_msgtype_names(type),
|
||||
(uintmax_t)pfkeystat.out_msgtype[type]);
|
||||
}
|
||||
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");
|
||||
|
||||
/* kernel -> userland */
|
||||
p(in_total, "\t%ju request%s sent to userland\n");
|
||||
p(in_bytes, "\t%ju byte%s sent to userland\n");
|
||||
for (first = 1, type = 0;
|
||||
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");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t%s: %ju\n", pfkey_msgtype_names(type),
|
||||
(uintmax_t)pfkeystat.in_msgtype[type]);
|
||||
}
|
||||
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");
|
||||
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");
|
||||
#undef p
|
||||
}
|
||||
#endif /* IPSEC */
|
1167
freebsd-userspace/commands/usr.bin/netstat/route.c
Normal file
1167
freebsd-userspace/commands/usr.bin/netstat/route.c
Normal file
File diff suppressed because it is too large
Load Diff
703
freebsd-userspace/commands/usr.bin/netstat/sctp.c
Normal file
703
freebsd-userspace/commands/usr.bin/netstat/sctp.c
Normal file
@ -0,0 +1,703 @@
|
||||
/*-
|
||||
* Copyright (c) 2001-2007, by Weongyo Jeong. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* a) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* b) Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* c) Neither the name of Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)sctp.c 0.1 (Berkeley) 4/18/2007";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/netinet/sctp.h>
|
||||
#include <freebsd/netinet/sctp_constants.h>
|
||||
#else
|
||||
#include <netinet/sctp.h>
|
||||
#include <netinet/sctp_constants.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#ifdef __rtems__
|
||||
/* apparently libutil.h is not needed */
|
||||
#else
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "netstat.h"
|
||||
|
||||
#ifdef SCTP
|
||||
|
||||
void inetprint(struct in_addr *, int, const char *, int);
|
||||
static void sctp_statesprint(uint32_t state);
|
||||
|
||||
#define NETSTAT_SCTP_STATES_CLOSED 0x0
|
||||
#define NETSTAT_SCTP_STATES_BOUND 0x1
|
||||
#define NETSTAT_SCTP_STATES_LISTEN 0x2
|
||||
#define NETSTAT_SCTP_STATES_COOKIE_WAIT 0x3
|
||||
#define NETSTAT_SCTP_STATES_COOKIE_ECHOED 0x4
|
||||
#define NETSTAT_SCTP_STATES_ESTABLISHED 0x5
|
||||
#define NETSTAT_SCTP_STATES_SHUTDOWN_SENT 0x6
|
||||
#define NETSTAT_SCTP_STATES_SHUTDOWN_RECEIVED 0x7
|
||||
#define NETSTAT_SCTP_STATES_SHUTDOWN_ACK_SENT 0x8
|
||||
#define NETSTAT_SCTP_STATES_SHUTDOWN_PENDING 0x9
|
||||
|
||||
char *sctpstates[] = {
|
||||
"CLOSED",
|
||||
"BOUND",
|
||||
"LISTEN",
|
||||
"COOKIE_WAIT",
|
||||
"COOKIE_ECHOED",
|
||||
"ESTABLISHED",
|
||||
"SHUTDOWN_SENT",
|
||||
"SHUTDOWN_RECEIVED",
|
||||
"SHUTDOWN_ACK_SENT",
|
||||
"SHUTDOWN_PENDING"
|
||||
};
|
||||
|
||||
LIST_HEAD(xladdr_list, xladdr_entry) xladdr_head;
|
||||
struct xladdr_entry {
|
||||
struct xsctp_laddr *xladdr;
|
||||
LIST_ENTRY(xladdr_entry) xladdr_entries;
|
||||
};
|
||||
|
||||
LIST_HEAD(xraddr_list, xraddr_entry) xraddr_head;
|
||||
struct xraddr_entry {
|
||||
struct xsctp_raddr *xraddr;
|
||||
LIST_ENTRY(xraddr_entry) xraddr_entries;
|
||||
};
|
||||
|
||||
static int
|
||||
sctp_skip_xinpcb_ifneed(char *buf, const size_t buflen, size_t *offset)
|
||||
{
|
||||
int exist_tcb = 0;
|
||||
struct xsctp_tcb *xstcb;
|
||||
struct xsctp_raddr *xraddr;
|
||||
struct xsctp_laddr *xladdr;
|
||||
|
||||
while (*offset < buflen) {
|
||||
xladdr = (struct xsctp_laddr *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_laddr);
|
||||
if (xladdr->last == 1)
|
||||
break;
|
||||
}
|
||||
|
||||
while (*offset < buflen) {
|
||||
xstcb = (struct xsctp_tcb *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_tcb);
|
||||
if (xstcb->last == 1)
|
||||
break;
|
||||
|
||||
exist_tcb = 1;
|
||||
|
||||
while (*offset < buflen) {
|
||||
xladdr = (struct xsctp_laddr *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_laddr);
|
||||
if (xladdr->last == 1)
|
||||
break;
|
||||
}
|
||||
|
||||
while (*offset < buflen) {
|
||||
xraddr = (struct xsctp_raddr *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_raddr);
|
||||
if (xraddr->last == 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If Lflag is set, we don't care about the return value.
|
||||
*/
|
||||
if (Lflag)
|
||||
return 0;
|
||||
|
||||
return exist_tcb;
|
||||
}
|
||||
|
||||
static void
|
||||
sctp_process_tcb(struct xsctp_tcb *xstcb, const char *name,
|
||||
char *buf, const size_t buflen, size_t *offset, int *indent)
|
||||
{
|
||||
int i, xl_total = 0, xr_total = 0, x_max;
|
||||
struct sockaddr *sa;
|
||||
struct xsctp_raddr *xraddr;
|
||||
struct xsctp_laddr *xladdr;
|
||||
struct xladdr_entry *prev_xl = NULL, *xl = NULL, *xl_tmp;
|
||||
struct xraddr_entry *prev_xr = NULL, *xr = NULL, *xr_tmp;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *in6;
|
||||
#endif
|
||||
|
||||
LIST_INIT(&xladdr_head);
|
||||
LIST_INIT(&xraddr_head);
|
||||
|
||||
/*
|
||||
* Make `struct xladdr_list' list and `struct xraddr_list' list
|
||||
* to handle the address flexibly.
|
||||
*/
|
||||
while (*offset < buflen) {
|
||||
xladdr = (struct xsctp_laddr *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_laddr);
|
||||
if (xladdr->last == 1)
|
||||
break;
|
||||
|
||||
prev_xl = xl;
|
||||
xl = malloc(sizeof(struct xladdr_entry));
|
||||
if (xl == NULL) {
|
||||
warnx("malloc %lu bytes",
|
||||
(u_long)sizeof(struct xladdr_entry));
|
||||
goto out;
|
||||
}
|
||||
xl->xladdr = xladdr;
|
||||
if (prev_xl == NULL)
|
||||
LIST_INSERT_HEAD(&xladdr_head, xl, xladdr_entries);
|
||||
else
|
||||
LIST_INSERT_AFTER(prev_xl, xl, xladdr_entries);
|
||||
xl_total++;
|
||||
}
|
||||
|
||||
while (*offset < buflen) {
|
||||
xraddr = (struct xsctp_raddr *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_raddr);
|
||||
if (xraddr->last == 1)
|
||||
break;
|
||||
|
||||
prev_xr = xr;
|
||||
xr = malloc(sizeof(struct xraddr_entry));
|
||||
if (xr == NULL) {
|
||||
warnx("malloc %lu bytes",
|
||||
(u_long)sizeof(struct xraddr_entry));
|
||||
goto out;
|
||||
}
|
||||
xr->xraddr = xraddr;
|
||||
if (prev_xr == NULL)
|
||||
LIST_INSERT_HEAD(&xraddr_head, xr, xraddr_entries);
|
||||
else
|
||||
LIST_INSERT_AFTER(prev_xr, xr, xraddr_entries);
|
||||
xr_total++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's print the address infos.
|
||||
*/
|
||||
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++) {
|
||||
if (((*indent == 0) && i > 0) || *indent > 0)
|
||||
printf("%-11s ", " ");
|
||||
|
||||
if (xl != NULL) {
|
||||
sa = &(xl->xladdr->address.sa);
|
||||
if ((sa->sa_family) == AF_INET)
|
||||
inetprint(&((struct sockaddr_in *)sa)->sin_addr,
|
||||
htons(xstcb->local_port),
|
||||
name, numeric_port);
|
||||
#ifdef INET6
|
||||
else {
|
||||
in6 = (struct sockaddr_in6 *)sa;
|
||||
inet6print(&in6->sin6_addr,
|
||||
htons(xstcb->local_port),
|
||||
name, numeric_port);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (xr != NULL && !Lflag) {
|
||||
sa = &(xr->xraddr->address.sa);
|
||||
if ((sa->sa_family) == AF_INET)
|
||||
inetprint(&((struct sockaddr_in *)sa)->sin_addr,
|
||||
htons(xstcb->remote_port),
|
||||
name, numeric_port);
|
||||
#ifdef INET6
|
||||
else {
|
||||
in6 = (struct sockaddr_in6 *)sa;
|
||||
inet6print(&in6->sin6_addr,
|
||||
htons(xstcb->remote_port),
|
||||
name, numeric_port);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (xl != NULL)
|
||||
xl = LIST_NEXT(xl, xladdr_entries);
|
||||
if (xr != NULL)
|
||||
xr = LIST_NEXT(xr, xraddr_entries);
|
||||
|
||||
if (i == 0 && !Lflag)
|
||||
sctp_statesprint(xstcb->state);
|
||||
|
||||
if (i < x_max)
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* Free the list which be used to handle the address.
|
||||
*/
|
||||
xl = LIST_FIRST(&xladdr_head);
|
||||
while (xl != NULL) {
|
||||
xl_tmp = LIST_NEXT(xl, xladdr_entries);
|
||||
free(xl);
|
||||
xl = xl_tmp;
|
||||
}
|
||||
|
||||
xr = LIST_FIRST(&xraddr_head);
|
||||
while (xr != NULL) {
|
||||
xr_tmp = LIST_NEXT(xr, xraddr_entries);
|
||||
free(xr);
|
||||
xr = xr_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SCTP_DEBUG
|
||||
uint32_t sctp_pdup[64];
|
||||
int sctp_pcnt = 0;
|
||||
#endif
|
||||
|
||||
static void
|
||||
sctp_process_inpcb(struct xsctp_inpcb *xinpcb, const char *name,
|
||||
char *buf, const size_t buflen, size_t *offset)
|
||||
{
|
||||
int offset_backup, indent = 0, xladdr_total = 0, is_listening = 0;
|
||||
static int first = 1;
|
||||
char *tname;
|
||||
struct xsctp_tcb *xstcb;
|
||||
struct xsctp_laddr *xladdr;
|
||||
struct sockaddr *sa;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *in6;
|
||||
#endif
|
||||
|
||||
if ((xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE) ==
|
||||
SCTP_PCB_FLAGS_TCPTYPE && xinpcb->maxqlen > 0)
|
||||
is_listening = 1;
|
||||
|
||||
if (!Lflag && !is_listening &&
|
||||
!(xinpcb->flags & SCTP_PCB_FLAGS_CONNECTED)) {
|
||||
#ifdef SCTP_DEBUG
|
||||
int i, found = 0;
|
||||
|
||||
for (i = 0; i < sctp_pcnt; i++) {
|
||||
if (sctp_pdup[i] == xinpcb->flags) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
sctp_pdup[sctp_pcnt++] = xinpcb->flags;
|
||||
if (sctp_pcnt >= 64)
|
||||
sctp_pcnt = 0;
|
||||
printf("[0x%08x]", xinpcb->flags);
|
||||
}
|
||||
#endif
|
||||
offset_backup = *offset;
|
||||
if (!sctp_skip_xinpcb_ifneed(buf, buflen, offset))
|
||||
return;
|
||||
*offset = offset_backup;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
if (!Lflag) {
|
||||
printf("Active SCTP associations");
|
||||
if (aflag)
|
||||
printf(" (including servers)");
|
||||
} else
|
||||
printf("Current listen queue sizes (qlen/maxqlen)");
|
||||
putchar('\n');
|
||||
if (Aflag)
|
||||
printf("%-8.8s ", "Socket");
|
||||
if (Lflag)
|
||||
printf("%-5.5s %-5.5s %-8.8s %-22.22s\n",
|
||||
"Proto", "Type", "Listen", "Local Address");
|
||||
else
|
||||
printf((Aflag && !Wflag) ?
|
||||
"%-5.5s %-5.5s %-18.18s %-18.18s %s\n" :
|
||||
"%-5.5s %-5.5s %-22.22s %-22.22s %s\n",
|
||||
"Proto", "Type",
|
||||
"Local Address", "Foreign Address",
|
||||
"(state)");
|
||||
first = 0;
|
||||
}
|
||||
if (Lflag && xinpcb->maxqlen == 0) {
|
||||
(int)sctp_skip_xinpcb_ifneed(buf, buflen, offset);
|
||||
return;
|
||||
}
|
||||
if (Aflag)
|
||||
printf("%8lx ", (u_long)xinpcb);
|
||||
|
||||
printf("%-5.5s ", name);
|
||||
|
||||
if (xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE)
|
||||
tname = "1to1";
|
||||
else if (xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE)
|
||||
tname = "1toN";
|
||||
else
|
||||
return;
|
||||
|
||||
printf("%-5.5s ", tname);
|
||||
|
||||
if (Lflag) {
|
||||
char buf1[9];
|
||||
|
||||
snprintf(buf1, 9, "%hu/%hu", xinpcb->qlen, xinpcb->maxqlen);
|
||||
printf("%-8.8s ", buf1);
|
||||
}
|
||||
/*
|
||||
* process the local address. This routine are used for Lflag.
|
||||
*/
|
||||
while (*offset < buflen) {
|
||||
xladdr = (struct xsctp_laddr *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_laddr);
|
||||
if (xladdr->last == 1)
|
||||
break;
|
||||
|
||||
if (!Lflag && !is_listening)
|
||||
continue;
|
||||
|
||||
if (xladdr_total != 0)
|
||||
putchar('\n');
|
||||
if (xladdr_total > 0)
|
||||
printf((Lflag) ?
|
||||
"%-20.20s " : "%-11.11s ", " ");
|
||||
|
||||
sa = &(xladdr->address.sa);
|
||||
if ((sa->sa_family) == AF_INET)
|
||||
inetprint(&((struct sockaddr_in *)sa)->sin_addr,
|
||||
htons(xinpcb->local_port), name, numeric_port);
|
||||
#ifdef INET6
|
||||
else {
|
||||
in6 = (struct sockaddr_in6 *)sa;
|
||||
inet6print(&in6->sin6_addr,
|
||||
htons(xinpcb->local_port), name, numeric_port);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!Lflag && xladdr_total == 0 && is_listening == 1)
|
||||
printf("%-22.22s LISTEN", " ");
|
||||
|
||||
xladdr_total++;
|
||||
}
|
||||
|
||||
xstcb = (struct xsctp_tcb *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_tcb);
|
||||
while (xstcb->last == 0 && *offset < buflen) {
|
||||
sctp_process_tcb(xstcb, name, buf, buflen, offset, &indent);
|
||||
indent++;
|
||||
xstcb = (struct xsctp_tcb *)(buf + *offset);
|
||||
*offset += sizeof(struct xsctp_tcb);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a summary of SCTP connections related to an Internet
|
||||
* protocol.
|
||||
*/
|
||||
void
|
||||
sctp_protopr(u_long off __unused,
|
||||
const char *name, int af1, int proto)
|
||||
{
|
||||
char *buf;
|
||||
const char *mibvar = "net.inet.sctp.assoclist";
|
||||
size_t offset = 0;
|
||||
size_t len = 0;
|
||||
struct xsctp_inpcb *xinpcb;
|
||||
|
||||
if (proto != IPPROTO_SCTP)
|
||||
return;
|
||||
|
||||
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: %s", mibvar);
|
||||
return;
|
||||
}
|
||||
if ((buf = malloc(len)) == 0) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
return;
|
||||
}
|
||||
if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
|
||||
warn("sysctl: %s", mibvar);
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
xinpcb = (struct xsctp_inpcb *)(buf + offset);
|
||||
offset += sizeof(struct xsctp_inpcb);
|
||||
while (xinpcb->last == 0 && offset < len) {
|
||||
sctp_process_inpcb(xinpcb, name, buf, (const size_t)len,
|
||||
&offset);
|
||||
|
||||
xinpcb = (struct xsctp_inpcb *)(buf + offset);
|
||||
offset += sizeof(struct xsctp_inpcb);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
sctp_statesprint(uint32_t state)
|
||||
{
|
||||
int idx;
|
||||
|
||||
switch (state) {
|
||||
case SCTP_STATE_COOKIE_WAIT:
|
||||
idx = NETSTAT_SCTP_STATES_COOKIE_WAIT;
|
||||
break;
|
||||
case SCTP_STATE_COOKIE_ECHOED:
|
||||
idx = NETSTAT_SCTP_STATES_COOKIE_ECHOED;
|
||||
break;
|
||||
case SCTP_STATE_OPEN:
|
||||
idx = NETSTAT_SCTP_STATES_ESTABLISHED;
|
||||
break;
|
||||
case SCTP_STATE_SHUTDOWN_SENT:
|
||||
idx = NETSTAT_SCTP_STATES_SHUTDOWN_SENT;
|
||||
break;
|
||||
case SCTP_STATE_SHUTDOWN_RECEIVED:
|
||||
idx = NETSTAT_SCTP_STATES_SHUTDOWN_RECEIVED;
|
||||
break;
|
||||
case SCTP_STATE_SHUTDOWN_ACK_SENT:
|
||||
idx = NETSTAT_SCTP_STATES_SHUTDOWN_ACK_SENT;
|
||||
break;
|
||||
case SCTP_STATE_SHUTDOWN_PENDING:
|
||||
idx = NETSTAT_SCTP_STATES_SHUTDOWN_PENDING;
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN 0x%08x", state);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s", sctpstates[idx]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump SCTP statistics structure.
|
||||
*/
|
||||
void
|
||||
sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
||||
{
|
||||
struct sctpstat sctpstat, zerostat;
|
||||
size_t len = sizeof(sctpstat);
|
||||
|
||||
if (live) {
|
||||
if (zflag)
|
||||
memset(&zerostat, 0, len);
|
||||
if (sysctlbyname("net.inet.sctp.stats", &sctpstat, &len,
|
||||
zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
|
||||
warn("sysctl: net.inet.sctp.stats");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
kread(off, &sctpstat, len);
|
||||
|
||||
printf ("%s:\n", name);
|
||||
|
||||
#define p(f, m) if (sctpstat.f || sflag <= 1) \
|
||||
printf(m, (uintmax_t)sctpstat.f, plural(sctpstat.f))
|
||||
#define p1a(f, m) if (sctpstat.f || sflag <= 1) \
|
||||
printf(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");
|
||||
|
||||
/*
|
||||
* 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 intput 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");
|
||||
|
||||
/*
|
||||
* 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");
|
||||
|
||||
/*
|
||||
* 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"
|
||||
"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");
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Early fast retransmission counters
|
||||
*/
|
||||
p(sctps_earlyfrstart, "\t%ju TODO:sctps_earlyfrstart\n");
|
||||
p(sctps_earlyfrstop, "\t%ju TODO:sctps_earlyfrstop\n");
|
||||
p(sctps_earlyfrmrkretrans, "\t%ju TODO:sctps_earlyfrmrkretrans\n");
|
||||
p(sctps_earlyfrstpout, "\t%ju TODO:sctps_earlyfrstpout\n");
|
||||
p(sctps_earlyfrstpidsck1, "\t%ju TODO:sctps_earlyfrstpidsck1\n");
|
||||
p(sctps_earlyfrstpidsck2, "\t%ju TODO:sctps_earlyfrstpidsck2\n");
|
||||
p(sctps_earlyfrstpidsck3, "\t%ju TODO:sctps_earlyfrstpidsck3\n");
|
||||
p(sctps_earlyfrstpidsck4, "\t%ju TODO:sctps_earlyfrstpidsck4\n");
|
||||
p(sctps_earlyfrstrid, "\t%ju TODO:sctps_earlyfrstrid\n");
|
||||
p(sctps_earlyfrstrout, "\t%ju TODO:sctps_earlyfrstrout\n");
|
||||
p(sctps_earlyfrstrtmr, "\t%ju TODO:sctps_earlyfrstrtmr\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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");
|
||||
#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");
|
||||
|
||||
#undef p
|
||||
#undef p1a
|
||||
}
|
||||
|
||||
#endif /* SCTP */
|
294
freebsd-userspace/commands/usr.bin/netstat/unix.c
Normal file
294
freebsd-userspace/commands/usr.bin/netstat/unix.c
Normal file
@ -0,0 +1,294 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)unix.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Display protocol blocks in the unix domain.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/protosw.h>
|
||||
#else
|
||||
#include <sys/protosw.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#ifdef __rtems__
|
||||
#include <freebsd/sys/mbuf.h>
|
||||
#else
|
||||
#include <sys/mbuf.h>
|
||||
#endif
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/unpcb.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <kvm.h>
|
||||
#include "netstat.h"
|
||||
|
||||
static void unixdomainpr(struct xunpcb *, struct xsocket *);
|
||||
|
||||
static const char *const socktype[] =
|
||||
{ "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
|
||||
|
||||
static int
|
||||
pcblist_sysctl(int type, char **bufp)
|
||||
{
|
||||
char *buf;
|
||||
size_t len;
|
||||
char mibvar[sizeof "net.local.seqpacket.pcblist"];
|
||||
|
||||
sprintf(mibvar, "net.local.%s.pcblist", socktype[type]);
|
||||
|
||||
len = 0;
|
||||
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
warn("sysctl: %s", mibvar);
|
||||
return (-1);
|
||||
}
|
||||
if ((buf = malloc(len)) == 0) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
return (-2);
|
||||
}
|
||||
if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
|
||||
warn("sysctl: %s", mibvar);
|
||||
free(buf);
|
||||
return (-2);
|
||||
}
|
||||
*bufp = buf;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp)
|
||||
{
|
||||
struct unp_head head;
|
||||
struct unpcb *unp, unp_conn;
|
||||
u_char sun_len;
|
||||
struct socket so;
|
||||
struct xunpgen xug;
|
||||
struct xunpcb xu;
|
||||
unp_gen_t unp_gencnt;
|
||||
u_int unp_count;
|
||||
char *buf, *p;
|
||||
size_t len;
|
||||
|
||||
if (count_off == 0 || gencnt_off == 0)
|
||||
return (-2);
|
||||
if (head_off == 0)
|
||||
return (-1);
|
||||
kread(count_off, &unp_count, sizeof(unp_count));
|
||||
len = 2 * sizeof(xug) + (unp_count + unp_count / 8) * sizeof(xu);
|
||||
if ((buf = malloc(len)) == 0) {
|
||||
warnx("malloc %lu bytes", (u_long)len);
|
||||
return (-2);
|
||||
}
|
||||
p = buf;
|
||||
|
||||
#define COPYOUT(obj, size) do { \
|
||||
if (len < (size)) { \
|
||||
warnx("buffer size exceeded"); \
|
||||
goto fail; \
|
||||
} \
|
||||
bcopy((obj), p, (size)); \
|
||||
len -= (size); \
|
||||
p += (size); \
|
||||
} while (0)
|
||||
|
||||
#define KREAD(off, buf, len) do { \
|
||||
if (kread((uintptr_t)(off), (buf), (len)) != 0) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
/* Write out header. */
|
||||
kread(gencnt_off, &unp_gencnt, sizeof(unp_gencnt));
|
||||
xug.xug_len = sizeof xug;
|
||||
xug.xug_count = unp_count;
|
||||
xug.xug_gen = unp_gencnt;
|
||||
xug.xug_sogen = 0;
|
||||
COPYOUT(&xug, sizeof xug);
|
||||
|
||||
/* Walk the PCB list. */
|
||||
xu.xu_len = sizeof xu;
|
||||
KREAD(head_off, &head, sizeof(head));
|
||||
LIST_FOREACH(unp, &head, unp_link) {
|
||||
xu.xu_unpp = unp;
|
||||
KREAD(unp, &xu.xu_unp, sizeof (*unp));
|
||||
unp = &xu.xu_unp;
|
||||
|
||||
if (unp->unp_gencnt > unp_gencnt)
|
||||
continue;
|
||||
if (unp->unp_addr != NULL) {
|
||||
KREAD(unp->unp_addr, &sun_len, sizeof(sun_len));
|
||||
KREAD(unp->unp_addr, &xu.xu_addr, sun_len);
|
||||
}
|
||||
if (unp->unp_conn != NULL) {
|
||||
KREAD(unp->unp_conn, &unp_conn, sizeof(unp_conn));
|
||||
if (unp_conn.unp_addr != NULL) {
|
||||
KREAD(unp_conn.unp_addr, &sun_len,
|
||||
sizeof(sun_len));
|
||||
KREAD(unp_conn.unp_addr, &xu.xu_caddr, sun_len);
|
||||
}
|
||||
}
|
||||
KREAD(unp->unp_socket, &so, sizeof(so));
|
||||
if (sotoxsocket(&so, &xu.xu_socket) != 0)
|
||||
goto fail;
|
||||
COPYOUT(&xu, sizeof(xu));
|
||||
}
|
||||
|
||||
/* Reread the counts and write the footer. */
|
||||
kread(count_off, &unp_count, sizeof(unp_count));
|
||||
kread(gencnt_off, &unp_gencnt, sizeof(unp_gencnt));
|
||||
xug.xug_count = unp_count;
|
||||
xug.xug_gen = unp_gencnt;
|
||||
COPYOUT(&xug, sizeof xug);
|
||||
|
||||
*bufp = buf;
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
free(buf);
|
||||
return (-1);
|
||||
#undef COPYOUT
|
||||
#undef KREAD
|
||||
}
|
||||
|
||||
void
|
||||
unixpr(u_long count_off, u_long gencnt_off, u_long dhead_off, u_long shead_off)
|
||||
{
|
||||
char *buf;
|
||||
int ret, type;
|
||||
struct xsocket *so;
|
||||
struct xunpgen *xug, *oxug;
|
||||
struct xunpcb *xunp;
|
||||
|
||||
for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) {
|
||||
if (live)
|
||||
ret = pcblist_sysctl(type, &buf);
|
||||
else
|
||||
ret = pcblist_kvm(count_off, gencnt_off,
|
||||
type == SOCK_STREAM ? shead_off :
|
||||
(type == SOCK_DGRAM ? dhead_off : 0), &buf);
|
||||
if (ret == -1)
|
||||
continue;
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
oxug = xug = (struct xunpgen *)buf;
|
||||
for (xug = (struct xunpgen *)((char *)xug + xug->xug_len);
|
||||
xug->xug_len > sizeof(struct xunpgen);
|
||||
xug = (struct xunpgen *)((char *)xug + xug->xug_len)) {
|
||||
xunp = (struct xunpcb *)xug;
|
||||
so = &xunp->xu_socket;
|
||||
|
||||
/* Ignore PCBs which were freed during copyout. */
|
||||
if (xunp->xu_unp.unp_gencnt > oxug->xug_gen)
|
||||
continue;
|
||||
unixdomainpr(xunp, so);
|
||||
}
|
||||
if (xug != oxug && xug->xug_gen != oxug->xug_gen) {
|
||||
if (oxug->xug_count > xug->xug_count) {
|
||||
printf("Some %s sockets may have been deleted.\n",
|
||||
socktype[type]);
|
||||
} else if (oxug->xug_count < xug->xug_count) {
|
||||
printf("Some %s sockets may have been created.\n",
|
||||
socktype[type]);
|
||||
} else {
|
||||
printf("Some %s sockets may have been created or deleted",
|
||||
socktype[type]);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
|
||||
{
|
||||
struct unpcb *unp;
|
||||
struct sockaddr_un *sa;
|
||||
static int first = 1;
|
||||
char buf1[15];
|
||||
|
||||
unp = &xunp->xu_unp;
|
||||
if (unp->unp_addr)
|
||||
sa = &xunp->xu_addr;
|
||||
else
|
||||
sa = (struct sockaddr_un *)0;
|
||||
|
||||
if (first && !Lflag) {
|
||||
printf("Active UNIX domain sockets\n");
|
||||
printf(
|
||||
"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
|
||||
"Address", "Type", "Recv-Q", "Send-Q",
|
||||
"Inode", "Conn", "Refs", "Nextref");
|
||||
first = 0;
|
||||
}
|
||||
|
||||
if (Lflag && so->so_qlimit == 0)
|
||||
return;
|
||||
|
||||
if (Lflag) {
|
||||
snprintf(buf1, 15, "%d/%d/%d", so->so_qlen,
|
||||
so->so_incqlen, so->so_qlimit);
|
||||
printf("unix %-14.14s", buf1);
|
||||
} else {
|
||||
printf("%8lx %-6.6s %6u %6u %8lx %8lx %8lx %8lx",
|
||||
(long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
|
||||
so->so_snd.sb_cc, (long)unp->unp_vnode, (long)unp->unp_conn,
|
||||
(long)LIST_FIRST(&unp->unp_refs),
|
||||
(long)LIST_NEXT(unp, unp_reflink));
|
||||
}
|
||||
if (sa)
|
||||
printf(" %.*s",
|
||||
(int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)),
|
||||
sa->sun_path);
|
||||
putchar('\n');
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user