__linux__ (already defined by compiler) not _linux_ (manually defined)
[ppp.git] / pppstats / pppstats.c
index 0e988a67b6a78b78ade901138c65734b16fee54c..6367988eb96bf03c588b6228ee0c0fdf115f0fbb 100644 (file)
@@ -1,10 +1,11 @@
 /*
  * print PPP statistics:
- *     pppstats [-a] [-v] [-r] [-z] [-c count] [-w wait] [interface]
+ *     pppstats [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]
  *
  *   -a Show absolute values rather than deltas
- *   -v Verbose mode for default display
- *   -r Show compression ratio in default display
+ *   -d Show data rate (kB/s) rather than bytes
+ *   -v Show more stats for VJ TCP header compression
+ *   -r Show compression ratio
  *   -z Show compression statistics instead of default display
  *
  * History:
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#ifndef __STDC__
+#define const
+#endif
+
 #ifndef lint
-static char rcsid[] = "$Id: pppstats.c,v 1.13 1996/07/01 01:22:36 paulus Exp $";
+static const char rcsid[] = "$Id: pppstats.c,v 1.29 2002/10/27 12:56:26 fcusack Exp $";
 #endif
 
 #include <stdio.h>
@@ -46,21 +51,41 @@ static char rcsid[] = "$Id: pppstats.c,v 1.13 1996/07/01 01:22:36 paulus Exp $";
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
-#include <net/ppp_defs.h>
 
 #ifndef STREAMS
+#if defined(__linux__) && defined(__powerpc__) \
+    && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+/* kludge alert! */
+#undef __GLIBC__
+#endif
 #include <sys/socket.h>                /* *BSD, Linux, NeXT, Ultrix etc. */
+#ifndef __linux__
 #include <net/if.h>
+#include <net/ppp_defs.h>
 #include <net/if_ppp.h>
+#else
+/* Linux */
+#if __GLIBC__ >= 2
+#include <asm/types.h>         /* glibc 2 conflicts with linux/types.h */
+#include <net/if.h>
+#else
+#include <linux/types.h>
+#include <linux/if.h>
+#endif
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#endif /* __linux__ */
 
 #else  /* STREAMS */
 #include <sys/stropts.h>       /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
+#include <net/ppp_defs.h>
 #include <net/pppio.h>
 
 #endif /* STREAMS */
 
 int    vflag, rflag, zflag;    /* select type of display */
 int    aflag;                  /* print absolute values, not deltas */
+int    dflag;                  /* print data rates, not bytes */
 int    interval, count;
 int    infinite;
 int    unit;
@@ -69,10 +94,31 @@ int signalled;              /* set if alarm goes off "early" */
 char   *progname;
 char   *interface;
 
