Commit 93610c03 authored by Kevin Bracey's avatar Kevin Bracey
Browse files

New inetstat that uses sysctl instead of kvm_nread. Main visible difference is...

New inetstat that uses sysctl instead of kvm_nread. Main visible difference is that raw sockets are listed, and there is no danger of garbage being printed if a socket opens or closes while running.

New sysctl that handles Internet 5.31's new sysctl code. No longer has any
hard-coded knowledge of any sysctls.
parent 37a156ff
| Copyright 1999 Pace Micro Technology plc
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|
Dir <Obey$Dir>
amu_machine install INSTDIR=<Obey$Dir>
......@@ -29,6 +29,7 @@ If "%1" = "" Then Obey
dir %1
amu_machine %0
if "%0" = "clean" Then stripdepnd
up
| No new-line at the end of this command, please!
......
......@@ -40,47 +40,3 @@ clean:; ${RM} ${TARGET}
${WIPE} o.* ${WFLAGS}
# Dynamic dependencies:
o.ARP: c.ARP
o.ARP: TCPIPLibs:sys.h.param
o.ARP: TCPIPLibs:sys.h.types
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:machine.h.endian
o.ARP: TCPIPLibs:machine.h.ansi
o.ARP: TCPIPLibs:machine.h.types
o.ARP: TCPIPLibs:sys.h.syslimits
o.ARP: TCPIPLibs:sys.h.signal
o.ARP: TCPIPLibs:machine.h.signal
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:machine.h.param
o.ARP: TCPIPLibs:machine.h.limits
o.ARP: TCPIPLibs:sys.h.file
o.ARP: TCPIPLibs:sys.h.fcntl
o.ARP: TCPIPLibs:sys.h.types
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:sys.h.unistd
o.ARP: TCPIPLibs:sys.h.socket
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:sys.h.sysctl
o.ARP: TCPIPLibs:net.h.if
o.ARP: TCPIPLibs:sys.h.socket
o.ARP: TCPIPLibs:sys.h.time
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:net.h.if_arp
o.ARP: TCPIPLibs:sys.h.socket
o.ARP: TCPIPLibs:net.h.if_dl
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:net.h.if_types
o.ARP: TCPIPLibs:net.h.route
o.ARP: TCPIPLibs:net.h.radix
o.ARP: TCPIPLibs:netinet.h.in
o.ARP: TCPIPLibs:netinet.h.if_ether
o.ARP: TCPIPLibs:arpa.h.inet
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:h.netdb
o.ARP: TCPIPLibs:sys.h.cdefs
o.ARP: TCPIPLibs:sys.h.errno
o.ARP: C:h.kernel
o.ARP: TCPIPLibs:h.unixlib
o.ARP: TCPIPLibs:h.riscos
o.ARP: TCPIPLibs:h.nlist
o.ARP: TCPIPLibs:sys.h.cdefs
......@@ -74,6 +74,7 @@ static const char rcsid[] =
#include <stdlib.h>
#include <string.h>
#ifdef __riscos
#include <sys/errno.h>
#include <unixlib.h>
#else
#include <unistd.h>
......@@ -94,46 +95,76 @@ void inetprint(struct in_addr *, int, char *, int);
* -a (all) flag is specified.
*/
void
protopr(off, name)
u_long off;
protopr(proto, name)
u_long proto; /* for sysctl version we pass proto # */
char *name;
{
struct inpcbhead head;
register struct inpcb *prev, *next;
int istcp;
static int first = 1;
#ifdef __riscos
struct inpcb *inp = &inpcb; /* Transitional hack */
#endif
if (off == 0)
return;
istcp = strcmp(name, "tcp") == 0;
kread(off, (char *)&head, sizeof (struct inpcbhead));
prev = (struct inpcb *)off;
char *buf;
const char *mibvar;
struct tcpcb *tp;
struct inpcb *inp;
struct xinpgen *xig, *oxig;
struct xsocket *so;
size_t len;
for (next = head.lh_first; next != NULL; next = inpcb.inp_list.le_next) {
if (kread((u_long)next, (char *)&inpcb, sizeof (inpcb))) {
printf("???\n");
istcp = 0;
switch (proto) {
case IPPROTO_TCP:
istcp = 1;
mibvar = "net.inet.tcp.pcblist";
break;
case IPPROTO_UDP:
mibvar = "net.inet.udp.pcblist";
break;
case IPPROTO_DIVERT:
mibvar = "net.inet.divert.pcblist";
break;
default:
mibvar = "net.inet.raw.pcblist";
break;
}
if (!aflag &&
inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) {
prev = next;
continue;
len = 0;
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
if (errno != ENOENT)
warn("sysctl: %s", mibvar);
return;
}
if (kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb))) {
printf("???\n");
break;
};
if ((buf = malloc(len)) == 0) {
warn("malloc %lu bytes", (u_long)len);
return;
}
if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
warn("sysctl: %s", mibvar);
free(buf);
return;
}
oxig = xig = (struct xinpgen *)buf;
for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
xig->xig_len > sizeof(struct xinpgen);
xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
if (istcp) {
if (kread((u_long)inpcb.inp_ppcb,
(char *)&tcpcb, sizeof (tcpcb))) {
printf("???\n");
break;
};
tp = &((struct xtcpcb *)xig)->xt_tp;
inp = &((struct xtcpcb *)xig)->xt_inp;
so = &((struct xtcpcb *)xig)->xt_socket;
} else {
inp = &((struct xinpcb *)xig)->xi_inp;
so = &((struct xinpcb *)xig)->xi_socket;
}
/* Ignore sockets for protocols other than the desired one. */
if (so->xso_protocol != proto)
continue;
/* Ignore PCBs which were freed during copyout. */
if (inp->inp_gencnt > oxig->xig_gen)
continue;
if (!aflag && inet_lnaof(inp->inp_laddr) == INADDR_ANY)
continue;
if (first) {
printf("Active Internet connections");
if (aflag)
......@@ -150,12 +181,12 @@ protopr(off, name)
}
if (Aflag) {
if (istcp)
printf("%8lx ", (u_long)inpcb.inp_ppcb);
printf("%8lx ", (u_long)inp->inp_ppcb);
else
printf("%8lx ", (u_long)next);
printf("%8lx ", (u_long)so->so_pcb);
}
printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
sockb.so_snd.sb_cc);
printf("%-5.5s %6ld %6ld ", name, so->so_rcv.sb_cc,
so->so_snd.sb_cc);
if (nflag) {
inetprint(&inp->inp_laddr, (int)inp->inp_lport,
name, 1);
......@@ -173,20 +204,32 @@ protopr(off, name)
name, inp->inp_lport != inp->inp_fport);
}
if (istcp) {
if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
printf(" %d", tcpcb.t_state);
if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
printf(" %d", tp->t_state);
else {
printf(" %s", tcpstates[tcpcb.t_state]);
printf(" %s", tcpstates[tp->t_state]);
#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
/* Show T/TCP `hidden state' */
if (tcpcb.t_flags & (TF_NEEDSYN|TF_NEEDFIN))
if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
putchar('*');
#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
}
}
putchar('\n');
prev = next;
}
if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
if (oxig->xig_count > xig->xig_count) {
printf("Some %s sockets may have been deleted.\n",
name);
} else if (oxig->xig_count < xig->xig_count) {
printf("Some %s sockets may have been created.\n",
name);
} else {
printf("Some %s sockets may have been created or deleted",
name);
}
}
free(buf);
}
/*
......@@ -198,11 +241,14 @@ tcp_stats(off, name)
char *name;
{
struct tcpstat tcpstat;
size_t len = sizeof tcpstat;
if (off == 0)
if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 0, 0) < 0) {
warn("sysctl: net.inet.tcp.stats");
return;
}
printf ("%s:\n", name);
kread(off, (char *)&tcpstat, sizeof (tcpstat));
#define p(f, m) if (tcpstat.f || sflag <= 1) \
printf(m, tcpstat.f, plural(tcpstat.f))
......@@ -288,11 +334,14 @@ udp_stats(off, name)
char *name;
{
struct udpstat udpstat;
size_t len = sizeof udpstat;
u_long delivered;
if (off == 0)
if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 0, 0) < 0) {
warn("sysctl: net.inet.udp.stats");
return;
kread(off, (char *)&udpstat, sizeof (udpstat));
}
printf("%s:\n", name);
#define p(f, m) if (udpstat.f || sflag <= 1) \
printf(m, udpstat.f, plural(udpstat.f))
......@@ -332,10 +381,13 @@ ip_stats(off, name)
char *name;
{
struct ipstat ipstat;
size_t len = sizeof ipstat;
if (off == 0)
if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, 0, 0) < 0) {
warn("sysctl: net.inet.ip.stats");
return;
kread(off, (char *)&ipstat, sizeof (ipstat));
}
printf("%s:\n", name);
#define p(f, m) if (ipstat.f || sflag <= 1) \
......@@ -480,10 +532,13 @@ igmp_stats(off, name)
char *name;
{
struct igmpstat igmpstat;
size_t len = sizeof igmpstat;
if (off == 0)
if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 0, 0) < 0) {
warn("sysctl: net.inet.igmp.stats");
return;
kread(off, (char *)&igmpstat, sizeof (igmpstat));
}
printf("%s:\n", name);
#define p(f, m) if (igmpstat.f || sflag <= 1) \
......
......@@ -140,17 +140,18 @@ struct protox {
void (*pr_cblocks)(); /* control blocks printing routine */
void (*pr_stats)(); /* statistics printing routine */
char *pr_name; /* well-known name */
int pr_usesysctl; /* true if we use sysctl, not kvm */
} protox[] = {
{ N_TCB, N_TCPSTAT, 1, protopr,
tcp_stats, "tcp" },
tcp_stats, "tcp", IPPROTO_TCP },
{ N_UDB, N_UDPSTAT, 1, protopr,
udp_stats, "udp" },
{ -1, N_IPSTAT, 1, 0,
ip_stats, "ip" },
{ -1, N_ICMPSTAT, 1, 0,
icmp_stats, "icmp" },
{ -1, N_IGMPSTAT, 1, 0,
igmp_stats, "igmp" },
udp_stats, "udp", IPPROTO_UDP },
{ -1, N_IPSTAT, 1, protopr,
ip_stats, "ip", IPPROTO_RAW },
{ -1, N_ICMPSTAT, 1, protopr,
icmp_stats, "icmp", IPPROTO_ICMP },
{ -1, N_IGMPSTAT, 1, protopr,
igmp_stats, "igmp", IPPROTO_IGMP },
{ -1, -1, 0, 0,
0, 0 }
};
......@@ -351,11 +352,17 @@ main(argc, argv)
}
#endif
if (pflag) {
if (tp->pr_stats)
if (!tp->pr_stats) {
printf("%s: no stats routine\n", tp->pr_name);
exit(0);
}
if (tp->pr_usesysctl) {
(*tp->pr_stats)(tp->pr_usesysctl, tp->pr_name);
} else {
kread(0, 0, 0);
(*tp->pr_stats)(nl[tp->pr_sindex].n_value,
tp->pr_name);
else
printf("%s: no stats routine\n", tp->pr_name);
}
exit(0);
}
/*
......@@ -427,10 +434,12 @@ printproto(tp, name)
if (sflag) {
pr = tp->pr_stats;
off = nl[tp->pr_sindex].n_value;
off = tp->pr_usesysctl ? tp->pr_usesysctl
: nl[tp->pr_sindex].n_value;
} else {
pr = tp->pr_cblocks;
off = nl[tp->pr_index].n_value;
off = tp->pr_usesysctl ? tp->pr_usesysctl
: nl[tp->pr_index].n_value;
}
if (pr != NULL && (off || af != AF_UNSPEC))
(*pr)(off, name);
......
......@@ -39,6 +39,3 @@ clean:; ${RM} ${TARGET}
${WIPE} o.* ${WFLAGS}
# Dynamic dependencies:
o.NewFiler: c.NewFiler
o.NewFiler: C:h.kernel
o.NewFiler: C:h.swis
......@@ -40,52 +40,3 @@ clean:; ${RM} ${TARGET}
${WIPE} o.* ${WFLAGS}
# Dynamic dependencies:
o.Ping: c.Ping
o.Ping: TCPIPLibs:sys.h.param
o.Ping: TCPIPLibs:sys.h.types
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:machine.h.endian
o.Ping: TCPIPLibs:machine.h.ansi
o.Ping: TCPIPLibs:machine.h.types
o.Ping: TCPIPLibs:sys.h.syslimits
o.Ping: TCPIPLibs:sys.h.signal
o.Ping: TCPIPLibs:machine.h.signal
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:machine.h.param
o.Ping: TCPIPLibs:machine.h.limits
o.Ping: TCPIPLibs:sys.h.socket
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:sys.h.file
o.Ping: TCPIPLibs:sys.h.fcntl
o.Ping: TCPIPLibs:sys.h.types
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:sys.h.unistd
o.Ping: TCPIPLibs:sys.h.time
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:sys.h.signal
o.Ping: TCPIPLibs:sys.h.ioctl
o.Ping: TCPIPLibs:sys.h.ttycom
o.Ping: TCPIPLibs:sys.h.ioccom
o.Ping: TCPIPLibs:sys.h.ioccom
o.Ping: TCPIPLibs:sys.h.filio
o.Ping: TCPIPLibs:sys.h.ioccom
o.Ping: TCPIPLibs:sys.h.sockio
o.Ping: TCPIPLibs:sys.h.ioccom
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:netinet.h.in_systm
o.Ping: TCPIPLibs:netinet.h.in
o.Ping: TCPIPLibs:netinet.h.ip
o.Ping: TCPIPLibs:netinet.h.ip_icmp
o.Ping: TCPIPLibs:netinet.h.ip_var
o.Ping: TCPIPLibs:arpa.h.inet
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:h.netdb
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:h.unistd
o.Ping: TCPIPLibs:sys.h.cdefs
o.Ping: TCPIPLibs:sys.h.types
o.Ping: TCPIPLibs:sys.h.unistd
o.Ping: TCPIPLibs:sys.h.errno
o.Ping: C:h.kernel
o.Ping: TCPIPLibs:h.riscos
o.Ping: TCPIPLibs:h.unixlib
......@@ -107,8 +107,9 @@ typedef union sockunion *sup;
int pid, rtm_addrs, uid;
int s = -1;
int forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword();
int errvarflag;
int iflag, verbose, aflen = sizeof (struct sockaddr_in);
int locking, lockrest, debugonly, errvarflag;
int locking, lockrest, debugonly;
struct rt_metrics rt_metrics;
u_long rtm_inits;
struct in_addr inet_makeaddr();
......@@ -172,6 +173,7 @@ main(argc, argv)
switch(ch) {
case 'e':
errvarflag = 1;
err_set_silent(1);
break;
case 'n':
nflag = 1;
......@@ -684,36 +686,6 @@ newroute(argc, argv)
gateway = *argv;
(void) getaddr(RTA_GATEWAY, *argv, &hp);
} else {
int ret = atoi(*argv);
if (ret == 0) {
if (strcmp(*argv, "0") == 0)
#ifdef __riscos
{
if (!errvarflag)
#endif
printf("%s,%s",
"old usage of trailing 0",
"assuming route to if\n");
#ifdef __riscos
}
#endif
else
printhelp();
iflag = 1;
continue;
} else if (ret > 0 && ret < 10) {
#ifdef __riscos
if (!errvarflag) {
#endif
printf("old usage of trailing digit, ");
printf("assuming route via gateway\n");
#ifdef __riscos
}
#endif
iflag = 0;
continue;
}
(void) getaddr(RTA_NETMASK, *argv, 0);
}
}
......
......@@ -43,56 +43,3 @@ PathConf: PathConf.o
Link -o $@ PathConf.o ${LIBS}
# Dynamic dependencies:
o.PathConf: c.PathConf
o.PathConf: TCPIPLibs:sys.h.param
o.PathConf: TCPIPLibs:sys.h.types
o.PathConf: TCPIPLibs:sys.h.cdefs
o.PathConf: TCPIPLibs:machine.h.endian
o.PathConf: TCPIPLibs:machine.h.ansi
o.PathConf: TCPIPLibs:machine.h.types
o.PathConf: TCPIPLibs:sys.h.syslimits
o.PathConf: TCPIPLibs:sys.h.signal
o.PathConf: TCPIPLibs:machine.h.signal
o.PathConf: TCPIPLibs:sys.h.cdefs
o.PathConf: TCPIPLibs:machine.h.param
o.PathConf: TCPIPLibs:machine.h.limits
o.PathConf: TCPIPLibs:sys.h.sysctl
o.PathConf: TCPIPLibs:sys.h.unistd
o.PathConf: TCPIPLibs:sys.h.errno
o.PathConf: C:h.kernel
o.SysCtl: c.SysCtl
o.SysCtl: TCPIPLibs:sys.h.param
o.SysCtl: TCPIPLibs:sys.h.types
o.SysCtl: TCPIPLibs:sys.h.cdefs
o.SysCtl: TCPIPLibs:machine.h.endian
o.SysCtl: TCPIPLibs:machine.h.ansi
o.SysCtl: TCPIPLibs:machine.h.types
o.SysCtl: TCPIPLibs:sys.h.syslimits
o.SysCtl: TCPIPLibs:sys.h.signal
o.SysCtl: TCPIPLibs:machine.h.signal
o.SysCtl: TCPIPLibs:sys.h.cdefs
o.SysCtl: TCPIPLibs:machine.h.param
o.SysCtl: TCPIPLibs:machine.h.limits
o.SysCtl: TCPIPLibs:sys.h.stat
o.SysCtl: TCPIPLibs:sys.h.time
o.SysCtl: TCPIPLibs:sys.h.cdefs
o.SysCtl: TCPIPLibs:sys.h.cdefs
o.SysCtl: TCPIPLibs:sys.h.sysctl
o.SysCtl: TCPIPLibs:sys.h.socket
o.SysCtl: TCPIPLibs:sys.h.cdefs
o.SysCtl: TCPIPLibs:netinet.h.in
o.SysCtl: TCPIPLibs:netinet.h.in_systm
o.SysCtl: TCPIPLibs:netinet.h.ip
o.SysCtl: TCPIPLibs:netinet.h.ip_icmp
o.SysCtl: TCPIPLibs:netinet.h.icmp_var
o.SysCtl: TCPIPLibs:netinet.h.ip_var
o.SysCtl: TCPIPLibs:netinet.h.udp
o.SysCtl: TCPIPLibs:netinet.h.udp_var
o.SysCtl: TCPIPLibs:netinet.h.tcp
o.SysCtl: TCPIPLibs:netinet.h.tcp_seq
o.SysCtl: TCPIPLibs:netinet.h.tcp_timer
o.SysCtl: TCPIPLibs:netinet.h.tcp_var
o.SysCtl: TCPIPLibs:netinet.h.igmp_var
o.SysCtl: TCPIPLibs:sys.h.errno
o.SysCtl: C:h.kernel
o.SysCtl: TCPIPLibs:h.riscos
This diff is collapsed.
......@@ -40,63 +40,82 @@
.Nd get or set kernel state
.Sh SYNOPSIS
.Nm sysctl
.Op Fl n
.Op Fl bdn
.Ar name ...
.Nm sysctl
.Op Fl n
.Op Fl bn
.Fl w
.Ar name=value ...
.Nm sysctl
.Op Fl n
.Fl aA
.Op Fl bdn
.Fl aAX
.Sh DESCRIPTION
The
.Nm sysctl
.Nm
utility retrieves kernel state and allows processes with
appropriate privilege to set kernel state.
The state to be retrieved or set is described using a
``Management Information Base'' (``MIB'') style name,
described as a dotted set of components.
The
.Fl a
flag can be used to list all the currently available string or integer values.
The
.Fl A
flag will list all the known MIB names including tables.
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl a
List all the currently available string or integer values.
.It Fl A
List all the known MIB names including opaques.
Those with string or integer values will be printed as with the
.Fl a
flag; for the table values,
the name of the utility to retrieve them is given.
.Pp
The
.Fl n
flag specifies that the printing of the field name should be
flag; for the opaque values,
information about the format and the length is printed in addition the first
few bytes is dumped in hex.
.It Fl X
Same as
.Fl A
except the entire value of opaque variables is hexdumped.
.It Fl n
Specify that the printing of the field name should be
suppressed and that only its value should be output.
This flag is useful for setting shell variables.
For example, to save the pagesize in variable psize, use:
.Bd -literal -offset indent -compact
set psize=`sysctl -n hw.pagesize`
.Ed
.Pp
If just a MIB style name is given,
.It Fl b
Force the value of the variable(s) to be output in raw, binary
format. No names are printed and no terminating newlines are output.
This is mostly useful with a single variable.
.It Fl d
Display the description rather than the value of the requested
variable(s).
.It Fl w Ar name=value ...
Set the MIB
.Ar name
to the new
.Ar value .
If just a MIB style