updated to be much closer to NetBSD version
authorPaul Mackerras <paulus@samba.org>
Mon, 1 Jul 1996 01:22:36 +0000 (01:22 +0000)
committerPaul Mackerras <paulus@samba.org>
Mon, 1 Jul 1996 01:22:36 +0000 (01:22 +0000)
pppstats/pppstats.8
pppstats/pppstats.c

index 3ec4db0364e2a48401027507cbb269c815592ab3..d7f89f7c6406f2f9dd16dbab2fd17136c6cb9a55 100644 (file)
-.\"    @(#) $Id: pppstats.8,v 1.2 1995/05/02 05:50:53 paulus Exp $
-.TH PPPSTATS 8 "2 May 1995"
+.\"    @(#) $Id: pppstats.8,v 1.3 1996/07/01 01:22:35 paulus Exp $
+.TH PPPSTATS 8 "26 June 1995"
 .SH NAME
 pppstats \- print PPP statistics
 .SH SYNOPSIS
 .B pppstats
 [
+.B -a
+] [
 .B -v
 ] [
 .B -r
 ] [
+.B -z
+] [
 .B -c
+.I <count>
 ] [
-.B -i
+.B -w
 .I <secs>
 ] [
-.I <unit#>
+.I interface
 ]
 .ti 12
 .SH DESCRIPTION
+The
 .B pppstats
-prints PPP-related statistics.
+utility reports PPP-related statistics at regular intervals for the
+specified PPP interface.  If the interface is unspecified, it will
+default to ppp0.
+The display is split horizontally
+into input and output sections containing columns of statistics
+describing the properties and volume of packets received and
+transmitted by the interface.
 .PP
-The
+The options are as follows:
+.TP
+.B -a
+Display absolute values rather than deltas.  With this option, all
+reports show statistics for the time since the link was initiated.
+Without this option, the second and subsequent reports show statistics
+for the time since the last report.
+.TP
+.B -c \fIcount
+Repeat the display
+.I count
+times.  If this option is not specified, the default repeat count is 1
+if the
+.B -w
+option is not specified, otherwise infinity.
+.TP
+.B -r
+Display additional statistics summarizing the compression ratio
+achieved by the packet compression algorithm in use.
+.TP
 .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).
+Display additional statistics relating to the performance of the Van
+Jacobson TCP header compression algorithm.
+.TP
+.B -w \fIwait
+Pause
+.I wait
+seconds between each display.  If this option is not specified, the
+default interval is 5 seconds.
+.TP
+.B -z
+Instead of the standard display, show statistics indicating the
+performance of the packet compression algorithm in use.
 .PP
-The
+The following fields are printed on the input side when the
+.B -z
+option is not used:
+.TP
+.B IN
+The total number of bytes received by this interface.
+.TP
+.B PACK
+The total number of packets received by this interface.
+.TP
+.B VJCOMP
+The number of header-compressed TCP packets received by this interface.
+.TP
+.B VJUNC
+The number of header-uncompressed TCP packets received by this
+interface.  Not reported when 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.
+option is specified.
+.TP
+.B VJERR
+The number of corrupted or bogus header-compressed TCP packets
+received by this interface.  Not reported when the
+.B -r
+option is specified.
+.TP
+.B VJTOSS
+The number of VJ header-compressed TCP packets dropped on reception by
+this interface because of preceding errors.  Only reported when the
+.B -v
+option is specified.
+.TP
+.B NON-VJ
+The total number of non-TCP packets received by this interface. Only
+reported when the
+.B -v
+option is specified.
+.TP
+.B RATIO
+The compression ratio achieved for received packets by the
+packet compression scheme in use, defined as the uncompressed size
+divided by the compressed size.
+Only reported when the
+.B -r
+option is specified.
+.TP
+.B UBYTE
+The total number of bytes received, after decompression of compressed
+packets.  Only reported when the
+.B -r
+option is specified.
 .PP
-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.
+The following fields are printed on the output side:
+.TP
+.B OUT
+The total number of bytes transmitted from this interface.
+.TP
+.B PACK
+The total number of packets transmitted from this interface.
+.TP
+.B VJCOMP
+The number of TCP packets transmitted from this interface with
+VJ-compressed TCP headers.
+.TP
+.B VJUNC
+The number of TCP packets transmitted from this interface with
+VJ-uncompressed TCP headers.
+Not reported when the
+.B -r
+option is specified.
+.TP
+.B NON-VJ
+The total number of non-TCP packets transmitted from this interface.
+Not reported when the
+.B -r
+option is specified.
+.TP
+.B VJSRCH
+The number of searches for the cached header entry for a VJ header
+compressed TCP packet.  Only reported when the
+.B -v
+option is specified.
+.TP
+.B VJMISS
+The number of failed searches for the cached header entry for a
+VJ header compressed TCP packet.  Only reported when the
+.B -v
+option is specified.
+.TP
+.B RATIO
+The compression ratio achieved for transmitted packets by the
+packet compression scheme in use, defined as the size
+before compression divided by the compressed size.
+Only reported when the
+.B -r
+option is specified.
+.TP
+.B UBYTE
+The total number of bytes to be transmitted, before packet compression
+is applied.  Only reported when the
+.B -r
+option is specified.
 .PP
