Import pppstats from the ppp-2.2 package onto vendor branch.

This commit is contained in:
Peter Wemm 1995-10-31 21:35:36 +00:00
parent 945f93070b
commit 4599db98a6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MACKERAS/; revision=11985
3 changed files with 345 additions and 414 deletions

View File

@ -1,12 +1,10 @@
# $Id: Makefile.bsd,v 1.2 1994/04/25 06:48:25 paulus Exp $
# $Id: Makefile.bsd,v 1.4 1995/04/28 06:23:18 paulus Exp $
PROG= pppstats
SRCS= pppstats.c
MAN8= pppstats.8
LDADD= -lutil -lkvm
BINMODE=2555
BINGRP= kmem
CFLAGS+=-I..
MAN8= pppstats.0
MAN= pppstats.cat8
BINDIR= /usr/sbin
.include <bsd.prog.mk>

View File

@ -1,131 +1,54 @@
.\" Modified from slstat.8 by Lars Fredriksen
.\"
.\" Copyright (c) 1986 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.
.\"
.\" @(#)pppstats.8 6.8 (Berkeley) 6/20/91
.\"
.TH PPPSTATS 1 "November 09, 1994"
.UC 4
.\" @(#) $Id: pppstats.8,v 1.2 1995/05/02 05:50:53 paulus Exp $
.TH PPPSTATS 8 "2 May 1995"
.SH NAME
pppstats \- report Point to Point Protocol statistics
pppstats \- print PPP statistics
.SH SYNOPSIS
.nf
.ft B
pppstats [ \-i interval ] [ \-v ] [ unit ] [ system ] [ core ]
.ft R
.fi
.B pppstats
[
.B -v
] [
.B -r
] [
.B -c
] [
.B -i
.I <secs>
] [
.I <unit#>
]
.ti 12
.SH DESCRIPTION
.I Pppstats
reports certain kernel statistics kept about Point to Point
Protocol traffic.
.B pppstats
prints PPP-related statistics.
.PP
The options are as follows:
.TP
\-i
Repeat the display indefinitely every
.I interval
seconds.
If no
.I interval
is specified, the default is 5 seconds.
.TP
\-v
Verbose display of extra fields of information.
.TP
unit
is a single digit specifying the slip interface. The default unit is
.I 0
for interface
.I ppp0.
.TP
system
Extract the name list from the specified system instead of the default, /kernel.
.TP
core
Extract values associated with the name list from the specified
core instead of the default, /dev/kmem.
The
.B -v
flag causes
.B pppstats
to display additional statistics, such as the number of packets tossed
(that is, which the VJ TCP header decompression code rejected).
.PP
By default,
.I pppstats
displays the following information:
The
.B -r
flag causes
.B pppstats
to display the overall packet compression rate. The rate value is
between 0 and 1, with 0 meaning that the data is incompressible.
.PP
.TP
in
bytes received
.TP
out
bytes sent
.TP
pack
packets received or sent
.TP
comp
compressed packets received or sent
.TP
uncomp
uncompressed packets received or sent
.TP
err
input or output errors
The
.B -c
flag is used to specify an alternate display mode that shows
packet compression statistics: the number of packets and bytes
uncompressed (that is, before compression or after decompression),
compressed, and incompressible (packets which did not shrink on
compression and were transmitted uncompressed), and the recent
compression rate. This rate reflects the recent performance of the
compression code rather than the overall rate achieved since
compression was enabled.
.PP
With the \-v option, the following information is also displayed:
.TP
toss
inbound packets tossed because of error
.TP
search
searches for connection state
.TP
miss
times we could not find a connectoin state
.SH EXAMPLES
The command ``pppstats -i 5'' will print what the system is doing every five
seconds.
.SH FILES
.ta \w'/dev/kmem 'u
/kernel default kernel namelist
.br
/dev/kmem default memory file
.SH SEE ALSO
.IR fstat (1),
.IR netstat (1),
.IR nfsstat (1),
.IR ps (1),
.IR systat (1),
.IR iostat (8),
.IR pstat (8)
.IR slstat (8)
.sp
The sections starting with ``Interpreting system activity'' in
.IR "Installing and Operating 4.3BSD" .
.SH BUGS
The
.B -i
flag is used to specify the interval between printouts. The default is
5 seconds.
.PP
<unit#> specifies which interface to use for gathering statistics.

View File

