121986Sdist /* 221986Sdist * Copyright (c) 1983 Regents of the University of California. 321986Sdist * All rights reserved. The Berkeley software License Agreement 421986Sdist * specifies the terms and conditions for redistribution. 521986Sdist */ 621986Sdist 77905Ssam #ifndef lint 8*29746Skupfer static char sccsid[] = "@(#)if.c 5.4 (Berkeley) 08/11/86"; 921986Sdist #endif not lint 107905Ssam 117905Ssam #include <sys/types.h> 127905Ssam #include <sys/socket.h> 139203Ssam 147905Ssam #include <net/if.h> 159203Ssam #include <netinet/in.h> 1621906Skarels #include <netinet/in_var.h> 1723499Ssklower #include <netns/ns.h> 189203Ssam 198331Ssam #include <stdio.h> 20*29746Skupfer #include <signal.h> 217905Ssam 22*29746Skupfer #define YES 1 23*29746Skupfer #define NO 0 24*29746Skupfer 257905Ssam extern int kmem; 267905Ssam extern int tflag; 277905Ssam extern int nflag; 2817402Sedward extern char *interface; 2917402Sedward extern int unit; 30*29746Skupfer extern char *routename(), *netname(), *ns_phost(); 317905Ssam 327905Ssam /* 337905Ssam * Print a description of the network interfaces. 347905Ssam */ 357905Ssam intpr(interval, ifnetaddr) 367905Ssam int interval; 377905Ssam off_t ifnetaddr; 387905Ssam { 397905Ssam struct ifnet ifnet; 4021906Skarels union { 4121906Skarels struct ifaddr ifa; 4221906Skarels struct in_ifaddr in; 4321906Skarels } ifaddr; 4421906Skarels off_t ifaddraddr; 457905Ssam char name[16]; 467905Ssam 477905Ssam if (ifnetaddr == 0) { 487905Ssam printf("ifnet: symbol not defined\n"); 497905Ssam return; 507905Ssam } 517905Ssam if (interval) { 52*29746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 537905Ssam return; 547905Ssam } 557905Ssam klseek(kmem, ifnetaddr, 0); 56*29746Skupfer read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr); 578372Ssam printf("%-5.5s %-5.5s %-10.10s %-12.12s %-7.7s %-5.5s %-7.7s %-5.5s", 587905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 597905Ssam "Opkts", "Oerrs"); 607905Ssam printf(" %-6.6s", "Collis"); 617905Ssam if (tflag) 627905Ssam printf(" %-6.6s", "Timer"); 637905Ssam putchar('\n'); 6421906Skarels ifaddraddr = 0; 6521906Skarels while (ifnetaddr || ifaddraddr) { 667905Ssam struct sockaddr_in *sin; 677905Ssam register char *cp; 6821906Skarels int n; 697905Ssam char *index(); 70*29746Skupfer struct in_addr inet_makeaddr(); 717905Ssam 7221906Skarels if (ifaddraddr == 0) { 7321906Skarels klseek(kmem, ifnetaddr, 0); 74*29746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 7521906Skarels klseek(kmem, (off_t)ifnet.if_name, 0); 7621906Skarels read(kmem, name, 16); 7721906Skarels name[15] = '\0'; 7821906Skarels ifnetaddr = (off_t) ifnet.if_next; 7921906Skarels if (interface != 0 && 8021906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 8121906Skarels continue; 8221906Skarels cp = index(name, '\0'); 8321906Skarels *cp++ = ifnet.if_unit + '0'; 8421906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 8521906Skarels *cp++ = '*'; 8621906Skarels *cp = '\0'; 8721906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 8821906Skarels } 897905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 9021906Skarels if (ifaddraddr == 0) { 9121906Skarels printf("%-10.10s ", "none"); 9221906Skarels printf("%-12.12s ", "none"); 9321906Skarels } else { 9421906Skarels klseek(kmem, ifaddraddr, 0); 95*29746Skupfer read(kmem, (char *)&ifaddr, sizeof ifaddr); 9621906Skarels ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 9721906Skarels switch (ifaddr.ifa.ifa_addr.sa_family) { 9821906Skarels case AF_UNSPEC: 9921906Skarels printf("%-10.10s ", "none"); 10021906Skarels printf("%-12.12s ", "none"); 10121906Skarels break; 10221906Skarels case AF_INET: 10321906Skarels sin = (struct sockaddr_in *)&ifaddr.in.ia_addr; 10421906Skarels #ifdef notdef 10521906Skarels /* can't use inet_makeaddr because kernel 10621906Skarels * keeps nets unshifted. 10721906Skarels */ 10821906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 10921906Skarels INADDR_ANY); 11021906Skarels printf("%-10.10s ", netname(in)); 11121906Skarels #else 11221906Skarels printf("%-10.10s ", 11321906Skarels netname(htonl(ifaddr.in.ia_subnet), 11421906Skarels ifaddr.in.ia_subnetmask)); 11521906Skarels #endif 11621906Skarels printf("%-12.12s ", routename(sin->sin_addr)); 11721906Skarels break; 11823499Ssklower case AF_NS: 11923499Ssklower { 12023499Ssklower struct sockaddr_ns *sns = 12123499Ssklower (struct sockaddr_ns *)&ifaddr.in.ia_addr; 122*29746Skupfer u_long net; 12327265Skarels char host[8]; 124*29746Skupfer char *ns_phost(); 125*29746Skupfer 12627265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 12727265Skarels sprintf(host, "%lxH", ntohl(net)); 12827265Skarels upHex(host); 12927265Skarels printf("ns:%-8s ", host); 130*29746Skupfer printf("%-12s ", ns_phost(sns)); 13123499Ssklower } 13223499Ssklower break; 13321906Skarels default: 13421906Skarels printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family); 13521906Skarels for (cp = (char *)&ifaddr.ifa.ifa_addr + 13621906Skarels sizeof(struct sockaddr) - 1; 13721906Skarels cp >= ifaddr.ifa.ifa_addr.sa_data; --cp) 13821906Skarels if (*cp != 0) 13921906Skarels break; 14021906Skarels n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1; 14121906Skarels cp = (char *)ifaddr.ifa.ifa_addr.sa_data; 14221906Skarels if (n <= 6) 14321906Skarels while (--n) 14421906Skarels printf("%02d.", *cp++ & 0xff); 14521906Skarels else 14621906Skarels while (--n) 14721906Skarels printf("%02d", *cp++ & 0xff); 14821906Skarels printf("%02d ", *cp & 0xff); 14921906Skarels break; 15021906Skarels } 15121906Skarels } 15221906Skarels printf("%-7d %-5d %-7d %-5d %-6d", 1537905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1547905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1557905Ssam ifnet.if_collisions); 1567905Ssam if (tflag) 1577905Ssam printf(" %-6d", ifnet.if_timer); 1587905Ssam putchar('\n'); 1597905Ssam } 1607905Ssam } 1617905Ssam 1628331Ssam #define MAXIF 10 1638331Ssam struct iftot { 1648331Ssam char ift_name[16]; /* interface name */ 1658331Ssam int ift_ip; /* input packets */ 1668331Ssam int ift_ie; /* input errors */ 1678331Ssam int ift_op; /* output packets */ 1688331Ssam int ift_oe; /* output errors */ 1698331Ssam int ift_co; /* collisions */ 1708331Ssam } iftot[MAXIF]; 1718331Ssam 172*29746Skupfer u_char signalled; /* set if alarm goes off "early" */ 173*29746Skupfer 1748331Ssam /* 1758331Ssam * Print a running summary of interface statistics. 176*29746Skupfer * Repeat display every interval seconds, showing statistics 177*29746Skupfer * collected over that interval. Assumes that interval is non-zero. 178*29746Skupfer * First line printed at top of screen is always cumulative. 1798331Ssam */ 1807905Ssam sidewaysintpr(interval, off) 181*29746Skupfer unsigned interval; 1827905Ssam off_t off; 1837905Ssam { 1847905Ssam struct ifnet ifnet; 1858331Ssam off_t firstifnet; 1868331Ssam register struct iftot *ip, *total; 1878331Ssam register int line; 1888331Ssam struct iftot *lastif, *sum, *interesting; 189*29746Skupfer int oldmask; 190*29746Skupfer int catchalarm(); 1917905Ssam 1927905Ssam klseek(kmem, off, 0); 193*29746Skupfer read(kmem, (char *)&firstifnet, sizeof (off_t)); 1948331Ssam lastif = iftot; 1958331Ssam sum = iftot + MAXIF - 1; 1968331Ssam total = sum - 1; 19717402Sedward interesting = iftot; 1988331Ssam for (off = firstifnet, ip = iftot; off;) { 1998331Ssam char *cp; 2007905Ssam 2017905Ssam klseek(kmem, off, 0); 202*29746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 203*29746Skupfer klseek(kmem, (off_t)ifnet.if_name, 0); 2048331Ssam ip->ift_name[0] = '('; 2058331Ssam read(kmem, ip->ift_name + 1, 15); 20617402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 20717402Sedward unit == ifnet.if_unit) 20817402Sedward interesting = ip; 2098331Ssam ip->ift_name[15] = '\0'; 2108331Ssam cp = index(ip->ift_name, '\0'); 2118331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2128331Ssam ip++; 2138331Ssam if (ip >= iftot + MAXIF - 2) 2148331Ssam break; 2157905Ssam off = (off_t) ifnet.if_next; 2167905Ssam } 2178331Ssam lastif = ip; 218*29746Skupfer 219*29746Skupfer (void)signal(SIGALRM, catchalarm); 220*29746Skupfer signalled = NO; 221*29746Skupfer (void)alarm(interval); 2228331Ssam banner: 2238331Ssam printf(" input %-6.6s output ", interesting->ift_name); 2248331Ssam if (lastif - iftot > 0) 22517402Sedward printf(" input (Total) output "); 2268331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2278331Ssam ip->ift_ip = 0; 2288331Ssam ip->ift_ie = 0; 2298331Ssam ip->ift_op = 0; 2308331Ssam ip->ift_oe = 0; 2318331Ssam ip->ift_co = 0; 2328331Ssam } 2338331Ssam putchar('\n'); 2348331Ssam printf("%-7.7s %-5.5s %-7.7s %-5.5s %-5.5s ", 2358331Ssam "packets", "errs", "packets", "errs", "colls"); 2368331Ssam if (lastif - iftot > 0) 2378331Ssam printf("%-7.7s %-5.5s %-7.7s %-5.5s %-5.5s ", 2388331Ssam "packets", "errs", "packets", "errs", "colls"); 2398331Ssam putchar('\n'); 2408331Ssam fflush(stdout); 2418331Ssam line = 0; 2428331Ssam loop: 2438331Ssam sum->ift_ip = 0; 2448331Ssam sum->ift_ie = 0; 2458331Ssam sum->ift_op = 0; 2468331Ssam sum->ift_oe = 0; 2478331Ssam sum->ift_co = 0; 2488331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 2498331Ssam klseek(kmem, off, 0); 250*29746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 2518331Ssam if (ip == interesting) 2528331Ssam printf("%-7d %-5d %-7d %-5d %-5d ", 2538331Ssam ifnet.if_ipackets - ip->ift_ip, 2548331Ssam ifnet.if_ierrors - ip->ift_ie, 2558331Ssam ifnet.if_opackets - ip->ift_op, 2568331Ssam ifnet.if_oerrors - ip->ift_oe, 2578331Ssam ifnet.if_collisions - ip->ift_co); 2588331Ssam ip->ift_ip = ifnet.if_ipackets; 2598331Ssam ip->ift_ie = ifnet.if_ierrors; 2608331Ssam ip->ift_op = ifnet.if_opackets; 2618331Ssam ip->ift_oe = ifnet.if_oerrors; 2628331Ssam ip->ift_co = ifnet.if_collisions; 2638331Ssam sum->ift_ip += ip->ift_ip; 2648331Ssam sum->ift_ie += ip->ift_ie; 2658331Ssam sum->ift_op += ip->ift_op; 2668331Ssam sum->ift_oe += ip->ift_oe; 2678331Ssam sum->ift_co += ip->ift_co; 2688331Ssam off = (off_t) ifnet.if_next; 2698331Ssam } 2708331Ssam if (lastif - iftot > 0) 2718331Ssam printf("%-7d %-5d %-7d %-5d %-5d\n", 2728331Ssam sum->ift_ip - total->ift_ip, 2738331Ssam sum->ift_ie - total->ift_ie, 2748331Ssam sum->ift_op - total->ift_op, 2758331Ssam sum->ift_oe - total->ift_oe, 2768331Ssam sum->ift_co - total->ift_co); 2778331Ssam *total = *sum; 2788331Ssam fflush(stdout); 2798331Ssam line++; 280*29746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 281*29746Skupfer if (! signalled) { 282*29746Skupfer sigpause(0); 283*29746Skupfer } 284*29746Skupfer sigsetmask(oldmask); 285*29746Skupfer signalled = NO; 286*29746Skupfer (void)alarm(interval); 2878331Ssam if (line == 21) 2888331Ssam goto banner; 2898331Ssam goto loop; 2908331Ssam /*NOTREACHED*/ 2917905Ssam } 292*29746Skupfer 293*29746Skupfer /* 294*29746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 295*29746Skupfer * Sets a flag to not wait for the alarm. 296*29746Skupfer */ 297*29746Skupfer catchalarm() 298*29746Skupfer { 299*29746Skupfer signalled = YES; 300*29746Skupfer } 301