-The
-.B -i
-flag is used to specify the interval between printouts. The default is
-5 seconds.
+When the
+.B -z
+option is specified,
+.Nm pppstats
+instead displays the following fields, relating to the packet
+compression algorithm currently in use.  If packet compression is not
+in use, these fields will all display zeroes.  The fields displayed on
+the input side are:
+.TP
+.B COMPRESSED BYTE
+The number of bytes of compressed packets received.
+.TP
+.B COMPRESSED PACK
+The number of compressed packets received.
+.TP
+.B INCOMPRESSIBLE BYTE
+The number of bytes of incompressible packets (that is, those which
+were transmitted in uncompressed form) received.
+.TP
+.B INCOMPRESSIBLE PACK
+The number of incompressible packets received.
+.TP
+.B COMP RATIO
+The recent compression ratio for incoming packets, defined as the
+uncompressed size divided by the compressed size (including both
+compressible and incompressible packets).
 .PP
-<unit#> specifies which interface to use for gathering statistics.
+The fields displayed on the output side are:
+.TP
+.B COMPRESSED BYTE
+The number of bytes of compressed packets transmitted.
+.TP
+.B COMPRESSED PACK
+The number of compressed packets transmitted.
+.TP
+.B INCOMPRESSIBLE BYTE
+The number of bytes of incompressible packets transmitted (that is,
+those which were transmitted in uncompressed form).
+.TP
+.B INCOMPRESSIBLE PACK
+The number of incompressible packets transmitted.
+.TP
+.B COMP RATIO
+The recent compression ratio for outgoing packets.
+.SH SEE ALSO
+pppd(8)
index 9863f32ced1fa4755f99f01564f1b041eb2a0656..0e988a67b6a78b78ade901138c65734b16fee54c 100644 (file)
@@ -1,21 +1,18 @@
 /*
  * print PPP statistics:
- *     pppstats [-i interval] [-v] [-r] [-c] [interface]
+ *     pppstats [-a] [-v] [-r] [-z] [-c count] [-w wait] [interface]
  *
- *   -i <update interval in seconds>
+ *   -a Show absolute values rather than deltas
  *   -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.
- *
+ *   -z Show compression statistics instead of default display
  *
  * 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
+ * from the original "slstats" by Van Jacobson
  *
  * Copyright (c) 1989 Regents of the University of California.
  * All rights reserved.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *     Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
- *     - Initial distribution.
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: pppstats.c,v 1.12 1995/12/11 05:18:59 paulus Exp $";
+static char rcsid[] = "$Id: pppstats.c,v 1.13 1996/07/01 01:22:36 paulus Exp $";
 #endif
 
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 #include <errno.h>
-#include <nlist.h>
-#include <stdio.h>
 #include <signal.h>
 #include <fcntl.h>
+#include <unistd.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/ioctl.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>
+#ifndef STREAMS
+#include <sys/socket.h>                /* *BSD, Linux, NeXT, Ultrix etc. */
 #include <net/if.h>
+#include <net/if_ppp.h>
 
-#ifndef STREAMS
-#include <net/if_ppp.h>                /* BSD, Linux, NeXT, etc. */
+#else  /* STREAMS */
+#include <sys/stropts.h>       /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
+#include <net/pppio.h>
 
-#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
-#endif
+#endif /* STREAMS */
 
-int    vflag, rflag, cflag, aflag;
-unsigned interval = 5;
+int    vflag, rflag, zflag;    /* select type of display */
+int    aflag;                  /* print absolute values, not deltas */
+int    interval, count;
+int    infinite;
 int    unit;
-int    s;                      /* socket file descriptor */
+int    s;                      /* socket or /dev/ppp file descriptor */
 int    signalled;              /* set if alarm goes off "early" */
+char   *progname;
+char   *interface;
 
-extern char *malloc();
-void catchalarm __P((int));
+void
+usage()
+{
+    fprintf(stderr, "Usage: %s [-v|-r|-z] [-a] [-c count] [-w wait] [interface]\n",
+           progname);
+    exit(1);
+}
 
