X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppstats%2Fpppstats.c;h=9863f32ced1fa4755f99f01564f1b041eb2a0656;hp=97239de90db642369352582f0ef56ab5ac608c17;hb=1b024cb02056cc81b5e8a4eb3d02f50fc0bb4f5a;hpb=f2e6fbd9dc3e665b9e6f30a41cb8ef22cc856ab6 diff --git a/pppstats/pppstats.c b/pppstats/pppstats.c index 97239de..9863f32 100644 --- a/pppstats/pppstats.c +++ b/pppstats/pppstats.c @@ -1,7 +1,18 @@ /* * print PPP statistics: - * pppstats [-i interval] [-v] [interface] [system] [core] + * pppstats [-i interval] [-v] [-r] [-c] [interface] * + * -i + * -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,146 +37,123 @@ */ #ifndef lint -static char rcsid[] = "$Id: pppstats.c,v 1.2 1993/12/15 05:00:47 paulus Exp $"; +static char rcsid[] = "$Id: pppstats.c,v 1.12 1995/12/11 05:18:59 paulus Exp $"; #endif -#include -#include -#include -#include -#include -#ifdef sun -#include -#endif #include #include #include #include #include -#ifndef sun -#include -#endif +#include +#include +#include +#include + +#include + +#ifdef __svr4__ +#include +#include /* SVR4, Solaris 2, etc. */ +#else +#include #include -#include -#include -#include -#include -#define VJC 1 -#include -#include +#ifndef STREAMS +#include /* 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 #include #endif - -#ifdef STREAMS -struct nlist nl[] = { -#define N_SOFTC 0 - { "_pii" }, - "", -}; -#else -struct nlist nl[] = { -#define N_SOFTC 0 - { "_ppp_softc" }, - "", -}; -#endif - -#ifdef sun -kvm_t *kd; #endif -#ifdef sun -char *system = "/vmunix"; -#else -char *system = _PATH_UNIX; -#endif - -char *kmemf; -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], "-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++; - } + --argc; ++argv; + while (argc > 0) { + if (strcmp(argv[0], "-a") == 0) { + ++aflag; + ++argv, --argc; + continue; } -#ifdef sun - /* SunOS */ - if ((kd = kvm_open(system, kmemf, (char *)0, O_RDONLY, NULL)) == NULL) { - perror("kvm_open"); - exit(1); + if (strcmp(argv[0], "-v") == 0) { + ++vflag; + ++argv, --argc; + continue; } -#else - /* BSD4.3+ */ - if (kvm_openfiles(system, kmemf, (char *)0) == -1) { - fprintf(stderr, "kvm_openfiles: %s", kvm_geterr()); - exit(1); + if (strcmp(argv[0], "-r") == 0) { + ++rflag; + ++argv, --argc; + continue; } -#endif + 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(); + } -#ifdef sun - if (kvm_nlist(kd, nl)) { +#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 (kvm_nlist(nl)) { + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("couldn't create IP socket"); + exit(1); + } #endif - fprintf(stderr, "pppstats: can't find symbols in nlist\n"); - exit(1); - } - intpr(); - exit(0); + intpr(); + exit(0); } 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) +#define CRATE(comp, inc, unc) ((unc) == 0? 0.0: \ + 1.0 - (double)((comp) + (inc)) / (unc)) /* * Print a running summary of interface statistics. @@ -175,106 +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 - -#ifdef STREAMS -#define STRUCT struct ppp_if_info -#else -#define STRUCT struct ppp_softc -#endif - - STRUCT *sc, *osc; + register int line = 0; + sigset_t oldmask, mask; + struct ppp_stats cur, old; + struct ppp_comp_stats ccs, ocs; - nl[N_SOFTC].n_value += unit * sizeof(struct ppp_softc); - sc = (STRUCT *)malloc(sizeof(STRUCT)); - osc = (STRUCT *)malloc(sizeof(STRUCT)); + memset(&old, 0, sizeof(old)); + memset(&ocs, 0, sizeof(ocs)); - bzero((char *)osc, sizeof(STRUCT)); + while (1) { + get_ppp_stats(&cur); + if (cflag || rflag) + get_ppp_cstats(&ccs); - while (1) { -#ifdef sun - if (kvm_read(kd, nl[N_SOFTC].n_value, -#else - if (kvm_read(nl[N_SOFTC].n_value, -#endif - sc, sizeof(STRUCT)) != - sizeof(STRUCT)) - perror("kvm_read"); - - (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", - "out", "pack", "comp", "uncomp", "ip"); - if (vflag) - printf(" %6.6s %6.6s", "search", "miss"); - putchar('\n'); - } - -#ifdef STREAMS -#define COMP pii_sc_comp -#define STATS pii_ifnet -#else -#define COMP sc_comp -#define STATS sc_if -#endif + (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 { - printf("%6d %6d %6d %6d %6d", -#if BSD > 43 - V(STATS.if_ibytes), -#else - 0, -#endif - V(STATS.if_ipackets), - V(COMP.sls_compressedin), - V(COMP.sls_uncompressedin), - V(COMP.sls_errorin)); + printf("%6.6s %6.6s %6.6s %6.6s %6.6s", + "in", "pack", "comp", "uncomp", "err"); 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", -#if BSD > 43 - V(STATS.if_obytes), -#else - 0, -#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(" %6.6s %6.6s", "toss", "ip"); + 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(" %6d %6d", - V(COMP.sls_searches), - V(COMP.sls_misses)); - + printf(" %6.6s %6.6s", "search", "miss"); + if(rflag) + printf(" %6.6s %6.6s", "ratio", "ubyte"); 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)); + } + 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", + 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(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(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++; + 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; } + } } /* @@ -282,7 +287,124 @@ intpr() * Sets a flag to not wait for the alarm. */ void catchalarm(arg) -int arg; + int arg; +{ + 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); + } + } + +#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"); + exit(1); + } +} + +get_ppp_cstats(csp) + struct ppp_comp_stats *csp; { - signalled = 1; + 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__ */