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.
50 #include <sys/param.h>
51 #include <sys/types.h>
52 #include <sys/ioctl.h>
55 #if defined(_linux_) && defined(__powerpc__) \
56 && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
60 #include <sys/socket.h> /* *BSD, Linux, NeXT, Ultrix etc. */
63 #include <net/ppp_defs.h>
64 #include <net/if_ppp.h>
68 #include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
71 #include <linux/types.h>
74 #include <linux/ppp_defs.h>
75 #include <linux/if_ppp.h>
79 #include <sys/stropts.h> /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
80 #include <net/ppp_defs.h>
81 #include <net/pppio.h>
83 #ifdef PPPIO_GETSTAT64
84 #define ppp_stats64 ppp_stats64
89 #define ppp_stats64 ppp_stats
92 static int vflag
, rflag
, zflag
; /* select type of display */
93 static int aflag
; /* print absolute values, not deltas */
94 static int dflag
; /* print data rates, not bytes */
95 static int interval
, count
;
98 static int s
; /* socket or /dev/ppp file descriptor */
99 static int signalled
; /* set if alarm goes off "early" */
100 static char *progname
;
101 static char *interface
;
103 #if defined(SUNOS4) || defined(ULTRIX) || defined(NeXT)
109 * If PPP_DRV_NAME is not defined, use the legacy "ppp" as the
112 #if !defined(PPP_DRV_NAME)
113 #define PPP_DRV_NAME "ppp"
114 #endif /* !defined(PPP_DRV_NAME) */
116 static void usage
__P((void));
117 static void catchalarm
__P((int));
118 static void get_ppp_stats
__P((struct ppp_stats64
*));
119 static void get_ppp_cstats
__P((struct ppp_comp_stats
*));
120 static void intpr
__P((void));
122 int main
__P((int, char *argv
[]));
127 (void) fprintf(stderr
,
128 "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n",
134 * Called if an interval expires before intpr has completed a loop.
135 * Sets a flag to not wait for the alarm.
149 struct ppp_stats64
*curp
;
151 struct ifpppstatsreq req
;
153 (void) memset (&req
, 0, sizeof (req
));
156 req
.stats_ptr
= (caddr_t
) &req
.stats
;
158 #define ifr_name ifr__name
161 strncpy(req
.ifr_name
, interface
, sizeof(req
.ifr_name
));
162 if (ioctl(s
, SIOCGPPPSTATS
, &req
) < 0) {
163 (void) fprintf(stderr
, "%s: ", progname
);
165 (void) fprintf(stderr
, "kernel support missing\n");
167 perror("couldn't get PPP statistics");
175 struct ppp_comp_stats
*csp
;
177 struct ifpppcstatsreq creq
;
179 (void) memset (&creq
, 0, sizeof (creq
));
182 creq
.stats_ptr
= (caddr_t
) &creq
.stats
;
184 #define ifr_name ifr__name
187 strncpy(creq
.ifr_name
, interface
, sizeof(creq
.ifr_name
));
188 if (ioctl(s
, SIOCGPPPCSTATS
, &creq
) < 0) {
189 (void) fprintf(stderr
, "%s: ", progname
);
190 if (errno
== ENOTTY
) {
191 (void) fprintf(stderr
, "no kernel compression support\n");
196 perror("couldn't get PPP compression stats");
202 if (creq
.stats
.c
.bytes_out
== 0) {
203 creq
.stats
.c
.bytes_out
= creq
.stats
.c
.comp_bytes
+ creq
.stats
.c
.inc_bytes
;
204 creq
.stats
.c
.in_count
= creq
.stats
.c
.unc_bytes
;
206 if (creq
.stats
.c
.bytes_out
== 0)
207 creq
.stats
.c
.ratio
= 0.0;
209 creq
.stats
.c
.ratio
= 256.0 * creq
.stats
.c
.in_count
/
210 creq
.stats
.c
.bytes_out
;
212 if (creq
.stats
.d
.bytes_out
== 0) {
213 creq
.stats
.d
.bytes_out
= creq
.stats
.d
.comp_bytes
+ creq
.stats
.d
.inc_bytes
;
214 creq
.stats
.d
.in_count
= creq
.stats
.d
.unc_bytes
;
216 if (creq
.stats
.d
.bytes_out
== 0)
217 creq
.stats
.d
.ratio
= 0.0;
219 creq
.stats
.d
.ratio
= 256.0 * creq
.stats
.d
.in_count
/
220 creq
.stats
.d
.bytes_out
;
229 strioctl(fd
, cmd
, ptr
, ilen
, olen
)
230 int fd
, cmd
, ilen
, olen
;
239 if (ioctl(fd
, I_STR
, &str
) == -1)
241 if (str
.ic_len
!= olen
)
242 (void) fprintf(stderr
,
243 "strioctl: expected %d bytes, got %d for cmd %x\n",
244 olen
, str
.ic_len
, cmd
);
250 struct ppp_stats64
*curp
;
252 #ifdef PPPIO_GETSTAT64
253 struct ppp_stats oldstat
;
254 if (strioctl(s
, PPPIO_GETSTAT64
, (char *)curp
, 0, sizeof(*curp
)) >= 0)
256 if (strioctl(s
, PPPIO_GETSTAT
, (char *)&oldstat
, 0, sizeof(oldstat
)) >= 0) {
257 curp
->p
.ppp_ibytes
= oldstat
.p
.ppp_ibytes
;
258 curp
->p
.ppp_ipackets
= oldstat
.p
.ppp_ipackets
;
259 curp
->p
.ppp_ierrors
= oldstat
.p
.ppp_ierrors
;
260 curp
->p
.ppp_obytes
= oldstat
.p
.ppp_obytes
;
261 curp
->p
.ppp_opackets
= oldstat
.p
.ppp_opackets
;
262 curp
->p
.ppp_oerrors
= oldstat
.p
.ppp_oerrors
;
263 curp
->vj
= oldstat
.vj
;
267 if (strioctl(s
, PPPIO_GETSTAT
, (char *)curp
, 0, sizeof(*curp
)) >= 0)
271 (void) fprintf(stderr
, "%s: ", progname
);
273 (void) fprintf(stderr
, "kernel support missing\n");
275 perror("couldn't get PPP statistics");
281 struct ppp_comp_stats
*csp
;
283 if (strioctl(s
, PPPIO_GETCSTAT
, (char *)csp
, 0, sizeof(*csp
)) < 0) {
284 (void) fprintf(stderr
, "%s: ", progname
);
285 if (errno
== ENOTTY
) {
286 (void) fprintf(stderr
, "no kernel compression support\n");
291 perror("couldn't get PPP compression statistics");
299 #define MAX0(a) ((int)(a) > 0? (a): 0)
300 #define V(offset) MAX0(cur.offset - old.offset)
301 #define W(offset) MAX0(ccs.offset - ocs.offset)
303 #define RATIO(c, i, u) ((c) == 0? 1.0: (u) / ((double)(c) + (i)))
304 #define CRATE(x) RATIO(W(x.comp_bytes), W(x.inc_bytes), W(x.unc_bytes))
306 #define KBPS(n) ((n) / (interval * 1000.0))
309 * Print a running summary of interface statistics.
310 * Repeat display every interval seconds, showing statistics
311 * collected over that interval. Assumes that interval is non-zero.
312 * First line printed is cumulative.
317 register int line
= 0;
318 sigset_t oldmask
, mask
;
321 struct ppp_stats64 cur
, old
;
322 struct ppp_comp_stats ccs
, ocs
;
324 (void) memset(&old
, 0, sizeof(old
));
325 (void) memset(&ocs
, 0, sizeof(ocs
));
330 get_ppp_cstats(&ccs
);
332 (void)signal(SIGALRM
, catchalarm
);
334 (void)alarm(interval
);
336 if ((line
% 20) == 0) {
338 (void) printf("IN: COMPRESSED INCOMPRESSIBLE COMP | ");
339 (void) printf("OUT: COMPRESSED INCOMPRESSIBLE COMP\n");
340 bunit
= dflag
? "KB/S": "BYTE";
341 (void) printf(" %s PACK %s PACK RATIO | ", bunit
,
343 (void) printf(" %s PACK %s PACK RATIO", bunit
,
346 (void) printf("%8.8s %6.6s %6.6s",
347 "IN", "PACK", "VJCOMP");
350 (void) printf(" %6.6s %6.6s", "VJUNC", "VJERR");
352 (void) printf(" %6.6s %6.6s", "VJTOSS", "NON-VJ");
354 (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
355 (void) printf(" | %8.8s %6.6s %6.6s",
356 "OUT", "PACK", "VJCOMP");
359 (void) printf(" %6.6s %6.6s", "VJUNC", "NON-VJ");
361 (void) printf(" %6.6s %6.6s", "VJSRCH", "VJMISS");
363 (void) printf(" %6.6s %6.6s", "RATIO", "UBYTE");
365 (void) putchar('\n');
370 (void) printf("%8.3f %6u %8.3f %6u %6.2f",
371 KBPS(W(d
.comp_bytes
)),
373 KBPS(W(d
.inc_bytes
)),
375 ccs
.d
.ratio
/ 256.0);
376 (void) printf(" | %8.3f %6u %8.3f %6u %6.2f",
377 KBPS(W(c
.comp_bytes
)),
379 KBPS(W(c
.inc_bytes
)),
381 ccs
.c
.ratio
/ 256.0);
383 (void) printf("%8u %6u %8u %6u %6.2f",
388 ccs
.d
.ratio
/ 256.0);
389 (void) printf(" | %8u %6u %8u %6u %6.2f",
394 ccs
.c
.ratio
/ 256.0);
399 (void) printf("%8.3f", KBPS(V(p
.ppp_ibytes
)));
401 (void) printf("%8" PPP_COUNTER_F
, V(p
.ppp_ibytes
));
402 (void) printf(" %6" PPP_COUNTER_F
" %6u",
404 V(vj
.vjs_compressedin
));
406 (void) printf(" %6u %6u",
407 V(vj
.vjs_uncompressedin
),
410 (void) printf(" %6u %6" PPP_COUNTER_F
,
412 V(p
.ppp_ipackets
) - V(vj
.vjs_compressedin
)
413 - V(vj
.vjs_uncompressedin
) - V(vj
.vjs_errorin
));
415 (void) printf(" %6.2f ", CRATE(d
));
417 (void) printf("%6.2f", KBPS(W(d
.unc_bytes
)));
419 (void) printf("%6u", W(d
.unc_bytes
));
422 (void) printf(" | %8.3f", KBPS(V(p
.ppp_obytes
)));
424 (void) printf(" | %8" PPP_COUNTER_F
, V(p
.ppp_obytes
));
425 (void) printf(" %6" PPP_COUNTER_F
" %6u",
427 V(vj
.vjs_compressed
));
429 (void) printf(" %6u %6" PPP_COUNTER_F
,
430 V(vj
.vjs_packets
) - V(vj
.vjs_compressed
),
431 V(p
.ppp_opackets
) - V(vj
.vjs_packets
));
433 (void) printf(" %6u %6u",
437 (void) printf(" %6.2f ", CRATE(c
));
439 (void) printf("%6.2f", KBPS(W(c
.unc_bytes
)));
441 (void) printf("%6u", W(c
.unc_bytes
));
446 (void) putchar('\n');
447 (void) fflush(stdout
);
451 if (!infinite
&& !count
)
454 (void) sigemptyset(&mask
);
455 (void) sigaddset(&mask
, SIGALRM
);
456 (void) sigprocmask(SIG_BLOCK
, &mask
, &oldmask
);
458 (void) sigemptyset(&mask
);
459 (void) sigsuspend(&mask
);
461 (void) sigprocmask(SIG_SETMASK
, &oldmask
, NULL
);
463 (void)alarm(interval
);
483 interface
= PPP_DRV_NAME
"0";
484 if ((progname
= strrchr(argv
[0], '/')) == NULL
)
489 while ((c
= getopt(argc
, argv
, "advrzc:w:")) != -1) {
507 count
= atoi(optarg
);
512 interval
= atoi(optarg
);
523 if (!interval
&& count
)
525 if (interval
&& !count
)
527 if (!interval
&& !count
)
537 if (sscanf(interface
, PPP_DRV_NAME
"%d", &unit
) != 1) {
538 (void) fprintf(stderr
, "%s: invalid interface '%s' specified\n",
539 progname
, interface
);
546 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
548 (void) fprintf(stderr
, "%s: ", progname
);
549 perror("couldn't create IP socket");
555 #define ifr_name ifr_ifrn.ifrn_name
557 strncpy(ifr
.ifr_name
, interface
, sizeof(ifr
.ifr_name
));
558 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0) {
559 (void) fprintf(stderr
, "%s: nonexistent interface '%s' specified\n",
560 progname
, interface
);
567 dev
= "/dev/streams/ppp";
569 dev
= "/dev/" PPP_DRV_NAME
;
571 if ((s
= open(dev
, O_RDONLY
)) < 0) {
572 (void) fprintf(stderr
, "%s: couldn't open ", progname
);
576 if (strioctl(s
, PPPIO_ATTACH
, (char *)&unit
, sizeof(int), 0) < 0) {
577 (void) fprintf(stderr
, "%s: " PPP_DRV_NAME
"%d is not available\n",