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"
43 static const char rcsid
[] = "$Id: pppstats.c,v 1.27 1999/08/13 06:46:23 paulus Exp $";
54 #include <sys/param.h>
55 #include <sys/types.h>
56 #include <sys/ioctl.h>
59 #if defined(_linux_) && defined(__powerpc__) \
60 && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
64 #include <sys/socket.h> /* *BSD, Linux, NeXT, Ultrix etc. */
67 #include <net/ppp_defs.h>
68 #include <net/if_ppp.h>
72 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
75 #include <linux/types.h>
78 #include <linux/ppp_defs.h>
79 #include <linux/if_ppp.h>
83 #include <sys/stropts.h> /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
84 #include <net/ppp_defs.h>
85 #include <net/pppio.h>
87 #ifdef PPPIO_GETSTAT64
88 #define ppp_stats64 ppp_stats64
93 #define ppp_stats64 ppp_stats
96 static int vflag
, rflag
, zflag
; /* select type of display */
97 static int aflag
; /* print absolute values, not deltas */
98 static int dflag
; /* print data rates, not bytes */
99 static int interval
, count
;
102 static int s
; /* socket or /dev/ppp file descriptor */
103 static int signalled
; /* set if alarm goes off "early" */
104 static char *progname
;
105 static char *interface
;
107 #if defined(SUNOS4) || defined(ULTRIX) || defined(NeXT)
113 * If PPP_DRV_NAME is not defined, use the legacy "ppp" as the
116 #if !defined(PPP_DRV_NAME)
117 #define PPP_DRV_NAME "ppp"
118 #endif /* !defined(PPP_DRV_NAME) */
120 static void usage
__P((void));
121 static void catchalarm
__P((int));
122 static void get_ppp_stats
__P((struct ppp_stats64
*));
123 static void get_ppp_cstats
__P((struct ppp_comp_stats
*));
124 static void intpr
__P((void));
126 int main
__P((int, char *argv
[]));
131 (void) fprintf(stderr
,
132 "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n",
138 * Called if an interval expires before intpr has completed a loop.
139 * Sets a flag to not wait for the alarm.
153 struct ppp_stats64
*curp
;
155 struct ifpppstatsreq req
;
157 (void) memset (&req
, 0, sizeof (req
));
160 req
.stats_ptr
= (caddr_t
) &req
.stats
;
162 #define ifr_name ifr__name
165 strncpy(req
.ifr_name
, interface
, sizeof(req
.ifr_name
));
166 if (ioctl(s
, SIOCGPPPSTATS
, &req
) < 0) {
167 (void) fprintf(stderr
, "%s: ", progname
);
169 (void) fprintf(stderr
, "kernel support missing\n");
171 perror("couldn't get PPP statistics");
179 struct ppp_comp_stats
*csp
;
181 struct ifpppcstatsreq creq
;
183 (void) memset (&creq
, 0, sizeof (creq
));
186 creq
.stats_ptr
= (caddr_t
) &creq
.stats
;
188 #define ifr_name ifr__name
191 strncpy(creq
.ifr_name
, interface
, sizeof(creq
.ifr_name
));
192 if (ioctl(s
, SIOCGPPPCSTATS
, &creq
) < 0) {
193 (void) fprintf(stderr
, "%s: ", progname
);
194 if (errno
== ENOTTY
) {
195 (void) fprintf(stderr
, "no kernel compression support\n");
200 perror("couldn't get PPP compression stats");
206 if (creq
.stats
.c
.bytes_out
== 0) {
207 creq
.stats
.c
.bytes_out
= creq
.stats
.c
.comp_bytes
+ creq
.stats
.c
.inc_bytes
;
208 creq
.stats
.c
.in_count
= creq
.stats
.c
.unc_bytes
;
210 if (creq
.stats
.c
.bytes_out
== 0)
211 creq
.stats
.c
.ratio
= 0.0;
213 creq
.stats
.c
.ratio
= 256.0 * creq
.stats
.c
.in_count
/
214 creq
.stats
.c
.bytes_out
;
216 if (creq
.stats
.d
.bytes_out
== 0) {
217 creq
.stats
.d
.bytes_out
= creq
.stats
.d
.comp_bytes
+ creq
.stats
.d
.inc_bytes
;
218 creq
.stats
.d
.in_count
= creq
.stats
.d
.unc_bytes
;
220 if (creq
.stats
.d
.bytes_out
== 0)
221 creq
.stats
.d
.ratio
= 0.0;
223 creq
.stats
.d
.ratio
= 256.0 * creq
.stats
.d
.in_count
/
224 creq
.stats
.d
.bytes_out
;
233 strioctl(fd
, cmd
, ptr
, ilen
, olen
)
234 int fd
, cmd
, ilen
, olen
;
243 if (ioctl(fd
, I_STR
, &str
) == -1)
245 if (str
.ic_len
!= olen
)
246 (void) fprintf(stderr
,
247 "strioctl: expected %d bytes, got %d for cmd %x\n",
248 olen
, str
.ic_len
, cmd
);
254 struct ppp_stats64
*curp
;
256 #ifdef PPPIO_GETSTAT64
257 struct ppp_stats oldstat
;
258 if (strioctl(s
, PPPIO_GETSTAT64
, (char *)curp
, 0, sizeof(*curp
)) >= 0)
260 if (strioctl(s
, PPPIO_GETSTAT
, (char *)&oldstat
, 0, sizeof(oldstat
)) >= 0) {
261 curp
->p
.ppp_ibytes
= oldstat
.p
.ppp_ibytes
;
262 curp
->p
.ppp_ipackets
= oldstat
.p
.ppp_ipackets
;
263 curp
->p
.ppp_ierrors
= oldstat
.p
.ppp_ierrors
;
264 curp
->p
.ppp_obytes
= oldstat
.p
.ppp_obytes
;
265 curp
->p
.ppp_opackets
= oldstat
.p
.ppp_opackets
;
266 curp
->p
.ppp_oerrors
= oldstat
.p
.ppp_oerrors
;
267 curp
->vj
= oldstat
.vj
;
271 if (strioctl(s
, PPPIO_GETSTAT
, (char *)curp
, 0, sizeof(*curp
)) >= 0)
275 (void) fprintf(stderr
, "%s: ", progname
);
277 (void) fprintf(stderr
, "kernel support missing\n");
279 perror("couldn't get PPP statistics");
285 struct ppp_comp_stats
*csp
;
287 if (strioctl(s
, PPPIO_GETCSTAT
, (char *)csp
, 0, sizeof(*csp
)) < 0) {
288 (void) fprintf(stderr
, "%s: ", progname
);
289 if (errno
== ENOTTY
) {
290 (void) fprintf(stderr
, "no kernel compression support\n");
295 perror("couldn't get PPP compression statistics");
303 #define MAX0(a) ((int)(a) > 0? (a): 0)
304 #define V(offset) MAX0(cur.offset - old.offset)
305 #define W(offset) MAX0(ccs.offset - ocs.offset)
307 #define RATIO(c, i, u) ((c) == 0? 1.0: (u) / ((double)(c) + (i)))
308 #define CRATE(x) RATIO(W(x.comp_bytes), W(x.inc_bytes), W(x.unc_bytes))
310 #define KBPS(n) ((n) / (interval * 1000.0))
313 * Print a running summary of interface statistics.
314 * Repeat display every interval seconds, showing statistics
315 * collected over that interval. Assumes that interval is non-zero.
316 * First line printed is cumulative.
321 register int line
= 0;
322 sigset_t oldmask
, mask
;
325 struct ppp_stats64 cur
, old
;
326 struct ppp_comp_stats ccs
, ocs
;
328 (void) memset(&old
, 0, sizeof(old
));
329 (void) memset(&ocs
, 0, sizeof(ocs
));
334 get_ppp_cstats(&ccs
);
336 (void)signal(SIGALRM
, catchalarm
);
338 (void)alarm(interval
);
340 if ((line
% 20) == 0) {
342 (void) printf("IN: COMPRESSED INCOMPRESSIBLE COMP | ");
343 (void) printf("OUT: COMPRESSED INCOMPRESSIBLE COMP\n");
344 bunit
= dflag
? "KB/S": "BYTE";
345 (void) printf(" %s PACK %s PACK RATIO | ", bunit
,
347 (void) printf(" %s PACK %s PACK RATIO", bunit
,
350 (void) printf("%8.8s %6.6s %6.6s",
351 "IN", "PACK", "VJCOMP");
354 (void) printf(" %6.6s %6.6s", "VJUNC", "VJERR");
356 (void) printf(" %6.6s %6.6s", "VJTOSS", "NON-VJ");
358 (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
359 (void) printf(" | %8.8s %6.6s %6.6s",
360 "OUT", "PACK", "VJCOMP");
363 (void) printf(" %6.6s %6.6s", "VJUNC", "NON-VJ");
365 (void) printf(" %6.6s %6.6s", "VJSRCH", "VJMISS");
367 (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
369 (void) putchar('\n');
374 (void) printf("%8.3f %6u %8.3f %6u %6.2f",
375 KBPS(W(d
.comp_bytes
)),
377 KBPS(W(d
.inc_bytes
)),
379 ccs
.d
.ratio
/ 256.0);
380 (void) printf(" | %8.3f %6u %8.3f %6u %6.2f",
381 KBPS(W(c
.comp_bytes
)),
383 KBPS(W(c
.inc_bytes
)),
385 ccs
.c
.ratio
/ 256.0);
387 (void) printf("%8u %6u %8u %6u %6.2f",
392 ccs
.d
.ratio
/ 256.0);
393 (void) printf(" | %8u %6u %8u %6u %6.2f",
398 ccs
.c
.ratio
/ 256.0);
403 (void) printf("%8.3f", KBPS(V(p
.ppp_ibytes
)));
405 (void) printf("%8" PPP_COUNTER_F
, V(p
.ppp_ibytes
));
406 (void) printf(" %6" PPP_COUNTER_F
" %6u",
408 V(vj
.vjs_compressedin
));
410 (void) printf(" %6u %6u",
411 V(vj
.vjs_uncompressedin
),
414 (void) printf(" %6u %6" PPP_COUNTER_F
,
416 V(p
.ppp_ipackets
) - V(vj
.vjs_compressedin
)
417 - V(vj
.vjs_uncompressedin
) - V(vj
.vjs_errorin
));
419 (void) printf(" %6.2f ", CRATE(d
));
421 (void) printf("%6.2f", KBPS(W(d
.unc_bytes
)));
423 (void) printf("%6u", W(d
.unc_bytes
));
426 (void) printf(" | %8.3f", KBPS(V(p
.ppp_obytes
)));
428 (void) printf(" | %8" PPP_COUNTER_F
, V(p
.ppp_obytes
));
429 (void) printf(" %6" PPP_COUNTER_F
" %6u",
431 V(vj
.vjs_compressed
));
433 (void) printf(" %6u %6" PPP_COUNTER_F
,
434 V(vj
.vjs_packets
) - V(vj
.vjs_compressed
),
435 V(p
.ppp_opackets
) - V(vj
.vjs_packets
));
437 (void) printf(" %6u %6u",
441 (void) printf(" %6.2f ", CRATE(c
));
443 (void) printf("%6.2f", KBPS(W(c
.unc_bytes
)));
445 (void) printf("%6u", W(c
.unc_bytes
));
450 (void) putchar('\n');
451 (void) fflush(stdout
);
455 if (!infinite
&& !count
)
458 (void) sigemptyset(&mask
);
459 (void) sigaddset(&mask
, SIGALRM
);
460 (void) sigprocmask(SIG_BLOCK
, &mask
, &oldmask
);
462 (void) sigemptyset(&mask
);
463 (void) sigsuspend(&mask
);
465 (void) sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);
467 (void)alarm(interval
);
487 interface
= PPP_DRV_NAME
"0";
488 if ((progname
= strrchr(argv
[0], '/')) == NULL
)
493 while ((c
= getopt(argc
, argv
, "advrzc:w:")) != -1) {
511 count
= atoi(optarg
);
516 interval
= atoi(optarg
);
527 if (!interval
&& count
)
529 if (interval
&& !count
)
531 if (!interval
&& !count
)
541 if (sscanf(interface
, PPP_DRV_NAME
"%d", &unit
) != 1) {
542 (void) fprintf(stderr
, "%s: invalid interface '%s' specified\n",
543 progname
, interface
);
550 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
552 (void) fprintf(stderr
, "%s: ", progname
);
553 perror("couldn't create IP socket");
559 #define ifr_name ifr_ifrn.ifrn_name
561 strncpy(ifr
.ifr_name
, interface
, sizeof(ifr
.ifr_name
));
562 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0) {
563 (void) fprintf(stderr
, "%s: nonexistent interface '%s' specified\n",
564 progname
, interface
);
571 dev
= "/dev/streams/ppp";
573 dev
= "/dev/" PPP_DRV_NAME
;
575 if ((s
= open(dev
, O_RDONLY
)) < 0) {
576 (void) fprintf(stderr
, "%s: couldn't open ", progname
);
580 if (strioctl(s
, PPPIO_ATTACH
, (char *)&unit
, sizeof(int), 0) < 0) {
581 (void) fprintf(stderr
, "%s: " PPP_DRV_NAME
"%d is not available\n",