1 | /*- |
---|
2 | * Copyright (c) 1983, 1988, 1993 |
---|
3 | * The Regents of the University of California. All rights reserved. |
---|
4 | * |
---|
5 | * Redistribution and use in source and binary forms, with or without |
---|
6 | * modification, are permitted provided that the following conditions |
---|
7 | * are met: |
---|
8 | * 1. Redistributions of source code must retain the above copyright |
---|
9 | * notice, this list of conditions and the following disclaimer. |
---|
10 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer in the |
---|
12 | * documentation and/or other materials provided with the distribution. |
---|
13 | * 3. All advertising materials mentioning features or use of this software |
---|
14 | * must display the following acknowledgement: |
---|
15 | * This product includes software developed by the University of |
---|
16 | * California, Berkeley and its contributors. |
---|
17 | * 4. Neither the name of the University nor the names of its contributors |
---|
18 | * may be used to endorse or promote products derived from this software |
---|
19 | * without specific prior written permission. |
---|
20 | * |
---|
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
31 | * SUCH DAMAGE. |
---|
32 | */ |
---|
33 | |
---|
34 | #if 0 |
---|
35 | #ifndef lint |
---|
36 | static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95"; |
---|
37 | #endif /* not lint */ |
---|
38 | #endif |
---|
39 | |
---|
40 | #include <sys/cdefs.h> |
---|
41 | __FBSDID("$FreeBSD$"); |
---|
42 | |
---|
43 | #include <sys/types.h> |
---|
44 | #ifdef __rtems__ |
---|
45 | #include <freebsd/sys/protosw.h> |
---|
46 | #else |
---|
47 | #include <sys/protosw.h> |
---|
48 | #endif |
---|
49 | #include <sys/socket.h> |
---|
50 | #include <sys/socketvar.h> |
---|
51 | #include <sys/sysctl.h> |
---|
52 | #include <sys/time.h> |
---|
53 | |
---|
54 | #include <net/if.h> |
---|
55 | #ifdef __rtems__ |
---|
56 | #include <freebsd/net/if_var.h> |
---|
57 | #else |
---|
58 | #include <net/if_var.h> |
---|
59 | #endif |
---|
60 | #include <net/if_dl.h> |
---|
61 | #include <net/if_types.h> |
---|
62 | #include <net/ethernet.h> |
---|
63 | #ifdef __rtems__ |
---|
64 | #include <freebsd/net/pfvar.h> |
---|
65 | #include <freebsd/net/if_pfsync.h> |
---|
66 | #include <netinet/in.h> |
---|
67 | #include <freebsd/netinet/in_var.h> |
---|
68 | /* IPX not on RTEMS */ |
---|
69 | /* #include <netipx/ipx.h> */ |
---|
70 | /* #include <netipx/ipx_if.h> */ |
---|
71 | #else |
---|
72 | #include <net/pfvar.h> |
---|
73 | #include <net/if_pfsync.h> |
---|
74 | #include <netinet/in.h> |
---|
75 | #include <netinet/in_var.h> |
---|
76 | #include <netipx/ipx.h> |
---|
77 | #include <netipx/ipx_if.h> |
---|
78 | #endif |
---|
79 | #include <arpa/inet.h> |
---|
80 | |
---|
81 | #include <err.h> |
---|
82 | #include <errno.h> |
---|
83 | #include <libutil.h> |
---|
84 | #include <signal.h> |
---|
85 | #include <stdint.h> |
---|
86 | #include <stdio.h> |
---|
87 | #include <stdlib.h> |
---|
88 | #include <string.h> |
---|
89 | #include <unistd.h> |
---|
90 | |
---|
91 | #include "netstat.h" |
---|
92 | |
---|
93 | #define YES 1 |
---|
94 | #define NO 0 |
---|
95 | |
---|
96 | static void sidewaysintpr(int, u_long); |
---|
97 | static void catchalarm(int); |
---|
98 | |
---|
99 | #ifdef INET6 |
---|
100 | static char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */ |
---|
101 | #endif |
---|
102 | |
---|
103 | /* |
---|
104 | * Dump pfsync statistics structure. |
---|
105 | */ |
---|
106 | void |
---|
107 | pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused) |
---|
108 | { |
---|
109 | struct pfsyncstats pfsyncstat, zerostat; |
---|
110 | size_t len = sizeof(struct pfsyncstats); |
---|
111 | |
---|
112 | if (live) { |
---|
113 | if (zflag) |
---|
114 | memset(&zerostat, 0, len); |
---|
115 | if (sysctlbyname("net.inet.pfsync.stats", &pfsyncstat, &len, |
---|
116 | zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { |
---|
117 | if (errno != ENOENT) |
---|
118 | warn("sysctl: net.inet.pfsync.stats"); |
---|
119 | return; |
---|
120 | } |
---|
121 | } else |
---|
122 | kread(off, &pfsyncstat, len); |
---|
123 | |
---|
124 | printf("%s:\n", name); |
---|
125 | |
---|
126 | #define p(f, m) if (pfsyncstat.f || sflag <= 1) \ |
---|
127 | printf(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f)) |
---|
128 | #define p2(f, m) if (pfsyncstat.f || sflag <= 1) \ |
---|
129 | printf(m, (uintmax_t)pfsyncstat.f) |
---|
130 | |
---|
131 | p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n"); |
---|
132 | p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n"); |
---|
133 | p(pfsyncs_badif, "\t\t%ju packet%s discarded for bad interface\n"); |
---|
134 | p(pfsyncs_badttl, "\t\t%ju packet%s discarded for bad ttl\n"); |
---|
135 | p(pfsyncs_hdrops, "\t\t%ju packet%s shorter than header\n"); |
---|
136 | p(pfsyncs_badver, "\t\t%ju packet%s discarded for bad version\n"); |
---|
137 | p(pfsyncs_badauth, "\t\t%ju packet%s discarded for bad HMAC\n"); |
---|
138 | p(pfsyncs_badact,"\t\t%ju packet%s discarded for bad action\n"); |
---|
139 | p(pfsyncs_badlen, "\t\t%ju packet%s discarded for short packet\n"); |
---|
140 | p(pfsyncs_badval, "\t\t%ju state%s discarded for bad values\n"); |
---|
141 | p(pfsyncs_stale, "\t\t%ju stale state%s\n"); |
---|
142 | p(pfsyncs_badstate, "\t\t%ju failed state lookup/insert%s\n"); |
---|
143 | p(pfsyncs_opackets, "\t%ju packet%s sent (IPv4)\n"); |
---|
144 | p(pfsyncs_opackets6, "\t%ju packet%s sent (IPv6)\n"); |
---|
145 | p2(pfsyncs_onomem, "\t\t%ju send failed due to mbuf memory error\n"); |
---|
146 | p2(pfsyncs_oerrors, "\t\t%ju send error\n"); |
---|
147 | #undef p |
---|
148 | #undef p2 |
---|
149 | } |
---|
150 | |
---|
151 | /* |
---|
152 | * Display a formatted value, or a '-' in the same space. |
---|
153 | */ |
---|
154 | static void |
---|
155 | show_stat(const char *fmt, int width, u_long value, short showvalue) |
---|
156 | { |
---|
157 | const char *lsep, *rsep; |
---|
158 | char newfmt[32]; |
---|
159 | |
---|
160 | lsep = ""; |
---|
161 | if (strncmp(fmt, "LS", 2) == 0) { |
---|
162 | lsep = " "; |
---|
163 | fmt += 2; |
---|
164 | } |
---|
165 | rsep = " "; |
---|
166 | if (strncmp(fmt, "NRS", 3) == 0) { |
---|
167 | rsep = ""; |
---|
168 | fmt += 3; |
---|
169 | } |
---|
170 | if (showvalue == 0) { |
---|
171 | /* Print just dash. */ |
---|
172 | sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep); |
---|
173 | printf(newfmt, "-"); |
---|
174 | return; |
---|
175 | } |
---|
176 | |
---|
177 | if (hflag) { |
---|
178 | char buf[5]; |
---|
179 | |
---|
180 | /* Format in human readable form. */ |
---|
181 | humanize_number(buf, sizeof(buf), (int64_t)value, "", |
---|
182 | HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL); |
---|
183 | sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep); |
---|
184 | printf(newfmt, buf); |
---|
185 | } else { |
---|
186 | /* Construct the format string. */ |
---|
187 | sprintf(newfmt, "%s%%%d%s%s", lsep, width, fmt, rsep); |
---|
188 | printf(newfmt, value); |
---|
189 | } |
---|
190 | } |
---|
191 | |
---|
192 | /* |
---|
193 | * Print a description of the network interfaces. |
---|
194 | */ |
---|
195 | void |
---|
196 | intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) |
---|
197 | { |
---|
198 | struct ifnet ifnet; |
---|
199 | struct ifnethead ifnethead; |
---|
200 | union { |
---|
201 | struct ifaddr ifa; |
---|
202 | struct in_ifaddr in; |
---|
203 | #ifdef INET6 |
---|
204 | struct in6_ifaddr in6; |
---|
205 | #endif |
---|
206 | #ifndef __rtems__ |
---|
207 | struct ipx_ifaddr ipx; |
---|
208 | #endif |
---|
209 | } ifaddr; |
---|
210 | u_long ifaddraddr; |
---|
211 | u_long ifaddrfound; |
---|
212 | u_long ifnetfound; |
---|
213 | u_long opackets; |
---|
214 | u_long ipackets; |
---|
215 | u_long obytes; |
---|
216 | u_long ibytes; |
---|
217 | u_long omcasts; |
---|
218 | u_long imcasts; |
---|
219 | u_long oerrors; |
---|
220 | u_long ierrors; |
---|
221 | u_long idrops; |
---|
222 | u_long collisions; |
---|
223 | short timer; |
---|
224 | int drops; |
---|
225 | struct sockaddr *sa = NULL; |
---|
226 | char name[IFNAMSIZ]; |
---|
227 | short network_layer; |
---|
228 | short link_layer; |
---|
229 | |
---|
230 | if (ifnetaddr == 0) { |
---|
231 | printf("ifnet: symbol not defined\n"); |
---|
232 | return; |
---|
233 | } |
---|
234 | if (interval1) { |
---|
235 | sidewaysintpr(interval1, ifnetaddr); |
---|
236 | return; |
---|
237 | } |
---|
238 | if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead) != 0) |
---|
239 | return; |
---|
240 | ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead); |
---|
241 | if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0) |
---|
242 | return; |
---|
243 | |
---|
244 | if (!pfunc) { |
---|
245 | if (Wflag) |
---|
246 | printf("%-7.7s", "Name"); |
---|
247 | else |
---|
248 | printf("%-5.5s", "Name"); |
---|
249 | printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s", |
---|
250 | "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop"); |
---|
251 | if (bflag) |
---|
252 | printf(" %10.10s","Ibytes"); |
---|
253 | printf(" %8.8s %5.5s", "Opkts", "Oerrs"); |
---|
254 | if (bflag) |
---|
255 | printf(" %10.10s","Obytes"); |
---|
256 | printf(" %5s", "Coll"); |
---|
257 | if (tflag) |
---|
258 | printf(" %s", "Time"); |
---|
259 | if (dflag) |
---|
260 | printf(" %s", "Drop"); |
---|
261 | putchar('\n'); |
---|
262 | } |
---|
263 | ifaddraddr = 0; |
---|
264 | while (ifnetaddr || ifaddraddr) { |
---|
265 | struct sockaddr_in *sockin; |
---|
266 | #ifdef INET6 |
---|
267 | struct sockaddr_in6 *sockin6; |
---|
268 | #endif |
---|
269 | char *cp; |
---|
270 | int n, m; |
---|
271 | |
---|
272 | network_layer = 0; |
---|
273 | link_layer = 0; |
---|
274 | |
---|
275 | if (ifaddraddr == 0) { |
---|
276 | ifnetfound = ifnetaddr; |
---|
277 | if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0) |
---|
278 | return; |
---|
279 | strlcpy(name, ifnet.if_xname, sizeof(name)); |
---|
280 | ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link); |
---|
281 | if (interface != 0 && strcmp(name, interface) != 0) |
---|
282 | continue; |
---|
283 | cp = index(name, '\0'); |
---|
284 | |
---|
285 | if (pfunc) { |
---|
286 | (*pfunc)(name); |
---|
287 | continue; |
---|
288 | } |
---|
289 | |
---|
290 | if ((ifnet.if_flags&IFF_UP) == 0) |
---|
291 | *cp++ = '*'; |
---|
292 | *cp = '\0'; |
---|
293 | ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead); |
---|
294 | } |
---|
295 | ifaddrfound = ifaddraddr; |
---|
296 | |
---|
297 | /* |
---|
298 | * Get the interface stats. These may get |
---|
299 | * overriden below on a per-interface basis. |
---|
300 | */ |
---|
301 | opackets = ifnet.if_opackets; |
---|
302 | ipackets = ifnet.if_ipackets; |
---|
303 | obytes = ifnet.if_obytes; |
---|
304 | ibytes = ifnet.if_ibytes; |
---|
305 | omcasts = ifnet.if_omcasts; |
---|
306 | imcasts = ifnet.if_imcasts; |
---|
307 | oerrors = ifnet.if_oerrors; |
---|
308 | ierrors = ifnet.if_ierrors; |
---|
309 | idrops = ifnet.if_iqdrops; |
---|
310 | collisions = ifnet.if_collisions; |
---|
311 | timer = ifnet.if_timer; |
---|
312 | drops = ifnet.if_snd.ifq_drops; |
---|
313 | |
---|
314 | if (ifaddraddr == 0) { |
---|
315 | if (Wflag) |
---|
316 | printf("%-7.7s", name); |
---|
317 | else |
---|
318 | printf("%-5.5s", name); |
---|
319 | printf(" %5lu ", ifnet.if_mtu); |
---|
320 | printf("%-13.13s ", "none"); |
---|
321 | printf("%-17.17s ", "none"); |
---|
322 | } else { |
---|
323 | if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr) |
---|
324 | != 0) { |
---|
325 | ifaddraddr = 0; |
---|
326 | continue; |
---|
327 | } |
---|
328 | #define CP(x) ((char *)(x)) |
---|
329 | cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + |
---|
330 | CP(&ifaddr); |
---|
331 | sa = (struct sockaddr *)cp; |
---|
332 | if (af != AF_UNSPEC && sa->sa_family != af) { |
---|
333 | ifaddraddr = |
---|
334 | (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); |
---|
335 | continue; |
---|
336 | } |
---|
337 | if (Wflag) |
---|
338 | printf("%-7.7s", name); |
---|
339 | else |
---|
340 | printf("%-5.5s", name); |
---|
341 | printf(" %5lu ", ifnet.if_mtu); |
---|
342 | switch (sa->sa_family) { |
---|
343 | case AF_UNSPEC: |
---|
344 | printf("%-13.13s ", "none"); |
---|
345 | printf("%-15.15s ", "none"); |
---|
346 | break; |
---|
347 | case AF_INET: |
---|
348 | sockin = (struct sockaddr_in *)sa; |
---|
349 | #ifdef notdef |
---|
350 | /* can't use inet_makeaddr because kernel |
---|
351 | * keeps nets unshifted. |
---|
352 | */ |
---|
353 | in = inet_makeaddr(ifaddr.in.ia_subnet, |
---|
354 | INADDR_ANY); |
---|
355 | printf("%-13.13s ", netname(in.s_addr, |
---|
356 | ifaddr.in.ia_subnetmask)); |
---|
357 | #else |
---|
358 | printf("%-13.13s ", |
---|
359 | netname(htonl(ifaddr.in.ia_subnet), |
---|
360 | ifaddr.in.ia_subnetmask)); |
---|
361 | #endif |
---|
362 | printf("%-17.17s ", |
---|
363 | routename(sockin->sin_addr.s_addr)); |
---|
364 | |
---|
365 | network_layer = 1; |
---|
366 | break; |
---|
367 | #ifdef INET6 |
---|
368 | case AF_INET6: |
---|
369 | sockin6 = (struct sockaddr_in6 *)sa; |
---|
370 | printf("%-13.13s ", |
---|
371 | netname6(&ifaddr.in6.ia_addr, |
---|
372 | &ifaddr.in6.ia_prefixmask.sin6_addr)); |
---|
373 | printf("%-17.17s ", |
---|
374 | inet_ntop(AF_INET6, |
---|
375 | &sockin6->sin6_addr, |
---|
376 | ntop_buf, sizeof(ntop_buf))); |
---|
377 | |
---|
378 | network_layer = 1; |
---|
379 | break; |
---|
380 | #endif /*INET6*/ |
---|
381 | #ifndef __rtems__ |
---|
382 | case AF_IPX: |
---|
383 | { |
---|
384 | struct sockaddr_ipx *sipx = |
---|
385 | (struct sockaddr_ipx *)sa; |
---|
386 | u_long net; |
---|
387 | char netnum[10]; |
---|
388 | |
---|
389 | *(union ipx_net *) &net = sipx->sipx_addr.x_net; |
---|
390 | sprintf(netnum, "%lx", (u_long)ntohl(net)); |
---|
391 | printf("ipx:%-8s ", netnum); |
---|
392 | /* printf("ipx:%-8s ", netname(net, 0L)); */ |
---|
393 | printf("%-17s ", |
---|
394 | ipx_phost((struct sockaddr *)sipx)); |
---|
395 | } |
---|
396 | |
---|
397 | network_layer = 1; |
---|
398 | break; |
---|
399 | #endif |
---|
400 | |
---|
401 | #ifndef __rtems__ |
---|
402 | case AF_APPLETALK: |
---|
403 | printf("atalk:%-12.12s ",atalk_print(sa,0x10) ); |
---|
404 | printf("%-11.11s ",atalk_print(sa,0x0b) ); |
---|
405 | break; |
---|
406 | #endif |
---|
407 | case AF_LINK: |
---|
408 | { |
---|
409 | struct sockaddr_dl *sdl = |
---|
410 | (struct sockaddr_dl *)sa; |
---|
411 | char linknum[10]; |
---|
412 | cp = (char *)LLADDR(sdl); |
---|
413 | n = sdl->sdl_alen; |
---|
414 | sprintf(linknum, "<Link#%d>", sdl->sdl_index); |
---|
415 | m = printf("%-13.13s ", linknum); |
---|
416 | } |
---|
417 | goto hexprint; |
---|
418 | default: |
---|
419 | m = printf("(%d)", sa->sa_family); |
---|
420 | for (cp = sa->sa_len + (char *)sa; |
---|
421 | --cp > sa->sa_data && (*cp == 0);) {} |
---|
422 | n = cp - sa->sa_data + 1; |
---|
423 | cp = sa->sa_data; |
---|
424 | hexprint: |
---|
425 | while (--n >= 0) |
---|
426 | m += printf("%02x%c", *cp++ & 0xff, |
---|
427 | n > 0 ? ':' : ' '); |
---|
428 | m = 32 - m; |
---|
429 | while (m-- > 0) |
---|
430 | putchar(' '); |
---|
431 | |
---|
432 | link_layer = 1; |
---|
433 | break; |
---|
434 | } |
---|
435 | |
---|
436 | /* |
---|
437 | * Fixup the statistics for interfaces that |
---|
438 | * update stats for their network addresses |
---|
439 | */ |
---|
440 | if (network_layer) { |
---|
441 | opackets = ifaddr.in.ia_ifa.if_opackets; |
---|
442 | ipackets = ifaddr.in.ia_ifa.if_ipackets; |
---|
443 | obytes = ifaddr.in.ia_ifa.if_obytes; |
---|
444 | ibytes = ifaddr.in.ia_ifa.if_ibytes; |
---|
445 | } |
---|
446 | |
---|
447 | ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); |
---|
448 | } |
---|
449 | |
---|
450 | show_stat("lu", 8, ipackets, link_layer|network_layer); |
---|
451 | show_stat("lu", 5, ierrors, link_layer); |
---|
452 | show_stat("lu", 5, idrops, link_layer); |
---|
453 | if (bflag) |
---|
454 | show_stat("lu", 10, ibytes, link_layer|network_layer); |
---|
455 | |
---|
456 | show_stat("lu", 8, opackets, link_layer|network_layer); |
---|
457 | show_stat("lu", 5, oerrors, link_layer); |
---|
458 | if (bflag) |
---|
459 | show_stat("lu", 10, obytes, link_layer|network_layer); |
---|
460 | |
---|
461 | show_stat("NRSlu", 5, collisions, link_layer); |
---|
462 | if (tflag) |
---|
463 | show_stat("LSd", 4, timer, link_layer); |
---|
464 | if (dflag) |
---|
465 | show_stat("LSd", 4, drops, link_layer); |
---|
466 | putchar('\n'); |
---|
467 | |
---|
468 | if (aflag && ifaddrfound) { |
---|
469 | /* |
---|
470 | * Print family's multicast addresses |
---|
471 | */ |
---|
472 | struct ifmultiaddr *multiaddr; |
---|
473 | struct ifmultiaddr ifma; |
---|
474 | union { |
---|
475 | struct sockaddr sa; |
---|
476 | struct sockaddr_in in; |
---|
477 | #ifdef INET6 |
---|
478 | struct sockaddr_in6 in6; |
---|
479 | #endif /* INET6 */ |
---|
480 | struct sockaddr_dl dl; |
---|
481 | } msa; |
---|
482 | const char *fmt; |
---|
483 | |
---|
484 | TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) { |
---|
485 | if (kread((u_long)multiaddr, (char *)&ifma, |
---|
486 | sizeof ifma) != 0) |
---|
487 | break; |
---|
488 | multiaddr = &ifma; |
---|
489 | if (kread((u_long)ifma.ifma_addr, (char *)&msa, |
---|
490 | sizeof msa) != 0) |
---|
491 | break; |
---|
492 | if (msa.sa.sa_family != sa->sa_family) |
---|
493 | continue; |
---|
494 | |
---|
495 | fmt = 0; |
---|
496 | switch (msa.sa.sa_family) { |
---|
497 | case AF_INET: |
---|
498 | fmt = routename(msa.in.sin_addr.s_addr); |
---|
499 | break; |
---|
500 | #ifdef INET6 |
---|
501 | case AF_INET6: |
---|
502 | printf("%*s %-19.19s(refs: %d)\n", |
---|
503 | Wflag ? 27 : 25, "", |
---|
504 | inet_ntop(AF_INET6, |
---|
505 | &msa.in6.sin6_addr, |
---|
506 | ntop_buf, |
---|
507 | sizeof(ntop_buf)), |
---|
508 | ifma.ifma_refcount); |
---|
509 | break; |
---|
510 | #endif /* INET6 */ |
---|
511 | case AF_LINK: |
---|
512 | switch (msa.dl.sdl_type) { |
---|
513 | case IFT_ETHER: |
---|
514 | case IFT_FDDI: |
---|
515 | fmt = ether_ntoa( |
---|
516 | (struct ether_addr *) |
---|
517 | LLADDR(&msa.dl)); |
---|
518 | break; |
---|
519 | } |
---|
520 | break; |
---|
521 | } |
---|
522 | if (fmt) { |
---|
523 | printf("%*s %-17.17s", |
---|
524 | Wflag ? 27 : 25, "", fmt); |
---|
525 | if (msa.sa.sa_family == AF_LINK) { |
---|
526 | printf(" %8lu", imcasts); |
---|
527 | printf("%*s", |
---|
528 | bflag ? 17 : 6, ""); |
---|
529 | printf(" %8lu", omcasts); |
---|
530 | } |
---|
531 | putchar('\n'); |
---|
532 | } |
---|
533 | } |
---|
534 | } |
---|
535 | } |
---|
536 | } |
---|
537 | |
---|
538 | struct iftot { |
---|
539 | SLIST_ENTRY(iftot) chain; |
---|
540 | char ift_name[IFNAMSIZ]; /* interface name */ |
---|
541 | u_long ift_ip; /* input packets */ |
---|
542 | u_long ift_ie; /* input errors */ |
---|
543 | u_long ift_id; /* input drops */ |
---|
544 | u_long ift_op; /* output packets */ |
---|
545 | u_long ift_oe; /* output errors */ |
---|
546 | u_long ift_co; /* collisions */ |
---|
547 | u_int ift_dr; /* drops */ |
---|
548 | u_long ift_ib; /* input bytes */ |
---|
549 | u_long ift_ob; /* output bytes */ |
---|
550 | }; |
---|
551 | |
---|
552 | u_char signalled; /* set if alarm goes off "early" */ |
---|
553 | |
---|
554 | /* |
---|
555 | * Print a running summary of interface statistics. |
---|
556 | * Repeat display every interval1 seconds, showing statistics |
---|
557 | * collected over that interval. Assumes that interval1 is non-zero. |
---|
558 | * First line printed at top of screen is always cumulative. |
---|
559 | * XXX - should be rewritten to use ifmib(4). |
---|
560 | */ |
---|
561 | static void |
---|
562 | sidewaysintpr(int interval1, u_long off) |
---|
563 | { |
---|
564 | struct ifnet ifnet; |
---|
565 | u_long firstifnet; |
---|
566 | struct ifnethead ifnethead; |
---|
567 | struct itimerval interval_it; |
---|
568 | struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting; |
---|
569 | int line; |
---|
570 | int oldmask, first; |
---|
571 | u_long interesting_off; |
---|
572 | |
---|
573 | if (kread(off, (char *)&ifnethead, sizeof ifnethead) != 0) |
---|
574 | return; |
---|
575 | firstifnet = (u_long)TAILQ_FIRST(&ifnethead); |
---|
576 | |
---|
577 | if ((iftot = malloc(sizeof(struct iftot))) == NULL) { |
---|
578 | printf("malloc failed\n"); |
---|
579 | exit(1); |
---|
580 | } |
---|
581 | memset(iftot, 0, sizeof(struct iftot)); |
---|
582 | |
---|
583 | interesting = NULL; |
---|
584 | interesting_off = 0; |
---|
585 | for (off = firstifnet, ip = iftot; off;) { |
---|
586 | char name[IFNAMSIZ]; |
---|
587 | |
---|
588 | if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) |
---|
589 | break; |
---|
590 | strlcpy(name, ifnet.if_xname, sizeof(name)); |
---|
591 | if (interface && strcmp(name, interface) == 0) { |
---|
592 | interesting = ip; |
---|
593 | interesting_off = off; |
---|
594 | } |
---|
595 | snprintf(ip->ift_name, sizeof(ip->ift_name), "(%s)", name);; |
---|
596 | if ((ipn = malloc(sizeof(struct iftot))) == NULL) { |
---|
597 | printf("malloc failed\n"); |
---|
598 | exit(1); |
---|
599 | } |
---|
600 | memset(ipn, 0, sizeof(struct iftot)); |
---|
601 | SLIST_NEXT(ip, chain) = ipn; |
---|
602 | ip = ipn; |
---|
603 | off = (u_long)TAILQ_NEXT(&ifnet, if_link); |
---|
604 | } |
---|
605 | if (interface && interesting == NULL) |
---|
606 | errx(1, "%s: unknown interface", interface); |
---|
607 | if ((total = malloc(sizeof(struct iftot))) == NULL) { |
---|
608 | printf("malloc failed\n"); |
---|
609 | exit(1); |
---|
610 | } |
---|
611 | memset(total, 0, sizeof(struct iftot)); |
---|
612 | if ((sum = malloc(sizeof(struct iftot))) == NULL) { |
---|
613 | printf("malloc failed\n"); |
---|
614 | exit(1); |
---|
615 | } |
---|
616 | memset(sum, 0, sizeof(struct iftot)); |
---|
617 | |
---|
618 | (void)signal(SIGALRM, catchalarm); |
---|
619 | signalled = NO; |
---|
620 | interval_it.it_interval.tv_sec = interval1; |
---|
621 | interval_it.it_interval.tv_usec = 0; |
---|
622 | interval_it.it_value = interval_it.it_interval; |
---|
623 | setitimer(ITIMER_REAL, &interval_it, NULL); |
---|
624 | first = 1; |
---|
625 | banner: |
---|
626 | printf("%17s %14s %16s", "input", |
---|
627 | interesting ? interesting->ift_name : "(Total)", "output"); |
---|
628 | putchar('\n'); |
---|
629 | printf("%10s %5s %5s %10s %10s %5s %10s %5s", |
---|
630 | "packets", "errs", "idrops", "bytes", "packets", "errs", "bytes", |
---|
631 | "colls"); |
---|
632 | if (dflag) |
---|
633 | printf(" %5.5s", "drops"); |
---|
634 | putchar('\n'); |
---|
635 | fflush(stdout); |
---|
636 | line = 0; |
---|
637 | loop: |
---|
638 | if (interesting != NULL) { |
---|
639 | ip = interesting; |
---|
640 | if (kread(interesting_off, (char *)&ifnet, sizeof ifnet) != 0) { |
---|
641 | printf("???\n"); |
---|
642 | exit(1); |
---|
643 | }; |
---|
644 | if (!first) { |
---|
645 | show_stat("lu", 10, ifnet.if_ipackets - ip->ift_ip, 1); |
---|
646 | show_stat("lu", 5, ifnet.if_ierrors - ip->ift_ie, 1); |
---|
647 | show_stat("lu", 5, ifnet.if_iqdrops - ip->ift_id, 1); |
---|
648 | show_stat("lu", 10, ifnet.if_ibytes - ip->ift_ib, 1); |
---|
649 | show_stat("lu", 10, ifnet.if_opackets - ip->ift_op, 1); |
---|
650 | show_stat("lu", 5, ifnet.if_oerrors - ip->ift_oe, 1); |
---|
651 | show_stat("lu", 10, ifnet.if_obytes - ip->ift_ob, 1); |
---|
652 | show_stat("NRSlu", 5, |
---|
653 | ifnet.if_collisions - ip->ift_co, 1); |
---|
654 | if (dflag) |
---|
655 | show_stat("LSu", 5, |
---|
656 | ifnet.if_snd.ifq_drops - ip->ift_dr, 1); |
---|
657 | } |
---|
658 | ip->ift_ip = ifnet.if_ipackets; |
---|
659 | ip->ift_ie = ifnet.if_ierrors; |
---|
660 | ip->ift_id = ifnet.if_iqdrops; |
---|
661 | ip->ift_ib = ifnet.if_ibytes; |
---|
662 | ip->ift_op = ifnet.if_opackets; |
---|
663 | ip->ift_oe = ifnet.if_oerrors; |
---|
664 | ip->ift_ob = ifnet.if_obytes; |
---|
665 | ip->ift_co = ifnet.if_collisions; |
---|
666 | ip->ift_dr = ifnet.if_snd.ifq_drops; |
---|
667 | } else { |
---|
668 | sum->ift_ip = 0; |
---|
669 | sum->ift_ie = 0; |
---|
670 | sum->ift_id = 0; |
---|
671 | sum->ift_ib = 0; |
---|
672 | sum->ift_op = 0; |
---|
673 | sum->ift_oe = 0; |
---|
674 | sum->ift_ob = 0; |
---|
675 | sum->ift_co = 0; |
---|
676 | sum->ift_dr = 0; |
---|
677 | for (off = firstifnet, ip = iftot; |
---|
678 | off && SLIST_NEXT(ip, chain) != NULL; |
---|
679 | ip = SLIST_NEXT(ip, chain)) { |
---|
680 | if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) { |
---|
681 | off = 0; |
---|
682 | continue; |
---|
683 | } |
---|
684 | sum->ift_ip += ifnet.if_ipackets; |
---|
685 | sum->ift_ie += ifnet.if_ierrors; |
---|
686 | sum->ift_id += ifnet.if_iqdrops; |
---|
687 | sum->ift_ib += ifnet.if_ibytes; |
---|
688 | sum->ift_op += ifnet.if_opackets; |
---|
689 | sum->ift_oe += ifnet.if_oerrors; |
---|
690 | sum->ift_ob += ifnet.if_obytes; |
---|
691 | sum->ift_co += ifnet.if_collisions; |
---|
692 | sum->ift_dr += ifnet.if_snd.ifq_drops; |
---|
693 | off = (u_long)TAILQ_NEXT(&ifnet, if_link); |
---|
694 | } |
---|
695 | if (!first) { |
---|
696 | show_stat("lu", 10, sum->ift_ip - total->ift_ip, 1); |
---|
697 | show_stat("lu", 5, sum->ift_ie - total->ift_ie, 1); |
---|
698 | show_stat("lu", 5, sum->ift_id - total->ift_id, 1); |
---|
699 | show_stat("lu", 10, sum->ift_ib - total->ift_ib, 1); |
---|
700 | show_stat("lu", 10, sum->ift_op - total->ift_op, 1); |
---|
701 | show_stat("lu", 5, sum->ift_oe - total->ift_oe, 1); |
---|
702 | show_stat("lu", 10, sum->ift_ob - total->ift_ob, 1); |
---|
703 | show_stat("NRSlu", 5, sum->ift_co - total->ift_co, 1); |
---|
704 | if (dflag) |
---|
705 | show_stat("LSu", 5, |
---|
706 | sum->ift_dr - total->ift_dr, 1); |
---|
707 | } |
---|
708 | *total = *sum; |
---|
709 | } |
---|
710 | if (!first) |
---|
711 | putchar('\n'); |
---|
712 | fflush(stdout); |
---|
713 | if ((noutputs != 0) && (--noutputs == 0)) |
---|
714 | exit(0); |
---|
715 | #ifndef __rtems__ |
---|
716 | oldmask = sigblock(sigmask(SIGALRM)); |
---|
717 | while (!signalled) |
---|
718 | sigpause(0); |
---|
719 | signalled = NO; |
---|
720 | sigsetmask(oldmask); |
---|
721 | #else |
---|
722 | #warning "Add BSD Signals wrapper" |
---|
723 | #endif |
---|
724 | line++; |
---|
725 | first = 0; |
---|
726 | if (line == 21) |
---|
727 | goto banner; |
---|
728 | else |
---|
729 | goto loop; |
---|
730 | /*NOTREACHED*/ |
---|
731 | } |
---|
732 | |
---|
733 | /* |
---|
734 | * Set a flag to indicate that a signal from the periodic itimer has been |
---|
735 | * caught. |
---|
736 | */ |
---|
737 | static void |
---|
738 | catchalarm(int signo __unused) |
---|
739 | { |
---|
740 | signalled = YES; |
---|
741 | } |
---|