-main(argc, argv)
-    int argc;
-    char *argv[];
+/*
+ * Called if an interval expires before intpr has completed a loop.
+ * Sets a flag to not wait for the alarm.
+ */
+void
+catchalarm(arg)
+    int arg;
 {
-    --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();
-    }
+    signalled = 1;
+}
 
-#ifdef __svr4__
-    if ((s = open("/dev/ppp", O_RDONLY)) < 0) {
-       perror("pppstats: Couldn't open /dev/ppp: ");
+
+#ifndef STREAMS
+void
+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
+
+    strncpy(req.ifr_name, interface, sizeof(req.ifr_name));
+    if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
+       fprintf(stderr, "%s: ", progname);
+       if (errno == ENOTTY)
+           fprintf(stderr, "kernel support missing\n");
+       else
+           perror("couldn't get PPP statistics");
        exit(1);
     }
-    if (strioctl(s, PPPIO_ATTACH, &unit, sizeof(int), 0) < 0) {
-       fprintf(stderr, "pppstats: ppp%d is not available\n", unit);
-       exit(1);
+    *curp = req.stats;
+}
+
+void
+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
+
+    strncpy(creq.ifr_name, interface, sizeof(creq.ifr_name));
+    if (ioctl(s, SIOCGPPPCSTATS, &creq) < 0) {
+       fprintf(stderr, "%s: ", progname);
+       if (errno == ENOTTY) {
+           fprintf(stderr, "no kernel compression support\n");
+           if (zflag)
+               exit(1);
+           rflag = 0;
+       } else {
+           perror("couldn't get PPP compression stats");
+           exit(1);
+       }
     }
-#else
-    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-       perror("couldn't create IP socket");
+
+#ifdef _linux_
+    if (creq.stats.c.bytes_out == 0)
+       creq.stats.c.ratio = 0.0;
+    else
+       creq.stats.c.ratio = (double) creq.stats.c.in_count /
+                            (double) creq.stats.c.bytes_out;
+
+    if (creq.stats.d.bytes_out == 0)
+       creq.stats.d.ratio = 0.0;
+    else
+       creq.stats.d.ratio = (double) creq.stats.d.in_count /
+                            (double) creq.stats.d.bytes_out;
+#endif
+
+    *csp = creq.stats;
+}
+
+#else  /* STREAMS */
+
+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;
+}
+
+void
+get_ppp_stats(curp)
+    struct ppp_stats *curp;
+{
+    if (strioctl(s, PPPIO_GETSTAT, curp, 0, sizeof(*curp)) < 0) {
+       fprintf(stderr, "%s: ", progname);
+       if (errno == EINVAL)
+           fprintf(stderr, "kernel support missing\n");
+       else
+           perror("couldn't get PPP statistics");
        exit(1);
     }
-#endif
-    intpr();
-    exit(0);
 }
 
-usage()
+void
+get_ppp_cstats(csp)
+    struct ppp_comp_stats *csp;
 {
-    fprintf(stderr, "Usage: pppstats [-v] [-r] [-c] [-i interval] [unit]\n");
-    exit(1);
+    if (strioctl(s, PPPIO_GETCSTAT, csp, 0, sizeof(*csp)) < 0) {
+       fprintf(stderr, "%s: ", progname);
+       if (errno == ENOTTY) {
+           fprintf(stderr, "no kernel compression support\n");
+           if (zflag)
+               exit(1);
+           rflag = 0;
+       } else {
+           perror("couldn't get PPP compression statistics");
+           exit(1);
+       }
+    }
 }
 
-#define V(offset) (line % 20? cur.offset - old.offset: cur.offset)
-#define W(offset) (line % 20? ccs.offset - ocs.offset: ccs.offset)
+#endif /* STREAMS */
+
+#define MAX0(a)                ((int)(a) > 0? (a): 0)
+#define V(offset)      MAX0(cur.offset - old.offset)
+#define W(offset)      MAX0(ccs.offset - ocs.offset)
 
-#define CRATE(comp, inc, unc)  ((unc) == 0? 0.0: \
-                                1.0 - (double)((comp) + (inc)) / (unc))
+#define RATIO(c, i, u) ((c) == 0? 1.0: (u) / ((double)(c) + (i)))
+#define CRATE(x)       RATIO(W(x.comp_bytes), W(x.inc_bytes), W(x.unc_bytes))
 
 /*
  * Print a running summary of interface statistics.
  * Repeat display every interval seconds, showing statistics
  * collected over that interval.  Assumes that interval is non-zero.
- * First line printed at top of screen is always cumulative.
+ * First line printed is cumulative.
  */