@ -1,7 +1,18 @@
/*
* print PPP statistics:
* pppstats [-i interval] [-v] [interface] [system] [core]
* pppstats [-i interval] [-v] [-r] [-c] [interface]
*
* -i <update interval in seconds>
* -v Verbose mode for default display
* -r Show compression ratio in default display
* -c Show Compression statistics instead of default display
* -a Do not show relative values. Show absolute values at all times.
*
*
* History:
* perkins@cps.msu.edu: Added compression statistics and alternate
* display. 11/94
* Brad Parker (brad@cayman.com) 6/92
*
* from the original "slstats" by Van Jaconson
@ -26,234 +37,123 @@
*/
#ifndef lint
static char rcsid[] = "$Id: pppstats.c,v 1.4 1994/06/08 00:38:49 paulus Exp $";
static char rcsid[] = "$Id: pppstats.c,v 1.11 1995/07/11 06:41:45 paulus Exp $";
#endif
#include <ctype.h>
#include <errno.h>
#include <nlist.h>
#include <stdio.h>
#include <limits.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <sys/ioctl.h>
#define VJC 1
#include <net/slcompress.h>
#include <net/ppp_defs.h>
#ifdef __svr4__
#include <sys/stropts.h>
#include <net/pppio.h> /* SVR4, Solaris 2, etc. */
#else
#include <sys/socket.h>
#include <net/if.h>
#ifndef STREAMS
#include <net/if_ppp.h>
#endif
#include <net/if_ppp.h> /* BSD, Linux, NeXT, etc. */
#ifdef STREAMS
#else /* SunOS 4, AIX 4, OSF/1, etc. */
#define PPP_STATS 1 /* should be defined iff it is in ppp_if.c */
#include <sys/stream.h>
#include <net/ppp_str.h>
#endif
#ifdef BSD4_4
#define KVMLIB
#endif
#ifndef KVMLIB
#include <machine/pte.h>
#ifdef ultrix
#include <machine/cpu.h>
#endif
struct pte *Sysmap;
int kmem;
char *kmemf = "/dev/kmem";
extern off_t lseek();
#else /* KVMLIB */
char *kmemf;
#if defined(sun) || defined(__FreeBSD__)
#include <kvm.h>
kvm_t *kd;
#define KDARG kd,
#else /* sun */
#define KDARG
#endif /* sun */
#endif /* KVMLIB */
#ifdef STREAMS
struct nlist nl[] = {
#define N_SOFTC 0
{ "_pii" },
"",
};
#else
struct nlist nl[] = {
#define N_SOFTC 0
{ "_ppp_softc" },
"",
};
#endif
#ifndef BSD4_4
char *system = "/vmunix";
#else
#include <paths.h>
#if defined(__FreeBSD__)
/* _PATH_UNIX is defined as "Do not use _PATH_UNIX" */
char *system = NULL;
#else
char *system = _PATH_UNIX;
#endif
#endif
int kflag;
int vflag;
int vflag, rflag, cflag, aflag;
unsigned interval = 5;
int unit;
int s; /* socket file descriptor */
int signalled; /* set if alarm goes off "early" */
extern char *malloc();
void catchalarm __P((int));
main(argc, argv)
int argc;
char *argv[];
int argc;
char *argv[];
{
--argc; ++argv;
while (argc > 0) {
if (strcmp(argv[0], "-a") == 0) {
++aflag;
++argv, --argc;
continue;
}
if (strcmp(argv[0], "-v") == 0) {
++vflag;
++argv, --argc;
continue;
}
if (strcmp(argv[0], "-r") == 0) {
++rflag;
++argv, --argc;
continue;
}
if (strcmp(argv[0], "-c") == 0) {
++cflag;
++argv, --argc;
continue;
}
if (strcmp(argv[0], "-i") == 0 && argv[1] &&
isdigit(argv[1][0])) {
interval = atoi(argv[1]);
if (interval < 0)
usage();
++argv, --argc;
++argv, --argc;
continue;
}
if (isdigit(argv[0][0])) {
unit = atoi(argv[0]);
if (unit < 0)
usage();
++argv, --argc;
continue;
}
usage();
}
char errbuf[_POSIX2_LINE_MAX];
--argc; ++argv;
while (argc > 0) {
if (strcmp(argv[0], "-v") == 0) {
++vflag;
++argv, --argc;
continue;
}
if (strcmp(argv[0], "-i") == 0 && argv[1] &&
isdigit(argv[1][0])) {
interval = atoi(argv[1]);
if (interval <= 0)
usage();
++argv, --argc;
++argv, --argc;
continue;
}
if (isdigit(argv[0][0])) {
unit = atoi(argv[0]);
if (unit < 0)
usage();
++argv, --argc;
continue;
}
if (kflag)
usage();
system = *argv;
++argv, --argc;
if (argc > 0) {
kmemf = *argv++;
--argc;
kflag++;
}
}
#ifndef KVMLIB
if (nlist(system, nl) < 0 || nl[0].n_type == 0) {
fprintf(stderr, "%s: no namelist\n", system);
exit(1);
}
kmem = open(kmemf, O_RDONLY);
if (kmem < 0) {
perror(kmemf);
exit(1);
}
#ifndef ultrix
if (kflag) {
off_t off;
Sysmap = (struct pte *)
malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
if (!Sysmap) {
fputs("pppstats: can't get memory for Sysmap.\n", stderr);
exit(1);
}
off = nl[N_SYSMAP].n_value & ~KERNBASE;
(void)lseek(kmem, off, L_SET);
(void)read(kmem, (char *)Sysmap,
(int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
}
#endif
#ifdef __svr4__
if ((s = open("/dev/ppp", O_RDONLY)) < 0) {
perror("pppstats: Couldn't open /dev/ppp: ");
exit(1);
}
if (strioctl(s, PPPIO_ATTACH, &unit, sizeof(int), 0) < 0) {
fprintf(stderr, "pppstats: ppp%d is not available\n", unit);
exit(1);
}
#else
#if defined(sun)
/* SunOS */
if ((kd = kvm_open(system, kmemf, (char *)0, O_RDONLY, NULL)) == NULL) {
perror("kvm_open");
exit(1);
}
#else
/* BSD4.3+ */
if ((kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, errbuf)) == NULL) {
fprintf(stderr, "kvm_openfiles: %s", errbuf);
exit(1);
}
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("couldn't create IP socket");
exit(1);
}
#endif
if (kvm_nlist(KDARG nl)) {
fprintf(stderr, "pppstats: can't find symbols in nlist\n");
exit(1);
}
#endif
intpr();
exit(0);
intpr();
exit(0);
}
#ifndef KVMLIB
/*
* Seek into the kernel for a value.
*/
off_t
klseek(fd, base, off)
int fd, off;
off_t base;
{
if (kflag) {
#ifdef ultrix
base = K0_TO_PHYS(base);
#else
/* get kernel pte */
base &= ~KERNBASE;
base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
#endif
}
return (lseek(fd, base, off));
}
#endif
usage()
{
fprintf(stderr,"usage: pppstats [-i interval] [-v] [unit] [system] [core]\n");
exit(1);
fprintf(stderr, "Usage: pppstats [-v] [-r] [-c] [-i interval] [unit]\n");
exit(1);
}
u_char signalled; /* set if alarm goes off "early" */
#define V(offset) (line % 20? cur.offset - old.offset: cur.offset)
#define W(offset) (line % 20? ccs.offset - ocs.offset: ccs.offset)
#define V(offset) ((line % 20)? sc->offset - osc->offset : sc->offset)
#ifdef STREAMS
#define STRUCT struct ppp_if_info
#define COMP pii_sc_comp
#define STATS pii_ifnet
#else
#define STRUCT struct ppp_softc
#define COMP sc_comp
#define STATS sc_if
#endif
#define CRATE(comp, inc, unc) ((unc) == 0? 0.0: \
1.0 - (double)((comp) + (inc)) / (unc))
/*
* Print a running summary of interface statistics.
@ -263,115 +163,123 @@ u_char signalled; /* set if alarm goes off "early" */
*/
intpr()
{
register int line = 0;
int oldmask;
#ifdef __STDC__
void catchalarm(int);
#else
void catchalarm();
#endif
register int line = 0;
sigset_t oldmask, mask;
struct ppp_stats cur, old;
struct ppp_comp_stats ccs, ocs;
STRUCT *sc, *osc;
memset(&old, 0, sizeof(old));
memset(&ocs, 0, sizeof(ocs));
nl[N_SOFTC].n_value += unit * sizeof(STRUCT);
sc = (STRUCT *)malloc(sizeof(STRUCT));
osc = (STRUCT *)malloc(sizeof(STRUCT));
while (1) {
get_ppp_stats(&cur);
if (cflag || rflag)
get_ppp_cstats(&ccs);
bzero((char *)osc, sizeof(STRUCT));
(void)signal(SIGALRM, catchalarm);
signalled = 0;
(void)alarm(interval);
if ((line % 20) == 0) {
if (line > 0)
putchar('\n');
if (cflag) {
printf("%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
"ubyte", "upack", "cbyte", "cpack", "ibyte", "ipack", "ratio");
printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
"ubyte", "upack", "cbyte", "cpack", "ibyte", "ipack", "ratio");
putchar('\n');
} else {
while (1) {
#ifndef KVMLIB
if (klseek(kmem, (off_t)nl[N_SOFTC].n_value, 0) == -1) {
perror("kmem seek");
exit(1);
}
if (read(kmem, (char *)sc, sizeof(STRUCT)) <= 0) {
perror("kmem read");
exit(1);
}
#else
if (kvm_read(KDARG nl[N_SOFTC].n_value, sc,
sizeof(STRUCT)) != sizeof(STRUCT)) {
perror("kvm_read");
exit(1);
}
#endif
(void)signal(SIGALRM, catchalarm);
signalled = 0;
(void)alarm(interval);
if ((line % 20) == 0) {
printf("%6.6s %6.6s %6.6s %6.6s %6.6s",
"in", "pack", "comp", "uncomp", "err");
if (vflag)
printf(" %6.6s %6.6s", "toss", "ip");
printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s",
if (rflag)
printf(" %6.6s %6.6s", "ratio", "ubyte");
printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s",
"out", "pack", "comp", "uncomp", "ip");
if (vflag)
printf(" %6.6s %6.6s", "search", "miss");
if(rflag)
printf(" %6.6s %6.6s", "ratio", "ubyte");
putchar('\n');
}
memset(&old, 0, sizeof(old));
memset(&ocs, 0, sizeof(ocs));
}
if (cflag) {
printf("%6d %6d %6d %6d %6d %6d %6.2f",
W(d.unc_bytes),
W(d.unc_packets),
W(d.comp_bytes),
W(d.comp_packets),
W(d.inc_bytes),
W(d.inc_packets),
W(d.ratio) == 0? 0.0: 1 - 1.0 / W(d.ratio) * 256.0);
printf(" | %6d %6d %6d %6d %6d %6d %6.2f",
W(c.unc_bytes),
W(c.unc_packets),
W(c.comp_bytes),
W(c.comp_packets),
W(c.inc_bytes),
W(c.inc_packets),
W(d.ratio) == 0? 0.0: 1 - 1.0 / W(d.ratio) * 256.0);
putchar('\n');
} else {
printf("%6d %6d %6d %6d %6d",
#ifdef BSD4_4
V(STATS.if_ibytes),
#else
#ifndef STREAMS
V(sc_bytesrcvd),
#else
#ifdef PPP_STATS
V(pii_stats.ppp_ibytes),
#else
0,
#endif
#endif
#endif
V(STATS.if_ipackets),
V(COMP.sls_compressedin),
V(COMP.sls_uncompressedin),
V(COMP.sls_errorin));
V(p.ppp_ibytes),
V(p.ppp_ipackets), V(vj.vjs_compressedin),
V(vj.vjs_uncompressedin), V(vj.vjs_errorin));
if (vflag)
printf(" %6d %6d",
V(COMP.sls_tossed),
V(STATS.if_ipackets) - V(COMP.sls_compressedin) -
V(COMP.sls_uncompressedin) - V(COMP.sls_errorin));
printf(" | %6d %6d %6d %6d %6d",
#ifdef BSD4_4
V(STATS.if_obytes),
#else
#ifndef STREAMS
V(sc_bytessent),
#else
#ifdef PPP_STATS
V(pii_stats.ppp_obytes),
#else
0,
#endif
#endif
#endif
V(STATS.if_opackets),
V(COMP.sls_compressed),
V(COMP.sls_packets) - V(COMP.sls_compressed),
V(STATS.if_opackets) - V(COMP.sls_packets));
printf(" %6d %6d", V(vj.vjs_tossed),
V(p.ppp_ipackets) - V(vj.vjs_compressedin) -
V(vj.vjs_uncompressedin) - V(vj.vjs_errorin));
if (rflag)
printf(" %6.2f %6d",
CRATE(W(d.comp_bytes), W(d.unc_bytes), W(d.unc_bytes)),
W(d.unc_bytes));
printf(" | %6d %6d %6d %6d %6d", V(p.ppp_obytes),
V(p.ppp_opackets), V(vj.vjs_compressed),
V(vj.vjs_packets) - V(vj.vjs_compressed),
V(p.ppp_opackets) - V(vj.vjs_packets));
if (vflag)
printf(" %6d %6d",
V(COMP.sls_searches),
V(COMP.sls_misses));
printf(" %6d %6d", V(vj.vjs_searches), V(vj.vjs_misses));
if (rflag)
printf(" %6.2f %6d",
CRATE(W(d.comp_bytes), W(d.unc_bytes), W(d.unc_bytes)),
W(c.unc_bytes));
putchar('\n');
fflush(stdout);
line++;
oldmask = sigblock(sigmask(SIGALRM));
if (! signalled) {
sigpause(0);
}
sigsetmask(oldmask);
signalled = 0;
(void)alarm(interval);
bcopy((char *)sc, (char *)osc, sizeof(STRUCT));
}
fflush(stdout);
line++;
if (interval == 0)
exit(0);
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
sigprocmask(SIG_BLOCK, &mask, &oldmask);
if (! signalled) {
sigemptyset(&mask);
sigsuspend(&mask);
}
sigprocmask(SIG_SETMASK, &oldmask, NULL);
signalled = 0;
(void)alarm(interval);
if (aflag==0) {
old = cur;
ocs = ccs;
}
}
}
/*
@ -379,7 +287,109 @@ intpr()
* Sets a flag to not wait for the alarm.
*/
void catchalarm(arg)
int arg;
int arg;
{
signalled = 1;
signalled = 1;
}
#ifndef __svr4__
get_ppp_stats(curp)
struct ppp_stats *curp;
{
struct ifpppstatsreq req;
memset (&req, 0, sizeof (req));
#ifdef _linux_
req.stats_ptr = (caddr_t) &req.stats;
#undef ifr_name
#define ifr_name ifr__name
#endif
sprintf(req.ifr_name, "ppp%d", unit);
if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
if (errno == ENOTTY)
fprintf(stderr, "pppstats: kernel support missing\n");
else
perror("ioctl(SIOCGPPPSTATS)");
exit(1);
}
*curp = req.stats;
}
get_ppp_cstats(csp)
struct ppp_comp_stats *csp;
{
struct ifpppcstatsreq creq;
memset (&creq, 0, sizeof (creq));
#ifdef _linux_
creq.stats_ptr = (caddr_t) &creq.stats;
#undef ifr_name
#define ifr_name ifr__name
#endif
sprintf(creq.ifr_name, "ppp%d", unit);
if (ioctl(s, SIOCGPPPCSTATS, &creq) < 0) {
if (errno == ENOTTY) {
fprintf(stderr, "pppstats: no kernel compression support\n");
if (cflag)
exit(1);
rflag = 0;
} else {
perror("ioctl(SIOCGPPPCSTATS)");
exit(1);
}
}
*csp = creq.stats;
}
#else /* __svr4__ */
get_ppp_stats(curp)
struct ppp_stats *curp;
{
if (strioctl(s, PPPIO_GETSTAT, curp, 0, sizeof(*curp)) < 0) {
if (errno == EINVAL)
fprintf(stderr, "pppstats: kernel support missing\n");
else
perror("pppstats: Couldn't get statistics");
exit(1);
}
}
get_ppp_cstats(csp)
struct ppp_comp_stats *csp;
{
if (strioctl(s, PPPIO_GETCSTAT, csp, 0, sizeof(*csp)) < 0) {
if (errno == ENOTTY) {
fprintf(stderr, "pppstats: no kernel compression support\n");
if (cflag)
exit(1);
rflag = 0;
} else {
perror("pppstats: Couldn't get compression statistics");
exit(1);
}
}
}
int
strioctl(fd, cmd, ptr, ilen, olen)
int fd, cmd, ilen, olen;
char *ptr;
{
struct strioctl str;
str.ic_cmd = cmd;
str.ic_timout = 0;
str.ic_len = ilen;
str.ic_dp = ptr;
if (ioctl(fd, I_STR, &str) == -1)
return -1;
if (str.ic_len != olen)
fprintf(stderr, "strioctl: expected %d bytes, got %d for cmd %x\n",
olen, str.ic_len, cmd);
return 0;
}
#endif /* __svr4__ */