121986Sdist /* 234902Sbostic * Copyright (c) 1983, 1988 Regents of the University of California. 333451Skarels * All rights reserved. 433451Skarels * 542748Sbostic * %sccs.include.redist.c% 621986Sdist */ 721986Sdist 87905Ssam #ifndef lint 9*43251Ssklower static char sccsid[] = "@(#)if.c 5.14 (Berkeley) 06/18/90"; 1034902Sbostic #endif /* not lint */ 117905Ssam 127905Ssam #include <sys/types.h> 137905Ssam #include <sys/socket.h> 149203Ssam 157905Ssam #include <net/if.h> 1640839Ssklower #include <net/if_dl.h> 179203Ssam #include <netinet/in.h> 1821906Skarels #include <netinet/in_var.h> 1923499Ssklower #include <netns/ns.h> 2039214Smarc #include <netns/ns_if.h> 21*43251Ssklower #include <netiso/iso.h> 22*43251Ssklower #include <netiso/iso_var.h> 239203Ssam 248331Ssam #include <stdio.h> 2529746Skupfer #include <signal.h> 267905Ssam 2729746Skupfer #define YES 1 2829746Skupfer #define NO 0 2929746Skupfer 307905Ssam extern int tflag; 3134270Skarels extern int dflag; 327905Ssam extern int nflag; 3317402Sedward extern char *interface; 3417402Sedward extern int unit; 3529746Skupfer extern char *routename(), *netname(), *ns_phost(); 367905Ssam 377905Ssam /* 387905Ssam * Print a description of the network interfaces. 397905Ssam */ 407905Ssam intpr(interval, ifnetaddr) 417905Ssam int interval; 427905Ssam off_t ifnetaddr; 437905Ssam { 447905Ssam struct ifnet ifnet; 4521906Skarels union { 4621906Skarels struct ifaddr ifa; 4721906Skarels struct in_ifaddr in; 4839214Smarc struct ns_ifaddr ns; 49*43251Ssklower struct iso_ifaddr iso; 5021906Skarels } ifaddr; 5121906Skarels off_t ifaddraddr; 5239214Smarc struct sockaddr *sa; 537905Ssam char name[16]; 547905Ssam 557905Ssam if (ifnetaddr == 0) { 567905Ssam printf("ifnet: symbol not defined\n"); 577905Ssam return; 587905Ssam } 597905Ssam if (interval) { 6029746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 617905Ssam return; 627905Ssam } 63*43251Ssklower kvm_read(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr); 6432085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 657905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 667905Ssam "Opkts", "Oerrs"); 6732085Skarels printf(" %5s", "Coll"); 687905Ssam if (tflag) 6932085Skarels printf(" %s", "Time"); 7034270Skarels if (dflag) 7134270Skarels printf(" %s", "Drop"); 727905Ssam putchar('\n'); 7321906Skarels ifaddraddr = 0; 7421906Skarels while (ifnetaddr || ifaddraddr) { 757905Ssam struct sockaddr_in *sin; 767905Ssam register char *cp; 7740839Ssklower int n, m; 7839214Smarc char *index(); 7939214Smarc struct in_addr inet_makeaddr(); 807905Ssam 8121906Skarels if (ifaddraddr == 0) { 82*43251Ssklower kvm_read(ifnetaddr, (char *)&ifnet, sizeof ifnet); 83*43251Ssklower kvm_read((off_t)ifnet.if_name, name, 16); 8421906Skarels name[15] = '\0'; 8521906Skarels ifnetaddr = (off_t) ifnet.if_next; 8621906Skarels if (interface != 0 && 8721906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 8821906Skarels continue; 8921906Skarels cp = index(name, '\0'); 9021906Skarels *cp++ = ifnet.if_unit + '0'; 9121906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 9221906Skarels *cp++ = '*'; 9321906Skarels *cp = '\0'; 9421906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 9521906Skarels } 967905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 9721906Skarels if (ifaddraddr == 0) { 9832085Skarels printf("%-11.11s ", "none"); 9932085Skarels printf("%-15.15s ", "none"); 10021906Skarels } else { 101*43251Ssklower kvm_read(ifaddraddr, (char *)&ifaddr, sizeof ifaddr); 10239214Smarc #define CP(x) ((char *)(x)) 10339214Smarc cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 10439214Smarc CP(&ifaddr); sa = (struct sockaddr *)cp; 10539214Smarc switch (sa->sa_family) { 10621906Skarels case AF_UNSPEC: 10732085Skarels printf("%-11.11s ", "none"); 10832085Skarels printf("%-15.15s ", "none"); 10921906Skarels break; 11021906Skarels case AF_INET: 11139214Smarc sin = (struct sockaddr_in *)sa; 11221906Skarels #ifdef notdef 11321906Skarels /* can't use inet_makeaddr because kernel 11421906Skarels * keeps nets unshifted. 11521906Skarels */ 11621906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 11721906Skarels INADDR_ANY); 11832085Skarels printf("%-11.11s ", netname(in)); 11921906Skarels #else 12032085Skarels printf("%-11.11s ", 12121906Skarels netname(htonl(ifaddr.in.ia_subnet), 12221906Skarels ifaddr.in.ia_subnetmask)); 12321906Skarels #endif 12432085Skarels printf("%-15.15s ", routename(sin->sin_addr)); 12521906Skarels break; 12623499Ssklower case AF_NS: 12723499Ssklower { 12823499Ssklower struct sockaddr_ns *sns = 12939214Smarc (struct sockaddr_ns *)sa; 13029746Skupfer u_long net; 13132085Skarels char netnum[8]; 13229746Skupfer char *ns_phost(); 13329746Skupfer 13427265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 13539214Smarc sprintf(netnum, "%lxH", ntohl(net)); 13632085Skarels upHex(netnum); 13732085Skarels printf("ns:%-8s ", netnum); 13832085Skarels printf("%-15s ", ns_phost(sns)); 13923499Ssklower } 14023499Ssklower break; 14140839Ssklower case AF_LINK: 14240839Ssklower { 14340839Ssklower struct sockaddr_dl *sdl = 14440839Ssklower (struct sockaddr_dl *)sa; 14541185Ssklower cp = (char *)LLADDR(sdl); 14641185Ssklower n = sdl->sdl_alen; 14740839Ssklower } 14841185Ssklower m = printf("<Link>"); 14941185Ssklower goto hexprint; 15021906Skarels default: 15141185Ssklower m = printf("(%d)", sa->sa_family); 15241185Ssklower for (cp = sa->sa_len + (char *)sa; 15341185Ssklower --cp > sa->sa_data && (*cp == 0);) {} 15439214Smarc n = cp - sa->sa_data + 1; 15539214Smarc cp = sa->sa_data; 15640839Ssklower hexprint: 15741185Ssklower while (--n >= 0) 15841185Ssklower m += printf("%x%c", *cp++ & 0xff, 15941185Ssklower n > 0 ? '.' : ' '); 16041185Ssklower m = 28 - m; 16140839Ssklower while (m-- > 0) 16240839Ssklower putchar(' '); 16321906Skarels break; 16421906Skarels } 16539214Smarc ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 16621906Skarels } 16732085Skarels printf("%8d %5d %8d %5d %5d", 1687905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1697905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1707905Ssam ifnet.if_collisions); 1717905Ssam if (tflag) 17232085Skarels printf(" %3d", ifnet.if_timer); 17334270Skarels if (dflag) 17434270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1757905Ssam putchar('\n'); 1767905Ssam } 1777905Ssam } 1787905Ssam 1798331Ssam #define MAXIF 10 1808331Ssam struct iftot { 1818331Ssam char ift_name[16]; /* interface name */ 1828331Ssam int ift_ip; /* input packets */ 1838331Ssam int ift_ie; /* input errors */ 1848331Ssam int ift_op; /* output packets */ 1858331Ssam int ift_oe; /* output errors */ 1868331Ssam int ift_co; /* collisions */ 18734270Skarels int ift_dr; /* drops */ 1888331Ssam } iftot[MAXIF]; 1898331Ssam 19029746Skupfer u_char signalled; /* set if alarm goes off "early" */ 19129746Skupfer 1928331Ssam /* 1938331Ssam * Print a running summary of interface statistics. 19429746Skupfer * Repeat display every interval seconds, showing statistics 19529746Skupfer * collected over that interval. Assumes that interval is non-zero. 19629746Skupfer * First line printed at top of screen is always cumulative. 1978331Ssam */ 1987905Ssam sidewaysintpr(interval, off) 19929746Skupfer unsigned interval; 2007905Ssam off_t off; 2017905Ssam { 2027905Ssam struct ifnet ifnet; 2038331Ssam off_t firstifnet; 2048331Ssam register struct iftot *ip, *total; 2058331Ssam register int line; 2068331Ssam struct iftot *lastif, *sum, *interesting; 20729746Skupfer int oldmask; 20829746Skupfer int catchalarm(); 2097905Ssam 210*43251Ssklower kvm_read(off, (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 218*43251Ssklower kvm_read(off, (char *)&ifnet, sizeof ifnet); 2198331Ssam ip->ift_name[0] = '('; 220*43251Ssklower kvm_read((off_t)ifnet.if_name, ip->ift_name + 1, 15); 22117402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 22217402Sedward unit == ifnet.if_unit) 22317402Sedward interesting = ip; 2248331Ssam ip->ift_name[15] = '\0'; 2258331Ssam cp = index(ip->ift_name, '\0'); 2268331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2278331Ssam ip++; 2288331Ssam if (ip >= iftot + MAXIF - 2) 2298331Ssam break; 2307905Ssam off = (off_t) ifnet.if_next; 2317905Ssam } 2328331Ssam lastif = ip; 23329746Skupfer 23429746Skupfer (void)signal(SIGALRM, catchalarm); 23529746Skupfer signalled = NO; 23629746Skupfer (void)alarm(interval); 2378331Ssam banner: 23834270Skarels printf(" input %-6.6s output ", interesting->ift_name); 23934270Skarels if (lastif - iftot > 0) { 24034270Skarels if (dflag) 24134270Skarels printf(" "); 24234270Skarels printf(" input (Total) output"); 24334270Skarels } 2448331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2458331Ssam ip->ift_ip = 0; 2468331Ssam ip->ift_ie = 0; 2478331Ssam ip->ift_op = 0; 2488331Ssam ip->ift_oe = 0; 2498331Ssam ip->ift_co = 0; 25034270Skarels ip->ift_dr = 0; 2518331Ssam } 2528331Ssam putchar('\n'); 25332085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2548331Ssam "packets", "errs", "packets", "errs", "colls"); 25534270Skarels if (dflag) 25634270Skarels printf("%5.5s ", "drops"); 2578331Ssam if (lastif - iftot > 0) 25834270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2598331Ssam "packets", "errs", "packets", "errs", "colls"); 26034270Skarels if (dflag) 26134270Skarels printf(" %5.5s", "drops"); 2628331Ssam putchar('\n'); 2638331Ssam fflush(stdout); 2648331Ssam line = 0; 2658331Ssam loop: 2668331Ssam sum->ift_ip = 0; 2678331Ssam sum->ift_ie = 0; 2688331Ssam sum->ift_op = 0; 2698331Ssam sum->ift_oe = 0; 2708331Ssam sum->ift_co = 0; 27134270Skarels sum->ift_dr = 0; 2728331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 273*43251Ssklower kvm_read(off, (char *)&ifnet, sizeof ifnet); 27434270Skarels if (ip == interesting) { 27534270Skarels printf("%8d %5d %8d %5d %5d", 2768331Ssam ifnet.if_ipackets - ip->ift_ip, 2778331Ssam ifnet.if_ierrors - ip->ift_ie, 2788331Ssam ifnet.if_opackets - ip->ift_op, 2798331Ssam ifnet.if_oerrors - ip->ift_oe, 2808331Ssam ifnet.if_collisions - ip->ift_co); 28134270Skarels if (dflag) 28234270Skarels printf(" %5d", 28334270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 28434270Skarels } 2858331Ssam ip->ift_ip = ifnet.if_ipackets; 2868331Ssam ip->ift_ie = ifnet.if_ierrors; 2878331Ssam ip->ift_op = ifnet.if_opackets; 2888331Ssam ip->ift_oe = ifnet.if_oerrors; 2898331Ssam ip->ift_co = ifnet.if_collisions; 29034270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 2918331Ssam sum->ift_ip += ip->ift_ip; 2928331Ssam sum->ift_ie += ip->ift_ie; 2938331Ssam sum->ift_op += ip->ift_op; 2948331Ssam sum->ift_oe += ip->ift_oe; 2958331Ssam sum->ift_co += ip->ift_co; 29634270Skarels sum->ift_dr += ip->ift_dr; 2978331Ssam off = (off_t) ifnet.if_next; 2988331Ssam } 29934270Skarels if (lastif - iftot > 0) { 30034270Skarels printf(" %8d %5d %8d %5d %5d", 3018331Ssam sum->ift_ip - total->ift_ip, 3028331Ssam sum->ift_ie - total->ift_ie, 3038331Ssam sum->ift_op - total->ift_op, 3048331Ssam sum->ift_oe - total->ift_oe, 3058331Ssam sum->ift_co - total->ift_co); 30634270Skarels if (dflag) 30734270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 30834270Skarels } 3098331Ssam *total = *sum; 31032085Skarels putchar('\n'); 3118331Ssam fflush(stdout); 3128331Ssam line++; 31329746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 31429746Skupfer if (! signalled) { 31529746Skupfer sigpause(0); 31629746Skupfer } 31729746Skupfer sigsetmask(oldmask); 31829746Skupfer signalled = NO; 31929746Skupfer (void)alarm(interval); 3208331Ssam if (line == 21) 3218331Ssam goto banner; 3228331Ssam goto loop; 3238331Ssam /*NOTREACHED*/ 3247905Ssam } 32529746Skupfer 32629746Skupfer /* 32729746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 32829746Skupfer * Sets a flag to not wait for the alarm. 32929746Skupfer */ 33029746Skupfer catchalarm() 33129746Skupfer { 33229746Skupfer signalled = YES; 33329746Skupfer } 334