+void
 intpr()
 {
     register int line = 0;
@@ -173,101 +242,108 @@ intpr()
 
     while (1) {
        get_ppp_stats(&cur);
-       if (cflag || rflag)
+       if (zflag || rflag)
            get_ppp_cstats(&ccs);
 
        (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');
+           if (zflag) {
+               printf("IN:  COMPRESSED  INCOMPRESSIBLE   COMP | ");
+               printf("OUT: COMPRESSED  INCOMPRESSIBLE   COMP\n");
+               printf("    BYTE   PACK     BYTE   PACK  RATIO | ");
+               printf("    BYTE   PACK     BYTE   PACK  RATIO");
            } else {
+               printf("%8.8s %6.6s %6.6s",
+                      "IN", "PACK", "VJCOMP");
 
-               printf("%6.6s %6.6s %6.6s %6.6s %6.6s",
-                      "in", "pack", "comp", "uncomp", "err");
+               if (!rflag)
+                   printf(" %6.6s %6.6s", "VJUNC", "VJERR");
                if (vflag)
-                   printf(" %6.6s %6.6s", "toss", "ip");
+                   printf(" %6.6s %6.6s", "VJTOSS", "NON-VJ");
                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");
+                   printf(" %6.6s %6.6s", "RATIO", "UBYTE");
+               printf("  | %8.8s %6.6s %6.6s",
+                      "OUT", "PACK", "VJCOMP");
+
+               if (!rflag)
+                   printf(" %6.6s %6.6s", "VJUNC", "NON-VJ");
                if (vflag)
-                   printf(" %6.6s %6.6s", "search", "miss");
-               if(rflag)
-                   printf("   %6.6s %6.6s", "ratio", "ubyte");
-               putchar('\n');
+                   printf(" %6.6s %6.6s", "VJSRCH", "VJMISS");
+               if (rflag)
+                   printf(" %6.6s %6.6s", "RATIO", "UBYTE");
            }
-           memset(&old, 0, sizeof(old));
-           memset(&ocs, 0, sizeof(ocs));
+           putchar('\n');
        }
-       
-       if (cflag) {
-           printf("%6d %6d %6d %6d %6d %6d %6.2f",
-                  W(d.unc_bytes),
-                  W(d.unc_packets),
+
+       if (zflag) {
+           printf("%8u %6u %8u %6u %6.2f",
                   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);
+                  ccs.d.ratio * 256.0);
 
-           printf(" | %6d %6d %6d %6d %6d %6d %6.2f",
-                  W(c.unc_bytes),
-                  W(c.unc_packets),
+           printf(" | %8u %6u %8u %6u %6.2f",
                   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);
+                  ccs.c.ratio * 256.0);
        
-           putchar('\n');
        } else {
 
-           printf("%6d %6d %6d %6d %6d",
+           printf("%8u %6u %6u",
                   V(p.ppp_ibytes),
-                  V(p.ppp_ipackets), V(vj.vjs_compressedin),
-                  V(vj.vjs_uncompressedin), V(vj.vjs_errorin));
+                  V(p.ppp_ipackets),
+                  V(vj.vjs_compressedin));
+           if (!rflag)
+               printf(" %6u %6u",
+                      V(vj.vjs_uncompressedin),
+                      V(vj.vjs_errorin));
            if (vflag)
-               printf(" %6d %6d", V(vj.vjs_tossed),
-                      V(p.ppp_ipackets) - V(vj.vjs_compressedin) -
-                      V(vj.vjs_uncompressedin) - V(vj.vjs_errorin));
+               printf(" %6u %6u",
+                      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)),
+               printf(" %6.2f %6u",
+                      CRATE(d),
                       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));
+           printf("  | %8u %6u %6u",
+                  V(p.ppp_obytes),
+                  V(p.ppp_opackets),
+                  V(vj.vjs_compressed));
+           if (!rflag)
+               printf(" %6u %6u",
+                      V(vj.vjs_packets) - V(vj.vjs_compressed),
+                      V(p.ppp_opackets) - V(vj.vjs_packets));
            if (vflag)
-               printf(" %6d %6d", V(vj.vjs_searches), V(vj.vjs_misses));
+               printf(" %6u %6u",
+                      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)),
+               printf(" %6.2f %6u",
+                      CRATE(c),
                       W(c.unc_bytes));
-           
-           putchar('\n');
+
        }
 
+       putchar('\n');
        fflush(stdout);
        line++;
