added names for IP up/down scripts
[ppp.git] / pppstats / pppstats.c
1 /*
2  * print PPP statistics:
3  *      pppstats [-i interval] [-v] [interface] [system] [core] 
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.2 1993/12/15 05:00:47 paulus Exp $";
30 #endif
31
32 #include <sys/param.h>
33 #include <sys/mbuf.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <sys/file.h>
37 #ifdef sun
38 #include <kvm.h>
39 #endif
40 #include <ctype.h>
41 #include <errno.h>
42 #include <nlist.h>
43 #include <stdio.h>
44 #include <signal.h>
45 #ifndef sun
46 #include <paths.h>
47 #endif
48
49 #include <net/if.h>
50 #include <netinet/in.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/ip.h>
53 #include <netinet/ip_var.h>
54
55 #define VJC     1
56 #include <net/slcompress.h>
57 #include <net/if_ppp.h>
58
59 #ifdef STREAMS
60 #include <sys/stream.h>
61 #include <net/ppp_str.h>
62 #endif
63
64 #ifdef STREAMS
65 struct nlist nl[] = {
66 #define N_SOFTC 0
67         { "_pii" },
68         "",
69 };
70 #else
71 struct nlist nl[] = {
72 #define N_SOFTC 0
73         { "_ppp_softc" },
74         "",
75 };
76 #endif
77
78 #ifdef sun
79 kvm_t   *kd;
80 #endif
81
82 #ifdef sun
83 char    *system = "/vmunix";
84 #else
85 char    *system = _PATH_UNIX;
86 #endif
87
88 char    *kmemf;
89 int     kflag;
90 int     vflag;
91 unsigned interval = 5;
92 int     unit;
93
94 extern  char *malloc();
95
96 main(argc, argv)
97         int argc;
98         char *argv[];
99 {
100         --argc; ++argv;
101         while (argc > 0) {
102                 if (strcmp(argv[0], "-v") == 0) {
103                         ++vflag;
104                         ++argv, --argc;
105                         continue;
106                 }
107                 if (strcmp(argv[0], "-i") == 0 && argv[1] &&
108                     isdigit(argv[1][0])) {
109                         interval = atoi(argv[1]);
110                         if (interval <= 0)
111                                 usage();
112                         ++argv, --argc;
113                         ++argv, --argc;
114                         continue;
115                 }
116                 if (isdigit(argv[0][0])) {
117                         unit = atoi(argv[0]);
118                         if (unit < 0)
119                                 usage();
120                         ++argv, --argc;
121                         continue;
122                 }
123                 if (kflag)
124                         usage();
125
126                 system = *argv;
127                 ++argv, --argc;
128                 if (argc > 0) {
129                         kmemf = *argv++;
130                         --argc;
131                         kflag++;
132                 }
133         }
134 #ifdef sun
135         /* SunOS */
136         if ((kd = kvm_open(system, kmemf, (char *)0, O_RDONLY, NULL)) == NULL) {
137           perror("kvm_open");
138           exit(1);
139         }
140 #else
141         /* BSD4.3+ */
142         if (kvm_openfiles(system, kmemf, (char *)0) == -1) {
143           fprintf(stderr, "kvm_openfiles: %s", kvm_geterr());
144           exit(1);
145         }
146 #endif
147
148 #ifdef sun
149         if (kvm_nlist(kd, nl)) {
150 #else
151         if (kvm_nlist(nl)) {
152 #endif
153           fprintf(stderr, "pppstats: can't find symbols in nlist\n");
154           exit(1);
155         }
156         intpr();
157         exit(0);
158 }
159
160 usage()
161 {
162         fprintf(stderr,"usage: pppstats [-i interval] [-v] [unit] [system] [core]\n");
163         exit(1);
164 }
165
166 u_char  signalled;                      /* set if alarm goes off "early" */
167
168 #define V(offset) ((line % 20)? sc->offset - osc->offset : sc->offset)
169
170 /*
171  * Print a running summary of interface statistics.
172  * Repeat display every interval seconds, showing statistics
173  * collected over that interval.  Assumes that interval is non-zero.
174  * First line printed at top of screen is always cumulative.
175  */
176 intpr()
177 {
178         register int line = 0;
179         int oldmask;
180 #ifdef __STDC__
181         void catchalarm(int);
182 #else
183         void catchalarm();
184 #endif
185
186 #ifdef STREAMS
187 #define STRUCT struct ppp_if_info
188 #else
189 #define STRUCT struct ppp_softc
190 #endif
191
192         STRUCT *sc, *osc;
193
194         nl[N_SOFTC].n_value += unit * sizeof(struct ppp_softc);
195         sc = (STRUCT *)malloc(sizeof(STRUCT));
196         osc = (STRUCT *)malloc(sizeof(STRUCT));
197
198         bzero((char *)osc, sizeof(STRUCT));
199
200         while (1) {
201 #ifdef sun
202                 if (kvm_read(kd, nl[N_SOFTC].n_value,
203 #else
204                 if (kvm_read(nl[N_SOFTC].n_value,
205 #endif
206                              sc, sizeof(STRUCT)) !=
207                     sizeof(STRUCT))
208                   perror("kvm_read");
209
210                 (void)signal(SIGALRM, catchalarm);
211                 signalled = 0;
212                 (void)alarm(interval);
213
214                 if ((line % 20) == 0) {
215                         printf("%6.6s %6.6s %6.6s %6.6s %6.6s",
216                                 "in", "pack", "comp", "uncomp", "err");
217                         if (vflag)
218                                 printf(" %6.6s %6.6s", "toss", "ip");
219                         printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s",
220                                 "out", "pack", "comp", "uncomp", "ip");
221                         if (vflag)
222                                 printf(" %6.6s %6.6s", "search", "miss");
223                         putchar('\n');
224                 }
225
226 #ifdef STREAMS
227 #define COMP    pii_sc_comp
228 #define STATS   pii_ifnet
229 #else
230 #define COMP    sc_comp
231 #define STATS   sc_if
232 #endif
233
234                 printf("%6d %6d %6d %6d %6d",
235 #if BSD > 43
236                         V(STATS.if_ibytes),
237 #else
238                         0,
239 #endif
240                         V(STATS.if_ipackets),
241                         V(COMP.sls_compressedin),
242                         V(COMP.sls_uncompressedin),
243                         V(COMP.sls_errorin));
244                 if (vflag)
245                         printf(" %6d %6d",
246                                 V(COMP.sls_tossed),
247                                 V(STATS.if_ipackets) -
248                                   V(COMP.sls_compressedin) -
249                                   V(COMP.sls_uncompressedin) -
250                                   V(COMP.sls_errorin));
251                 printf(" | %6d %6d %6d %6d %6d",
252 #if BSD > 43
253                         V(STATS.if_obytes),
254 #else
255                         0,
256 #endif
257                         V(STATS.if_opackets),
258                         V(COMP.sls_compressed),
259                         V(COMP.sls_packets) - V(COMP.sls_compressed),
260                         V(STATS.if_opackets) - V(COMP.sls_packets));
261                 if (vflag)
262                         printf(" %6d %6d",
263                                 V(COMP.sls_searches),
264                                 V(COMP.sls_misses));
265
266                 putchar('\n');
267                 fflush(stdout);
268                 line++;
269                 oldmask = sigblock(sigmask(SIGALRM));
270                 if (! signalled) {
271                         sigpause(0);
272                 }
273                 sigsetmask(oldmask);
274                 signalled = 0;
275                 (void)alarm(interval);
276                 bcopy((char *)sc, (char *)osc, sizeof(STRUCT));
277         }
278 }
279
280 /*
281  * Called if an interval expires before sidewaysintpr has completed a loop.
282  * Sets a flag to not wait for the alarm.
283  */
284 void catchalarm(arg)
285 int arg;
286 {
287         signalled = 1;
288 }