1 1.109 mrg /* $NetBSD: if.c,v 1.109 2022/12/28 18:34:33 mrg Exp $ */ 2 1.13 thorpej 3 1.1 cgd /* 4 1.8 mycroft * Copyright (c) 1983, 1988, 1993 5 1.8 mycroft * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.55 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.25 lukem #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.13 thorpej #if 0 35 1.13 thorpej static char sccsid[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94"; 36 1.13 thorpej #else 37 1.109 mrg __RCSID("$NetBSD: if.c,v 1.109 2022/12/28 18:34:33 mrg Exp $"); 38 1.13 thorpej #endif 39 1.1 cgd #endif /* not lint */ 40 1.1 cgd 41 1.64 elad #include <sys/param.h> 42 1.1 cgd #include <sys/types.h> 43 1.8 mycroft #include <sys/protosw.h> 44 1.1 cgd #include <sys/socket.h> 45 1.57 ragge #include <sys/time.h> 46 1.64 elad #include <sys/sysctl.h> 47 1.82 mrg #include <sys/ioctl.h> 48 1.1 cgd 49 1.1 cgd #include <net/if.h> 50 1.1 cgd #include <net/if_dl.h> 51 1.20 thorpej #include <net/if_types.h> 52 1.64 elad #include <net/route.h> 53 1.1 cgd #include <netinet/in.h> 54 1.1 cgd #include <netinet/in_var.h> 55 1.8 mycroft #include <arpa/inet.h> 56 1.1 cgd 57 1.59 rpaulo #include <kvm.h> 58 1.8 mycroft #include <signal.h> 59 1.1 cgd #include <stdio.h> 60 1.42 matt #include <stdlib.h> 61 1.8 mycroft #include <string.h> 62 1.8 mycroft #include <unistd.h> 63 1.34 itojun #include <netdb.h> 64 1.64 elad #include <err.h> 65 1.8 mycroft 66 1.8 mycroft #include "netstat.h" 67 1.80 christos #include "rtutil.h" 68 1.70 pooka #include "prog_ops.h" 69 1.1 cgd 70 1.64 elad #define MAXIF 100 71 1.64 elad 72 1.68 pooka #define HUMBUF_SIZE 7 73 1.68 pooka 74 1.64 elad struct iftot { 75 1.64 elad char ift_name[IFNAMSIZ]; /* interface name */ 76 1.105 msaitoh uint64_t ift_ip; /* input packets */ 77 1.105 msaitoh uint64_t ift_ib; /* input bytes */ 78 1.105 msaitoh uint64_t ift_ie; /* input errors */ 79 1.105 msaitoh uint64_t ift_iq; /* input drops */ 80 1.105 msaitoh uint64_t ift_op; /* output packets */ 81 1.105 msaitoh uint64_t ift_ob; /* output bytes */ 82 1.105 msaitoh uint64_t ift_oe; /* output errors */ 83 1.105 msaitoh uint64_t ift_oq; /* output drops */ 84 1.105 msaitoh uint64_t ift_co; /* collisions */ 85 1.101 msaitoh }; 86 1.101 msaitoh 87 1.101 msaitoh struct if_data_ext { 88 1.101 msaitoh uint64_t ifi_oqdrops; 89 1.64 elad }; 90 1.64 elad 91 1.82 mrg static void set_lines(void); 92 1.91 ozaki static void print_addr(const int, struct sockaddr *, struct sockaddr **, 93 1.101 msaitoh struct if_data *, struct ifnet *, struct if_data_ext *); 94 1.64 elad static void sidewaysintpr(u_int, u_long); 95 1.64 elad 96 1.64 elad static void iftot_banner(struct iftot *); 97 1.64 elad static void iftot_print_sum(struct iftot *, struct iftot *); 98 1.64 elad static void iftot_print(struct iftot *, struct iftot *); 99 1.1 cgd 100 1.87 christos static void catchalarm(int); 101 1.64 elad static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); 102 1.64 elad static void fetchifs(void); 103 1.64 elad 104 1.101 msaitoh static int if_data_ext_get(const char *, struct if_data_ext *); 105 1.64 elad static void intpr_sysctl(void); 106 1.64 elad static void intpr_kvm(u_long, void (*)(const char *)); 107 1.64 elad 108 1.64 elad struct iftot iftot[MAXIF], ip_cur, ip_old, sum_cur, sum_old; 109 1.90 dholland static sig_atomic_t signalled; /* set when alarm goes off */ 110 1.32 itojun 111 1.82 mrg static unsigned redraw_lines = 21; 112 1.82 mrg 113 1.82 mrg static void 114 1.82 mrg set_lines(void) 115 1.82 mrg { 116 1.82 mrg static bool first = true; 117 1.82 mrg struct ttysize ts; 118 1.82 mrg 119 1.82 mrg if (!first) 120 1.82 mrg return; 121 1.82 mrg first = false; 122 1.82 mrg if (ioctl(STDOUT_FILENO, TIOCGSIZE, &ts) != -1 && ts.ts_lines) 123 1.82 mrg redraw_lines = ts.ts_lines - 3; 124 1.82 mrg } 125 1.82 mrg 126 1.82 mrg 127 1.1 cgd /* 128 1.1 cgd * Print a description of the network interfaces. 129 1.15 thorpej * NOTE: ifnetaddr is the location of the kernel global "ifnet", 130 1.15 thorpej * which is a TAILQ_HEAD. 131 1.1 cgd */ 132 1.8 mycroft void 133 1.74 matt intpr(int interval, u_long ifnetaddr, void (*pfunc)(const char *)) 134 1.1 cgd { 135 1.64 elad 136 1.64 elad if (interval) { 137 1.64 elad sidewaysintpr((unsigned)interval, ifnetaddr); 138 1.64 elad return; 139 1.64 elad } 140 1.64 elad 141 1.99 msaitoh if (use_sysctl) 142 1.64 elad intpr_sysctl(); 143 1.99 msaitoh else 144 1.64 elad intpr_kvm(ifnetaddr, pfunc); 145 1.64 elad } 146 1.64 elad 147 1.64 elad static void 148 1.64 elad intpr_header(void) 149 1.64 elad { 150 1.64 elad 151 1.83 christos if (!sflag && !pflag) { 152 1.64 elad if (bflag) { 153 1.64 elad printf("%-5.5s %-5.5s %-13.13s %-17.17s " 154 1.98 msaitoh "%10.10s %10.10s", 155 1.98 msaitoh "Name", "Mtu", "Network", "Address", 156 1.98 msaitoh "Ibytes", "Obytes"); 157 1.64 elad } else { 158 1.64 elad printf("%-5.5s %-5.5s %-13.13s %-17.17s " 159 1.95 msaitoh "%8.8s %5.5s", 160 1.95 msaitoh "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs"); 161 1.95 msaitoh if (dflag) 162 1.95 msaitoh printf(" %6.6s", "Idrops"); 163 1.95 msaitoh printf(" %8.8s %5.5s %5.5s", 164 1.95 msaitoh "Opkts", "Oerrs", "Colls"); 165 1.64 elad } 166 1.95 msaitoh if (dflag) 167 1.95 msaitoh printf(" %6.6s", "Odrops"); 168 1.64 elad if (tflag) 169 1.64 elad printf(" %4.4s", "Time"); 170 1.64 elad putchar('\n'); 171 1.64 elad } 172 1.64 elad } 173 1.64 elad 174 1.101 msaitoh int 175 1.101 msaitoh if_data_ext_get(const char *ifname, struct if_data_ext *dext) 176 1.101 msaitoh { 177 1.101 msaitoh char namebuf[1024]; 178 1.101 msaitoh size_t len; 179 1.107 taca uint64_t drops; 180 1.101 msaitoh 181 1.101 msaitoh /* For sysctl */ 182 1.101 msaitoh snprintf(namebuf, sizeof(namebuf), 183 1.101 msaitoh "net.interfaces.%s.sndq.drops", ifname); 184 1.101 msaitoh len = sizeof(drops); 185 1.108 msaitoh if (sysctlbyname(namebuf, &drops, &len, NULL, 0) == -1) { 186 1.108 msaitoh warn("%s", namebuf); 187 1.101 msaitoh dext->ifi_oqdrops = 0; 188 1.101 msaitoh return -1; 189 1.101 msaitoh } else 190 1.101 msaitoh dext->ifi_oqdrops = drops; 191 1.101 msaitoh 192 1.101 msaitoh return 0; 193 1.101 msaitoh } 194 1.101 msaitoh 195 1.64 elad static void 196 1.64 elad intpr_sysctl(void) 197 1.64 elad { 198 1.64 elad struct if_msghdr *ifm; 199 1.64 elad int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; 200 1.93 mrg static char *buf = NULL; 201 1.93 mrg static size_t olen; 202 1.93 mrg char *next, *lim, *cp; 203 1.64 elad struct rt_msghdr *rtm; 204 1.64 elad struct ifa_msghdr *ifam; 205 1.64 elad struct if_data *ifd = NULL; 206 1.64 elad struct sockaddr *sa, *rti_info[RTAX_MAX]; 207 1.64 elad struct sockaddr_dl *sdl; 208 1.64 elad uint64_t total = 0; 209 1.64 elad size_t len; 210 1.84 christos int did = 1, rtax = 0, n; 211 1.64 elad char name[IFNAMSIZ + 1]; /* + 1 for `*' */ 212 1.101 msaitoh char origname[IFNAMSIZ]; /* without `*' */ 213 1.91 ozaki int ifindex = 0; 214 1.64 elad 215 1.70 pooka if (prog_sysctl(mib, 6, NULL, &len, NULL, 0) == -1) 216 1.64 elad err(1, "sysctl"); 217 1.93 mrg if (len > olen) { 218 1.93 mrg free(buf); 219 1.93 mrg if ((buf = malloc(len)) == NULL) 220 1.93 mrg err(1, NULL); 221 1.93 mrg olen = len; 222 1.93 mrg } 223 1.70 pooka if (prog_sysctl(mib, 6, buf, &len, NULL, 0) == -1) 224 1.64 elad err(1, "sysctl"); 225 1.64 elad 226 1.64 elad intpr_header(); 227 1.64 elad 228 1.64 elad lim = buf + len; 229 1.64 elad for (next = buf; next < lim; next += rtm->rtm_msglen) { 230 1.101 msaitoh struct if_data_ext dext; 231 1.101 msaitoh 232 1.64 elad rtm = (struct rt_msghdr *)next; 233 1.64 elad if (rtm->rtm_version != RTM_VERSION) 234 1.64 elad continue; 235 1.64 elad switch (rtm->rtm_type) { 236 1.64 elad case RTM_IFINFO: 237 1.64 elad total = 0; 238 1.64 elad ifm = (struct if_msghdr *)next; 239 1.64 elad ifd = &ifm->ifm_data; 240 1.64 elad 241 1.64 elad sa = (struct sockaddr *)(ifm + 1); 242 1.64 elad get_rtaddrs(ifm->ifm_addrs, sa, rti_info); 243 1.64 elad 244 1.64 elad sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP]; 245 1.99 msaitoh if (sdl == NULL || sdl->sdl_family != AF_LINK) 246 1.64 elad continue; 247 1.99 msaitoh 248 1.64 elad bzero(name, sizeof(name)); 249 1.64 elad if (sdl->sdl_nlen >= IFNAMSIZ) 250 1.64 elad memcpy(name, sdl->sdl_data, IFNAMSIZ - 1); 251 1.98 msaitoh else if (sdl->sdl_nlen > 0) 252 1.64 elad memcpy(name, sdl->sdl_data, sdl->sdl_nlen); 253 1.64 elad 254 1.97 msaitoh if (interface != NULL && strcmp(name, interface) != 0) 255 1.64 elad continue; 256 1.64 elad 257 1.91 ozaki ifindex = sdl->sdl_index; 258 1.91 ozaki 259 1.101 msaitoh /* Keep the original name */ 260 1.101 msaitoh strcpy(origname, name); 261 1.101 msaitoh 262 1.101 msaitoh /* Mark inactive interfaces with a '*' */ 263 1.64 elad cp = strchr(name, '\0'); 264 1.101 msaitoh if ((ifm->ifm_flags & IFF_UP) == 0) { 265 1.64 elad *cp++ = '*'; 266 1.101 msaitoh *cp = '\0'; 267 1.101 msaitoh } 268 1.64 elad 269 1.64 elad if (qflag) { 270 1.64 elad total = ifd->ifi_ibytes + ifd->ifi_obytes + 271 1.64 elad ifd->ifi_ipackets + ifd->ifi_ierrors + 272 1.64 elad ifd->ifi_opackets + ifd->ifi_oerrors + 273 1.64 elad ifd->ifi_collisions; 274 1.64 elad if (dflag) 275 1.88 christos total += ifd->ifi_iqdrops; 276 1.64 elad if (total == 0) 277 1.64 elad continue; 278 1.64 elad } 279 1.84 christos /* Skip the first one */ 280 1.84 christos if (did) { 281 1.84 christos did = 0; 282 1.84 christos continue; 283 1.84 christos } 284 1.84 christos rtax = RTAX_IFP; 285 1.64 elad break; 286 1.64 elad case RTM_NEWADDR: 287 1.64 elad if (qflag && total == 0) 288 1.64 elad continue; 289 1.97 msaitoh if (interface != NULL && strcmp(name, interface) != 0) 290 1.64 elad continue; 291 1.64 elad ifam = (struct ifa_msghdr *)next; 292 1.64 elad if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA | 293 1.64 elad RTA_BRD)) == 0) 294 1.64 elad break; 295 1.64 elad 296 1.64 elad sa = (struct sockaddr *)(ifam + 1); 297 1.64 elad 298 1.64 elad get_rtaddrs(ifam->ifam_addrs, sa, rti_info); 299 1.84 christos rtax = RTAX_IFA; 300 1.84 christos did = 1; 301 1.64 elad break; 302 1.84 christos default: 303 1.84 christos continue; 304 1.64 elad } 305 1.84 christos if (vflag) 306 1.84 christos n = strlen(name) < 5 ? 5 : strlen(name); 307 1.84 christos else 308 1.84 christos n = 5; 309 1.84 christos 310 1.84 christos printf("%-*.*s %-5" PRIu64 " ", n, n, name, ifd->ifi_mtu); 311 1.102 msaitoh if (dflag) 312 1.101 msaitoh if_data_ext_get(origname, &dext); 313 1.101 msaitoh 314 1.101 msaitoh print_addr(ifindex, rti_info[rtax], rti_info, ifd, 315 1.101 msaitoh NULL, dflag ? &dext : NULL); 316 1.64 elad } 317 1.64 elad } 318 1.64 elad 319 1.73 christos union ifaddr_u { 320 1.73 christos struct ifaddr ifa; 321 1.73 christos struct in_ifaddr in; 322 1.73 christos #ifdef INET6 323 1.73 christos struct in6_ifaddr in6; 324 1.73 christos #endif /* INET6 */ 325 1.73 christos }; 326 1.73 christos 327 1.64 elad static void 328 1.100 msaitoh ifname_to_ifdata(int s, const char *ifname, struct if_data * const ifd) 329 1.96 thorpej { 330 1.100 msaitoh struct ifdatareq ifdr; 331 1.96 thorpej 332 1.96 thorpej memset(ifd, 0, sizeof(*ifd)); 333 1.100 msaitoh strlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name)); 334 1.100 msaitoh if (ioctl(s, SIOCGIFDATA, &ifdr) != 0) 335 1.100 msaitoh return; 336 1.100 msaitoh memcpy(ifd, &ifdr.ifdr_data, sizeof(ifdr.ifdr_data)); 337 1.96 thorpej } 338 1.96 thorpej 339 1.96 thorpej static void 340 1.64 elad intpr_kvm(u_long ifnetaddr, void (*pfunc)(const char *)) 341 1.64 elad { 342 1.1 cgd struct ifnet ifnet; 343 1.96 thorpej struct if_data ifd; 344 1.73 christos union ifaddr_u ifaddr; 345 1.7 cgd u_long ifaddraddr; 346 1.15 thorpej struct ifnet_head ifhead; /* TAILQ_HEAD */ 347 1.43 enami char name[IFNAMSIZ + 1]; /* + 1 for `*' */ 348 1.100 msaitoh int s; 349 1.1 cgd 350 1.1 cgd if (ifnetaddr == 0) { 351 1.1 cgd printf("ifnet: symbol not defined\n"); 352 1.1 cgd return; 353 1.1 cgd } 354 1.15 thorpej 355 1.15 thorpej /* 356 1.15 thorpej * Find the pointer to the first ifnet structure. Replace 357 1.15 thorpej * the pointer to the TAILQ_HEAD with the actual pointer 358 1.15 thorpej * to the first list element. 359 1.15 thorpej */ 360 1.15 thorpej if (kread(ifnetaddr, (char *)&ifhead, sizeof ifhead)) 361 1.8 mycroft return; 362 1.15 thorpej ifnetaddr = (u_long)ifhead.tqh_first; 363 1.15 thorpej 364 1.100 msaitoh if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 365 1.100 msaitoh return; 366 1.100 msaitoh 367 1.64 elad intpr_header(); 368 1.64 elad 369 1.1 cgd ifaddraddr = 0; 370 1.1 cgd while (ifnetaddr || ifaddraddr) { 371 1.25 lukem char *cp; 372 1.64 elad int n; 373 1.1 cgd 374 1.1 cgd if (ifaddraddr == 0) { 375 1.15 thorpej if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet)) 376 1.8 mycroft return; 377 1.25 lukem memmove(name, ifnet.if_xname, IFNAMSIZ); 378 1.15 thorpej name[IFNAMSIZ - 1] = '\0'; /* sanity */ 379 1.10 mycroft ifnetaddr = (u_long)ifnet.if_list.tqe_next; 380 1.97 msaitoh if (interface != NULL && strcmp(name, interface) != 0) 381 1.1 cgd continue; 382 1.25 lukem cp = strchr(name, '\0'); 383 1.34 itojun 384 1.34 itojun if (pfunc) { 385 1.34 itojun (*pfunc)(name); 386 1.34 itojun continue; 387 1.34 itojun } 388 1.34 itojun 389 1.10 mycroft if ((ifnet.if_flags & IFF_UP) == 0) 390 1.1 cgd *cp++ = '*'; 391 1.1 cgd *cp = '\0'; 392 1.10 mycroft ifaddraddr = (u_long)ifnet.if_addrlist.tqh_first; 393 1.1 cgd } 394 1.41 itojun if (vflag) 395 1.41 itojun n = strlen(name) < 5 ? 5 : strlen(name); 396 1.41 itojun else 397 1.41 itojun n = 5; 398 1.41 itojun printf("%-*.*s %-5llu ", n, n, name, 399 1.33 bouyer (unsigned long long)ifnet.if_mtu); 400 1.1 cgd if (ifaddraddr == 0) { 401 1.21 christos printf("%-13.13s ", "none"); 402 1.23 mikel printf("%-17.17s ", "none"); 403 1.1 cgd } else { 404 1.64 elad struct sockaddr *sa; 405 1.64 elad 406 1.98 msaitoh if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) 407 1.98 msaitoh { 408 1.8 mycroft ifaddraddr = 0; 409 1.8 mycroft continue; 410 1.8 mycroft } 411 1.1 cgd #define CP(x) ((char *)(x)) 412 1.8 mycroft cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 413 1.56 itojun CP(&ifaddr); 414 1.56 itojun sa = (struct sockaddr *)cp; 415 1.100 msaitoh ifname_to_ifdata(s, name, &ifd); 416 1.91 ozaki print_addr(ifnet.if_index, sa, (void *)&ifaddr, 417 1.101 msaitoh &ifd, &ifnet, NULL); 418 1.64 elad } 419 1.64 elad ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next; 420 1.64 elad } 421 1.100 msaitoh close(s); 422 1.64 elad } 423 1.64 elad 424 1.64 elad static void 425 1.91 ozaki mc_print(const int ifindex, const size_t ias, const char *oid, int *mcast_oids, 426 1.86 christos void (*pr)(const void *)) 427 1.84 christos { 428 1.85 christos uint8_t *mcast_addrs, *p; 429 1.86 christos const size_t incr = 2 * ias + sizeof(uint32_t); 430 1.85 christos size_t len; 431 1.85 christos 432 1.85 christos if (mcast_oids[0] == 0) { 433 1.86 christos size_t oidlen = 4; 434 1.86 christos if (sysctlnametomib(oid, mcast_oids, &oidlen) == -1) { 435 1.86 christos warnx("'%s' not found", oid); 436 1.85 christos return; 437 1.85 christos } 438 1.85 christos if (oidlen != 3) { 439 1.86 christos warnx("Wrong OID path for '%s'", oid); 440 1.85 christos return; 441 1.85 christos } 442 1.85 christos } 443 1.86 christos 444 1.86 christos if (mcast_oids[3] == ifindex) 445 1.86 christos return; 446 1.85 christos mcast_oids[3] = ifindex; 447 1.85 christos 448 1.85 christos mcast_addrs = asysctl(mcast_oids, 4, &len); 449 1.85 christos if (mcast_addrs == NULL && len != 0) { 450 1.86 christos warn("failed to read '%s'", oid); 451 1.85 christos return; 452 1.85 christos } 453 1.85 christos if (len) { 454 1.85 christos p = mcast_addrs; 455 1.85 christos while (len >= incr) { 456 1.86 christos (*pr)((p + ias)); 457 1.85 christos p += incr; 458 1.85 christos len -= incr; 459 1.85 christos } 460 1.85 christos } 461 1.85 christos free(mcast_addrs); 462 1.85 christos } 463 1.85 christos 464 1.86 christos #ifdef INET6 465 1.86 christos static void 466 1.86 christos ia6_print(const struct in6_addr *ia) 467 1.86 christos { 468 1.86 christos struct sockaddr_in6 as6; 469 1.86 christos char hbuf[NI_MAXHOST]; /* for getnameinfo() */ 470 1.86 christos int n; 471 1.86 christos 472 1.86 christos memset(&as6, 0, sizeof(as6)); 473 1.86 christos as6.sin6_len = sizeof(struct sockaddr_in6); 474 1.86 christos as6.sin6_family = AF_INET6; 475 1.86 christos as6.sin6_addr = *ia; 476 1.86 christos inet6_getscopeid(&as6, INET6_IS_ADDR_MC_LINKLOCAL); 477 1.86 christos if (getnameinfo((struct sockaddr *)&as6, as6.sin6_len, hbuf, 478 1.86 christos sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) { 479 1.86 christos strlcpy(hbuf, "??", sizeof(hbuf)); 480 1.86 christos } 481 1.86 christos if (vflag) 482 1.86 christos n = strlen(hbuf) < 17 ? 17 : strlen(hbuf); 483 1.86 christos else 484 1.86 christos n = 17; 485 1.86 christos printf("\n%25s %-*.*s ", "", n, n, hbuf); 486 1.86 christos } 487 1.86 christos 488 1.86 christos static void 489 1.91 ozaki mc6_print(const int ifindex) 490 1.86 christos { 491 1.86 christos static int mcast_oids[4]; 492 1.86 christos 493 1.91 ozaki mc_print(ifindex, sizeof(struct in6_addr), "net.inet6.multicast", 494 1.86 christos mcast_oids, (void (*)(const void *))ia6_print); 495 1.86 christos } 496 1.86 christos #endif 497 1.86 christos 498 1.85 christos static void 499 1.85 christos ia4_print(const struct in_addr *ia) 500 1.85 christos { 501 1.85 christos printf("\n%25s %-17.17s ", "", routename4(ia->s_addr, nflag)); 502 1.85 christos } 503 1.85 christos 504 1.85 christos static void 505 1.91 ozaki mc4_print(const int ifindex) 506 1.85 christos { 507 1.85 christos static int mcast_oids[4]; 508 1.85 christos 509 1.91 ozaki mc_print(ifindex, sizeof(struct in_addr), "net.inet.multicast", 510 1.86 christos mcast_oids, (void (*)(const void *))ia4_print); 511 1.85 christos } 512 1.85 christos 513 1.85 christos static void 514 1.101 msaitoh print_addr(const int ifindex, struct sockaddr *sa, struct sockaddr **rtinfo, 515 1.101 msaitoh struct if_data *ifd, struct ifnet *ifnet, struct if_data_ext *dext) 516 1.64 elad { 517 1.64 elad char hexsep = '.'; /* for hexprint */ 518 1.64 elad static const char hexfmt[] = "%02x%c"; /* for hexprint */ 519 1.64 elad char hbuf[NI_MAXHOST]; /* for getnameinfo() */ 520 1.64 elad #ifdef INET6 521 1.64 elad const int niflag = NI_NUMERICHOST; 522 1.67 plunky struct sockaddr_in6 *sin6, *netmask6; 523 1.64 elad #endif 524 1.81 christos struct sockaddr_in netmask; 525 1.64 elad struct sockaddr_in *sin; 526 1.64 elad char *cp; 527 1.64 elad int n, m; 528 1.64 elad 529 1.64 elad switch (sa->sa_family) { 530 1.64 elad case AF_UNSPEC: 531 1.64 elad printf("%-13.13s ", "none"); 532 1.64 elad printf("%-17.17s ", "none"); 533 1.64 elad break; 534 1.64 elad case AF_INET: 535 1.64 elad sin = (struct sockaddr_in *)sa; 536 1.64 elad if (use_sysctl) { 537 1.98 msaitoh netmask = 538 1.98 msaitoh *((struct sockaddr_in *)rtinfo[RTAX_NETMASK]); 539 1.64 elad } else { 540 1.64 elad struct in_ifaddr *ifaddr_in = (void *)rtinfo; 541 1.81 christos netmask.sin_addr.s_addr = ifaddr_in->ia_subnetmask; 542 1.64 elad } 543 1.81 christos cp = netname4(sin, &netmask, nflag); 544 1.64 elad if (vflag) 545 1.64 elad n = strlen(cp) < 13 ? 13 : strlen(cp); 546 1.64 elad else 547 1.64 elad n = 13; 548 1.64 elad printf("%-*.*s ", n, n, cp); 549 1.80 christos cp = routename4(sin->sin_addr.s_addr, nflag); 550 1.64 elad if (vflag) 551 1.64 elad n = strlen(cp) < 17 ? 17 : strlen(cp); 552 1.64 elad else 553 1.64 elad n = 17; 554 1.64 elad printf("%-*.*s ", n, n, cp); 555 1.64 elad 556 1.84 christos if (!aflag) 557 1.84 christos break; 558 1.84 christos if (ifnet) { 559 1.64 elad u_long multiaddr; 560 1.64 elad struct in_multi inm; 561 1.73 christos union ifaddr_u *ifaddr = (union ifaddr_u *)rtinfo; 562 1.64 elad 563 1.85 christos multiaddr = (u_long)ifaddr->in.ia_multiaddrs.lh_first; 564 1.64 elad while (multiaddr != 0) { 565 1.85 christos kread(multiaddr, (char *)&inm, sizeof inm); 566 1.85 christos ia4_print(&inm.inm_addr); 567 1.85 christos multiaddr = (u_long)inm.inm_list.le_next; 568 1.64 elad } 569 1.99 msaitoh } else 570 1.91 ozaki mc4_print(ifindex); 571 1.64 elad break; 572 1.32 itojun #ifdef INET6 573 1.64 elad case AF_INET6: 574 1.64 elad sin6 = (struct sockaddr_in6 *)sa; 575 1.79 christos inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); 576 1.54 itojun #ifdef __KAME__ 577 1.78 christos if (!vflag) 578 1.78 christos sin6->sin6_scope_id = 0; 579 1.34 itojun #endif 580 1.64 elad 581 1.99 msaitoh if (use_sysctl) 582 1.64 elad netmask6 = (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK]; 583 1.99 msaitoh else { 584 1.64 elad struct in6_ifaddr *ifaddr_in6 = (void *)rtinfo; 585 1.64 elad netmask6 = &ifaddr_in6->ia_prefixmask; 586 1.64 elad } 587 1.64 elad 588 1.80 christos cp = netname6(sin6, netmask6, nflag); 589 1.64 elad if (vflag) 590 1.64 elad n = strlen(cp) < 13 ? 13 : strlen(cp); 591 1.64 elad else 592 1.64 elad n = 13; 593 1.64 elad printf("%-*.*s ", n, n, cp); 594 1.64 elad if (getnameinfo((struct sockaddr *)sin6, 595 1.64 elad sin6->sin6_len, 596 1.64 elad hbuf, sizeof(hbuf), NULL, 0, 597 1.64 elad niflag) != 0) { 598 1.64 elad strlcpy(hbuf, "?", sizeof(hbuf)); 599 1.64 elad } 600 1.64 elad cp = hbuf; 601 1.64 elad if (vflag) 602 1.64 elad n = strlen(cp) < 17 ? 17 : strlen(cp); 603 1.64 elad else 604 1.64 elad n = 17; 605 1.64 elad printf("%-*.*s ", n, n, cp); 606 1.64 elad 607 1.98 msaitoh if (!aflag) 608 1.84 christos break; 609 1.84 christos if (ifnet) { 610 1.64 elad u_long multiaddr; 611 1.64 elad struct in6_multi inm; 612 1.73 christos union ifaddr_u *ifaddr = (union ifaddr_u *)rtinfo; 613 1.98 msaitoh 614 1.94 ozaki multiaddr = (u_long)ifaddr->in6._ia6_multiaddrs.lh_first; 615 1.64 elad while (multiaddr != 0) { 616 1.84 christos kread(multiaddr, (char *)&inm, sizeof inm); 617 1.84 christos ia6_print(&inm.in6m_addr); 618 1.84 christos multiaddr = (u_long)inm.in6m_entry.le_next; 619 1.1 cgd } 620 1.99 msaitoh } else 621 1.91 ozaki mc6_print(ifindex); 622 1.64 elad break; 623 1.64 elad #endif /*INET6*/ 624 1.64 elad #ifndef SMALL 625 1.64 elad case AF_APPLETALK: 626 1.98 msaitoh printf("atalk:%-7.7s ", atalk_print(sa, 0x10)); 627 1.98 msaitoh printf("%-17.17s ", atalk_print(sa, 0x0b)); 628 1.64 elad break; 629 1.64 elad #endif 630 1.64 elad case AF_LINK: 631 1.64 elad printf("%-13.13s ", "<Link>"); 632 1.64 elad if (getnameinfo(sa, sa->sa_len, 633 1.64 elad hbuf, sizeof(hbuf), NULL, 0, 634 1.64 elad NI_NUMERICHOST) != 0) { 635 1.64 elad strlcpy(hbuf, "?", sizeof(hbuf)); 636 1.26 kml } 637 1.64 elad cp = hbuf; 638 1.64 elad if (vflag) 639 1.64 elad n = strlen(cp) < 17 ? 17 : strlen(cp); 640 1.64 elad else 641 1.64 elad n = 17; 642 1.64 elad printf("%-*.*s ", n, n, cp); 643 1.64 elad break; 644 1.64 elad 645 1.64 elad default: 646 1.64 elad m = printf("(%d)", sa->sa_family); 647 1.64 elad for (cp = sa->sa_len + (char *)sa; 648 1.64 elad --cp > sa->sa_data && (*cp == 0);) {} 649 1.64 elad n = cp - sa->sa_data + 1; 650 1.64 elad cp = sa->sa_data; 651 1.64 elad 652 1.64 elad while (--n >= 0) 653 1.64 elad m += printf(hexfmt, *cp++ & 0xff, 654 1.64 elad n > 0 ? hexsep : ' '); 655 1.64 elad m = 32 - m; 656 1.64 elad while (m-- > 0) 657 1.64 elad putchar(' '); 658 1.64 elad break; 659 1.64 elad } 660 1.64 elad 661 1.64 elad if (bflag) { 662 1.68 pooka char humbuf[HUMBUF_SIZE]; 663 1.68 pooka 664 1.68 pooka if (hflag && humanize_number(humbuf, sizeof(humbuf), 665 1.68 pooka ifd->ifi_ibytes, "", HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0) 666 1.68 pooka printf("%10s ", humbuf); 667 1.68 pooka else 668 1.68 pooka printf("%10llu ", (unsigned long long)ifd->ifi_ibytes); 669 1.68 pooka 670 1.68 pooka if (hflag && humanize_number(humbuf, sizeof(humbuf), 671 1.68 pooka ifd->ifi_obytes, "", HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0) 672 1.68 pooka printf("%10s", humbuf); 673 1.68 pooka else 674 1.68 pooka printf("%10llu", (unsigned long long)ifd->ifi_obytes); 675 1.64 elad } else { 676 1.95 msaitoh printf("%8llu %5llu", 677 1.64 elad (unsigned long long)ifd->ifi_ipackets, 678 1.95 msaitoh (unsigned long long)ifd->ifi_ierrors); 679 1.95 msaitoh if (dflag) 680 1.95 msaitoh printf(" %6" PRIu64, ifd->ifi_iqdrops); 681 1.95 msaitoh printf(" %8llu %5llu %5llu", 682 1.64 elad (unsigned long long)ifd->ifi_opackets, 683 1.64 elad (unsigned long long)ifd->ifi_oerrors, 684 1.64 elad (unsigned long long)ifd->ifi_collisions); 685 1.1 cgd } 686 1.95 msaitoh if (dflag) 687 1.106 msaitoh printf(" %6" PRIu64, ifnet ? 688 1.106 msaitoh ifnet->if_snd.ifq_drops : dext->ifi_oqdrops); 689 1.64 elad if (tflag) 690 1.73 christos printf(" %4d", ifnet ? ifnet->if_timer : 0); 691 1.64 elad putchar('\n'); 692 1.64 elad } 693 1.64 elad 694 1.64 elad static void 695 1.64 elad iftot_banner(struct iftot *ift) 696 1.64 elad { 697 1.64 elad if (bflag) 698 1.64 elad printf("%7.7s in %8.8s %6.6s out %5.5s", 699 1.64 elad ift->ift_name, " ", 700 1.64 elad ift->ift_name, " "); 701 1.64 elad else 702 1.64 elad printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", 703 1.64 elad ift->ift_name, " ", 704 1.64 elad ift->ift_name, " ", " "); 705 1.64 elad if (dflag) 706 1.64 elad printf(" %5.5s", " "); 707 1.64 elad 708 1.64 elad if (bflag) 709 1.64 elad printf(" %7.7s in %8.8s %6.6s out %5.5s", 710 1.64 elad "total", " ", "total", " "); 711 1.64 elad else 712 1.64 elad printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", 713 1.64 elad "total", " ", "total", " ", " "); 714 1.64 elad if (dflag) 715 1.64 elad printf(" %5.5s", " "); 716 1.64 elad putchar('\n'); 717 1.64 elad if (bflag) 718 1.64 elad printf("%10.10s %8.8s %10.10s %5.5s", 719 1.64 elad "bytes", " ", "bytes", " "); 720 1.64 elad else 721 1.64 elad printf("%8.8s %5.5s %8.8s %5.5s %5.5s", 722 1.64 elad "packets", "errs", "packets", "errs", "colls"); 723 1.64 elad if (dflag) 724 1.64 elad printf(" %5.5s", "drops"); 725 1.64 elad 726 1.64 elad if (bflag) 727 1.64 elad printf(" %10.10s %8.8s %10.10s %5.5s", 728 1.64 elad "bytes", " ", "bytes", " "); 729 1.64 elad else 730 1.64 elad printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 731 1.64 elad "packets", "errs", "packets", "errs", "colls"); 732 1.64 elad if (dflag) 733 1.64 elad printf(" %5.5s", "drops"); 734 1.64 elad putchar('\n'); 735 1.64 elad fflush(stdout); 736 1.1 cgd } 737 1.1 cgd 738 1.64 elad static void 739 1.64 elad iftot_print(struct iftot *cur, struct iftot *old) 740 1.64 elad { 741 1.64 elad if (bflag) 742 1.75 msaitoh printf("%10" PRIu64 " %8.8s %10" PRIu64 " %5.5s", 743 1.66 pgoyette cur->ift_ib - old->ift_ib, " ", 744 1.66 pgoyette cur->ift_ob - old->ift_ob, " "); 745 1.64 elad else 746 1.75 msaitoh printf("%8" PRIu64 " %5" PRIu64 " %8" PRIu64 " %5" PRIu64 " %5" PRIu64, 747 1.66 pgoyette cur->ift_ip - old->ift_ip, 748 1.66 pgoyette cur->ift_ie - old->ift_ie, 749 1.66 pgoyette cur->ift_op - old->ift_op, 750 1.66 pgoyette cur->ift_oe - old->ift_oe, 751 1.66 pgoyette cur->ift_co - old->ift_co); 752 1.64 elad if (dflag) 753 1.101 msaitoh printf(" %5" PRIu64, cur->ift_oq - old->ift_oq); 754 1.64 elad } 755 1.64 elad 756 1.64 elad static void 757 1.64 elad iftot_print_sum(struct iftot *cur, struct iftot *old) 758 1.64 elad { 759 1.64 elad if (bflag) 760 1.75 msaitoh printf(" %10" PRIu64 " %8.8s %10" PRIu64 " %5.5s", 761 1.66 pgoyette cur->ift_ib - old->ift_ib, " ", 762 1.66 pgoyette cur->ift_ob - old->ift_ob, " "); 763 1.64 elad else 764 1.75 msaitoh printf(" %8" PRIu64 " %5" PRIu64 " %8" PRIu64 " %5" PRIu64 " %5" PRIu64, 765 1.66 pgoyette cur->ift_ip - old->ift_ip, 766 1.66 pgoyette cur->ift_ie - old->ift_ie, 767 1.66 pgoyette cur->ift_op - old->ift_op, 768 1.66 pgoyette cur->ift_oe - old->ift_oe, 769 1.66 pgoyette cur->ift_co - old->ift_co); 770 1.64 elad 771 1.64 elad if (dflag) 772 1.101 msaitoh printf(" %5" PRIu64, cur->ift_oq - old->ift_oq); 773 1.64 elad } 774 1.64 elad 775 1.72 joerg __dead static void 776 1.64 elad sidewaysintpr_sysctl(unsigned interval) 777 1.64 elad { 778 1.90 dholland struct itimerval it; 779 1.64 elad sigset_t emptyset; 780 1.90 dholland sigset_t noalrm; 781 1.82 mrg unsigned line; 782 1.82 mrg 783 1.82 mrg set_lines(); 784 1.64 elad 785 1.64 elad fetchifs(); 786 1.64 elad if (ip_cur.ift_name[0] == '\0') { 787 1.64 elad fprintf(stderr, "%s: %s: unknown interface\n", 788 1.64 elad getprogname(), interface); 789 1.64 elad exit(1); 790 1.64 elad } 791 1.64 elad 792 1.90 dholland sigemptyset(&emptyset); 793 1.90 dholland sigemptyset(&noalrm); 794 1.90 dholland sigaddset(&noalrm, SIGALRM); 795 1.90 dholland sigprocmask(SIG_SETMASK, &noalrm, NULL); 796 1.90 dholland 797 1.90 dholland signalled = 0; 798 1.64 elad (void)signal(SIGALRM, catchalarm); 799 1.90 dholland 800 1.90 dholland it.it_interval.tv_sec = it.it_value.tv_sec = interval; 801 1.90 dholland it.it_interval.tv_usec = it.it_value.tv_usec = 0; 802 1.90 dholland setitimer(ITIMER_REAL, &it, NULL); 803 1.90 dholland 804 1.64 elad banner: 805 1.64 elad iftot_banner(&ip_cur); 806 1.64 elad 807 1.64 elad line = 0; 808 1.64 elad bzero(&ip_old, sizeof(ip_old)); 809 1.64 elad bzero(&sum_old, sizeof(sum_old)); 810 1.64 elad loop: 811 1.64 elad bzero(&sum_cur, sizeof(sum_cur)); 812 1.64 elad 813 1.64 elad fetchifs(); 814 1.64 elad 815 1.64 elad iftot_print(&ip_cur, &ip_old); 816 1.64 elad 817 1.64 elad ip_old = ip_cur; 818 1.64 elad 819 1.64 elad iftot_print_sum(&sum_cur, &sum_old); 820 1.64 elad 821 1.64 elad sum_old = sum_cur; 822 1.1 cgd 823 1.64 elad putchar('\n'); 824 1.64 elad fflush(stdout); 825 1.64 elad line++; 826 1.98 msaitoh if (signalled == 0) 827 1.64 elad sigsuspend(&emptyset); 828 1.98 msaitoh 829 1.64 elad signalled = 0; 830 1.82 mrg if (line == redraw_lines) 831 1.64 elad goto banner; 832 1.64 elad goto loop; 833 1.64 elad /*NOTREACHED*/ 834 1.64 elad } 835 1.1 cgd 836 1.8 mycroft static void 837 1.64 elad sidewaysintpr_kvm(unsigned interval, u_long off) 838 1.1 cgd { 839 1.57 ragge struct itimerval it; 840 1.90 dholland sigset_t emptyset; 841 1.90 dholland sigset_t noalrm; 842 1.1 cgd struct ifnet ifnet; 843 1.96 thorpej struct if_data ifd; 844 1.7 cgd u_long firstifnet; 845 1.25 lukem struct iftot *ip, *total; 846 1.82 mrg unsigned line; 847 1.1 cgd struct iftot *lastif, *sum, *interesting; 848 1.15 thorpej struct ifnet_head ifhead; /* TAILQ_HEAD */ 849 1.100 msaitoh int s; 850 1.1 cgd 851 1.82 mrg set_lines(); 852 1.82 mrg 853 1.15 thorpej /* 854 1.15 thorpej * Find the pointer to the first ifnet structure. Replace 855 1.15 thorpej * the pointer to the TAILQ_HEAD with the actual pointer 856 1.15 thorpej * to the first list element. 857 1.15 thorpej */ 858 1.15 thorpej if (kread(off, (char *)&ifhead, sizeof ifhead)) 859 1.8 mycroft return; 860 1.15 thorpej firstifnet = (u_long)ifhead.tqh_first; 861 1.15 thorpej 862 1.100 msaitoh if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 863 1.100 msaitoh return; 864 1.100 msaitoh 865 1.1 cgd lastif = iftot; 866 1.1 cgd sum = iftot + MAXIF - 1; 867 1.1 cgd total = sum - 1; 868 1.17 cgd interesting = (interface == NULL) ? iftot : NULL; 869 1.1 cgd for (off = firstifnet, ip = iftot; off;) { 870 1.8 mycroft if (kread(off, (char *)&ifnet, sizeof ifnet)) 871 1.8 mycroft break; 872 1.25 lukem memset(ip->ift_name, 0, sizeof(ip->ift_name)); 873 1.31 mycroft snprintf(ip->ift_name, IFNAMSIZ, "%s", ifnet.if_xname); 874 1.19 thorpej if (interface && strcmp(ifnet.if_xname, interface) == 0) 875 1.1 cgd interesting = ip; 876 1.1 cgd ip++; 877 1.1 cgd if (ip >= iftot + MAXIF - 2) 878 1.1 cgd break; 879 1.10 mycroft off = (u_long)ifnet.if_list.tqe_next; 880 1.17 cgd } 881 1.17 cgd if (interesting == NULL) { 882 1.17 cgd fprintf(stderr, "%s: %s: unknown interface\n", 883 1.47 cgd getprogname(), interface); 884 1.17 cgd exit(1); 885 1.1 cgd } 886 1.1 cgd lastif = ip; 887 1.1 cgd 888 1.90 dholland sigemptyset(&emptyset); 889 1.90 dholland sigemptyset(&noalrm); 890 1.90 dholland sigaddset(&noalrm, SIGALRM); 891 1.90 dholland sigprocmask(SIG_SETMASK, &noalrm, NULL); 892 1.90 dholland 893 1.90 dholland signalled = 0; 894 1.1 cgd (void)signal(SIGALRM, catchalarm); 895 1.57 ragge 896 1.57 ragge it.it_interval.tv_sec = it.it_value.tv_sec = interval; 897 1.57 ragge it.it_interval.tv_usec = it.it_value.tv_usec = 0; 898 1.57 ragge setitimer(ITIMER_REAL, &it, NULL); 899 1.57 ragge 900 1.1 cgd banner: 901 1.31 mycroft if (bflag) 902 1.31 mycroft printf("%7.7s in %8.8s %6.6s out %5.5s", 903 1.31 mycroft interesting->ift_name, " ", 904 1.31 mycroft interesting->ift_name, " "); 905 1.31 mycroft else 906 1.31 mycroft printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", 907 1.31 mycroft interesting->ift_name, " ", 908 1.31 mycroft interesting->ift_name, " ", " "); 909 1.31 mycroft if (dflag) 910 1.31 mycroft printf(" %5.5s", " "); 911 1.1 cgd if (lastif - iftot > 0) { 912 1.31 mycroft if (bflag) 913 1.31 mycroft printf(" %7.7s in %8.8s %6.6s out %5.5s", 914 1.31 mycroft "total", " ", "total", " "); 915 1.31 mycroft else 916 1.31 mycroft printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", 917 1.31 mycroft "total", " ", "total", " ", " "); 918 1.1 cgd if (dflag) 919 1.31 mycroft printf(" %5.5s", " "); 920 1.1 cgd } 921 1.1 cgd for (ip = iftot; ip < iftot + MAXIF; ip++) { 922 1.1 cgd ip->ift_ip = 0; 923 1.26 kml ip->ift_ib = 0; 924 1.1 cgd ip->ift_ie = 0; 925 1.104 msaitoh ip->ift_iq = 0; 926 1.1 cgd ip->ift_op = 0; 927 1.26 kml ip->ift_ob = 0; 928 1.1 cgd ip->ift_oe = 0; 929 1.104 msaitoh ip->ift_oq = 0; 930 1.1 cgd ip->ift_co = 0; 931 1.1 cgd } 932 1.1 cgd putchar('\n'); 933 1.31 mycroft if (bflag) 934 1.26 kml printf("%10.10s %8.8s %10.10s %5.5s", 935 1.31 mycroft "bytes", " ", "bytes", " "); 936 1.31 mycroft else 937 1.31 mycroft printf("%8.8s %5.5s %8.8s %5.5s %5.5s", 938 1.31 mycroft "packets", "errs", "packets", "errs", "colls"); 939 1.1 cgd if (dflag) 940 1.31 mycroft printf(" %5.5s", "drops"); 941 1.29 ross if (lastif - iftot > 0) { 942 1.31 mycroft if (bflag) 943 1.31 mycroft printf(" %10.10s %8.8s %10.10s %5.5s", 944 1.31 mycroft "bytes", " ", "bytes", " "); 945 1.31 mycroft else 946 1.31 mycroft printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 947 1.31 mycroft "packets", "errs", "packets", "errs", "colls"); 948 1.31 mycroft if (dflag) 949 1.31 mycroft printf(" %5.5s", "drops"); 950 1.29 ross } 951 1.1 cgd putchar('\n'); 952 1.1 cgd fflush(stdout); 953 1.1 cgd line = 0; 954 1.1 cgd loop: 955 1.1 cgd sum->ift_ip = 0; 956 1.26 kml sum->ift_ib = 0; 957 1.1 cgd sum->ift_ie = 0; 958 1.104 msaitoh sum->ift_iq = 0; 959 1.1 cgd sum->ift_op = 0; 960 1.26 kml sum->ift_ob = 0; 961 1.1 cgd sum->ift_oe = 0; 962 1.104 msaitoh sum->ift_oq = 0; 963 1.1 cgd sum->ift_co = 0; 964 1.1 cgd for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 965 1.8 mycroft if (kread(off, (char *)&ifnet, sizeof ifnet)) { 966 1.8 mycroft off = 0; 967 1.8 mycroft continue; 968 1.8 mycroft } 969 1.100 msaitoh ifname_to_ifdata(s, ip->ift_name, &ifd); 970 1.1 cgd if (ip == interesting) { 971 1.26 kml if (bflag) { 972 1.68 pooka char humbuf[HUMBUF_SIZE]; 973 1.68 pooka 974 1.68 pooka if (hflag && humanize_number(humbuf, 975 1.68 pooka sizeof(humbuf), 976 1.96 thorpej ifd.ifi_ibytes - ip->ift_ib, "", 977 1.68 pooka HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0) 978 1.68 pooka printf("%10s %8.8s ", humbuf, " "); 979 1.68 pooka else 980 1.98 msaitoh printf("%10llu %8.8s ", 981 1.68 pooka (unsigned long long) 982 1.96 thorpej (ifd.ifi_ibytes-ip->ift_ib), " "); 983 1.68 pooka 984 1.68 pooka if (hflag && humanize_number(humbuf, 985 1.68 pooka sizeof(humbuf), 986 1.96 thorpej ifd.ifi_obytes - ip->ift_ob, "", 987 1.68 pooka HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0) 988 1.68 pooka printf("%10s %5.5s", humbuf, " "); 989 1.68 pooka else 990 1.98 msaitoh printf("%10llu %5.5s", 991 1.68 pooka (unsigned long long) 992 1.96 thorpej (ifd.ifi_obytes-ip->ift_ob), " "); 993 1.26 kml } else { 994 1.33 bouyer printf("%8llu %5llu %8llu %5llu %5llu", 995 1.33 bouyer (unsigned long long) 996 1.96 thorpej (ifd.ifi_ipackets - ip->ift_ip), 997 1.33 bouyer (unsigned long long) 998 1.96 thorpej (ifd.ifi_ierrors - ip->ift_ie), 999 1.33 bouyer (unsigned long long) 1000 1.96 thorpej (ifd.ifi_opackets - ip->ift_op), 1001 1.33 bouyer (unsigned long long) 1002 1.96 thorpej (ifd.ifi_oerrors - ip->ift_oe), 1003 1.33 bouyer (unsigned long long) 1004 1.96 thorpej (ifd.ifi_collisions - ip->ift_co)); 1005 1.26 kml } 1006 1.1 cgd if (dflag) 1007 1.89 christos printf(" %5" PRIu64, 1008 1.101 msaitoh ifnet.if_snd.ifq_drops - ip->ift_oq); 1009 1.1 cgd } 1010 1.96 thorpej ip->ift_ip = ifd.ifi_ipackets; 1011 1.96 thorpej ip->ift_ib = ifd.ifi_ibytes; 1012 1.96 thorpej ip->ift_ie = ifd.ifi_ierrors; 1013 1.96 thorpej ip->ift_op = ifd.ifi_opackets; 1014 1.96 thorpej ip->ift_ob = ifd.ifi_obytes; 1015 1.96 thorpej ip->ift_oe = ifd.ifi_oerrors; 1016 1.96 thorpej ip->ift_co = ifd.ifi_collisions; 1017 1.101 msaitoh ip->ift_oq = ifnet.if_snd.ifq_drops; 1018 1.1 cgd sum->ift_ip += ip->ift_ip; 1019 1.26 kml sum->ift_ib += ip->ift_ib; 1020 1.1 cgd sum->ift_ie += ip->ift_ie; 1021 1.1 cgd sum->ift_op += ip->ift_op; 1022 1.26 kml sum->ift_ob += ip->ift_ob; 1023 1.1 cgd sum->ift_oe += ip->ift_oe; 1024 1.1 cgd sum->ift_co += ip->ift_co; 1025 1.101 msaitoh sum->ift_oq += ip->ift_oq; 1026 1.10 mycroft off = (u_long)ifnet.if_list.tqe_next; 1027 1.1 cgd } 1028 1.1 cgd if (lastif - iftot > 0) { 1029 1.26 kml if (bflag) { 1030 1.68 pooka char humbuf[HUMBUF_SIZE]; 1031 1.68 pooka 1032 1.68 pooka if (hflag && humanize_number(humbuf, 1033 1.68 pooka sizeof(humbuf), sum->ift_ib - total->ift_ib, "", 1034 1.68 pooka HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0) 1035 1.69 enami printf(" %10s %8.8s ", humbuf, " "); 1036 1.68 pooka else 1037 1.98 msaitoh printf(" %10llu %8.8s ", 1038 1.68 pooka (unsigned long long) 1039 1.68 pooka (sum->ift_ib - total->ift_ib), " "); 1040 1.68 pooka 1041 1.68 pooka if (hflag && humanize_number(humbuf, 1042 1.68 pooka sizeof(humbuf), sum->ift_ob - total->ift_ob, "", 1043 1.68 pooka HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0) 1044 1.68 pooka printf("%10s %5.5s", humbuf, " "); 1045 1.68 pooka else 1046 1.98 msaitoh printf("%10llu %5.5s", 1047 1.68 pooka (unsigned long long) 1048 1.68 pooka (sum->ift_ob - total->ift_ob), " "); 1049 1.26 kml } else { 1050 1.33 bouyer printf(" %8llu %5llu %8llu %5llu %5llu", 1051 1.33 bouyer (unsigned long long) 1052 1.33 bouyer (sum->ift_ip - total->ift_ip), 1053 1.33 bouyer (unsigned long long) 1054 1.33 bouyer (sum->ift_ie - total->ift_ie), 1055 1.33 bouyer (unsigned long long) 1056 1.33 bouyer (sum->ift_op - total->ift_op), 1057 1.33 bouyer (unsigned long long) 1058 1.33 bouyer (sum->ift_oe - total->ift_oe), 1059 1.33 bouyer (unsigned long long) 1060 1.33 bouyer (sum->ift_co - total->ift_co)); 1061 1.26 kml } 1062 1.1 cgd if (dflag) 1063 1.33 bouyer printf(" %5llu", 1064 1.101 msaitoh (unsigned long long)(sum->ift_oq - total->ift_oq)); 1065 1.1 cgd } 1066 1.1 cgd *total = *sum; 1067 1.1 cgd putchar('\n'); 1068 1.1 cgd fflush(stdout); 1069 1.1 cgd line++; 1070 1.98 msaitoh if (signalled == 0) 1071 1.90 dholland sigsuspend(&emptyset); 1072 1.98 msaitoh 1073 1.90 dholland signalled = 0; 1074 1.82 mrg if (line == redraw_lines) 1075 1.1 cgd goto banner; 1076 1.1 cgd goto loop; 1077 1.1 cgd /*NOTREACHED*/ 1078 1.1 cgd } 1079 1.1 cgd 1080 1.1 cgd /* 1081 1.64 elad * Print a running summary of interface statistics. 1082 1.64 elad * Repeat display every interval seconds, showing statistics 1083 1.64 elad * collected over that interval. Assumes that interval is non-zero. 1084 1.64 elad * First line printed at top of screen is always cumulative. 1085 1.64 elad */ 1086 1.64 elad static void 1087 1.74 matt sidewaysintpr(unsigned int interval, u_long off) 1088 1.64 elad { 1089 1.64 elad 1090 1.98 msaitoh if (use_sysctl) 1091 1.64 elad sidewaysintpr_sysctl(interval); 1092 1.98 msaitoh else 1093 1.64 elad sidewaysintpr_kvm(interval, off); 1094 1.64 elad } 1095 1.64 elad 1096 1.64 elad /* 1097 1.1 cgd * Called if an interval expires before sidewaysintpr has completed a loop. 1098 1.1 cgd * Sets a flag to not wait for the alarm. 1099 1.1 cgd */ 1100 1.8 mycroft static void 1101 1.74 matt catchalarm(int signo) 1102 1.1 cgd { 1103 1.28 mrg 1104 1.64 elad signalled = true; 1105 1.64 elad } 1106 1.64 elad 1107 1.64 elad static void 1108 1.64 elad get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 1109 1.98 msaitoh { 1110 1.64 elad int i; 1111 1.64 elad 1112 1.64 elad for (i = 0; i < RTAX_MAX; i++) { 1113 1.64 elad if (addrs & (1 << i)) { 1114 1.64 elad rti_info[i] = sa; 1115 1.71 martin sa = (struct sockaddr *)((char *)(sa) + 1116 1.71 martin RT_ROUNDUP(sa->sa_len)); 1117 1.98 msaitoh } else 1118 1.64 elad rti_info[i] = NULL; 1119 1.64 elad } 1120 1.64 elad } 1121 1.64 elad 1122 1.64 elad static void 1123 1.64 elad fetchifs(void) 1124 1.64 elad { 1125 1.64 elad struct if_msghdr *ifm; 1126 1.64 elad int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; 1127 1.64 elad struct rt_msghdr *rtm; 1128 1.64 elad struct if_data *ifd = NULL; 1129 1.64 elad struct sockaddr *sa, *rti_info[RTAX_MAX]; 1130 1.64 elad struct sockaddr_dl *sdl; 1131 1.93 mrg static char *buf = NULL; 1132 1.93 mrg static size_t olen; 1133 1.101 msaitoh struct if_data_ext dext; 1134 1.93 mrg char *next, *lim; 1135 1.64 elad char name[IFNAMSIZ]; 1136 1.64 elad size_t len; 1137 1.64 elad 1138 1.70 pooka if (prog_sysctl(mib, 6, NULL, &len, NULL, 0) == -1) 1139 1.64 elad err(1, "sysctl"); 1140 1.93 mrg if (len > olen) { 1141 1.93 mrg free(buf); 1142 1.93 mrg if ((buf = malloc(len)) == NULL) 1143 1.93 mrg err(1, NULL); 1144 1.93 mrg olen = len; 1145 1.93 mrg } 1146 1.70 pooka if (prog_sysctl(mib, 6, buf, &len, NULL, 0) == -1) 1147 1.64 elad err(1, "sysctl"); 1148 1.64 elad 1149 1.101 msaitoh memset(&dext, 0, sizeof(dext)); 1150 1.64 elad lim = buf + len; 1151 1.64 elad for (next = buf; next < lim; next += rtm->rtm_msglen) { 1152 1.64 elad rtm = (struct rt_msghdr *)next; 1153 1.64 elad if (rtm->rtm_version != RTM_VERSION) 1154 1.64 elad continue; 1155 1.64 elad switch (rtm->rtm_type) { 1156 1.64 elad case RTM_IFINFO: 1157 1.64 elad ifm = (struct if_msghdr *)next; 1158 1.64 elad ifd = &ifm->ifm_data; 1159 1.64 elad 1160 1.64 elad sa = (struct sockaddr *)(ifm + 1); 1161 1.64 elad get_rtaddrs(ifm->ifm_addrs, sa, rti_info); 1162 1.64 elad 1163 1.64 elad sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP]; 1164 1.64 elad if (sdl == NULL || sdl->sdl_family != AF_LINK) 1165 1.64 elad continue; 1166 1.64 elad bzero(name, sizeof(name)); 1167 1.64 elad if (sdl->sdl_nlen >= IFNAMSIZ) 1168 1.64 elad memcpy(name, sdl->sdl_data, IFNAMSIZ - 1); 1169 1.98 msaitoh else if (sdl->sdl_nlen > 0) 1170 1.64 elad memcpy(name, sdl->sdl_data, sdl->sdl_nlen); 1171 1.64 elad 1172 1.101 msaitoh if_data_ext_get(name, &dext); 1173 1.101 msaitoh 1174 1.109 mrg if ((interface != NULL && !strcmp(name, interface)) || 1175 1.109 mrg (interface == NULL && 1176 1.109 mrg ((ip_cur.ift_ib + ip_cur.ift_ob) == 0 || 1177 1.109 mrg (ip_cur.ift_ib + ip_cur.ift_ob < 1178 1.109 mrg ifd->ifi_ibytes + ifd->ifi_obytes)))) { 1179 1.64 elad strlcpy(ip_cur.ift_name, name, 1180 1.64 elad sizeof(ip_cur.ift_name)); 1181 1.64 elad ip_cur.ift_ip = ifd->ifi_ipackets; 1182 1.64 elad ip_cur.ift_ib = ifd->ifi_ibytes; 1183 1.64 elad ip_cur.ift_ie = ifd->ifi_ierrors; 1184 1.64 elad ip_cur.ift_op = ifd->ifi_opackets; 1185 1.64 elad ip_cur.ift_ob = ifd->ifi_obytes; 1186 1.64 elad ip_cur.ift_oe = ifd->ifi_oerrors; 1187 1.64 elad ip_cur.ift_co = ifd->ifi_collisions; 1188 1.101 msaitoh ip_cur.ift_iq = ifd->ifi_iqdrops; 1189 1.103 msaitoh ip_cur.ift_oq = dext.ifi_oqdrops; 1190 1.64 elad } 1191 1.64 elad 1192 1.64 elad sum_cur.ift_ip += ifd->ifi_ipackets; 1193 1.64 elad sum_cur.ift_ib += ifd->ifi_ibytes; 1194 1.64 elad sum_cur.ift_ie += ifd->ifi_ierrors; 1195 1.64 elad sum_cur.ift_op += ifd->ifi_opackets; 1196 1.64 elad sum_cur.ift_ob += ifd->ifi_obytes; 1197 1.64 elad sum_cur.ift_oe += ifd->ifi_oerrors; 1198 1.64 elad sum_cur.ift_co += ifd->ifi_collisions; 1199 1.101 msaitoh sum_cur.ift_iq += ifd->ifi_iqdrops; 1200 1.101 msaitoh sum_cur.ift_oq += dext.ifi_oqdrops; 1201 1.64 elad break; 1202 1.64 elad } 1203 1.64 elad } 1204 1.109 mrg 1205 1.109 mrg /* 1206 1.109 mrg * If we picked an interface, be sure to keep using it for the rest 1207 1.109 mrg * of this instance. 1208 1.109 mrg */ 1209 1.109 mrg if (interface == NULL) 1210 1.109 mrg interface = ip_cur.ift_name; 1211 1.1 cgd } 1212