-void
+#if defined(SUNOS4) || defined(ULTRIX) || defined(NeXT)
+extern int optind;
+extern char *optarg;
+#endif
+
+/*
+ * If PPP_DRV_NAME is not defined, use the legacy "ppp" as the
+ * device name.
+ */
+#if !defined(PPP_DRV_NAME)
+#define PPP_DRV_NAME    "ppp"
+#endif /* !defined(PPP_DRV_NAME) */
+
+static void usage __P((void));
+static void catchalarm __P((int));
+static void get_ppp_stats __P((struct ppp_stats *));
+static void get_ppp_cstats __P((struct ppp_comp_stats *));
+static void intpr __P((void));
+
+int main __P((int, char *argv[]));
+
+static void
 usage()
 {
-    fprintf(stderr, "Usage: %s [-v|-r|-z] [-a] [-c count] [-w wait] [interface]\n",
+    fprintf(stderr, "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n",
            progname);
     exit(1);
 }
@@ -81,7 +127,7 @@ usage()
  * Called if an interval expires before intpr has completed a loop.
  * Sets a flag to not wait for the alarm.
  */
-void
+static void
 catchalarm(arg)
     int arg;
 {
@@ -90,7 +136,7 @@ catchalarm(arg)
 
 
 #ifndef STREAMS
-void
+static void
 get_ppp_stats(curp)
     struct ppp_stats *curp;
 {
@@ -98,7 +144,7 @@ get_ppp_stats(curp)
 
     memset (&req, 0, sizeof (req));
 
-#ifdef _linux_
+#ifdef __linux__
     req.stats_ptr = (caddr_t) &req.stats;
 #undef ifr_name
 #define ifr_name ifr__name
@@ -116,7 +162,7 @@ get_ppp_stats(curp)
     *curp = req.stats;
 }
 
-void
+static void
 get_ppp_cstats(csp)
     struct ppp_comp_stats *csp;
 {
@@ -124,7 +170,7 @@ get_ppp_cstats(csp)
 
     memset (&creq, 0, sizeof (creq));
 
-#ifdef _linux_
+#ifdef __linux__
     creq.stats_ptr = (caddr_t) &creq.stats;
 #undef  ifr_name
 #define ifr_name ifr__name
@@ -144,18 +190,26 @@ get_ppp_cstats(csp)
        }
     }
 
-#ifdef _linux_
+#ifdef __linux__
+    if (creq.stats.c.bytes_out == 0) {
+       creq.stats.c.bytes_out = creq.stats.c.comp_bytes + creq.stats.c.inc_bytes;
+       creq.stats.c.in_count = creq.stats.c.unc_bytes;
+    }
     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;
+       creq.stats.c.ratio = 256.0 * creq.stats.c.in_count /
+                            creq.stats.c.bytes_out;
 
+    if (creq.stats.d.bytes_out == 0) {
+       creq.stats.d.bytes_out = creq.stats.d.comp_bytes + creq.stats.d.inc_bytes;
+       creq.stats.d.in_count = creq.stats.d.unc_bytes;
+    }
     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;
+       creq.stats.d.ratio = 256.0 * creq.stats.d.in_count /
+                            creq.stats.d.bytes_out;
 #endif
 
     *csp = creq.stats;
@@ -182,7 +236,7 @@ strioctl(fd, cmd, ptr, ilen, olen)
     return 0;
 }
 
-void
+static void
 get_ppp_stats(curp)
     struct ppp_stats *curp;
 {
@@ -196,7 +250,7 @@ get_ppp_stats(curp)
     }
 }
 
-void
+static void
 get_ppp_cstats(csp)
     struct ppp_comp_stats *csp;
 {
@@ -223,17 +277,21 @@ get_ppp_cstats(csp)
 #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))
 
+#define KBPS(n)                ((n) / (interval * 1000.0))
+
 /*
  * 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 is cumulative.
  */
-void
+static void
 intpr()
 {
     register int line = 0;
     sigset_t oldmask, mask;
+    char *bunit;
+    int ratef = 0;
     struct ppp_stats cur, old;
     struct ppp_comp_stats ccs, ocs;
 
@@ -253,8 +311,9 @@ intpr()
            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");
+               bunit = dflag? "KB/S": "BYTE";
+               printf("    %s   PACK     %s   PACK  RATIO | ", bunit, bunit);
+               printf("    %s   PACK     %s   PACK  RATIO", bunit, bunit);
            } else {
                printf("%8.8s %6.6s %6.6s",
                       "IN", "PACK", "VJCOMP");
@@ -279,24 +338,40 @@ intpr()
        }
 
        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),
