17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * print PPP statistics:
37c478bd9Sstevel@tonic-gate  * 	pppstats [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  *   -a Show absolute values rather than deltas
67c478bd9Sstevel@tonic-gate  *   -d Show data rate (kB/s) rather than bytes
77c478bd9Sstevel@tonic-gate  *   -v Show more stats for VJ TCP header compression
87c478bd9Sstevel@tonic-gate  *   -r Show compression ratio
97c478bd9Sstevel@tonic-gate  *   -z Show compression statistics instead of default display
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  * History:
12*55fea89dSDan Cross  *      perkins@cps.msu.edu: Added compression statistics and alternate
137c478bd9Sstevel@tonic-gate  *                display. 11/94
147c478bd9Sstevel@tonic-gate  *	Brad Parker (brad@cayman.com) 6/92
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  * from the original "slstats" by Van Jacobson
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
197c478bd9Sstevel@tonic-gate  * All rights reserved.
207c478bd9Sstevel@tonic-gate  *
217c478bd9Sstevel@tonic-gate  * Copyright (c) 1989 Regents of the University of California.
227c478bd9Sstevel@tonic-gate  * All rights reserved.
237c478bd9Sstevel@tonic-gate  *
247c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
257c478bd9Sstevel@tonic-gate  * provided that the above copyright notice and this paragraph are
267c478bd9Sstevel@tonic-gate  * duplicated in all such forms and that any documentation,
277c478bd9Sstevel@tonic-gate  * advertising materials, and other materials related to such
287c478bd9Sstevel@tonic-gate  * distribution and use acknowledge that the software was developed
297c478bd9Sstevel@tonic-gate  * by the University of California, Berkeley.  The name of the
307c478bd9Sstevel@tonic-gate  * University may not be used to endorse or promote products derived
317c478bd9Sstevel@tonic-gate  * from this software without specific prior written permission.
327c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
337c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
347c478bd9Sstevel@tonic-gate  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #ifndef __STDC__
387c478bd9Sstevel@tonic-gate #define const
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <stdio.h>
427c478bd9Sstevel@tonic-gate #include <stddef.h>
437c478bd9Sstevel@tonic-gate #include <stdlib.h>
447c478bd9Sstevel@tonic-gate #include <string.h>
457c478bd9Sstevel@tonic-gate #include <ctype.h>
467c478bd9Sstevel@tonic-gate #include <errno.h>
477c478bd9Sstevel@tonic-gate #include <signal.h>
487c478bd9Sstevel@tonic-gate #include <fcntl.h>
497c478bd9Sstevel@tonic-gate #include <unistd.h>
507c478bd9Sstevel@tonic-gate #include <sys/param.h>
517c478bd9Sstevel@tonic-gate #include <sys/types.h>
527c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #ifndef STREAMS
557c478bd9Sstevel@tonic-gate #if defined(_linux_) && defined(__powerpc__) \
567c478bd9Sstevel@tonic-gate     && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
577c478bd9Sstevel@tonic-gate /* kludge alert! */
587c478bd9Sstevel@tonic-gate #undef __GLIBC__
597c478bd9Sstevel@tonic-gate #endif
607c478bd9Sstevel@tonic-gate #include <sys/socket.h>		/* *BSD, Linux, NeXT, Ultrix etc. */
617c478bd9Sstevel@tonic-gate #ifndef _linux_
627c478bd9Sstevel@tonic-gate #include <net/if.h>
637c478bd9Sstevel@tonic-gate #include <net/ppp_defs.h>
647c478bd9Sstevel@tonic-gate #include <net/if_ppp.h>
657c478bd9Sstevel@tonic-gate #else
667c478bd9Sstevel@tonic-gate /* Linux */
677c478bd9Sstevel@tonic-gate #if __GLIBC__ >= 2
687c478bd9Sstevel@tonic-gate #include <asm/types.h>		/* glibc 2 conflicts with linux/types.h */
697c478bd9Sstevel@tonic-gate #include <net/if.h>
707c478bd9Sstevel@tonic-gate #else
717c478bd9Sstevel@tonic-gate #include <linux/types.h>
727c478bd9Sstevel@tonic-gate #include <linux/if.h>
737c478bd9Sstevel@tonic-gate #endif
747c478bd9Sstevel@tonic-gate #include <linux/ppp_defs.h>
757c478bd9Sstevel@tonic-gate #include <linux/if_ppp.h>
767c478bd9Sstevel@tonic-gate #endif /* _linux_ */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate #else	/* STREAMS */
797c478bd9Sstevel@tonic-gate #include <sys/stropts.h>	/* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
807c478bd9Sstevel@tonic-gate #include <net/ppp_defs.h>
817c478bd9Sstevel@tonic-gate #include <net/pppio.h>
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #ifdef PPPIO_GETSTAT64
847c478bd9Sstevel@tonic-gate #define	ppp_stats64	ppp_stats64
857c478bd9Sstevel@tonic-gate #endif
867c478bd9Sstevel@tonic-gate #endif	/* STREAMS */
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate #ifndef ppp_stats64
897c478bd9Sstevel@tonic-gate #define	ppp_stats64	ppp_stats
907c478bd9Sstevel@tonic-gate #endif
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate static int	vflag, rflag, zflag;	/* select type of display */
937c478bd9Sstevel@tonic-gate static int	aflag;			/* print absolute values, not deltas */
947c478bd9Sstevel@tonic-gate static int	dflag;			/* print data rates, not bytes */
957c478bd9Sstevel@tonic-gate static int	interval, count;
967c478bd9Sstevel@tonic-gate static int	infinite;
977c478bd9Sstevel@tonic-gate static int	unit;
987c478bd9Sstevel@tonic-gate static int	s;			/* socket or /dev/ppp file descriptor */
997c478bd9Sstevel@tonic-gate static int	signalled;		/* set if alarm goes off "early" */
1007c478bd9Sstevel@tonic-gate static char	*progname;
1017c478bd9Sstevel@tonic-gate static char	*interface;
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate #if defined(SUNOS4) || defined(ULTRIX) || defined(NeXT)
1047c478bd9Sstevel@tonic-gate extern int optind;
1057c478bd9Sstevel@tonic-gate extern char *optarg;
1067c478bd9Sstevel@tonic-gate #endif
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate  * If PPP_DRV_NAME is not defined, use the legacy "ppp" as the
1107c478bd9Sstevel@tonic-gate  * device name.
1117c478bd9Sstevel@tonic-gate  */
1127c478bd9Sstevel@tonic-gate #if !defined(PPP_DRV_NAME)
1137c478bd9Sstevel@tonic-gate #define PPP_DRV_NAME    "ppp"
1147c478bd9Sstevel@tonic-gate #endif /* !defined(PPP_DRV_NAME) */
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate static void usage __P((void));
1177c478bd9Sstevel@tonic-gate static void catchalarm __P((int));
1187c478bd9Sstevel@tonic-gate static void get_ppp_stats __P((struct ppp_stats64 *));
1197c478bd9Sstevel@tonic-gate static void get_ppp_cstats __P((struct ppp_comp_stats *));
1207c478bd9Sstevel@tonic-gate static void intpr __P((void));
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate int main __P((int, char *argv[]));
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate static void
usage()1257c478bd9Sstevel@tonic-gate usage()
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate     (void) fprintf(stderr,
1287c478bd9Sstevel@tonic-gate 	"Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n",
1297c478bd9Sstevel@tonic-gate 	progname);
1307c478bd9Sstevel@tonic-gate     exit(1);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate /*
1347c478bd9Sstevel@tonic-gate  * Called if an interval expires before intpr has completed a loop.
1357c478bd9Sstevel@tonic-gate  * Sets a flag to not wait for the alarm.
1367c478bd9Sstevel@tonic-gate  */
1377c478bd9Sstevel@tonic-gate /* ARGSUSED */
1387c478bd9Sstevel@tonic-gate static void
catchalarm(arg)1397c478bd9Sstevel@tonic-gate catchalarm(arg)
1407c478bd9Sstevel@tonic-gate     int arg;
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate     signalled = 1;
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate #ifndef STREAMS
1477c478bd9Sstevel@tonic-gate static void
get_ppp_stats(curp)1487c478bd9Sstevel@tonic-gate get_ppp_stats(curp)
1497c478bd9Sstevel@tonic-gate     struct ppp_stats64 *curp;
1507c478bd9Sstevel@tonic-gate {
1517c478bd9Sstevel@tonic-gate     struct ifpppstatsreq req;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate     (void) memset (&req, 0, sizeof (req));
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate #ifdef _linux_
1567c478bd9Sstevel@tonic-gate     req.stats_ptr = (caddr_t) &req.stats;
1577c478bd9Sstevel@tonic-gate #undef ifr_name
1587c478bd9Sstevel@tonic-gate #define ifr_name ifr__name
1597c478bd9Sstevel@tonic-gate #endif
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate     strncpy(req.ifr_name, interface, sizeof(req.ifr_name));
1627c478bd9Sstevel@tonic-gate     if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
1637c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: ", progname);
1647c478bd9Sstevel@tonic-gate 	if (errno == ENOTTY)
1657c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, "kernel support missing\n");
1667c478bd9Sstevel@tonic-gate 	else
1677c478bd9Sstevel@tonic-gate 	    perror("couldn't get PPP statistics");
1687c478bd9Sstevel@tonic-gate 	exit(1);
1697c478bd9Sstevel@tonic-gate     }
1707c478bd9Sstevel@tonic-gate     *curp = req.stats;
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate static void
get_ppp_cstats(csp)1747c478bd9Sstevel@tonic-gate get_ppp_cstats(csp)
1757c478bd9Sstevel@tonic-gate     struct ppp_comp_stats *csp;
1767c478bd9Sstevel@tonic-gate {
1777c478bd9Sstevel@tonic-gate     struct ifpppcstatsreq creq;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate     (void) memset (&creq, 0, sizeof (creq));
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate #ifdef _linux_
1827c478bd9Sstevel@tonic-gate     creq.stats_ptr = (caddr_t) &creq.stats;
1837c478bd9Sstevel@tonic-gate #undef  ifr_name
1847c478bd9Sstevel@tonic-gate #define ifr_name ifr__name
1857c478bd9Sstevel@tonic-gate #endif
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate     strncpy(creq.ifr_name, interface, sizeof(creq.ifr_name));
1887c478bd9Sstevel@tonic-gate     if (ioctl(s, SIOCGPPPCSTATS, &creq) < 0) {
1897c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: ", progname);
1907c478bd9Sstevel@tonic-gate 	if (errno == ENOTTY) {
1917c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, "no kernel compression support\n");
1927c478bd9Sstevel@tonic-gate 	    if (zflag)
1937c478bd9Sstevel@tonic-gate 		exit(1);
1947c478bd9Sstevel@tonic-gate 	    rflag = 0;
1957c478bd9Sstevel@tonic-gate 	} else {
1967c478bd9Sstevel@tonic-gate 	    perror("couldn't get PPP compression stats");
1977c478bd9Sstevel@tonic-gate 	    exit(1);
1987c478bd9Sstevel@tonic-gate 	}
1997c478bd9Sstevel@tonic-gate     }
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate #ifdef _linux_
2027c478bd9Sstevel@tonic-gate     if (creq.stats.c.bytes_out == 0) {
2037c478bd9Sstevel@tonic-gate 	creq.stats.c.bytes_out = creq.stats.c.comp_bytes + creq.stats.c.inc_bytes;
2047c478bd9Sstevel@tonic-gate 	creq.stats.c.in_count = creq.stats.c.unc_bytes;
2057c478bd9Sstevel@tonic-gate     }
2067c478bd9Sstevel@tonic-gate     if (creq.stats.c.bytes_out == 0)
2077c478bd9Sstevel@tonic-gate 	creq.stats.c.ratio = 0.0;
2087c478bd9Sstevel@tonic-gate     else
2097c478bd9Sstevel@tonic-gate 	creq.stats.c.ratio = 256.0 * creq.stats.c.in_count /
2107c478bd9Sstevel@tonic-gate 			     creq.stats.c.bytes_out;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate     if (creq.stats.d.bytes_out == 0) {
2137c478bd9Sstevel@tonic-gate 	creq.stats.d.bytes_out = creq.stats.d.comp_bytes + creq.stats.d.inc_bytes;
2147c478bd9Sstevel@tonic-gate 	creq.stats.d.in_count = creq.stats.d.unc_bytes;
2157c478bd9Sstevel@tonic-gate     }
2167c478bd9Sstevel@tonic-gate     if (creq.stats.d.bytes_out == 0)
2177c478bd9Sstevel@tonic-gate 	creq.stats.d.ratio = 0.0;
2187c478bd9Sstevel@tonic-gate     else
2197c478bd9Sstevel@tonic-gate 	creq.stats.d.ratio = 256.0 * creq.stats.d.in_count /
2207c478bd9Sstevel@tonic-gate 			     creq.stats.d.bytes_out;
2217c478bd9Sstevel@tonic-gate #endif
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate     *csp = creq.stats;
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate #else	/* STREAMS */
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate static int
strioctl(fd,cmd,ptr,ilen,olen)2297c478bd9Sstevel@tonic-gate strioctl(fd, cmd, ptr, ilen, olen)
2307c478bd9Sstevel@tonic-gate     int fd, cmd, ilen, olen;
2317c478bd9Sstevel@tonic-gate     char *ptr;
2327c478bd9Sstevel@tonic-gate {
2337c478bd9Sstevel@tonic-gate     struct strioctl str;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate     str.ic_cmd = cmd;
2367c478bd9Sstevel@tonic-gate     str.ic_timout = 0;
2377c478bd9Sstevel@tonic-gate     str.ic_len = ilen;
2387c478bd9Sstevel@tonic-gate     str.ic_dp = ptr;
2397c478bd9Sstevel@tonic-gate     if (ioctl(fd, I_STR, &str) == -1)
2407c478bd9Sstevel@tonic-gate 	return -1;
2417c478bd9Sstevel@tonic-gate     if (str.ic_len != olen)
2427c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
2437c478bd9Sstevel@tonic-gate 	    "strioctl: expected %d bytes, got %d for cmd %x\n",
2447c478bd9Sstevel@tonic-gate 	    olen, str.ic_len, cmd);
2457c478bd9Sstevel@tonic-gate     return 0;
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate static void
get_ppp_stats(curp)2497c478bd9Sstevel@tonic-gate get_ppp_stats(curp)
2507c478bd9Sstevel@tonic-gate     struct ppp_stats64 *curp;
2517c478bd9Sstevel@tonic-gate {
2527c478bd9Sstevel@tonic-gate #ifdef PPPIO_GETSTAT64
2537c478bd9Sstevel@tonic-gate     struct ppp_stats oldstat;
2547c478bd9Sstevel@tonic-gate     if (strioctl(s, PPPIO_GETSTAT64, (char *)curp, 0, sizeof(*curp)) >= 0)
2557c478bd9Sstevel@tonic-gate 	return;
2567c478bd9Sstevel@tonic-gate     if (strioctl(s, PPPIO_GETSTAT, (char *)&oldstat, 0, sizeof(oldstat)) >= 0) {
2577c478bd9Sstevel@tonic-gate 	curp->p.ppp_ibytes = oldstat.p.ppp_ibytes;
2587c478bd9Sstevel@tonic-gate 	curp->p.ppp_ipackets = oldstat.p.ppp_ipackets;
2597c478bd9Sstevel@tonic-gate 	curp->p.ppp_ierrors = oldstat.p.ppp_ierrors;
2607c478bd9Sstevel@tonic-gate 	curp->p.ppp_obytes = oldstat.p.ppp_obytes;
2617c478bd9Sstevel@tonic-gate 	curp->p.ppp_opackets = oldstat.p.ppp_opackets;
2627c478bd9Sstevel@tonic-gate 	curp->p.ppp_oerrors = oldstat.p.ppp_oerrors;
2637c478bd9Sstevel@tonic-gate 	curp->vj = oldstat.vj;
2647c478bd9Sstevel@tonic-gate 	return;
2657c478bd9Sstevel@tonic-gate     }
2667c478bd9Sstevel@tonic-gate #else
2677c478bd9Sstevel@tonic-gate     if (strioctl(s, PPPIO_GETSTAT, (char *)curp, 0, sizeof(*curp)) >= 0)
2687c478bd9Sstevel@tonic-gate 	return;
2697c478bd9Sstevel@tonic-gate #endif
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate     (void) fprintf(stderr, "%s: ", progname);
2727c478bd9Sstevel@tonic-gate     if (errno == EINVAL)
2737c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "kernel support missing\n");
2747c478bd9Sstevel@tonic-gate     else
2757c478bd9Sstevel@tonic-gate 	perror("couldn't get PPP statistics");
2767c478bd9Sstevel@tonic-gate     exit(1);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate static void
get_ppp_cstats(csp)2807c478bd9Sstevel@tonic-gate get_ppp_cstats(csp)
2817c478bd9Sstevel@tonic-gate     struct ppp_comp_stats *csp;
2827c478bd9Sstevel@tonic-gate {
2837c478bd9Sstevel@tonic-gate     if (strioctl(s, PPPIO_GETCSTAT, (char *)csp, 0, sizeof(*csp)) < 0) {
2847c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: ", progname);
2857c478bd9Sstevel@tonic-gate 	if (errno == ENOTTY) {
2867c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, "no kernel compression support\n");
2877c478bd9Sstevel@tonic-gate 	    if (zflag)
2887c478bd9Sstevel@tonic-gate 		exit(1);
2897c478bd9Sstevel@tonic-gate 	    rflag = 0;
2907c478bd9Sstevel@tonic-gate 	} else {
2917c478bd9Sstevel@tonic-gate 	    perror("couldn't get PPP compression statistics");
2927c478bd9Sstevel@tonic-gate 	    exit(1);
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate     }
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate #endif /* STREAMS */
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate #define MAX0(a)		((int)(a) > 0? (a): 0)
3007c478bd9Sstevel@tonic-gate #define V(offset)	MAX0(cur.offset - old.offset)
3017c478bd9Sstevel@tonic-gate #define W(offset)	MAX0(ccs.offset - ocs.offset)
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate #define RATIO(c, i, u)	((c) == 0? 1.0: (u) / ((double)(c) + (i)))
3047c478bd9Sstevel@tonic-gate #define CRATE(x)	RATIO(W(x.comp_bytes), W(x.inc_bytes), W(x.unc_bytes))
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate #define KBPS(n)		((n) / (interval * 1000.0))
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate /*
3097c478bd9Sstevel@tonic-gate  * Print a running summary of interface statistics.
3107c478bd9Sstevel@tonic-gate  * Repeat display every interval seconds, showing statistics
3117c478bd9Sstevel@tonic-gate  * collected over that interval.  Assumes that interval is non-zero.
3127c478bd9Sstevel@tonic-gate  * First line printed is cumulative.
3137c478bd9Sstevel@tonic-gate  */
3147c478bd9Sstevel@tonic-gate static void
intpr()3157c478bd9Sstevel@tonic-gate intpr()
3167c478bd9Sstevel@tonic-gate {
3177c478bd9Sstevel@tonic-gate     register int line = 0;
3187c478bd9Sstevel@tonic-gate     sigset_t oldmask, mask;
3197c478bd9Sstevel@tonic-gate     char *bunit;
3207c478bd9Sstevel@tonic-gate     int ratef = 0;
3217c478bd9Sstevel@tonic-gate     struct ppp_stats64 cur, old;
3227c478bd9Sstevel@tonic-gate     struct ppp_comp_stats ccs, ocs;
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate     (void) memset(&old, 0, sizeof(old));
3257c478bd9Sstevel@tonic-gate     (void) memset(&ocs, 0, sizeof(ocs));
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate     for (;;) {
3287c478bd9Sstevel@tonic-gate 	get_ppp_stats(&cur);
3297c478bd9Sstevel@tonic-gate 	if (zflag || rflag)
3307c478bd9Sstevel@tonic-gate 	    get_ppp_cstats(&ccs);
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	(void)signal(SIGALRM, catchalarm);
3337c478bd9Sstevel@tonic-gate 	signalled = 0;
3347c478bd9Sstevel@tonic-gate 	(void)alarm(interval);
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 	if ((line % 20) == 0) {
3377c478bd9Sstevel@tonic-gate 	    if (zflag) {
3387c478bd9Sstevel@tonic-gate 		(void) printf("IN:  COMPRESSED  INCOMPRESSIBLE   COMP | ");
3397c478bd9Sstevel@tonic-gate 		(void) printf("OUT: COMPRESSED  INCOMPRESSIBLE   COMP\n");
3407c478bd9Sstevel@tonic-gate 		bunit = dflag? "KB/S": "BYTE";
3417c478bd9Sstevel@tonic-gate 		(void) printf("    %s   PACK     %s   PACK  RATIO | ", bunit,
3427c478bd9Sstevel@tonic-gate 		    bunit);
3437c478bd9Sstevel@tonic-gate 		(void) printf("    %s   PACK     %s   PACK  RATIO", bunit,
3447c478bd9Sstevel@tonic-gate 		    bunit);
3457c478bd9Sstevel@tonic-gate 	    } else {
3467c478bd9Sstevel@tonic-gate 		(void) printf("%8.8s %6.6s %6.6s",
3477c478bd9Sstevel@tonic-gate 		       "IN", "PACK", "VJCOMP");
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 		if (!rflag)
3507c478bd9Sstevel@tonic-gate 		    (void) printf(" %6.6s %6.6s", "VJUNC", "VJERR");
3517c478bd9Sstevel@tonic-gate 		if (vflag)
3527c478bd9Sstevel@tonic-gate 		    (void) printf(" %6.6s %6.6s", "VJTOSS", "NON-VJ");
3537c478bd9Sstevel@tonic-gate 		if (rflag)
3547c478bd9Sstevel@tonic-gate 		    (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
3557c478bd9Sstevel@tonic-gate 		(void) printf("  | %8.8s %6.6s %6.6s",
3567c478bd9Sstevel@tonic-gate 		       "OUT", "PACK", "VJCOMP");
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 		if (!rflag)
3597c478bd9Sstevel@tonic-gate 		    (void) printf(" %6.6s %6.6s", "VJUNC", "NON-VJ");
3607c478bd9Sstevel@tonic-gate 		if (vflag)
3617c478bd9Sstevel@tonic-gate 		    (void) printf(" %6.6s %6.6s", "VJSRCH", "VJMISS");
3627c478bd9Sstevel@tonic-gate 		if (rflag)
3637c478bd9Sstevel@tonic-gate 		    (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
3647c478bd9Sstevel@tonic-gate 	    }
3657c478bd9Sstevel@tonic-gate 	    (void) putchar('\n');
3667c478bd9Sstevel@tonic-gate 	}
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 	if (zflag) {
3697c478bd9Sstevel@tonic-gate 	    if (ratef) {
3707c478bd9Sstevel@tonic-gate 		(void) printf("%8.3f %6u %8.3f %6u %6.2f",
3717c478bd9Sstevel@tonic-gate 		       KBPS(W(d.comp_bytes)),
3727c478bd9Sstevel@tonic-gate 		       W(d.comp_packets),
3737c478bd9Sstevel@tonic-gate 		       KBPS(W(d.inc_bytes)),
3747c478bd9Sstevel@tonic-gate 		       W(d.inc_packets),
3757c478bd9Sstevel@tonic-gate 		       ccs.d.ratio / 256.0);
3767c478bd9Sstevel@tonic-gate 		(void) printf(" | %8.3f %6u %8.3f %6u %6.2f",
3777c478bd9Sstevel@tonic-gate 		       KBPS(W(c.comp_bytes)),
3787c478bd9Sstevel@tonic-gate 		       W(c.comp_packets),
3797c478bd9Sstevel@tonic-gate 		       KBPS(W(c.inc_bytes)),
3807c478bd9Sstevel@tonic-gate 		       W(c.inc_packets),
3817c478bd9Sstevel@tonic-gate 		       ccs.c.ratio / 256.0);
3827c478bd9Sstevel@tonic-gate 	    } else {
3837c478bd9Sstevel@tonic-gate 		(void) printf("%8u %6u %8u %6u %6.2f",
3847c478bd9Sstevel@tonic-gate 		       W(d.comp_bytes),
3857c478bd9Sstevel@tonic-gate 		       W(d.comp_packets),
3867c478bd9Sstevel@tonic-gate 		       W(d.inc_bytes),
3877c478bd9Sstevel@tonic-gate 		       W(d.inc_packets),
3887c478bd9Sstevel@tonic-gate 		       ccs.d.ratio / 256.0);
3897c478bd9Sstevel@tonic-gate 		(void) printf(" | %8u %6u %8u %6u %6.2f",
3907c478bd9Sstevel@tonic-gate 		       W(c.comp_bytes),
3917c478bd9Sstevel@tonic-gate 		       W(c.comp_packets),
3927c478bd9Sstevel@tonic-gate 		       W(c.inc_bytes),
3937c478bd9Sstevel@tonic-gate 		       W(c.inc_packets),
3947c478bd9Sstevel@tonic-gate 		       ccs.c.ratio / 256.0);
3957c478bd9Sstevel@tonic-gate 	    }
396*55fea89dSDan Cross 
3977c478bd9Sstevel@tonic-gate 	} else {
3987c478bd9Sstevel@tonic-gate 	    if (ratef)
3997c478bd9Sstevel@tonic-gate 		(void) printf("%8.3f", KBPS(V(p.ppp_ibytes)));
4007c478bd9Sstevel@tonic-gate 	    else
4017c478bd9Sstevel@tonic-gate 		(void) printf("%8" PPP_COUNTER_F, V(p.ppp_ibytes));
4027c478bd9Sstevel@tonic-gate 	    (void) printf(" %6" PPP_COUNTER_F " %6u",
4037c478bd9Sstevel@tonic-gate 		   V(p.ppp_ipackets),
4047c478bd9Sstevel@tonic-gate 		   V(vj.vjs_compressedin));
4057c478bd9Sstevel@tonic-gate 	    if (!rflag)
4067c478bd9Sstevel@tonic-gate 		(void) printf(" %6u %6u",
4077c478bd9Sstevel@tonic-gate 		       V(vj.vjs_uncompressedin),
4087c478bd9Sstevel@tonic-gate 		       V(vj.vjs_errorin));
4097c478bd9Sstevel@tonic-gate 	    if (vflag)
4107c478bd9Sstevel@tonic-gate 		(void) printf(" %6u %6" PPP_COUNTER_F,
4117c478bd9Sstevel@tonic-gate 		       V(vj.vjs_tossed),
4127c478bd9Sstevel@tonic-gate 		       V(p.ppp_ipackets) - V(vj.vjs_compressedin)
4137c478bd9Sstevel@tonic-gate 		       - V(vj.vjs_uncompressedin) - V(vj.vjs_errorin));
4147c478bd9Sstevel@tonic-gate 	    if (rflag) {
4157c478bd9Sstevel@tonic-gate 		(void) printf(" %6.2f ", CRATE(d));
4167c478bd9Sstevel@tonic-gate 		if (ratef)
4177c478bd9Sstevel@tonic-gate 		    (void) printf("%6.2f", KBPS(W(d.unc_bytes)));
4187c478bd9Sstevel@tonic-gate 		else
4197c478bd9Sstevel@tonic-gate 		    (void) printf("%6u", W(d.unc_bytes));
4207c478bd9Sstevel@tonic-gate 	    }
4217c478bd9Sstevel@tonic-gate 	    if (ratef)
4227c478bd9Sstevel@tonic-gate 		(void) printf("  | %8.3f", KBPS(V(p.ppp_obytes)));
4237c478bd9Sstevel@tonic-gate 	    else
4247c478bd9Sstevel@tonic-gate 		(void) printf("  | %8" PPP_COUNTER_F, V(p.ppp_obytes));
4257c478bd9Sstevel@tonic-gate 	    (void) printf(" %6" PPP_COUNTER_F " %6u",
4267c478bd9Sstevel@tonic-gate 		   V(p.ppp_opackets),
4277c478bd9Sstevel@tonic-gate 		   V(vj.vjs_compressed));
4287c478bd9Sstevel@tonic-gate 	    if (!rflag)
4297c478bd9Sstevel@tonic-gate 		(void) printf(" %6u %6" PPP_COUNTER_F,
4307c478bd9Sstevel@tonic-gate 		       V(vj.vjs_packets) - V(vj.vjs_compressed),
4317c478bd9Sstevel@tonic-gate 		       V(p.ppp_opackets) - V(vj.vjs_packets));
4327c478bd9Sstevel@tonic-gate 	    if (vflag)
4337c478bd9Sstevel@tonic-gate 		(void) printf(" %6u %6u",
4347c478bd9Sstevel@tonic-gate 		       V(vj.vjs_searches),
4357c478bd9Sstevel@tonic-gate 		       V(vj.vjs_misses));
4367c478bd9Sstevel@tonic-gate 	    if (rflag) {
4377c478bd9Sstevel@tonic-gate 		(void) printf(" %6.2f ", CRATE(c));
4387c478bd9Sstevel@tonic-gate 		if (ratef)
4397c478bd9Sstevel@tonic-gate 		    (void) printf("%6.2f", KBPS(W(c.unc_bytes)));
4407c478bd9Sstevel@tonic-gate 		else
4417c478bd9Sstevel@tonic-gate 		    (void) printf("%6u", W(c.unc_bytes));
4427c478bd9Sstevel@tonic-gate 	    }
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 	}
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 	(void) putchar('\n');
4477c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
4487c478bd9Sstevel@tonic-gate 	line++;
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 	count--;
4517c478bd9Sstevel@tonic-gate 	if (!infinite && !count)
4527c478bd9Sstevel@tonic-gate 	    break;
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 	(void) sigemptyset(&mask);
4557c478bd9Sstevel@tonic-gate 	(void) sigaddset(&mask, SIGALRM);
4567c478bd9Sstevel@tonic-gate 	(void) sigprocmask(SIG_BLOCK, &mask, &oldmask);
4577c478bd9Sstevel@tonic-gate 	if (!signalled) {
4587c478bd9Sstevel@tonic-gate 	    (void) sigemptyset(&mask);
4597c478bd9Sstevel@tonic-gate 	    (void) sigsuspend(&mask);
4607c478bd9Sstevel@tonic-gate 	}
4617c478bd9Sstevel@tonic-gate 	(void) sigprocmask(SIG_SETMASK, &oldmask, NULL);
4627c478bd9Sstevel@tonic-gate 	signalled = 0;
4637c478bd9Sstevel@tonic-gate 	(void)alarm(interval);
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	if (!aflag) {
4667c478bd9Sstevel@tonic-gate 	    old = cur;
4677c478bd9Sstevel@tonic-gate 	    ocs = ccs;
4687c478bd9Sstevel@tonic-gate 	    ratef = dflag;
4697c478bd9Sstevel@tonic-gate 	}
4707c478bd9Sstevel@tonic-gate     }
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate int
main(argc,argv)4747c478bd9Sstevel@tonic-gate main(argc, argv)
4757c478bd9Sstevel@tonic-gate     int argc;
4767c478bd9Sstevel@tonic-gate     char *argv[];
4777c478bd9Sstevel@tonic-gate {
4787c478bd9Sstevel@tonic-gate     int c;
4797c478bd9Sstevel@tonic-gate #ifdef STREAMS
4807c478bd9Sstevel@tonic-gate     char *dev;
4817c478bd9Sstevel@tonic-gate #endif
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate     interface = PPP_DRV_NAME "0";
4847c478bd9Sstevel@tonic-gate     if ((progname = strrchr(argv[0], '/')) == NULL)
4857c478bd9Sstevel@tonic-gate 	progname = argv[0];
4867c478bd9Sstevel@tonic-gate     else
4877c478bd9Sstevel@tonic-gate 	++progname;
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate     while ((c = getopt(argc, argv, "advrzc:w:")) != -1) {
4907c478bd9Sstevel@tonic-gate 	switch (c) {
4917c478bd9Sstevel@tonic-gate 	case 'a':
4927c478bd9Sstevel@tonic-gate 	    ++aflag;
4937c478bd9Sstevel@tonic-gate 	    break;
4947c478bd9Sstevel@tonic-gate 	case 'd':
4957c478bd9Sstevel@tonic-gate 	    ++dflag;
4967c478bd9Sstevel@tonic-gate 	    break;
4977c478bd9Sstevel@tonic-gate 	case 'v':
4987c478bd9Sstevel@tonic-gate 	    ++vflag;
4997c478bd9Sstevel@tonic-gate 	    break;
5007c478bd9Sstevel@tonic-gate 	case 'r':
5017c478bd9Sstevel@tonic-gate 	    ++rflag;
5027c478bd9Sstevel@tonic-gate 	    break;
5037c478bd9Sstevel@tonic-gate 	case 'z':
5047c478bd9Sstevel@tonic-gate 	    ++zflag;
5057c478bd9Sstevel@tonic-gate 	    break;
5067c478bd9Sstevel@tonic-gate 	case 'c':
5077c478bd9Sstevel@tonic-gate 	    count = atoi(optarg);
5087c478bd9Sstevel@tonic-gate 	    if (count <= 0)
5097c478bd9Sstevel@tonic-gate 		usage();
5107c478bd9Sstevel@tonic-gate 	    break;
5117c478bd9Sstevel@tonic-gate 	case 'w':
5127c478bd9Sstevel@tonic-gate 	    interval = atoi(optarg);
5137c478bd9Sstevel@tonic-gate 	    if (interval <= 0)
5147c478bd9Sstevel@tonic-gate 		usage();
5157c478bd9Sstevel@tonic-gate 	    break;
5167c478bd9Sstevel@tonic-gate 	default:
5177c478bd9Sstevel@tonic-gate 	    usage();
5187c478bd9Sstevel@tonic-gate 	}
5197c478bd9Sstevel@tonic-gate     }
5207c478bd9Sstevel@tonic-gate     argc -= optind;
5217c478bd9Sstevel@tonic-gate     argv += optind;
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate     if (!interval && count)
5247c478bd9Sstevel@tonic-gate 	interval = 5;
5257c478bd9Sstevel@tonic-gate     if (interval && !count)
5267c478bd9Sstevel@tonic-gate 	infinite = 1;
5277c478bd9Sstevel@tonic-gate     if (!interval && !count)
5287c478bd9Sstevel@tonic-gate 	count = 1;
5297c478bd9Sstevel@tonic-gate     if (aflag)
5307c478bd9Sstevel@tonic-gate 	dflag = 0;
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate     if (argc > 1)
5337c478bd9Sstevel@tonic-gate 	usage();
5347c478bd9Sstevel@tonic-gate     if (argc > 0)
5357c478bd9Sstevel@tonic-gate 	interface = argv[0];
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate     if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) {
5387c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: invalid interface '%s' specified\n",
5397c478bd9Sstevel@tonic-gate 		progname, interface);
5407c478bd9Sstevel@tonic-gate     }
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate #ifndef STREAMS
5437c478bd9Sstevel@tonic-gate     {
5447c478bd9Sstevel@tonic-gate 	struct ifreq ifr;
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 	s = socket(AF_INET, SOCK_DGRAM, 0);
5477c478bd9Sstevel@tonic-gate 	if (s < 0) {
5487c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, "%s: ", progname);
5497c478bd9Sstevel@tonic-gate 	    perror("couldn't create IP socket");
5507c478bd9Sstevel@tonic-gate 	    exit(1);
5517c478bd9Sstevel@tonic-gate 	}
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate #ifdef _linux_
5547c478bd9Sstevel@tonic-gate #undef  ifr_name
5557c478bd9Sstevel@tonic-gate #define ifr_name ifr_ifrn.ifrn_name
5567c478bd9Sstevel@tonic-gate #endif
5577c478bd9Sstevel@tonic-gate 	strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
5587c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
5597c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, "%s: nonexistent interface '%s' specified\n",
5607c478bd9Sstevel@tonic-gate 		    progname, interface);
5617c478bd9Sstevel@tonic-gate 	    exit(1);
5627c478bd9Sstevel@tonic-gate 	}
5637c478bd9Sstevel@tonic-gate     }
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate #else	/* STREAMS */
5667c478bd9Sstevel@tonic-gate #ifdef __osf__
5677c478bd9Sstevel@tonic-gate     dev = "/dev/streams/ppp";
5687c478bd9Sstevel@tonic-gate #else
5697c478bd9Sstevel@tonic-gate     dev = "/dev/" PPP_DRV_NAME;
5707c478bd9Sstevel@tonic-gate #endif
5717c478bd9Sstevel@tonic-gate     if ((s = open(dev, O_RDONLY)) < 0) {
5727c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: couldn't open ", progname);
5737c478bd9Sstevel@tonic-gate 	perror(dev);
5747c478bd9Sstevel@tonic-gate 	exit(1);
5757c478bd9Sstevel@tonic-gate     }
5767c478bd9Sstevel@tonic-gate     if (strioctl(s, PPPIO_ATTACH, (char *)&unit, sizeof(int), 0) < 0) {
5777c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: " PPP_DRV_NAME "%d is not available\n",
5787c478bd9Sstevel@tonic-gate 	    progname, unit);
5797c478bd9Sstevel@tonic-gate 	exit(1);
5807c478bd9Sstevel@tonic-gate     }
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate #endif	/* STREAMS */
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate     intpr();
5857c478bd9Sstevel@tonic-gate     return (0);
5867c478bd9Sstevel@tonic-gate }
587