2 * print PPP statistics:
3 * pppstats [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]
5 * -a Show absolute values rather than deltas
6 * -d Show data rate (kB/s) rather than bytes
7 * -v Show more stats for VJ TCP header compression
8 * -r Show compression ratio
9 * -z Show compression statistics instead of default display
12 * perkins@cps.msu.edu: Added compression statistics and alternate
14 * Brad Parker (brad@cayman.com) 6/92
16 * from the original "slstats" by Van Jacobson
18 * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
19 * All rights reserved.
21 * Copyright (c) 1989 Regents of the University of California.
22 * All rights reserved.
24 * Redistribution and use in source and binary forms are permitted
25 * provided that the above copyright notice and this paragraph are
26 * duplicated in all such forms and that any documentation,
27 * advertising materials, and other materials related to such
28 * distribution and use acknowledge that the software was developed
29 * by the University of California, Berkeley. The name of the
30 * University may not be used to endorse or promote products derived
31 * from this software without specific prior written permission.
32 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
34 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
41 #pragma ident "%Z%%M% %I% %E% SMI"
44 static const char rcsid
[] = "$Id: pppstats.c,v 1.27 1999/08/13 06:46:23 paulus Exp $";
56 #include <sys/param.h>
57 #include <sys/types.h>
58 #include <sys/ioctl.h>
61 #if defined(_linux_) && defined(__powerpc__) \
62 && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
66 #include <sys/socket.h> /* *BSD, Linux, NeXT, Ultrix etc. */
69 #include <net/ppp_defs.h>
70 #include <net/if_ppp.h>
74 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
77 #include <linux/types.h>
80 #include <linux/ppp_defs.h>
81 #include <linux/if_ppp.h>
85 #include <sys/stropts.h> /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
86 #include <net/ppp_defs.h>
87 #include <net/pppio.h>
89 #ifdef PPPIO_GETSTAT64
90 #define ppp_stats64 ppp_stats64
95 #define ppp_stats64 ppp_stats
98 static int vflag
, rflag
, zflag
; /* select type of display */
99 static int aflag
; /* print absolute values, not deltas */
100 static int dflag
; /* print data rates, not bytes */
101 static int interval
, count
;
104 static int s
; /* socket or /dev/ppp file descriptor */
105 static int signalled
; /* set if alarm goes off "early" */
106 static char *progname
;
107 static char *interface
;
109 #if defined(SUNOS4) || defined(ULTRIX) || defined(NeXT)
115 * If PPP_DRV_NAME is not defined, use the legacy "ppp" as the
118 #if !defined(PPP_DRV_NAME)
119 #define PPP_DRV_NAME "ppp"
120 #endif /* !defined(PPP_DRV_NAME) */
122 static void usage
__P((void));
123 static void catchalarm
__P((int));
124 static void get_ppp_stats
__P((struct ppp_stats64
*));
125 static void get_ppp_cstats
__P((struct ppp_comp_stats
*));
126 static void intpr
__P((void));
128 int main
__P((int, char *argv
[]));
133 (void) fprintf(stderr
,
134 "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n",
140 * Called if an interval expires before intpr has completed a loop.
141 * Sets a flag to not wait for the alarm.
155 struct ppp_stats64
*curp
;
157 struct ifpppstatsreq req
;
159 (void) memset (&req
, 0, sizeof (req
));
162 req
.stats_ptr
= (caddr_t
) &req
.stats
;
164 #define ifr_name ifr__name
167 strncpy(req
.ifr_name
, interface
, sizeof(req
.ifr_name
));
168 if (ioctl(s
, SIOCGPPPSTATS
, &req
) < 0) {
169 (void) fprintf(stderr
, "%s: ", progname
);
171 (void) fprintf(stderr
, "kernel support missing\n");
173 perror("couldn't get PPP statistics");
181 struct ppp_comp_stats
*csp
;
183 struct ifpppcstatsreq creq
;
185 (void) memset (&creq
, 0, sizeof (creq
));
188 creq
.stats_ptr
= (caddr_t
) &creq
.stats
;
190 #define ifr_name ifr__name
193 strncpy(creq
.ifr_name
, interface
, sizeof(creq
.ifr_name
));
194 if (ioctl(s
, SIOCGPPPCSTATS
, &creq
) < 0) {
195 (void) fprintf(stderr
, "%s: ", progname
);
196 if (errno
== ENOTTY
) {
197 (void) fprintf(stderr
, "no kernel compression support\n");
202 perror("couldn't get PPP compression stats");
208 if (creq
.stats
.c
.bytes_out
== 0) {
209 creq
.stats
.c
.bytes_out
= creq
.stats
.c
.comp_bytes
+ creq
.stats
.c
.inc_bytes
;
210 creq
.stats
.c
.in_count
= creq
.stats
.c
.unc_bytes
;
212 if (creq
.stats
.c
.bytes_out
== 0)
213 creq
.stats
.c
.ratio
= 0.0;
215 creq
.stats
.c
.ratio
= 256.0 * creq
.stats
.c
.in_count
/
216 creq
.stats
.c
.bytes_out
;
218 if (creq
.stats
.d
.bytes_out
== 0) {
219 creq
.stats
.d
.bytes_out
= creq
.stats
.d
.comp_bytes
+ creq
.stats
.d
.inc_bytes
;
220 creq
.stats
.d
.in_count
= creq
.stats
.d
.unc_bytes
;
222 if (creq
.stats
.d
.bytes_out
== 0)
223 creq
.stats
.d
.ratio
= 0.0;
225 creq
.stats
.d
.ratio
= 256.0 * creq
.stats
.d
.in_count
/
226 creq
.stats
.d
.bytes_out
;
235 strioctl(fd
, cmd
, ptr
, ilen
, olen
)
236 int fd
, cmd
, ilen
, olen
;
245 if (ioctl(fd
, I_STR
, &str
) == -1)
247 if (str
.ic_len
!= olen
)
248 (void) fprintf(stderr
,
249 "strioctl: expected %d bytes, got %d for cmd %x\n",
250 olen
, str
.ic_len
, cmd
);
256 struct ppp_stats64
*curp
;
258 #ifdef PPPIO_GETSTAT64
259 struct ppp_stats oldstat
;
260 if (strioctl(s
, PPPIO_GETSTAT64
, (char *)curp
, 0, sizeof(*curp
)) >= 0)
262 if (strioctl(s
, PPPIO_GETSTAT
, (char *)&oldstat
, 0, sizeof(oldstat
)) >= 0) {
263 curp
->p
.ppp_ibytes
= oldstat
.p
.ppp_ibytes
;
264 curp
->p
.ppp_ipackets
= oldstat
.p
.ppp_ipackets
;
265 curp
->p
.ppp_ierrors
= oldstat
.p
.ppp_ierrors
;
266 curp
->p
.ppp_obytes
= oldstat
.p
.ppp_obytes
;
267 curp
->p
.ppp_opackets
= oldstat
.p
.ppp_opackets
;
268 curp
->p
.ppp_oerrors
= oldstat
.p
.ppp_oerrors
;
269 curp
->vj
= oldstat
.vj
;
273 if (strioctl(s
, PPPIO_GETSTAT
, (char *)curp
, 0, sizeof(*curp
)) >= 0)
277 (void) fprintf(stderr
, "%s: ", progname
);
279 (void) fprintf(stderr
, "kernel support missing\n");
281 perror("couldn't get PPP statistics");
287 struct ppp_comp_stats
*csp
;
289 if (strioctl(s
, PPPIO_GETCSTAT
, (char *)csp
, 0, sizeof(*csp
)) < 0) {
290 (void) fprintf(stderr
, "%s: ", progname
);
291 if (errno
== ENOTTY
) {
292 (void) fprintf(stderr
, "no kernel compression support\n");
297 perror("couldn't get PPP compression statistics");
305 #define MAX0(a) ((int)(a) > 0? (a): 0)
306 #define V(offset) MAX0(cur.offset - old.offset)
307 #define W(offset) MAX0(ccs.offset - ocs.offset)
309 #define RATIO(c, i, u) ((c) == 0? 1.0: (u) / ((double)(c) + (i)))
310 #define CRATE(x) RATIO(W(x.comp_bytes), W(x.inc_bytes), W(x.unc_bytes))
312 #define KBPS(n) ((n) / (interval * 1000.0))
315 * Print a running summary of interface statistics.
316 * Repeat display every interval seconds, showing statistics
317 * collected over that interval. Assumes that interval is non-zero.
318 * First line printed is cumulative.
323 register int line
= 0;
324 sigset_t oldmask
, mask
;
327 struct ppp_stats64 cur
, old
;
328 struct ppp_comp_stats ccs
, ocs
;
330 (void) memset(&old
, 0, sizeof(old
));
331 (void) memset(&ocs
, 0, sizeof(ocs
));
336 get_ppp_cstats(&ccs
);
338 (void)signal(SIGALRM
, catchalarm
);
340 (void)alarm(interval
);
342 if ((line
% 20) == 0) {
344 (void) printf("IN: COMPRESSED INCOMPRESSIBLE COMP | ");
345 (void) printf("OUT: COMPRESSED INCOMPRESSIBLE COMP\n");
346 bunit
= dflag
? "KB/S": "BYTE";
347 (void) printf(" %s PACK %s PACK RATIO | ", bunit
,
349 (void) printf(" %s PACK %s PACK RATIO", bunit
,
352 (void) printf("%8.8s %6.6s %6.6s",
353 "IN", "PACK", "VJCOMP");
356 (void) printf(" %6.6s %6.6s", "VJUNC", "VJERR");
358 (void) printf(" %6.6s %6.6s", "VJTOSS", "NON-VJ");
360 (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
361 (void) printf(" | %8.8s %6.6s %6.6s",
362 "OUT", "PACK", "VJCOMP");
365 (void) printf(" %6.6s %6.6s", "VJUNC", "NON-VJ");
367 (void) printf(" %6.6s %6.6s", "VJSRCH", "VJMISS");
369 (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
371 (void) putchar('\n');
376 (void) printf("%8.3f %6u %8.3f %6u %6.2f",
377 KBPS(W(d
.comp_bytes
)),
379 KBPS(W(d
.inc_bytes
)),
381 ccs
.d
.ratio
/ 256.0);
382 (void) printf(" | %8.3f %6u %8.3f %6u %6.2f",
383 KBPS(W(c
.comp_bytes
)),
385 KBPS(W(c
.inc_bytes
)),
387 ccs
.c
.ratio
/ 256.0);
389 (void) printf("%8u %6u %8u %6u %6.2f",
394 ccs
.d
.ratio
/ 256.0);
395 (void) printf(" | %8u %6u %8u %6u %6.2f",
400 ccs
.c
.ratio
/ 256.0);
405 (void) printf("%8.3f", KBPS(V(p
.ppp_ibytes
)));
407 (void) printf("%8" PPP_COUNTER_F
, V(p
.ppp_ibytes
));
408 (void) printf(" %6" PPP_COUNTER_F
" %6u",
410 V(vj
.vjs_compressedin
));
412 (void) printf(" %6u %6u",
413 V(vj
.vjs_uncompressedin
),
416 (void) printf(" %6u %6" PPP_COUNTER_F
,
418 V(p
.ppp_ipackets
) - V(vj
.vjs_compressedin
)
419 - V(vj
.vjs_uncompressedin
) - V(vj
.vjs_errorin
));
421 (void) printf(" %6.2f ", CRATE(d
));
423 (void) printf("%6.2f", KBPS(W(d
.unc_bytes
)));
425 (void) printf("%6u", W(d
.unc_bytes
));
428 (void) printf(" | %8.3f", KBPS(V(p
.ppp_obytes
)));
430 (void) printf(" | %8" PPP_COUNTER_F
, V(p
.ppp_obytes
));
431 (void) printf(" %6" PPP_COUNTER_F
" %6u",
433 V(vj
.vjs_compressed
));
435 (void) printf(" %6u %6" PPP_COUNTER_F
,
436 V(vj
.vjs_packets
) - V(vj
.vjs_compressed
),
437 V(p
.ppp_opackets
) - V(vj
.vjs_packets
));
439 (void) printf(" %6u %6u",
443 (void) printf(" %6.2f ", CRATE(c
));
445 (void) printf("%6.2f", KBPS(W(c
.unc_bytes
)));
447 (void) printf("%6u", W(c
.unc_bytes
));
452 (void) putchar('\n');
453 (void) fflush(stdout
);
457 if (!infinite
&& !count
)
460 (void) sigemptyset(&mask
);
461 (void) sigaddset(&mask
, SIGALRM
);
462 (void) sigprocmask(SIG_BLOCK
, &mask
, &oldmask
);
464 (void) sigemptyset(&mask
);
465 (void) sigsuspend(&mask
);
467 (void) sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);
469 (void)alarm(interval
);
489 interface
= PPP_DRV_NAME
"0";
490 if ((progname
= strrchr(argv
[0], '/')) == NULL
)
495 while ((c
= getopt(argc
, argv
, "advrzc:w:")) != -1) {
513 count
= atoi(optarg
);
518 interval
= atoi(optarg
);
529 if (!interval
&& count
)
531 if (interval
&& !count
)
533 if (!interval
&& !count
)
543 if (sscanf(interface
, PPP_DRV_NAME
"%d", &unit
) != 1) {
544 (void) fprintf(stderr
, "%s: invalid interface '%s' specified\n",
545 progname
, interface
);
552 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
554 (void) fprintf(stderr
, "%s: ", progname
);
555 perror("couldn't create IP socket");
561 #define ifr_name ifr_ifrn.ifrn_name
563 strncpy(ifr
.ifr_name
, interface
, sizeof(ifr
.ifr_name
));
564 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0) {
565 (void) fprintf(stderr
, "%s: nonexistent interface '%s' specified\n",
566 progname
, interface
);
573 dev
= "/dev/streams/ppp";
575 dev
= "/dev/" PPP_DRV_NAME
;
577 if ((s
= open(dev
, O_RDONLY
)) < 0) {
578 (void) fprintf(stderr
, "%s: couldn't open ", progname
);
582 if (strioctl(s
, PPPIO_ATTACH
, (char *)&unit
, sizeof(int), 0) < 0) {
583 (void) fprintf(stderr
, "%s: " PPP_DRV_NAME
"%d is not available\n",