added papcrypt option
[ppp.git] / pppstats / pppstats.c
1 /*
2  * print PPP statistics:
3  *      pppstats [-i interval] [-v] [interface]
4  *
5  *      Brad Parker (brad@cayman.com) 6/92
6  *
7  * from the original "slstats" by Van Jaconson
8  *
9  * Copyright (c) 1989 Regents of the University of California.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms are permitted
13  * provided that the above copyright notice and this paragraph are
14  * duplicated in all such forms and that any documentation,
15  * advertising materials, and other materials related to such
16  * distribution and use acknowledge that the software was developed
17  * by the University of California, Berkeley.  The name of the
18  * University may not be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
22  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23  *
24  *      Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
25  *      - Initial distribution.
26  */
27
28 #ifndef lint
29 static char rcsid[] = "$Id: pppstats.c,v 1.6 1994/09/21 01:52:58 paulus Exp $";
30 #endif
31
32 #include <ctype.h>
33 #include <errno.h>
34 #include <nlist.h>
35 #include <stdio.h>
36 #include <signal.h>
37 #include <sys/param.h>
38 #include <sys/mbuf.h>
39 #include <sys/types.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
42 #include <sys/file.h>
43 #include <net/if.h>
44 #include <netinet/in.h>
45 #include <netinet/in_systm.h>
46 #include <netinet/ip.h>
47 #include <netinet/ip_var.h>
48
49 #include <net/ppp_defs.h>
50
51 #ifndef STREAMS
52 #include <net/if_ppp.h>
53 #endif
54
55 #ifdef STREAMS
56 #define PPP_STATS       1       /* should be defined iff it is in ppp_if.c */
57 #include <sys/stream.h>
58 #include <net/ppp_str.h>
59 #endif
60
61 int     vflag;
62 unsigned interval = 5;
63 int     unit;
64 int     s;                      /* socket file descriptor */
65 int     signalled;              /* set if alarm goes off "early" */
66
67 extern  char *malloc();
68 void catchalarm __P((int));
69
70 main(argc, argv)
71     int argc;
72     char *argv[];
73 {
74     --argc; ++argv;
75     while (argc > 0) {
76         if (strcmp(argv[0], "-v") == 0) {
77             ++vflag;
78             ++argv, --argc;
79             continue;
80         }
81         if (strcmp(argv[0], "-i") == 0 && argv[1] &&
82             isdigit(argv[1][0])) {
83             interval = atoi(argv[1]);
84             if (interval <= 0)
85                 usage();
86             ++argv, --argc;
87             ++argv, --argc;
88             continue;
89         }
90         if (isdigit(argv[0][0])) {
91             unit = atoi(argv[0]);
92             if (unit < 0)
93                 usage();
94             ++argv, --argc;
95             continue;
96         }
97         usage();
98     }
99     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
100         perror("couldn't create IP socket");
101         exit(1);
102     }
103     intpr();
104     exit(0);
105 }
106
107 usage()
108 {
109     fprintf(stderr, "Usage: pppstats [-v] [-i interval] [unit]\n");
110     exit(1);
111 }
112
113 #define V(offset) (line % 20? req.stats.offset - osc.offset: req.stats.offset)
114
115 /*
116  * Print a running summary of interface statistics.
117  * Repeat display every interval seconds, showing statistics
118  * collected over that interval.  Assumes that interval is non-zero.
119  * First line printed at top of screen is always cumulative.
120  */
121 intpr()
122 {
123     register int line = 0;
124     int oldmask;
125     struct ifpppstatsreq req;
126     struct ppp_stats osc;
127
128     bzero(&osc, sizeof(osc));
129
130     sprintf(req.ifr_name, "ppp%d", unit);
131     while (1) {
132         if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
133             if (errno == ENOTTY)
134                 fprintf(stderr, "pppstats: kernel support missing\n");
135             else
136                 perror("ioctl(SIOCGPPPSTATS)");
137             exit(1);
138         }
139         (void)signal(SIGALRM, catchalarm);
140         signalled = 0;
141         (void)alarm(interval);
142
143         if ((line % 20) == 0) {
144             printf("%6.6s %6.6s %6.6s %6.6s %6.6s",
145                    "in", "pack", "comp", "uncomp", "err");
146             if (vflag)
147                 printf(" %6.6s %6.6s", "toss", "ip");
148             printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s",
149                    "out", "pack", "comp", "uncomp", "ip");
150             if (vflag)
151                 printf(" %6.6s %6.6s", "search", "miss");
152             putchar('\n');
153         }
154
155         printf("%6d %6d %6d %6d %6d", V(p.ppp_ibytes),
156                V(p.ppp_ipackets), V(vj.vjs_compressedin),
157                V(vj.vjs_uncompressedin), V(vj.vjs_errorin));
158         if (vflag)
159             printf(" %6d %6d", V(vj.vjs_tossed),
160                    V(p.ppp_ipackets) - V(vj.vjs_compressedin) -
161                      V(vj.vjs_uncompressedin) - V(vj.vjs_errorin));
162         printf(" | %6d %6d %6d %6d %6d", V(p.ppp_obytes),
163                V(p.ppp_opackets), V(vj.vjs_compressed),
164                V(vj.vjs_packets) - V(vj.vjs_compressed),
165                V(p.ppp_opackets) - V(vj.vjs_packets));
166         if (vflag)
167             printf(" %6d %6d", V(vj.vjs_searches), V(vj.vjs_misses));
168
169         putchar('\n');
170         fflush(stdout);
171         line++;
172
173         oldmask = sigblock(sigmask(SIGALRM));
174         if (! signalled) {
175             sigpause(0);
176         }
177         sigsetmask(oldmask);
178         signalled = 0;
179         (void)alarm(interval);
180         osc = req.stats;
181     }
182 }
183
184 /*
185  * Called if an interval expires before sidewaysintpr has completed a loop.
186  * Sets a flag to not wait for the alarm.
187  */
188 void catchalarm(arg)
189     int arg;
190 {
191     signalled = 1;
192 }