| File: | src/usr.bin/netstat/if.c |
| Warning: | line 592, column 19 Access to field 'ifi_ipackets' results in a dereference of an undefined pointer value (loaded from variable 'ifd') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: if.c,v 1.78 2021/11/29 06:39:23 deraadt Exp $ */ | |||
| 2 | /* $NetBSD: if.c,v 1.16.4.2 1996/06/07 21:46:46 thorpej Exp $ */ | |||
| 3 | ||||
| 4 | /* | |||
| 5 | * Copyright (c) 1983, 1988, 1993 | |||
| 6 | * The Regents of the University of California. All rights reserved. | |||
| 7 | * | |||
| 8 | * Redistribution and use in source and binary forms, with or without | |||
| 9 | * modification, are permitted provided that the following conditions | |||
| 10 | * are met: | |||
| 11 | * 1. Redistributions of source code must retain the above copyright | |||
| 12 | * notice, this list of conditions and the following disclaimer. | |||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | |||
| 14 | * notice, this list of conditions and the following disclaimer in the | |||
| 15 | * documentation and/or other materials provided with the distribution. | |||
| 16 | * 3. Neither the name of the University nor the names of its contributors | |||
| 17 | * may be used to endorse or promote products derived from this software | |||
| 18 | * without specific prior written permission. | |||
| 19 | * | |||
| 20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
| 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
| 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
| 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
| 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
| 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
| 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
| 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| 30 | * SUCH DAMAGE. | |||
| 31 | */ | |||
| 32 | ||||
| 33 | #include <sys/types.h> | |||
| 34 | #include <sys/ioctl.h> | |||
| 35 | #include <sys/protosw.h> | |||
| 36 | #include <sys/socket.h> | |||
| 37 | #include <sys/sysctl.h> | |||
| 38 | ||||
| 39 | #include <net/if.h> | |||
| 40 | #include <net/if_dl.h> | |||
| 41 | #include <net/if_types.h> | |||
| 42 | #include <net/route.h> | |||
| 43 | #include <netinet/in.h> | |||
| 44 | #include <netinet/in_var.h> | |||
| 45 | #include <netinet/if_ether.h> | |||
| 46 | #include <arpa/inet.h> | |||
| 47 | ||||
| 48 | #include <err.h> | |||
| 49 | #include <limits.h> | |||
| 50 | #include <signal.h> | |||
| 51 | #include <stdio.h> | |||
| 52 | #include <stdlib.h> | |||
| 53 | #include <string.h> | |||
| 54 | #include <unistd.h> | |||
| 55 | #include <util.h> | |||
| 56 | ||||
| 57 | #define roundup(x, y)((((x)+((y)-1))/(y))*(y)) ((((x)+((y)-1))/(y))*(y)) | |||
| 58 | ||||
| 59 | #include "netstat.h" | |||
| 60 | ||||
| 61 | static void print_addr(struct sockaddr *, struct sockaddr **, struct if_data *); | |||
| 62 | static void sidewaysintpr(u_int, int); | |||
| 63 | static void catchalarm(int); | |||
| 64 | static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); | |||
| 65 | static void fetchifs(void); | |||
| 66 | ||||
| 67 | struct iftot; | |||
| 68 | ||||
| 69 | struct if_show_err { | |||
| 70 | const char *name; | |||
| 71 | const char *iname; | |||
| 72 | const char *oname; | |||
| 73 | uint64_t (*count)(uint64_t, uint64_t); | |||
| 74 | }; | |||
| 75 | ||||
| 76 | static uint64_t if_show_fails(uint64_t, uint64_t); | |||
| 77 | static uint64_t if_show_errors(uint64_t, uint64_t); | |||
| 78 | static uint64_t if_show_qdrops(uint64_t, uint64_t); | |||
| 79 | ||||
| 80 | static const struct if_show_err if_show_errs[] = { | |||
| 81 | [IF_SHOW_FAIL0] = { "fails", "Ifail", "Ofail", if_show_fails }, | |||
| 82 | [IF_SHOW_ERRS1] = { "errs", "Ierrs", "Oerrs", if_show_errors }, | |||
| 83 | [IF_SHOW_DROP2] = { "drops", "Idrop", "Odrop", if_show_qdrops }, | |||
| 84 | }; | |||
| 85 | static const struct if_show_err *if_errs = if_show_errs; | |||
| 86 | ||||
| 87 | /* | |||
| 88 | * Print a description of the network interfaces. | |||
| 89 | * NOTE: ifnetaddr is the location of the kernel global "ifnet", | |||
| 90 | * which is a TAILQ_HEAD. | |||
| 91 | */ | |||
| 92 | void | |||
| 93 | intpr(int interval, int repeatcount) | |||
| 94 | { | |||
| 95 | struct if_msghdr ifm; | |||
| 96 | int mib[6] = { CTL_NET4, PF_ROUTE17, 0, 0, NET_RT_IFLIST3, 0 }; | |||
| 97 | char name[IFNAMSIZ16 + 1]; /* + 1 for the '*' */ | |||
| 98 | char *buf = NULL((void *)0), *next, *lim, *cp; | |||
| 99 | struct rt_msghdr *rtm; | |||
| 100 | struct ifa_msghdr *ifam; | |||
| 101 | struct if_data *ifd; | |||
| 102 | struct sockaddr *sa, *rti_info[RTAX_MAX15]; | |||
| 103 | struct sockaddr_dl *sdl; | |||
| 104 | u_int64_t total = 0; | |||
| 105 | size_t len; | |||
| 106 | ||||
| 107 | if_errs = &if_show_errs[dflag]; | |||
| 108 | ||||
| 109 | if (interval) { | |||
| ||||
| 110 | sidewaysintpr((unsigned)interval, repeatcount); | |||
| 111 | return; | |||
| 112 | } | |||
| 113 | ||||
| 114 | len = get_sysctl(mib, 6, &buf); | |||
| 115 | ||||
| 116 | printf("%-7.7s %-5.5s %-11.11s %-17.17s ", | |||
| 117 | "Name", "Mtu", "Network", "Address"); | |||
| 118 | if (bflag) | |||
| 119 | printf("%10.10s %10.10s", "Ibytes", "Obytes"); | |||
| 120 | else { | |||
| 121 | printf("%8.8s %5.5s %8.8s %5.5s %5.5s", | |||
| 122 | "Ipkts", if_errs->iname, | |||
| 123 | "Opkts", if_errs->oname, "Colls"); | |||
| 124 | } | |||
| 125 | if (tflag) | |||
| 126 | printf(" %s", "Time"); | |||
| 127 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
| 128 | ||||
| 129 | lim = buf + len; | |||
| 130 | for (next = buf; next < lim; next += rtm->rtm_msglen) { | |||
| 131 | rtm = (struct rt_msghdr *)next; | |||
| 132 | if (rtm->rtm_version != RTM_VERSION5) | |||
| 133 | continue; | |||
| 134 | switch (rtm->rtm_type) { | |||
| 135 | case RTM_IFINFO0xe: | |||
| 136 | total = 0; | |||
| 137 | bcopy(next, &ifm, sizeof ifm); | |||
| 138 | ifd = &ifm.ifm_data; | |||
| 139 | ||||
| 140 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
| 141 | get_rtaddrs(ifm.ifm_addrs, sa, rti_info); | |||
| 142 | ||||
| 143 | sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP4]; | |||
| 144 | if (sdl == NULL((void *)0) || sdl->sdl_family != AF_LINK18) | |||
| 145 | continue; | |||
| 146 | bzero(name, sizeof(name)); | |||
| 147 | if (sdl->sdl_nlen >= IFNAMSIZ16) | |||
| 148 | memcpy(name, sdl->sdl_data, IFNAMSIZ16 - 1); | |||
| 149 | else if (sdl->sdl_nlen > 0) | |||
| 150 | memcpy(name, sdl->sdl_data, sdl->sdl_nlen); | |||
| 151 | ||||
| 152 | if (interface != 0 && strcmp(name, interface) != 0) | |||
| 153 | continue; | |||
| 154 | ||||
| 155 | /* mark inactive interfaces with a '*' */ | |||
| 156 | cp = strchr(name, '\0'); | |||
| 157 | if ((ifm.ifm_flags & IFF_UP0x1) == 0) | |||
| 158 | *cp++ = '*'; | |||
| 159 | *cp = '\0'; | |||
| 160 | ||||
| 161 | if (qflag) { | |||
| 162 | total = ifd->ifi_ibytes + ifd->ifi_obytes + | |||
| 163 | ifd->ifi_ipackets + | |||
| 164 | ifd->ifi_opackets + | |||
| 165 | ifd->ifi_collisions; | |||
| 166 | total += if_errs->count(ifd->ifi_ierrors, | |||
| 167 | ifd->ifi_iqdrops); | |||
| 168 | total += if_errs->count(ifd->ifi_oerrors, | |||
| 169 | ifd->ifi_oqdrops); | |||
| 170 | if (tflag) | |||
| 171 | total += 0; // XXX ifnet.if_timer; | |||
| 172 | if (total == 0) | |||
| 173 | continue; | |||
| 174 | } | |||
| 175 | ||||
| 176 | printf("%-7s %-5d ", name, ifd->ifi_mtu); | |||
| 177 | print_addr(rti_info[RTAX_IFP4], rti_info, ifd); | |||
| 178 | break; | |||
| 179 | case RTM_NEWADDR0xc: | |||
| 180 | if (qflag && total == 0) | |||
| 181 | continue; | |||
| 182 | if (interface != 0 && strcmp(name, interface) != 0) | |||
| 183 | continue; | |||
| 184 | ||||
| 185 | ifam = (struct ifa_msghdr *)next; | |||
| 186 | if ((ifam->ifam_addrs & (RTA_NETMASK0x4 | RTA_IFA0x20 | | |||
| 187 | RTA_BRD0x80)) == 0) | |||
| 188 | break; | |||
| 189 | ||||
| 190 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
| 191 | get_rtaddrs(ifam->ifam_addrs, sa, rti_info); | |||
| 192 | ||||
| 193 | printf("%-7s %-5d ", name, ifd->ifi_mtu); | |||
| 194 | print_addr(rti_info[RTAX_IFA5], rti_info, ifd); | |||
| 195 | break; | |||
| 196 | } | |||
| 197 | } | |||
| 198 | free(buf); | |||
| 199 | } | |||
| 200 | ||||
| 201 | static void | |||
| 202 | print_addr(struct sockaddr *sa, struct sockaddr **rtinfo, struct if_data *ifd) | |||
| 203 | { | |||
| 204 | struct sockaddr_dl *sdl; | |||
| 205 | struct sockaddr_in *sin; | |||
| 206 | struct sockaddr_in6 *sin6; | |||
| 207 | char *cp; | |||
| 208 | int m, n; | |||
| 209 | ||||
| 210 | switch (sa->sa_family) { | |||
| 211 | case AF_UNSPEC0: | |||
| 212 | printf("%-11.11s ", "none"); | |||
| 213 | printf("%-17.17s ", "none"); | |||
| 214 | break; | |||
| 215 | case AF_INET2: | |||
| 216 | sin = (struct sockaddr_in *)sa; | |||
| 217 | cp = netname4(sin->sin_addr.s_addr, | |||
| 218 | ((struct sockaddr_in *)rtinfo[RTAX_NETMASK2])->sin_addr.s_addr); | |||
| 219 | if (vflag) | |||
| 220 | n = strlen(cp) < 11 ? 11 : strlen(cp); | |||
| 221 | else | |||
| 222 | n = 11; | |||
| 223 | printf("%-*.*s ", n, n, cp); | |||
| 224 | cp = routename4(sin->sin_addr.s_addr); | |||
| 225 | if (vflag) | |||
| 226 | n = strlen(cp) < 17 ? 17 : strlen(cp); | |||
| 227 | else | |||
| 228 | n = 17; | |||
| 229 | printf("%-*.*s ", n, n, cp); | |||
| 230 | ||||
| 231 | break; | |||
| 232 | case AF_INET624: | |||
| 233 | sin6 = (struct sockaddr_in6 *)sa; | |||
| 234 | #ifdef __KAME__ | |||
| 235 | if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)(((&sin6->sin6_addr)->__u6_addr.__u6_addr8[0] == 0xfe ) && (((&sin6->sin6_addr)->__u6_addr.__u6_addr8 [1] & 0xc0) == 0x80)) && | |||
| 236 | sin6->sin6_scope_id == 0) { | |||
| 237 | sin6->sin6_scope_id = | |||
| 238 | ntohs(*(u_int16_t *)(__uint16_t)(__builtin_constant_p(*(u_int16_t *) &sin6-> sin6_addr.__u6_addr.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t )(*(u_int16_t *) &sin6->sin6_addr.__u6_addr.__u6_addr8 [2]) & 0xffU) << 8 | ((__uint16_t)(*(u_int16_t *) & sin6->sin6_addr.__u6_addr.__u6_addr8[2]) & 0xff00U) >> 8) : __swap16md(*(u_int16_t *) &sin6->sin6_addr.__u6_addr .__u6_addr8[2])) | |||
| 239 | &sin6->sin6_addr.s6_addr[2])(__uint16_t)(__builtin_constant_p(*(u_int16_t *) &sin6-> sin6_addr.__u6_addr.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t )(*(u_int16_t *) &sin6->sin6_addr.__u6_addr.__u6_addr8 [2]) & 0xffU) << 8 | ((__uint16_t)(*(u_int16_t *) & sin6->sin6_addr.__u6_addr.__u6_addr8[2]) & 0xff00U) >> 8) : __swap16md(*(u_int16_t *) &sin6->sin6_addr.__u6_addr .__u6_addr8[2])); | |||
| 240 | sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[2] = 0; | |||
| 241 | sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[3] = 0; | |||
| 242 | } | |||
| 243 | #endif | |||
| 244 | cp = netname6(sin6, | |||
| 245 | (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK2]); | |||
| 246 | if (vflag) | |||
| 247 | n = strlen(cp) < 11 ? 11 : strlen(cp); | |||
| 248 | else | |||
| 249 | n = 11; | |||
| 250 | printf("%-*.*s ", n, n, cp); | |||
| 251 | cp = routename6(sin6); | |||
| 252 | if (vflag) | |||
| 253 | n = strlen(cp) < 17 ? 17 : strlen(cp); | |||
| 254 | else | |||
| 255 | n = 17; | |||
| 256 | printf("%-*.*s ", n, n, cp); | |||
| 257 | break; | |||
| 258 | case AF_LINK18: | |||
| 259 | sdl = (struct sockaddr_dl *)sa; | |||
| 260 | m = printf("%-11.11s ", "<Link>"); | |||
| 261 | if (sdl->sdl_type == IFT_ETHER0x06 || | |||
| 262 | sdl->sdl_type == IFT_CARP0xf7 || | |||
| 263 | sdl->sdl_type == IFT_FDDI0x0f || | |||
| 264 | sdl->sdl_type == IFT_ISO880250x09) | |||
| 265 | printf("%-17.17s ", | |||
| 266 | ether_ntoa((struct ether_addr *)LLADDR(sdl)((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)))); | |||
| 267 | else { | |||
| 268 | cp = (char *)LLADDR(sdl)((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen)); | |||
| 269 | n = sdl->sdl_alen; | |||
| 270 | goto hexprint; | |||
| 271 | } | |||
| 272 | break; | |||
| 273 | default: | |||
| 274 | m = printf("(%d)", sa->sa_family); | |||
| 275 | for (cp = sa->sa_len + (char *)sa; | |||
| 276 | --cp > sa->sa_data && (*cp == 0);) {} | |||
| 277 | n = cp - sa->sa_data + 1; | |||
| 278 | cp = sa->sa_data; | |||
| 279 | hexprint: | |||
| 280 | while (--n >= 0) | |||
| 281 | m += printf("%x%c", *cp++ & 0xff, | |||
| 282 | n > 0 ? '.' : ' '); | |||
| 283 | m = 30 - m; | |||
| 284 | while (m-- > 0) | |||
| 285 | putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', ( &__sF[1]))); | |||
| 286 | break; | |||
| 287 | } | |||
| 288 | if (bflag) { | |||
| 289 | if (hflag) { | |||
| 290 | char ibytes[FMT_SCALED_STRSIZE7]; | |||
| 291 | char obytes[FMT_SCALED_STRSIZE7]; | |||
| 292 | fmt_scaled(ifd->ifi_ibytes, ibytes); | |||
| 293 | fmt_scaled(ifd->ifi_obytes, obytes); | |||
| 294 | printf("%10s %10s", ibytes, obytes); | |||
| 295 | } else | |||
| 296 | printf("%10llu %10llu", | |||
| 297 | ifd->ifi_ibytes, ifd->ifi_obytes); | |||
| 298 | } else | |||
| 299 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
| 300 | ifd->ifi_ipackets, | |||
| 301 | if_errs->count(ifd->ifi_ierrors, ifd->ifi_iqdrops), | |||
| 302 | ifd->ifi_opackets, | |||
| 303 | if_errs->count(ifd->ifi_oerrors, ifd->ifi_oqdrops), | |||
| 304 | ifd->ifi_collisions); | |||
| 305 | if (tflag) | |||
| 306 | printf(" %4d", 0 /* XXX ifnet.if_timer */); | |||
| 307 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
| 308 | } | |||
| 309 | ||||
| 310 | struct iftot { | |||
| 311 | char ift_name[IFNAMSIZ16]; /* interface name */ | |||
| 312 | u_int64_t ift_ip; /* input packets */ | |||
| 313 | u_int64_t ift_ib; /* input bytes */ | |||
| 314 | u_int64_t ift_ie; /* input errors */ | |||
| 315 | u_int64_t ift_iq; /* input qdrops */ | |||
| 316 | u_int64_t ift_op; /* output packets */ | |||
| 317 | u_int64_t ift_ob; /* output bytes */ | |||
| 318 | u_int64_t ift_oe; /* output errors */ | |||
| 319 | u_int64_t ift_oq; /* output qdrops */ | |||
| 320 | u_int64_t ift_co; /* collisions */ | |||
| 321 | } ip_cur, ip_old, sum_cur, sum_old; | |||
| 322 | ||||
| 323 | volatile sig_atomic_t signalled; /* set if alarm goes off "early" */ | |||
| 324 | ||||
| 325 | /* | |||
| 326 | * Print a running summary of interface statistics. | |||
| 327 | * Repeat display every interval seconds, showing statistics | |||
| 328 | * collected over that interval. Assumes that interval is non-zero. | |||
| 329 | * First line printed at top of screen is always cumulative. | |||
| 330 | */ | |||
| 331 | static void | |||
| 332 | sidewaysintpr(unsigned int interval, int repeatcount) | |||
| 333 | { | |||
| 334 | sigset_t emptyset; | |||
| 335 | int line; | |||
| 336 | char ibytes[FMT_SCALED_STRSIZE7]; | |||
| 337 | char obytes[FMT_SCALED_STRSIZE7]; | |||
| 338 | ||||
| 339 | fetchifs(); | |||
| 340 | if (ip_cur.ift_name[0] == '\0') { | |||
| 341 | fprintf(stderr(&__sF[2]), "%s: %s: unknown interface\n", | |||
| 342 | __progname, interface); | |||
| 343 | exit(1); | |||
| 344 | } | |||
| 345 | ||||
| 346 | (void)signal(SIGALRM14, catchalarm); | |||
| 347 | signalled = 0; | |||
| 348 | (void)alarm(interval); | |||
| 349 | banner: | |||
| 350 | if (bflag) | |||
| 351 | printf("%7.7s in %8.8s %6.6s out %5.5s", | |||
| 352 | ip_cur.ift_name, " ", | |||
| 353 | ip_cur.ift_name, " "); | |||
| 354 | else | |||
| 355 | printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", | |||
| 356 | ip_cur.ift_name, " ", | |||
| 357 | ip_cur.ift_name, " ", " "); | |||
| 358 | ||||
| 359 | if (bflag) | |||
| 360 | printf(" %7.7s in %8.8s %6.6s out %5.5s", | |||
| 361 | "total", " ", "total", " "); | |||
| 362 | else | |||
| 363 | printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", | |||
| 364 | "total", " ", "total", " ", " "); | |||
| 365 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
| 366 | if (bflag) | |||
| 367 | printf("%10.10s %8.8s %10.10s %5.5s", | |||
| 368 | "bytes", " ", "bytes", " "); | |||
| 369 | else | |||
| 370 | printf("%8.8s %5.5s %8.8s %5.5s %5.5s", | |||
| 371 | "packets", if_errs->name, | |||
| 372 | "packets", if_errs->name, "colls"); | |||
| 373 | ||||
| 374 | if (bflag) | |||
| 375 | printf("%10.10s %8.8s %10.10s %5.5s", | |||
| 376 | "bytes", " ", "bytes", " "); | |||
| 377 | else | |||
| 378 | printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", | |||
| 379 | "packets", "errs", "packets", "errs", "colls"); | |||
| 380 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
| 381 | fflush(stdout(&__sF[1])); | |||
| 382 | line = 0; | |||
| 383 | bzero(&ip_old, sizeof(ip_old)); | |||
| 384 | bzero(&sum_old, sizeof(sum_old)); | |||
| 385 | loop: | |||
| 386 | bzero(&sum_cur, sizeof(sum_cur)); | |||
| 387 | ||||
| 388 | fetchifs(); | |||
| 389 | ||||
| 390 | if (bflag) { | |||
| 391 | if (hflag) { | |||
| 392 | fmt_scaled(ip_cur.ift_ib - ip_old.ift_ib, ibytes); | |||
| 393 | fmt_scaled(ip_cur.ift_ob - ip_old.ift_ob, obytes); | |||
| 394 | printf("%10s %8.8s %10s %5.5s", | |||
| 395 | ibytes, " ", obytes, " "); | |||
| 396 | } else | |||
| 397 | printf("%10llu %8.8s %10llu %5.5s", | |||
| 398 | ip_cur.ift_ib - ip_old.ift_ib, " ", | |||
| 399 | ip_cur.ift_ob - ip_old.ift_ob, " "); | |||
| 400 | } else | |||
| 401 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
| 402 | ip_cur.ift_ip - ip_old.ift_ip, | |||
| 403 | if_errs->count(ip_cur.ift_ie - ip_old.ift_ie, | |||
| 404 | ip_cur.ift_iq - ip_old.ift_iq), | |||
| 405 | ip_cur.ift_op - ip_old.ift_op, | |||
| 406 | if_errs->count(ip_cur.ift_oe - ip_old.ift_oe, | |||
| 407 | ip_cur.ift_oq - ip_old.ift_oq), | |||
| 408 | ip_cur.ift_co - ip_old.ift_co); | |||
| 409 | ||||
| 410 | ip_old = ip_cur; | |||
| 411 | ||||
| 412 | if (bflag) { | |||
| 413 | if (hflag) { | |||
| 414 | fmt_scaled(sum_cur.ift_ib - sum_old.ift_ib, ibytes); | |||
| 415 | fmt_scaled(sum_cur.ift_ob - sum_old.ift_ob, obytes); | |||
| 416 | printf("%10s %8.8s %10s %5.5s", | |||
| 417 | ibytes, " ", obytes, " "); | |||
| 418 | } else | |||
| 419 | printf("%10llu %8.8s %10llu %5.5s", | |||
| 420 | sum_cur.ift_ib - sum_old.ift_ib, " ", | |||
| 421 | sum_cur.ift_ob - sum_old.ift_ob, " "); | |||
| 422 | } else | |||
| 423 | printf("%8llu %5llu %8llu %5llu %5llu", | |||
| 424 | sum_cur.ift_ip - sum_old.ift_ip, | |||
| 425 | if_errs->count(sum_cur.ift_ie - sum_old.ift_ie, | |||
| 426 | sum_cur.ift_iq - sum_old.ift_iq), | |||
| 427 | sum_cur.ift_op - sum_old.ift_op, | |||
| 428 | if_errs->count(sum_cur.ift_oe - sum_old.ift_oe, | |||
| 429 | sum_cur.ift_oq - sum_old.ift_oq), | |||
| 430 | sum_cur.ift_co - sum_old.ift_co); | |||
| 431 | ||||
| 432 | sum_old = sum_cur; | |||
| 433 | ||||
| 434 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | |||
| 435 | fflush(stdout(&__sF[1])); | |||
| 436 | if (repeatcount && --repeatcount == 0) | |||
| 437 | return; | |||
| 438 | line++; | |||
| 439 | sigemptyset(&emptyset); | |||
| 440 | if (!signalled) | |||
| 441 | sigsuspend(&emptyset); | |||
| 442 | signalled = 0; | |||
| 443 | (void)alarm(interval); | |||
| 444 | if (line == 21 && isatty(STDOUT_FILENO1)) | |||
| 445 | goto banner; | |||
| 446 | goto loop; | |||
| 447 | } | |||
| 448 | ||||
| 449 | /* | |||
| 450 | * Called if an interval expires before sidewaysintpr has completed a loop. | |||
| 451 | * Sets a flag to not wait for the alarm. | |||
| 452 | */ | |||
| 453 | /* ARGSUSED */ | |||
| 454 | static void | |||
| 455 | catchalarm(int signo) | |||
| 456 | { | |||
| 457 | signalled = 1; | |||
| 458 | } | |||
| 459 | ||||
| 460 | static void | |||
| 461 | get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) | |||
| 462 | { | |||
| 463 | int i; | |||
| 464 | ||||
| 465 | for (i = 0; i < RTAX_MAX15; i++) { | |||
| 466 | if (addrs & (1 << i)) { | |||
| 467 | rti_info[i] = sa; | |||
| 468 | sa = (struct sockaddr *)((char *)(sa) + | |||
| 469 | roundup(sa->sa_len, sizeof(long))((((sa->sa_len)+((sizeof(long))-1))/(sizeof(long)))*(sizeof (long)))); | |||
| 470 | } else | |||
| 471 | rti_info[i] = NULL((void *)0); | |||
| 472 | } | |||
| 473 | } | |||
| 474 | ||||
| 475 | ||||
| 476 | static int | |||
| 477 | isegress(char *name) | |||
| 478 | { | |||
| 479 | static int s = -1; | |||
| 480 | int len; | |||
| 481 | struct ifgroupreq ifgr; | |||
| 482 | struct ifg_req *ifg; | |||
| 483 | int rv = 0; | |||
| 484 | ||||
| 485 | if (s == -1) { | |||
| 486 | if ((s = socket(AF_INET2, SOCK_DGRAM2, 0)) == -1) | |||
| 487 | return 0; | |||
| 488 | } | |||
| 489 | ||||
| 490 | memset(&ifgr, 0, sizeof(ifgr)); | |||
| 491 | strlcpy(ifgr.ifgr_name, name, IFNAMSIZ16); | |||
| 492 | ||||
| 493 | if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifgroupreq) & 0x1fff) << 16) | ((('i')) << 8) | ((136))), (caddr_t)&ifgr) == -1) { | |||
| 494 | return 0; | |||
| 495 | } | |||
| 496 | ||||
| 497 | len = ifgr.ifgr_len; | |||
| 498 | ifgr.ifgr_groupsifgr_ifgru.ifgru_groups = calloc(len, 1); | |||
| 499 | if (ifgr.ifgr_groupsifgr_ifgru.ifgru_groups == NULL((void *)0)) | |||
| 500 | err(1, "getifgroups"); | |||
| 501 | if (ioctl(s, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifgroupreq) & 0x1fff) << 16) | ((('i')) << 8) | ((136))), (caddr_t)&ifgr) == -1) | |||
| 502 | err(1, "SIOCGIFGROUP"); | |||
| 503 | ||||
| 504 | ifg = ifgr.ifgr_groupsifgr_ifgru.ifgru_groups; | |||
| 505 | for (; ifg && len >= sizeof(struct ifg_req); ifg++) { | |||
| 506 | len -= sizeof(struct ifg_req); | |||
| 507 | if (strcmp(ifg->ifgrq_groupifgrq_ifgrqu.ifgrqu_group, IFG_EGRESS"egress") == 0) | |||
| 508 | rv = 1; | |||
| 509 | } | |||
| 510 | ||||
| 511 | free(ifgr.ifgr_groupsifgr_ifgru.ifgru_groups); | |||
| 512 | return rv; | |||
| 513 | } | |||
| 514 | ||||
| 515 | static void | |||
| 516 | fetchifs(void) | |||
| 517 | { | |||
| 518 | struct if_msghdr ifm; | |||
| 519 | int mib[6] = { CTL_NET4, PF_ROUTE17, 0, 0, NET_RT_IFLIST3, 0 }; | |||
| 520 | struct rt_msghdr *rtm; | |||
| 521 | struct if_data *ifd; | |||
| 522 | struct sockaddr *sa, *rti_info[RTAX_MAX15]; | |||
| 523 | struct sockaddr_dl *sdl; | |||
| 524 | char *buf = NULL((void *)0), *next, *lim; | |||
| 525 | char name[IFNAMSIZ16]; | |||
| 526 | size_t len; | |||
| 527 | int takeit = 0; | |||
| 528 | int foundone = 0; | |||
| 529 | ||||
| 530 | len = get_sysctl(mib, 6, &buf); | |||
| 531 | ||||
| 532 | memset(&ip_cur, 0, sizeof(ip_cur)); | |||
| 533 | lim = buf + len; | |||
| 534 | for (next = buf; next < lim; next += rtm->rtm_msglen) { | |||
| 535 | rtm = (struct rt_msghdr *)next; | |||
| 536 | if (rtm->rtm_version != RTM_VERSION5) | |||
| 537 | continue; | |||
| 538 | switch (rtm->rtm_type) { | |||
| 539 | case RTM_IFINFO0xe: | |||
| 540 | bcopy(next, &ifm, sizeof ifm); | |||
| 541 | ifd = &ifm.ifm_data; | |||
| 542 | ||||
| 543 | sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); | |||
| 544 | get_rtaddrs(ifm.ifm_addrs, sa, rti_info); | |||
| 545 | ||||
| 546 | sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP4]; | |||
| 547 | if (sdl == NULL((void *)0) || sdl->sdl_family != AF_LINK18) | |||
| 548 | continue; | |||
| 549 | bzero(name, sizeof(name)); | |||
| 550 | if (sdl->sdl_nlen >= IFNAMSIZ16) | |||
| 551 | memcpy(name, sdl->sdl_data, IFNAMSIZ16 - 1); | |||
| 552 | else if (sdl->sdl_nlen > 0) | |||
| 553 | memcpy(name, sdl->sdl_data, sdl->sdl_nlen); | |||
| 554 | ||||
| 555 | if (interface != NULL((void *)0) && !strcmp(name, interface)) { | |||
| 556 | takeit = 1; | |||
| 557 | } else if (interface == NULL((void *)0) && foundone == 0 && | |||
| 558 | isegress(name)) { | |||
| 559 | takeit = 1; | |||
| 560 | foundone = 1; | |||
| 561 | } else | |||
| 562 | takeit = 0; | |||
| 563 | if (takeit) { | |||
| 564 | strlcpy(ip_cur.ift_name, name, | |||
| 565 | sizeof(ip_cur.ift_name)); | |||
| 566 | ip_cur.ift_ip = ifd->ifi_ipackets; | |||
| 567 | ip_cur.ift_ib = ifd->ifi_ibytes; | |||
| 568 | ip_cur.ift_ie = ifd->ifi_ierrors; | |||
| 569 | ip_cur.ift_iq = ifd->ifi_iqdrops; | |||
| 570 | ip_cur.ift_op = ifd->ifi_opackets; | |||
| 571 | ip_cur.ift_ob = ifd->ifi_obytes; | |||
| 572 | ip_cur.ift_oe = ifd->ifi_oerrors; | |||
| 573 | ip_cur.ift_oq = ifd->ifi_oqdrops; | |||
| 574 | ip_cur.ift_co = ifd->ifi_collisions; | |||
| 575 | } | |||
| 576 | ||||
| 577 | sum_cur.ift_ip += ifd->ifi_ipackets; | |||
| 578 | sum_cur.ift_ib += ifd->ifi_ibytes; | |||
| 579 | sum_cur.ift_ie += ifd->ifi_ierrors; | |||
| 580 | sum_cur.ift_iq += ifd->ifi_iqdrops; | |||
| 581 | sum_cur.ift_op += ifd->ifi_opackets; | |||
| 582 | sum_cur.ift_ob += ifd->ifi_obytes; | |||
| 583 | sum_cur.ift_oe += ifd->ifi_oerrors; | |||
| 584 | sum_cur.ift_oq += ifd->ifi_oqdrops; | |||
| 585 | sum_cur.ift_co += ifd->ifi_collisions; | |||
| 586 | break; | |||
| 587 | } | |||
| 588 | } | |||
| 589 | if (interface == NULL((void *)0) && foundone
| |||
| 590 | strlcpy(ip_cur.ift_name, name, | |||
| 591 | sizeof(ip_cur.ift_name)); | |||
| 592 | ip_cur.ift_ip = ifd->ifi_ipackets; | |||
| ||||
| 593 | ip_cur.ift_ib = ifd->ifi_ibytes; | |||
| 594 | ip_cur.ift_ie = ifd->ifi_ierrors; | |||
| 595 | ip_cur.ift_iq = ifd->ifi_iqdrops; | |||
| 596 | ip_cur.ift_op = ifd->ifi_opackets; | |||
| 597 | ip_cur.ift_ob = ifd->ifi_obytes; | |||
| 598 | ip_cur.ift_oe = ifd->ifi_oerrors; | |||
| 599 | ip_cur.ift_oq = ifd->ifi_oqdrops; | |||
| 600 | ip_cur.ift_co = ifd->ifi_collisions; | |||
| 601 | } | |||
| 602 | free(buf); | |||
| 603 | } | |||
| 604 | ||||
| 605 | static uint64_t | |||
| 606 | if_show_fails(uint64_t errors, uint64_t qdrops) | |||
| 607 | { | |||
| 608 | return (errors + qdrops); | |||
| 609 | } | |||
| 610 | ||||
| 611 | static uint64_t | |||
| 612 | if_show_errors(uint64_t errors, uint64_t qdrops) | |||
| 613 | { | |||
| 614 | return (errors); | |||
| 615 | } | |||
| 616 | ||||
| 617 | static uint64_t | |||
| 618 | if_show_qdrops(uint64_t errors, uint64_t qdrops) | |||
| 619 | { | |||
| 620 | return (qdrops); | |||
| 621 | } |