]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/pppstats/pppstats.c
Fixed a typo. Poited out by Bruce & Phillipe.
[FreeBSD/FreeBSD.git] / usr.sbin / 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 1994/11/12 19:33:41 lars Exp $";
30 #endif
31
32 #include <ctype.h>
33 #include <errno.h>
34 #include <nlist.h>
35 #include <stdio.h>
36 #include <limits.h>
37 #include <signal.h>
38 #include <sys/param.h>
39 #include <sys/mbuf.h>
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <sys/sockio.h>
43 #include <sys/file.h>
44 #include <net/if.h>
45 #include <netinet/in.h>
46 #include <netinet/in_systm.h>
47 #include <netinet/ip.h>
48 #include <netinet/ip_var.h>
49
50 #define VJC     1
51 #include <net/slcompress.h>
52
53 #ifndef STREAMS
54 #include <net/if_ppp.h>
55 #endif
56
57 #ifdef STREAMS
58 #define PPP_STATS       1       /* should be defined iff it is in ppp_if.c */
59 #include <sys/stream.h>
60 #include <net/ppp_str.h>
61 #endif
62
63 #define INTERFACE_PREFIX        "ppp%d"
64 char    interface[IFNAMSIZ];
65
66 #ifdef BSD4_4
67 #define KVMLIB
68 #endif
69
70 #ifndef KVMLIB
71
72 #include <machine/pte.h>
73 #ifdef ultrix
74 #include <machine/cpu.h>
75 #endif
76
77 struct  pte *Sysmap;
78 int     kmem;
79 char    *kmemf = "/dev/kmem";
80 extern  off_t lseek();
81
82 #else   /* KVMLIB */
83
84 char    *kmemf;
85
86 #if defined(sun) || defined(BSD4_4)
87 #include <kvm.h>
88 kvm_t   *kd;
89 #define KDARG   kd,
90
91 #else   /* sun */
92 #define KDARG
93 #endif  /* sun */
94
95 #endif  /* KVMLIB */
96
97 #ifdef STREAMS
98 struct nlist nl[] = {
99 #define N_SOFTC 0
100         { "_pii" },
101         "",
102 };
103 #else
104 struct nlist nl[] = {
105 #define N_SOFTC 0
106         { "_ppp_softc" },
107         "",
108 };
109 #endif
110
111 #ifndef BSD4_4
112 char    *system = "/vmunix";
113 #else
114 #include <paths.h>
115 #if defined(__FreeBSD__) 
116         /* _PATH_UNIX is defined as "Do not use _PATH_UNIX" */
117 char    *system = NULL;
118 #else
119 char    *system = _PATH_UNIX;
120 #endif
121 #endif
122
123 int     kflag;
124 int     vflag;
125 unsigned interval = 5;
126 int     unit;
127
128 extern  char *malloc();
129
130 main(argc, argv)
131         int argc;
132         char *argv[];
133 {
134
135         char errbuf[_POSIX2_LINE_MAX];
136         --argc; ++argv;
137         while (argc > 0) {
138                 if (strcmp(argv[0], "-v") == 0) {
139                         ++vflag;
140                         ++argv, --argc;
141                         continue;
142                 }
143                 if (strcmp(argv[0], "-i") == 0 && argv[1] &&
144                     isdigit(argv[1][0])) {
145                         interval = atoi(argv[1]);
146                         if (interval <= 0)
147                                 usage();
148                         ++argv, --argc;
149                         ++argv, --argc;
150                         continue;
151                 }
152                 if (isdigit(argv[0][0])) {
153                         int s;
154                         struct ifreq ifr;
155
156                         unit = atoi(argv[0]);
157                         if (unit < 0)
158                                 usage();
159                         sprintf(interface, INTERFACE_PREFIX, unit);
160                         s = socket(AF_INET, SOCK_DGRAM, 0);
161                         if (s < 0)
162                                 err(1, "creating socket");
163                         strcpy(ifr.ifr_name, interface);
164                         if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0)
165                                 errx(1,
166                                 "unable to confirm existence of interface '%s'",
167                                 interface);
168                         ++argv, --argc;
169                         continue;
170                 }
171                 if (kflag)
172                         usage();
173
174                 system = *argv;
175                 ++argv, --argc;
176                 if (argc > 0) {
177                         kmemf = *argv++;
178                         --argc;
179                         kflag++;
180                 }
181         }
182 #ifndef KVMLIB
183         if (nlist(system, nl) < 0 || nl[0].n_type == 0) {
184                 fprintf(stderr, "%s: no namelist\n", system);
185                 exit(1);
186         }
187         kmem = open(kmemf, O_RDONLY);
188         if (kmem < 0) {
189                 perror(kmemf);
190                 exit(1);
191         }
192 #ifndef ultrix
193         if (kflag) {
194                 off_t off;
195
196                 Sysmap = (struct pte *)
197                    malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
198                 if (!Sysmap) {
199                         fputs("pppstats: can't get memory for Sysmap.\n", stderr);
200                         exit(1);
201                 }
202                 off = nl[N_SYSMAP].n_value & ~KERNBASE;
203                 (void)lseek(kmem, off, L_SET);
204                 (void)read(kmem, (char *)Sysmap,
205                     (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
206         }
207 #endif
208 #else
209 #if defined(sun) 
210         /* SunOS */
211         if ((kd = kvm_open(system, kmemf, (char *)0, O_RDONLY, NULL)) == NULL) {
212             perror("kvm_open");
213             exit(1);
214         }
215 #elif defined(BSD4_4)
216         /* BSD4.4+ */
217         if ((kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, errbuf)) == NULL) {
218             fprintf(stderr, "kvm_openfiles: %s", errbuf);
219             exit(1);
220         }
221 #else
222         /* BSD4.3+ */
223         if (kvm_openfiles(system, kmemf, (char *)0) == -1) {
224             fprintf(stderr, "kvm_openfiles: %s", kvm_geterr());
225             exit(1);
226         }
227 #endif
228
229         if (kvm_nlist(KDARG nl)) {
230             fprintf(stderr, "pppstats: can't find symbols in nlist\n");
231             exit(1);
232         }
233 #endif
234         intpr();
235         exit(0);
236 }
237
238 #ifndef KVMLIB
239 /*
240  * Seek into the kernel for a value.
241  */
242 off_t
243 klseek(fd, base, off)
244         int fd, off;
245         off_t base;
246 {
247         if (kflag) {
248 #ifdef ultrix
249                 base = K0_TO_PHYS(base);
250 #else
251                 /* get kernel pte */
252                 base &= ~KERNBASE;
253                 base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
254 #endif
255         }
256         return (lseek(fd, base, off));
257 }
258 #endif
259
260 usage()
261 {
262         fprintf(stderr,"usage: pppstats [-i interval] [-v] [unit] [system] [core]\n");
263         exit(1);
264 }
265
266 u_char  signalled;                      /* set if alarm goes off "early" */
267
268 #define V(offset) ((line % 20)? sc->offset - osc->offset : sc->offset)
269
270 #ifdef STREAMS
271 #define STRUCT  struct ppp_if_info
272 #define COMP    pii_sc_comp
273 #define STATS   pii_ifnet
274 #else
275 #define STRUCT  struct ppp_softc
276 #define COMP    sc_comp
277 #define STATS   sc_if
278 #endif
279
280 /*
281  * Print a running summary of interface statistics.
282  * Repeat display every interval seconds, showing statistics
283  * collected over that interval.  Assumes that interval is non-zero.
284  * First line printed at top of screen is always cumulative.
285  */
286 intpr()
287 {
288         register int line = 0;
289         int oldmask;
290 #ifdef __STDC__
291         void catchalarm(int);
292 #else
293         void catchalarm();
294 #endif
295
296         STRUCT *sc, *osc;
297
298         nl[N_SOFTC].n_value += unit * sizeof(STRUCT);
299         sc = (STRUCT *)malloc(sizeof(STRUCT));
300         osc = (STRUCT *)malloc(sizeof(STRUCT));
301
302         bzero((char *)osc, sizeof(STRUCT));
303
304         while (1) {
305 #ifndef KVMLIB
306             if (klseek(kmem, (off_t)nl[N_SOFTC].n_value, 0) == -1) {
307                 perror("kmem seek");
308                 exit(1);
309             }
310             if (read(kmem, (char *)sc, sizeof(STRUCT)) <= 0) {
311                 perror("kmem read");
312                 exit(1);
313             }
314 #else
315             if (kvm_read(KDARG nl[N_SOFTC].n_value, sc,
316                          sizeof(STRUCT)) != sizeof(STRUCT)) {
317                 perror("kvm_read");
318                 exit(1);
319             }
320 #endif
321
322             (void)signal(SIGALRM, catchalarm);
323             signalled = 0;
324             (void)alarm(interval);
325
326             if ((line % 20) == 0) {
327                 printf("%6.6s %6.6s %6.6s %6.6s %6.6s",
328                        "in", "pack", "comp", "uncomp", "err");
329                 if (vflag)
330                     printf(" %6.6s %6.6s", "toss", "ip");
331                 printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s",
332                        "out", "pack", "comp", "uncomp", "ip");
333                 if (vflag)
334                     printf(" %6.6s %6.6s", "search", "miss");
335                 putchar('\n');
336             }
337
338             printf("%6d %6d %6d %6d %6d",
339 #ifdef BSD4_4
340                    V(STATS.if_ibytes),
341 #else
342 #ifndef STREAMS
343                    V(sc_bytesrcvd),
344 #else
345 #ifdef PPP_STATS
346                    V(pii_stats.ppp_ibytes),
347 #else
348                    0,
349 #endif
350 #endif
351 #endif
352                    V(STATS.if_ipackets),
353                    V(COMP.sls_compressedin),
354                    V(COMP.sls_uncompressedin),
355                    V(COMP.sls_errorin));
356             if (vflag)
357                 printf(" %6d %6d",
358                        V(COMP.sls_tossed),
359                        V(STATS.if_ipackets) - V(COMP.sls_compressedin) -
360                         V(COMP.sls_uncompressedin) - V(COMP.sls_errorin));
361             printf(" | %6d %6d %6d %6d %6d",
362 #ifdef BSD4_4
363                    V(STATS.if_obytes),
364 #else
365 #ifndef STREAMS
366                    V(sc_bytessent),
367 #else
368 #ifdef PPP_STATS
369                    V(pii_stats.ppp_obytes),
370 #else
371                    0,
372 #endif
373 #endif
374 #endif
375                    V(STATS.if_opackets),
376                    V(COMP.sls_compressed),
377                    V(COMP.sls_packets) - V(COMP.sls_compressed),
378                    V(STATS.if_opackets) - V(COMP.sls_packets));
379             if (vflag)
380                 printf(" %6d %6d",
381                        V(COMP.sls_searches),
382                        V(COMP.sls_misses));
383
384             putchar('\n');
385             fflush(stdout);
386             line++;
387
388             oldmask = sigblock(sigmask(SIGALRM));
389             if (! signalled) {
390                 sigpause(0);
391             }
392             sigsetmask(oldmask);
393             signalled = 0;
394             (void)alarm(interval);
395             bcopy((char *)sc, (char *)osc, sizeof(STRUCT));
396         }
397 }
398
399 /*
400  * Called if an interval expires before sidewaysintpr has completed a loop.
401  * Sets a flag to not wait for the alarm.
402  */
403 void catchalarm(arg)
404 int arg;
405 {
406         signalled = 1;
407 }