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