-       if (interval == 0)
-           exit(0);
+
+       count--;
+       if (!infinite && !count)
+           break;
 
        sigemptyset(&mask);
        sigaddset(&mask, SIGALRM);
        sigprocmask(SIG_BLOCK, &mask, &oldmask);
-       if (! signalled) {
+       if (!signalled) {
            sigemptyset(&mask);
            sigsuspend(&mask);
        }
@@ -275,136 +351,105 @@ intpr()
        signalled = 0;
        (void)alarm(interval);
 
-       if (aflag==0) {
+       if (!aflag) {
            old = cur;
            ocs = ccs;
        }
     }
 }
 
-/*
- * Called if an interval expires before sidewaysintpr has completed a loop.
- * Sets a flag to not wait for the alarm.
- */
-void catchalarm(arg)
-    int arg;
-{
-    signalled = 1;
-}
-
-#ifndef __svr4__
-get_ppp_stats(curp)
-    struct ppp_stats *curp;
+int
+main(argc, argv)
+    int argc;
+    char *argv[];
 {
-    struct ifpppstatsreq req;
-
-    memset (&req, 0, sizeof (req));
+    int c;
 
-#ifdef _linux_
-    req.stats_ptr = (caddr_t) &req.stats;
-#undef ifr_name
-#define ifr_name ifr__name
-#endif
+    interface = "ppp0";
+    if ((progname = strrchr(argv[0], '/')) == NULL)
+       progname = argv[0];
+    else
+       ++progname;
 
-    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);
+    while ((c = getopt(argc, argv, "avrzc:w:")) != -1) {
+       switch (c) {
+       case 'a':
+           ++aflag;
+           break;
+       case 'v':
+           ++vflag;
+           break;
+       case 'r':
+           ++rflag;
+           break;
+       case 'z':
+           ++zflag;
+           break;
+       case 'c':
+           count = atoi(optarg);
+           if (count <= 0)
+               usage();
+           break;
+       case 'w':
+           interval = atoi(optarg);
+           if (interval <= 0)
+               usage();
+           break;
+       default:
+           usage();
+       }
     }
-    *curp = req.stats;
-}
+    argc -= optind;
+    argv += optind;
 
-get_ppp_cstats(csp)
-    struct ppp_comp_stats *csp;
-{
-    struct ifpppcstatsreq creq;
+    if (!interval && count)
+       interval = 5;
+    if (interval && !count)
+       infinite = 1;
+    if (!interval && !count)
+       count = 1;
 
-    memset (&creq, 0, sizeof (creq));
+    if (argc > 1)
+       usage();
+    if (argc > 0)
+       interface = argv[0];
 
-#ifdef _linux_
-    creq.stats_ptr = (caddr_t) &creq.stats;
-#undef  ifr_name
-#define ifr_name ifr__name
-#endif
+    if (sscanf(interface, "ppp%d", &unit) != 1) {
+       fprintf(stderr, "%s: invalid interface '%s' specified\n",
+               progname, interface);
+    }
 
-    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)");
+#ifndef STREAMS
+    {
+       struct ifreq ifr;
+
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       if (s < 0) {
+           fprintf(stderr, "%s: ", progname);
+           perror("couldn't create IP socket");
+           exit(1);
+       }
+       strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
+       if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
+           fprintf(stderr, "%s: nonexistent interface '%s' specified\n",
+                   progname, interface);
            exit(1);
        }
     }
 
-#ifdef _linux_
-    if (creq.stats.c.bytes_out == 0)
-       creq.stats.c.ratio = 0.0;
-    else
-       creq.stats.c.ratio = (double) creq.stats.c.in_count /
-                            (double) creq.stats.c.bytes_out;
-
-    if (creq.stats.d.bytes_out == 0)
-       creq.stats.d.ratio = 0.0;
-    else
-       creq.stats.d.ratio = (double) creq.stats.d.in_count /
-                            (double) creq.stats.d.bytes_out;
-#endif
-
-    *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");
+#else  /* STREAMS */
+    if ((s = open("/dev/ppp", O_RDONLY)) < 0) {
+       fprintf(stderr, "%s: ", progname);
+       perror("couldn't open /dev/ppp");
        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);
-       }
+    if (strioctl(s, PPPIO_ATTACH, &unit, sizeof(int), 0) < 0) {
+       fprintf(stderr, "%s: ppp%d is not available\n", progname, unit);
+       exit(1);
     }
-}
 
-int
-strioctl(fd, cmd, ptr, ilen, olen)
-    int fd, cmd, ilen, olen;
-    char *ptr;
-{
-    struct strioctl str;
+#endif /* STREAMS */
 
-    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;
+    intpr();
+    exit(0);
 }
-#endif /* __svr4__ */