Annotation of src/usr.bin/netstat/if.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: if.c,v 1.13 1995/10/03 21:42:36 thorpej Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1983, 1988, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by the University of
! 18: * California, Berkeley and its contributors.
! 19: * 4. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: */
! 35:
! 36: #ifndef lint
! 37: #if 0
! 38: static char sccsid[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94";
! 39: #else
! 40: static char *rcsid = "$NetBSD: if.c,v 1.13 1995/10/03 21:42:36 thorpej Exp $";
! 41: #endif
! 42: #endif /* not lint */
! 43:
! 44: #include <sys/types.h>
! 45: #include <sys/protosw.h>
! 46: #include <sys/socket.h>
! 47:
! 48: #include <net/if.h>
! 49: #include <net/if_dl.h>
! 50: #include <netinet/in.h>
! 51: #include <netinet/in_var.h>
! 52: #include <netns/ns.h>
! 53: #include <netns/ns_if.h>
! 54: #include <netiso/iso.h>
! 55: #include <netiso/iso_var.h>
! 56: #include <arpa/inet.h>
! 57:
! 58: #include <signal.h>
! 59: #include <stdio.h>
! 60: #include <string.h>
! 61: #include <unistd.h>
! 62:
! 63: #include "netstat.h"
! 64:
! 65: #define YES 1
! 66: #define NO 0
! 67:
! 68: static void sidewaysintpr __P((u_int, u_long));
! 69: static void catchalarm __P((int));
! 70:
! 71: /*
! 72: * Print a description of the network interfaces.
! 73: */
! 74: void
! 75: intpr(interval, ifnetaddr)
! 76: int interval;
! 77: u_long ifnetaddr;
! 78: {
! 79: struct ifnet ifnet;
! 80: union {
! 81: struct ifaddr ifa;
! 82: struct in_ifaddr in;
! 83: struct ns_ifaddr ns;
! 84: struct iso_ifaddr iso;
! 85: } ifaddr;
! 86: u_long ifaddraddr;
! 87: struct sockaddr *sa;
! 88: char name[16];
! 89:
! 90: if (ifnetaddr == 0) {
! 91: printf("ifnet: symbol not defined\n");
! 92: return;
! 93: }
! 94: if (interval) {
! 95: sidewaysintpr((unsigned)interval, ifnetaddr);
! 96: return;
! 97: }
! 98: if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr))
! 99: return;
! 100: printf("%-5.5s %-5.5s %-11.11s %-15.15s %10.10s %5.5s %8.8s %5.5s",
! 101: "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
! 102: "Opkts", "Oerrs");
! 103: printf(" %5s", "Coll");
! 104: if (tflag)
! 105: printf(" %s", "Time");
! 106: if (dflag)
! 107: printf(" %s", "Drop");
! 108: putchar('\n');
! 109: ifaddraddr = 0;
! 110: while (ifnetaddr || ifaddraddr) {
! 111: struct sockaddr_in *sin;
! 112: register char *cp;
! 113: int n, m;
! 114:
! 115: if (ifaddraddr == 0) {
! 116: if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) ||
! 117: kread((u_long)ifnet.if_name, name, 16))
! 118: return;
! 119: name[15] = '\0';
! 120: ifnetaddr = (u_long)ifnet.if_list.tqe_next;
! 121: if (interface != 0 && (strcmp(name, interface) != 0 ||
! 122: unit != ifnet.if_unit))
! 123: continue;
! 124: cp = index(name, '\0');
! 125: cp += sprintf(cp, "%d", ifnet.if_unit);
! 126: if ((ifnet.if_flags & IFF_UP) == 0)
! 127: *cp++ = '*';
! 128: *cp = '\0';
! 129: ifaddraddr = (u_long)ifnet.if_addrlist.tqh_first;
! 130: }
! 131: printf("%-5.5s %-5d ", name, ifnet.if_mtu);
! 132: if (ifaddraddr == 0) {
! 133: printf("%-11.11s ", "none");
! 134: printf("%-15.15s ", "none");
! 135: } else {
! 136: if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) {
! 137: ifaddraddr = 0;
! 138: continue;
! 139: }
! 140: #define CP(x) ((char *)(x))
! 141: cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
! 142: CP(&ifaddr); sa = (struct sockaddr *)cp;
! 143: switch (sa->sa_family) {
! 144: case AF_UNSPEC:
! 145: printf("%-11.11s ", "none");
! 146: printf("%-17.17s ", "none");
! 147: break;
! 148: case AF_INET:
! 149: sin = (struct sockaddr_in *)sa;
! 150: #ifdef notdef
! 151: /* can't use inet_makeaddr because kernel
! 152: * keeps nets unshifted.
! 153: */
! 154: in = inet_makeaddr(ifaddr.in.ia_subnet,
! 155: INADDR_ANY);
! 156: printf("%-11.11s ", netname(in.s_addr,
! 157: ifaddr.in.ia_subnetmask));
! 158: #else
! 159: printf("%-11.11s ",
! 160: netname(ifaddr.in.ia_subnet,
! 161: ifaddr.in.ia_subnetmask));
! 162: #endif
! 163: printf("%-17.17s ",
! 164: routename(sin->sin_addr.s_addr));
! 165:
! 166: if (aflag) {
! 167: u_long multiaddr;
! 168: struct in_multi inm;
! 169:
! 170: multiaddr = (u_long)ifaddr.in.ia_multiaddrs.lh_first;
! 171: while (multiaddr != 0) {
! 172: kread(multiaddr, (char *)&inm,
! 173: sizeof inm);
! 174: printf("\n%23s %-15.15s ", "",
! 175: routename(inm.inm_addr.s_addr));
! 176: multiaddr = (u_long)inm.inm_list.le_next;
! 177: }
! 178: }
! 179: break;
! 180: case AF_NS:
! 181: {
! 182: struct sockaddr_ns *sns =
! 183: (struct sockaddr_ns *)sa;
! 184: u_long net;
! 185: char netnum[8];
! 186:
! 187: *(union ns_net *) &net = sns->sns_addr.x_net;
! 188: sprintf(netnum, "%lxH", ntohl(net));
! 189: upHex(netnum);
! 190: printf("ns:%-8s ", netnum);
! 191: printf("%-17s ",
! 192: ns_phost((struct sockaddr *)sns));
! 193: }
! 194: break;
! 195: case AF_LINK:
! 196: {
! 197: struct sockaddr_dl *sdl =
! 198: (struct sockaddr_dl *)sa;
! 199: cp = (char *)LLADDR(sdl);
! 200: n = sdl->sdl_alen;
! 201: }
! 202: m = printf("%-11.11s ", "<Link>");
! 203: goto hexprint;
! 204: default:
! 205: m = printf("(%d)", sa->sa_family);
! 206: for (cp = sa->sa_len + (char *)sa;
! 207: --cp > sa->sa_data && (*cp == 0);) {}
! 208: n = cp - sa->sa_data + 1;
! 209: cp = sa->sa_data;
! 210: hexprint:
! 211: while (--n >= 0)
! 212: m += printf("%x%c", *cp++ & 0xff,
! 213: n > 0 ? '.' : ' ');
! 214: m = 30 - m;
! 215: while (m-- > 0)
! 216: putchar(' ');
! 217: break;
! 218: }
! 219: ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next;
! 220: }
! 221: printf("%8d %5d %8d %5d %5d",
! 222: ifnet.if_ipackets, ifnet.if_ierrors,
! 223: ifnet.if_opackets, ifnet.if_oerrors,
! 224: ifnet.if_collisions);
! 225: if (tflag)
! 226: printf(" %3d", ifnet.if_timer);
! 227: if (dflag)
! 228: printf(" %3d", ifnet.if_snd.ifq_drops);
! 229: putchar('\n');
! 230: }
! 231: }
! 232:
! 233: #define MAXIF 10
! 234: struct iftot {
! 235: char ift_name[16]; /* interface name */
! 236: int ift_ip; /* input packets */
! 237: int ift_ie; /* input errors */
! 238: int ift_op; /* output packets */
! 239: int ift_oe; /* output errors */
! 240: int ift_co; /* collisions */
! 241: int ift_dr; /* drops */
! 242: } iftot[MAXIF];
! 243:
! 244: u_char signalled; /* set if alarm goes off "early" */
! 245:
! 246: /*
! 247: * Print a running summary of interface statistics.
! 248: * Repeat display every interval seconds, showing statistics
! 249: * collected over that interval. Assumes that interval is non-zero.
! 250: * First line printed at top of screen is always cumulative.
! 251: */
! 252: static void
! 253: sidewaysintpr(interval, off)
! 254: unsigned interval;
! 255: u_long off;
! 256: {
! 257: struct ifnet ifnet;
! 258: u_long firstifnet;
! 259: register struct iftot *ip, *total;
! 260: register int line;
! 261: struct iftot *lastif, *sum, *interesting;
! 262: int oldmask;
! 263:
! 264: if (kread(off, (char *)&firstifnet, sizeof (u_long)))
! 265: return;
! 266: lastif = iftot;
! 267: sum = iftot + MAXIF - 1;
! 268: total = sum - 1;
! 269: interesting = iftot;
! 270: for (off = firstifnet, ip = iftot; off;) {
! 271: char *cp;
! 272:
! 273: if (kread(off, (char *)&ifnet, sizeof ifnet))
! 274: break;
! 275: ip->ift_name[0] = '(';
! 276: if (kread((u_long)ifnet.if_name, ip->ift_name + 1, 15))
! 277: break;
! 278: if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
! 279: unit == ifnet.if_unit)
! 280: interesting = ip;
! 281: ip->ift_name[15] = '\0';
! 282: cp = index(ip->ift_name, '\0');
! 283: sprintf(cp, "%d)", ifnet.if_unit);
! 284: ip++;
! 285: if (ip >= iftot + MAXIF - 2)
! 286: break;
! 287: off = (u_long)ifnet.if_list.tqe_next;
! 288: }
! 289: lastif = ip;
! 290:
! 291: (void)signal(SIGALRM, catchalarm);
! 292: signalled = NO;
! 293: (void)alarm(interval);
! 294: banner:
! 295: printf(" input %-6.6s output ", interesting->ift_name);
! 296: if (lastif - iftot > 0) {
! 297: if (dflag)
! 298: printf(" ");
! 299: printf(" input (Total) output");
! 300: }
! 301: for (ip = iftot; ip < iftot + MAXIF; ip++) {
! 302: ip->ift_ip = 0;
! 303: ip->ift_ie = 0;
! 304: ip->ift_op = 0;
! 305: ip->ift_oe = 0;
! 306: ip->ift_co = 0;
! 307: ip->ift_dr = 0;
! 308: }
! 309: putchar('\n');
! 310: printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
! 311: "packets", "errs", "packets", "errs", "colls");
! 312: if (dflag)
! 313: printf("%5.5s ", "drops");
! 314: if (lastif - iftot > 0)
! 315: printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
! 316: "packets", "errs", "packets", "errs", "colls");
! 317: if (dflag)
! 318: printf(" %5.5s", "drops");
! 319: putchar('\n');
! 320: fflush(stdout);
! 321: line = 0;
! 322: loop:
! 323: sum->ift_ip = 0;
! 324: sum->ift_ie = 0;
! 325: sum->ift_op = 0;
! 326: sum->ift_oe = 0;
! 327: sum->ift_co = 0;
! 328: sum->ift_dr = 0;
! 329: for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
! 330: if (kread(off, (char *)&ifnet, sizeof ifnet)) {
! 331: off = 0;
! 332: continue;
! 333: }
! 334: if (ip == interesting) {
! 335: printf("%8d %5d %8d %5d %5d",
! 336: ifnet.if_ipackets - ip->ift_ip,
! 337: ifnet.if_ierrors - ip->ift_ie,
! 338: ifnet.if_opackets - ip->ift_op,
! 339: ifnet.if_oerrors - ip->ift_oe,
! 340: ifnet.if_collisions - ip->ift_co);
! 341: if (dflag)
! 342: printf(" %5d",
! 343: ifnet.if_snd.ifq_drops - ip->ift_dr);
! 344: }
! 345: ip->ift_ip = ifnet.if_ipackets;
! 346: ip->ift_ie = ifnet.if_ierrors;
! 347: ip->ift_op = ifnet.if_opackets;
! 348: ip->ift_oe = ifnet.if_oerrors;
! 349: ip->ift_co = ifnet.if_collisions;
! 350: ip->ift_dr = ifnet.if_snd.ifq_drops;
! 351: sum->ift_ip += ip->ift_ip;
! 352: sum->ift_ie += ip->ift_ie;
! 353: sum->ift_op += ip->ift_op;
! 354: sum->ift_oe += ip->ift_oe;
! 355: sum->ift_co += ip->ift_co;
! 356: sum->ift_dr += ip->ift_dr;
! 357: off = (u_long)ifnet.if_list.tqe_next;
! 358: }
! 359: if (lastif - iftot > 0) {
! 360: printf(" %8d %5d %8d %5d %5d",
! 361: sum->ift_ip - total->ift_ip,
! 362: sum->ift_ie - total->ift_ie,
! 363: sum->ift_op - total->ift_op,
! 364: sum->ift_oe - total->ift_oe,
! 365: sum->ift_co - total->ift_co);
! 366: if (dflag)
! 367: printf(" %5d", sum->ift_dr - total->ift_dr);
! 368: }
! 369: *total = *sum;
! 370: putchar('\n');
! 371: fflush(stdout);
! 372: line++;
! 373: oldmask = sigblock(sigmask(SIGALRM));
! 374: if (! signalled) {
! 375: sigpause(0);
! 376: }
! 377: sigsetmask(oldmask);
! 378: signalled = NO;
! 379: (void)alarm(interval);
! 380: if (line == 21)
! 381: goto banner;
! 382: goto loop;
! 383: /*NOTREACHED*/
! 384: }
! 385:
! 386: /*
! 387: * Called if an interval expires before sidewaysintpr has completed a loop.
! 388: * Sets a flag to not wait for the alarm.
! 389: */
! 390: static void
! 391: catchalarm(signo)
! 392: int signo;
! 393: {
! 394: signalled = YES;
! 395: }