-                  ccs.d.ratio * 256.0);
-
-           printf(" | %8u %6u %8u %6u %6.2f",
-                  W(c.comp_bytes),
-                  W(c.comp_packets),
-                  W(c.inc_bytes),
-                  W(c.inc_packets),
-                  ccs.c.ratio * 256.0);
+           if (ratef) {
+               printf("%8.3f %6u %8.3f %6u %6.2f",
+                      KBPS(W(d.comp_bytes)),
+                      W(d.comp_packets),
+                      KBPS(W(d.inc_bytes)),
+                      W(d.inc_packets),
+                      ccs.d.ratio / 256.0);
+               printf(" | %8.3f %6u %8.3f %6u %6.2f",
+                      KBPS(W(c.comp_bytes)),
+                      W(c.comp_packets),
+                      KBPS(W(c.inc_bytes)),
+                      W(c.inc_packets),
+                      ccs.c.ratio / 256.0);
+           } else {
+               printf("%8u %6u %8u %6u %6.2f",
+                      W(d.comp_bytes),
+                      W(d.comp_packets),
+                      W(d.inc_bytes),
+                      W(d.inc_packets),
+                      ccs.d.ratio / 256.0);
+               printf(" | %8u %6u %8u %6u %6.2f",
+                      W(c.comp_bytes),
+                      W(c.comp_packets),
+                      W(c.inc_bytes),
+                      W(c.inc_packets),
+                      ccs.c.ratio / 256.0);
+           }
        
        } else {
-
-           printf("%8u %6u %6u",
-                  V(p.ppp_ibytes),
+           if (ratef)
+               printf("%8.3f", KBPS(V(p.ppp_ibytes)));
+           else
+               printf("%8u", V(p.ppp_ibytes));
+           printf(" %6u %6u",
                   V(p.ppp_ipackets),
                   V(vj.vjs_compressedin));
            if (!rflag)
@@ -308,12 +383,18 @@ intpr()
                       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 %6u",
-                      CRATE(d),
-                      W(d.unc_bytes));
-           printf("  | %8u %6u %6u",
-                  V(p.ppp_obytes),
+           if (rflag) {
+               printf(" %6.2f ", CRATE(d));
+               if (ratef)
+                   printf("%6.2f", KBPS(W(d.unc_bytes)));
+               else
+                   printf("%6u", W(d.unc_bytes));
+           }
+           if (ratef)
+               printf("  | %8.3f", KBPS(V(p.ppp_obytes)));
+           else
+               printf("  | %8u", V(p.ppp_obytes));
+           printf(" %6u %6u",
                   V(p.ppp_opackets),
                   V(vj.vjs_compressed));
            if (!rflag)
@@ -324,11 +405,13 @@ intpr()
                printf(" %6u %6u",
                       V(vj.vjs_searches),
                       V(vj.vjs_misses));
-
-           if (rflag)
-               printf(" %6.2f %6u",
-                      CRATE(c),
-                      W(c.unc_bytes));
+           if (rflag) {
+               printf(" %6.2f ", CRATE(c));
+               if (ratef)
+                   printf("%6.2f", KBPS(W(c.unc_bytes)));
+               else
+                   printf("%6u", W(c.unc_bytes));
+           }
 
        }
 
@@ -354,6 +437,7 @@ intpr()
        if (!aflag) {
            old = cur;
            ocs = ccs;
+           ratef = dflag;
        }
     }
 }
@@ -364,18 +448,24 @@ main(argc, argv)
     char *argv[];
 {
     int c;
+#ifdef STREAMS
+    char *dev;
+#endif
 
-    interface = "ppp0";
+    interface = PPP_DRV_NAME "0";
     if ((progname = strrchr(argv[0], '/')) == NULL)
        progname = argv[0];
     else
        ++progname;
 
-    while ((c = getopt(argc, argv, "avrzc:w:")) != -1) {
+    while ((c = getopt(argc, argv, "advrzc:w:")) != -1) {
        switch (c) {
        case 'a':
            ++aflag;
            break;
+       case 'd':
+           ++dflag;
+           break;
        case 'v':
            ++vflag;
            break;
@@ -408,13 +498,15 @@ main(argc, argv)
        infinite = 1;
     if (!interval && !count)
        count = 1;
+    if (aflag)
+       dflag = 0;
 
     if (argc > 1)
        usage();
     if (argc > 0)
        interface = argv[0];
 
-    if (sscanf(interface, "ppp%d", &unit) != 1) {
+    if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) {
        fprintf(stderr, "%s: invalid interface '%s' specified\n",
                progname, interface);
     }
@@ -429,6 +521,11 @@ main(argc, argv)
            perror("couldn't create IP socket");
            exit(1);
        }
+
+#ifdef __linux__
+#undef  ifr_name
+#define ifr_name ifr_ifrn.ifrn_name
+#endif
        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",
@@ -438,9 +535,14 @@ main(argc, argv)
     }
 
 #else  /* STREAMS */
-    if ((s = open("/dev/ppp", O_RDONLY)) < 0) {
-       fprintf(stderr, "%s: ", progname);
-       perror("couldn't open /dev/ppp");
+#ifdef __osf__
+    dev = "/dev/streams/ppp";
+#else
+    dev = "/dev/" PPP_DRV_NAME;
+#endif
+    if ((s = open(dev, O_RDONLY)) < 0) {
+       fprintf(stderr, "%s: couldn't open ", progname);
+       perror(dev);
        exit(1);
     }
     if (strioctl(s, PPPIO_ATTACH, &unit, sizeof(int), 0) < 0) {