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*53698Ssklower static char sccsid[] = "@(#)if.c 5.16 (Berkeley) 05/27/92"; 1034902Sbostic #endif /* not lint */ 117905Ssam 127905Ssam #include <sys/types.h> 13*53698Ssklower #include <sys/protosw.h> 147905Ssam #include <sys/socket.h> 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> 2143251Ssklower #include <netiso/iso.h> 2243251Ssklower #include <netiso/iso_var.h> 239203Ssam 24*53698Ssklower #include <arpa/inet.h> 258331Ssam #include <stdio.h> 26*53698Ssklower #include <string.h> 2729746Skupfer #include <signal.h> 28*53698Ssklower #include "netstat.h" 297905Ssam 3029746Skupfer #define YES 1 3129746Skupfer #define NO 0 3229746Skupfer 33*53698Ssklower static void sidewaysintpr __P((unsigned, off_t)); 34*53698Ssklower static void catchalarm __P(()); 357905Ssam 367905Ssam /* 377905Ssam * Print a description of the network interfaces. 387905Ssam */ 39*53698Ssklower void 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; 4943251Ssklower 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*53698Ssklower if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr)) 64*53698Ssklower return; 6532085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 667905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 677905Ssam "Opkts", "Oerrs"); 6832085Skarels printf(" %5s", "Coll"); 697905Ssam if (tflag) 7032085Skarels printf(" %s", "Time"); 7134270Skarels if (dflag) 7234270Skarels printf(" %s", "Drop"); 737905Ssam putchar('\n'); 7421906Skarels ifaddraddr = 0; 7521906Skarels while (ifnetaddr || ifaddraddr) { 767905Ssam struct sockaddr_in *sin; 777905Ssam register char *cp; 7840839Ssklower int n, m; 797905Ssam 8021906Skarels if (ifaddraddr == 0) { 81*53698Ssklower if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) || 82*53698Ssklower kread((off_t)ifnet.if_name, name, 16)) 83*53698Ssklower return; 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*53698Ssklower if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) { 102*53698Ssklower ifaddraddr = 0; 103*53698Ssklower continue; 104*53698Ssklower } 10539214Smarc #define CP(x) ((char *)(x)) 10639214Smarc cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 10739214Smarc CP(&ifaddr); sa = (struct sockaddr *)cp; 10839214Smarc switch (sa->sa_family) { 10921906Skarels case AF_UNSPEC: 11032085Skarels printf("%-11.11s ", "none"); 11132085Skarels printf("%-15.15s ", "none"); 11221906Skarels break; 11321906Skarels case AF_INET: 11439214Smarc sin = (struct sockaddr_in *)sa; 11521906Skarels #ifdef notdef 11621906Skarels /* can't use inet_makeaddr because kernel 11721906Skarels * keeps nets unshifted. 11821906Skarels */ 11921906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 12021906Skarels INADDR_ANY); 121*53698Ssklower printf("%-11.11s ", netname(in.s_addr, 122*53698Ssklower ifaddr.in.ia_subnetmask)); 12321906Skarels #else 12432085Skarels printf("%-11.11s ", 125*53698Ssklower netname(htonl(ifaddr.in.ia_subnet), 126*53698Ssklower ifaddr.in.ia_subnetmask)); 12721906Skarels #endif 128*53698Ssklower printf("%-15.15s ", 129*53698Ssklower routename(sin->sin_addr.s_addr)); 13021906Skarels break; 13123499Ssklower case AF_NS: 13223499Ssklower { 13323499Ssklower struct sockaddr_ns *sns = 13439214Smarc (struct sockaddr_ns *)sa; 13529746Skupfer u_long net; 13632085Skarels char netnum[8]; 13729746Skupfer 13827265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 13939214Smarc sprintf(netnum, "%lxH", ntohl(net)); 14032085Skarels upHex(netnum); 14132085Skarels printf("ns:%-8s ", netnum); 142*53698Ssklower printf("%-15s ", 143*53698Ssklower ns_phost((struct sockaddr *)sns)); 14423499Ssklower } 14523499Ssklower break; 14640839Ssklower case AF_LINK: 14740839Ssklower { 14840839Ssklower struct sockaddr_dl *sdl = 14940839Ssklower (struct sockaddr_dl *)sa; 15041185Ssklower cp = (char *)LLADDR(sdl); 15141185Ssklower n = sdl->sdl_alen; 15240839Ssklower } 15341185Ssklower m = printf("<Link>"); 15441185Ssklower goto hexprint; 15521906Skarels default: 15641185Ssklower m = printf("(%d)", sa->sa_family); 15741185Ssklower for (cp = sa->sa_len + (char *)sa; 15841185Ssklower --cp > sa->sa_data && (*cp == 0);) {} 15939214Smarc n = cp - sa->sa_data + 1; 16039214Smarc cp = sa->sa_data; 16140839Ssklower hexprint: 16241185Ssklower while (--n >= 0) 16341185Ssklower m += printf("%x%c", *cp++ & 0xff, 16441185Ssklower n > 0 ? '.' : ' '); 16541185Ssklower m = 28 - m; 16640839Ssklower while (m-- > 0) 16740839Ssklower putchar(' '); 16821906Skarels break; 16921906Skarels } 17039214Smarc ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 17121906Skarels } 17232085Skarels printf("%8d %5d %8d %5d %5d", 1737905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1747905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1757905Ssam ifnet.if_collisions); 1767905Ssam if (tflag) 17732085Skarels printf(" %3d", ifnet.if_timer); 17834270Skarels if (dflag) 17934270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1807905Ssam putchar('\n'); 1817905Ssam } 1827905Ssam } 1837905Ssam 1848331Ssam #define MAXIF 10 1858331Ssam struct iftot { 1868331Ssam char ift_name[16]; /* interface name */ 1878331Ssam int ift_ip; /* input packets */ 1888331Ssam int ift_ie; /* input errors */ 1898331Ssam int ift_op; /* output packets */ 1908331Ssam int ift_oe; /* output errors */ 1918331Ssam int ift_co; /* collisions */ 19234270Skarels int ift_dr; /* drops */ 1938331Ssam } iftot[MAXIF]; 1948331Ssam 19529746Skupfer u_char signalled; /* set if alarm goes off "early" */ 19629746Skupfer 1978331Ssam /* 1988331Ssam * Print a running summary of interface statistics. 19929746Skupfer * Repeat display every interval seconds, showing statistics 20029746Skupfer * collected over that interval. Assumes that interval is non-zero. 20129746Skupfer * First line printed at top of screen is always cumulative. 2028331Ssam */ 203*53698Ssklower static void 2047905Ssam sidewaysintpr(interval, off) 20529746Skupfer unsigned interval; 2067905Ssam off_t off; 2077905Ssam { 2087905Ssam struct ifnet ifnet; 2098331Ssam off_t firstifnet; 2108331Ssam register struct iftot *ip, *total; 2118331Ssam register int line; 2128331Ssam struct iftot *lastif, *sum, *interesting; 21329746Skupfer int oldmask; 2147905Ssam 215*53698Ssklower if (kread(off, (char *)&firstifnet, sizeof (off_t))) 216*53698Ssklower return; 2178331Ssam lastif = iftot; 2188331Ssam sum = iftot + MAXIF - 1; 2198331Ssam total = sum - 1; 22017402Sedward interesting = iftot; 2218331Ssam for (off = firstifnet, ip = iftot; off;) { 2228331Ssam char *cp; 2237905Ssam 224*53698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet)) 225*53698Ssklower break; 2268331Ssam ip->ift_name[0] = '('; 227*53698Ssklower if (kread((off_t)ifnet.if_name, ip->ift_name + 1, 15)) 228*53698Ssklower break; 22917402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 23017402Sedward unit == ifnet.if_unit) 23117402Sedward interesting = ip; 2328331Ssam ip->ift_name[15] = '\0'; 2338331Ssam cp = index(ip->ift_name, '\0'); 2348331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2358331Ssam ip++; 2368331Ssam if (ip >= iftot + MAXIF - 2) 2378331Ssam break; 2387905Ssam off = (off_t) ifnet.if_next; 2397905Ssam } 2408331Ssam lastif = ip; 24129746Skupfer 24229746Skupfer (void)signal(SIGALRM, catchalarm); 24329746Skupfer signalled = NO; 24429746Skupfer (void)alarm(interval); 2458331Ssam banner: 24634270Skarels printf(" input %-6.6s output ", interesting->ift_name); 24734270Skarels if (lastif - iftot > 0) { 24834270Skarels if (dflag) 24934270Skarels printf(" "); 25034270Skarels printf(" input (Total) output"); 25134270Skarels } 2528331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2538331Ssam ip->ift_ip = 0; 2548331Ssam ip->ift_ie = 0; 2558331Ssam ip->ift_op = 0; 2568331Ssam ip->ift_oe = 0; 2578331Ssam ip->ift_co = 0; 25834270Skarels ip->ift_dr = 0; 2598331Ssam } 2608331Ssam putchar('\n'); 26132085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2628331Ssam "packets", "errs", "packets", "errs", "colls"); 26334270Skarels if (dflag) 26434270Skarels printf("%5.5s ", "drops"); 2658331Ssam if (lastif - iftot > 0) 26634270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2678331Ssam "packets", "errs", "packets", "errs", "colls"); 26834270Skarels if (dflag) 26934270Skarels printf(" %5.5s", "drops"); 2708331Ssam putchar('\n'); 2718331Ssam fflush(stdout); 2728331Ssam line = 0; 2738331Ssam loop: 2748331Ssam sum->ift_ip = 0; 2758331Ssam sum->ift_ie = 0; 2768331Ssam sum->ift_op = 0; 2778331Ssam sum->ift_oe = 0; 2788331Ssam sum->ift_co = 0; 27934270Skarels sum->ift_dr = 0; 2808331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 281*53698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet)) { 282*53698Ssklower off = 0; 283*53698Ssklower continue; 284*53698Ssklower } 28534270Skarels if (ip == interesting) { 28634270Skarels printf("%8d %5d %8d %5d %5d", 2878331Ssam ifnet.if_ipackets - ip->ift_ip, 2888331Ssam ifnet.if_ierrors - ip->ift_ie, 2898331Ssam ifnet.if_opackets - ip->ift_op, 2908331Ssam ifnet.if_oerrors - ip->ift_oe, 2918331Ssam ifnet.if_collisions - ip->ift_co); 29234270Skarels if (dflag) 29334270Skarels printf(" %5d", 29434270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 29534270Skarels } 2968331Ssam ip->ift_ip = ifnet.if_ipackets; 2978331Ssam ip->ift_ie = ifnet.if_ierrors; 2988331Ssam ip->ift_op = ifnet.if_opackets; 2998331Ssam ip->ift_oe = ifnet.if_oerrors; 3008331Ssam ip->ift_co = ifnet.if_collisions; 30134270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 3028331Ssam sum->ift_ip += ip->ift_ip; 3038331Ssam sum->ift_ie += ip->ift_ie; 3048331Ssam sum->ift_op += ip->ift_op; 3058331Ssam sum->ift_oe += ip->ift_oe; 3068331Ssam sum->ift_co += ip->ift_co; 30734270Skarels sum->ift_dr += ip->ift_dr; 3088331Ssam off = (off_t) ifnet.if_next; 3098331Ssam } 31034270Skarels if (lastif - iftot > 0) { 31134270Skarels printf(" %8d %5d %8d %5d %5d", 3128331Ssam sum->ift_ip - total->ift_ip, 3138331Ssam sum->ift_ie - total->ift_ie, 3148331Ssam sum->ift_op - total->ift_op, 3158331Ssam sum->ift_oe - total->ift_oe, 3168331Ssam sum->ift_co - total->ift_co); 31734270Skarels if (dflag) 31834270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 31934270Skarels } 3208331Ssam *total = *sum; 32132085Skarels putchar('\n'); 3228331Ssam fflush(stdout); 3238331Ssam line++; 32429746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 32529746Skupfer if (! signalled) { 32629746Skupfer sigpause(0); 32729746Skupfer } 32829746Skupfer sigsetmask(oldmask); 32929746Skupfer signalled = NO; 33029746Skupfer (void)alarm(interval); 3318331Ssam if (line == 21) 3328331Ssam goto banner; 3338331Ssam goto loop; 3348331Ssam /*NOTREACHED*/ 3357905Ssam } 33629746Skupfer 33729746Skupfer /* 33829746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 33929746Skupfer * Sets a flag to not wait for the alarm. 34029746Skupfer */ 341*53698Ssklower static void 34229746Skupfer catchalarm() 34329746Skupfer { 34429746Skupfer signalled = YES; 34529746Skupfer } 346