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