121986Sdist /* 2*34902Sbostic * Copyright (c) 1983, 1988 Regents of the University of California. 333451Skarels * All rights reserved. 433451Skarels * 533451Skarels * Redistribution and use in source and binary forms are permitted 6*34902Sbostic * provided that the above copyright notice and this paragraph are 7*34902Sbostic * duplicated in all such forms and that any documentation, 8*34902Sbostic * advertising materials, and other materials related to such 9*34902Sbostic * distribution and use acknowledge that the software was developed 10*34902Sbostic * by the University of California, Berkeley. The name of the 11*34902Sbostic * University may not be used to endorse or promote products derived 12*34902Sbostic * from this software without specific prior written permission. 13*34902Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34902Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34902Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621986Sdist */ 1721986Sdist 187905Ssam #ifndef lint 19*34902Sbostic static char sccsid[] = "@(#)if.c 5.8 (Berkeley) 06/29/88"; 20*34902Sbostic #endif /* not lint */ 217905Ssam 227905Ssam #include <sys/types.h> 237905Ssam #include <sys/socket.h> 249203Ssam 257905Ssam #include <net/if.h> 269203Ssam #include <netinet/in.h> 2721906Skarels #include <netinet/in_var.h> 2823499Ssklower #include <netns/ns.h> 299203Ssam 308331Ssam #include <stdio.h> 3129746Skupfer #include <signal.h> 327905Ssam 3329746Skupfer #define YES 1 3429746Skupfer #define NO 0 3529746Skupfer 367905Ssam extern int kmem; 377905Ssam extern int tflag; 3834270Skarels extern int dflag; 397905Ssam extern int nflag; 4017402Sedward extern char *interface; 4117402Sedward extern int unit; 4229746Skupfer extern char *routename(), *netname(), *ns_phost(); 437905Ssam 447905Ssam /* 457905Ssam * Print a description of the network interfaces. 467905Ssam */ 477905Ssam intpr(interval, ifnetaddr) 487905Ssam int interval; 497905Ssam off_t ifnetaddr; 507905Ssam { 517905Ssam struct ifnet ifnet; 5221906Skarels union { 5321906Skarels struct ifaddr ifa; 5421906Skarels struct in_ifaddr in; 5521906Skarels } ifaddr; 5621906Skarels off_t ifaddraddr; 577905Ssam char name[16]; 587905Ssam 597905Ssam if (ifnetaddr == 0) { 607905Ssam printf("ifnet: symbol not defined\n"); 617905Ssam return; 627905Ssam } 637905Ssam if (interval) { 6429746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 657905Ssam return; 667905Ssam } 677905Ssam klseek(kmem, ifnetaddr, 0); 6829746Skupfer read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr); 6932085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 707905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 717905Ssam "Opkts", "Oerrs"); 7232085Skarels printf(" %5s", "Coll"); 737905Ssam if (tflag) 7432085Skarels printf(" %s", "Time"); 7534270Skarels if (dflag) 7634270Skarels printf(" %s", "Drop"); 777905Ssam putchar('\n'); 7821906Skarels ifaddraddr = 0; 7921906Skarels while (ifnetaddr || ifaddraddr) { 807905Ssam struct sockaddr_in *sin; 817905Ssam register char *cp; 8221906Skarels int n; 837905Ssam char *index(); 8429746Skupfer struct in_addr inet_makeaddr(); 857905Ssam 8621906Skarels if (ifaddraddr == 0) { 8721906Skarels klseek(kmem, ifnetaddr, 0); 8829746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 8921906Skarels klseek(kmem, (off_t)ifnet.if_name, 0); 9021906Skarels read(kmem, name, 16); 9121906Skarels name[15] = '\0'; 9221906Skarels ifnetaddr = (off_t) ifnet.if_next; 9321906Skarels if (interface != 0 && 9421906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 9521906Skarels continue; 9621906Skarels cp = index(name, '\0'); 9721906Skarels *cp++ = ifnet.if_unit + '0'; 9821906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 9921906Skarels *cp++ = '*'; 10021906Skarels *cp = '\0'; 10121906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 10221906Skarels } 1037905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 10421906Skarels if (ifaddraddr == 0) { 10532085Skarels printf("%-11.11s ", "none"); 10632085Skarels printf("%-15.15s ", "none"); 10721906Skarels } else { 10821906Skarels klseek(kmem, ifaddraddr, 0); 10929746Skupfer read(kmem, (char *)&ifaddr, sizeof ifaddr); 11021906Skarels ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 11121906Skarels switch (ifaddr.ifa.ifa_addr.sa_family) { 11221906Skarels case AF_UNSPEC: 11332085Skarels printf("%-11.11s ", "none"); 11432085Skarels printf("%-15.15s ", "none"); 11521906Skarels break; 11621906Skarels case AF_INET: 11721906Skarels sin = (struct sockaddr_in *)&ifaddr.in.ia_addr; 11821906Skarels #ifdef notdef 11921906Skarels /* can't use inet_makeaddr because kernel 12021906Skarels * keeps nets unshifted. 12121906Skarels */ 12221906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 12321906Skarels INADDR_ANY); 12432085Skarels printf("%-11.11s ", netname(in)); 12521906Skarels #else 12632085Skarels printf("%-11.11s ", 12721906Skarels netname(htonl(ifaddr.in.ia_subnet), 12821906Skarels ifaddr.in.ia_subnetmask)); 12921906Skarels #endif 13032085Skarels printf("%-15.15s ", routename(sin->sin_addr)); 13121906Skarels break; 13223499Ssklower case AF_NS: 13323499Ssklower { 13423499Ssklower struct sockaddr_ns *sns = 13523499Ssklower (struct sockaddr_ns *)&ifaddr.in.ia_addr; 13629746Skupfer u_long net; 13732085Skarels char netnum[8]; 13829746Skupfer char *ns_phost(); 13929746Skupfer 14027265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 14132085Skarels sprintf(netnum, "%lxH", ntohl(net)); 14232085Skarels upHex(netnum); 14332085Skarels printf("ns:%-8s ", netnum); 14432085Skarels printf("%-15s ", ns_phost(sns)); 14523499Ssklower } 14623499Ssklower break; 14721906Skarels default: 14821906Skarels printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family); 14921906Skarels for (cp = (char *)&ifaddr.ifa.ifa_addr + 15021906Skarels sizeof(struct sockaddr) - 1; 15121906Skarels cp >= ifaddr.ifa.ifa_addr.sa_data; --cp) 15221906Skarels if (*cp != 0) 15321906Skarels break; 15421906Skarels n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1; 15521906Skarels cp = (char *)ifaddr.ifa.ifa_addr.sa_data; 15632085Skarels if (n <= 7) 15721906Skarels while (--n) 15821906Skarels printf("%02d.", *cp++ & 0xff); 15921906Skarels else 16021906Skarels while (--n) 16121906Skarels printf("%02d", *cp++ & 0xff); 16221906Skarels printf("%02d ", *cp & 0xff); 16321906Skarels break; 16421906Skarels } 16521906Skarels } 16632085Skarels printf("%8d %5d %8d %5d %5d", 1677905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1687905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1697905Ssam ifnet.if_collisions); 1707905Ssam if (tflag) 17132085Skarels printf(" %3d", ifnet.if_timer); 17234270Skarels if (dflag) 17334270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1747905Ssam putchar('\n'); 1757905Ssam } 1767905Ssam } 1777905Ssam 1788331Ssam #define MAXIF 10 1798331Ssam struct iftot { 1808331Ssam char ift_name[16]; /* interface name */ 1818331Ssam int ift_ip; /* input packets */ 1828331Ssam int ift_ie; /* input errors */ 1838331Ssam int ift_op; /* output packets */ 1848331Ssam int ift_oe; /* output errors */ 1858331Ssam int ift_co; /* collisions */ 18634270Skarels int ift_dr; /* drops */ 1878331Ssam } iftot[MAXIF]; 1888331Ssam 18929746Skupfer u_char signalled; /* set if alarm goes off "early" */ 19029746Skupfer 1918331Ssam /* 1928331Ssam * Print a running summary of interface statistics. 19329746Skupfer * Repeat display every interval seconds, showing statistics 19429746Skupfer * collected over that interval. Assumes that interval is non-zero. 19529746Skupfer * First line printed at top of screen is always cumulative. 1968331Ssam */ 1977905Ssam sidewaysintpr(interval, off) 19829746Skupfer unsigned interval; 1997905Ssam off_t off; 2007905Ssam { 2017905Ssam struct ifnet ifnet; 2028331Ssam off_t firstifnet; 2038331Ssam register struct iftot *ip, *total; 2048331Ssam register int line; 2058331Ssam struct iftot *lastif, *sum, *interesting; 20629746Skupfer int oldmask; 20729746Skupfer int catchalarm(); 2087905Ssam 2097905Ssam klseek(kmem, off, 0); 21029746Skupfer read(kmem, (char *)&firstifnet, sizeof (off_t)); 2118331Ssam lastif = iftot; 2128331Ssam sum = iftot + MAXIF - 1; 2138331Ssam total = sum - 1; 21417402Sedward interesting = iftot; 2158331Ssam for (off = firstifnet, ip = iftot; off;) { 2168331Ssam char *cp; 2177905Ssam 2187905Ssam klseek(kmem, off, 0); 21929746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 22029746Skupfer klseek(kmem, (off_t)ifnet.if_name, 0); 2218331Ssam ip->ift_name[0] = '('; 2228331Ssam read(kmem, ip->ift_name + 1, 15); 22317402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 22417402Sedward unit == ifnet.if_unit) 22517402Sedward interesting = ip; 2268331Ssam ip->ift_name[15] = '\0'; 2278331Ssam cp = index(ip->ift_name, '\0'); 2288331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2298331Ssam ip++; 2308331Ssam if (ip >= iftot + MAXIF - 2) 2318331Ssam break; 2327905Ssam off = (off_t) ifnet.if_next; 2337905Ssam } 2348331Ssam lastif = ip; 23529746Skupfer 23629746Skupfer (void)signal(SIGALRM, catchalarm); 23729746Skupfer signalled = NO; 23829746Skupfer (void)alarm(interval); 2398331Ssam banner: 24034270Skarels printf(" input %-6.6s output ", interesting->ift_name); 24134270Skarels if (lastif - iftot > 0) { 24234270Skarels if (dflag) 24334270Skarels printf(" "); 24434270Skarels printf(" input (Total) output"); 24534270Skarels } 2468331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2478331Ssam ip->ift_ip = 0; 2488331Ssam ip->ift_ie = 0; 2498331Ssam ip->ift_op = 0; 2508331Ssam ip->ift_oe = 0; 2518331Ssam ip->ift_co = 0; 25234270Skarels ip->ift_dr = 0; 2538331Ssam } 2548331Ssam putchar('\n'); 25532085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2568331Ssam "packets", "errs", "packets", "errs", "colls"); 25734270Skarels if (dflag) 25834270Skarels printf("%5.5s ", "drops"); 2598331Ssam if (lastif - iftot > 0) 26034270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2618331Ssam "packets", "errs", "packets", "errs", "colls"); 26234270Skarels if (dflag) 26334270Skarels printf(" %5.5s", "drops"); 2648331Ssam putchar('\n'); 2658331Ssam fflush(stdout); 2668331Ssam line = 0; 2678331Ssam loop: 2688331Ssam sum->ift_ip = 0; 2698331Ssam sum->ift_ie = 0; 2708331Ssam sum->ift_op = 0; 2718331Ssam sum->ift_oe = 0; 2728331Ssam sum->ift_co = 0; 27334270Skarels sum->ift_dr = 0; 2748331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 2758331Ssam klseek(kmem, off, 0); 27629746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 27734270Skarels if (ip == interesting) { 27834270Skarels printf("%8d %5d %8d %5d %5d", 2798331Ssam ifnet.if_ipackets - ip->ift_ip, 2808331Ssam ifnet.if_ierrors - ip->ift_ie, 2818331Ssam ifnet.if_opackets - ip->ift_op, 2828331Ssam ifnet.if_oerrors - ip->ift_oe, 2838331Ssam ifnet.if_collisions - ip->ift_co); 28434270Skarels if (dflag) 28534270Skarels printf(" %5d", 28634270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 28734270Skarels } 2888331Ssam ip->ift_ip = ifnet.if_ipackets; 2898331Ssam ip->ift_ie = ifnet.if_ierrors; 2908331Ssam ip->ift_op = ifnet.if_opackets; 2918331Ssam ip->ift_oe = ifnet.if_oerrors; 2928331Ssam ip->ift_co = ifnet.if_collisions; 29334270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 2948331Ssam sum->ift_ip += ip->ift_ip; 2958331Ssam sum->ift_ie += ip->ift_ie; 2968331Ssam sum->ift_op += ip->ift_op; 2978331Ssam sum->ift_oe += ip->ift_oe; 2988331Ssam sum->ift_co += ip->ift_co; 29934270Skarels sum->ift_dr += ip->ift_dr; 3008331Ssam off = (off_t) ifnet.if_next; 3018331Ssam } 30234270Skarels if (lastif - iftot > 0) { 30334270Skarels printf(" %8d %5d %8d %5d %5d", 3048331Ssam sum->ift_ip - total->ift_ip, 3058331Ssam sum->ift_ie - total->ift_ie, 3068331Ssam sum->ift_op - total->ift_op, 3078331Ssam sum->ift_oe - total->ift_oe, 3088331Ssam sum->ift_co - total->ift_co); 30934270Skarels if (dflag) 31034270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 31134270Skarels } 3128331Ssam *total = *sum; 31332085Skarels putchar('\n'); 3148331Ssam fflush(stdout); 3158331Ssam line++; 31629746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 31729746Skupfer if (! signalled) { 31829746Skupfer sigpause(0); 31929746Skupfer } 32029746Skupfer sigsetmask(oldmask); 32129746Skupfer signalled = NO; 32229746Skupfer (void)alarm(interval); 3238331Ssam if (line == 21) 3248331Ssam goto banner; 3258331Ssam goto loop; 3268331Ssam /*NOTREACHED*/ 3277905Ssam } 32829746Skupfer 32929746Skupfer /* 33029746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 33129746Skupfer * Sets a flag to not wait for the alarm. 33229746Skupfer */ 33329746Skupfer catchalarm() 33429746Skupfer { 33529746Skupfer signalled = YES; 33629746Skupfer } 337