121986Sdist /* 2*62144Sbostic * Copyright (c) 1983, 1988, 1993 3*62144Sbostic * The Regents of the University of California. All rights reserved. 433451Skarels * 542748Sbostic * %sccs.include.redist.c% 621986Sdist */ 721986Sdist 87905Ssam #ifndef lint 9*62144Sbostic static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 06/06/93"; 1034902Sbostic #endif /* not lint */ 117905Ssam 127905Ssam #include <sys/types.h> 1353698Ssklower #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 2453698Ssklower #include <arpa/inet.h> 258331Ssam #include <stdio.h> 2653698Ssklower #include <string.h> 2729746Skupfer #include <signal.h> 2854721Ssklower #include <unistd.h> 2953698Ssklower #include "netstat.h" 307905Ssam 3129746Skupfer #define YES 1 3229746Skupfer #define NO 0 3329746Skupfer 3454761Ssklower static void sidewaysintpr __P((unsigned, u_long)); 3553698Ssklower static void catchalarm __P(()); 367905Ssam 377905Ssam /* 387905Ssam * Print a description of the network interfaces. 397905Ssam */ 4053698Ssklower void 417905Ssam intpr(interval, ifnetaddr) 427905Ssam int interval; 4354761Ssklower u_long ifnetaddr; 447905Ssam { 457905Ssam struct ifnet ifnet; 4621906Skarels union { 4721906Skarels struct ifaddr ifa; 4821906Skarels struct in_ifaddr in; 4939214Smarc struct ns_ifaddr ns; 5043251Ssklower struct iso_ifaddr iso; 5121906Skarels } ifaddr; 5254761Ssklower u_long ifaddraddr; 5339214Smarc struct sockaddr *sa; 547905Ssam char name[16]; 557905Ssam 567905Ssam if (ifnetaddr == 0) { 577905Ssam printf("ifnet: symbol not defined\n"); 587905Ssam return; 597905Ssam } 607905Ssam if (interval) { 6129746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 627905Ssam return; 637905Ssam } 6453698Ssklower if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr)) 6553698Ssklower return; 6632085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 677905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 687905Ssam "Opkts", "Oerrs"); 6932085Skarels printf(" %5s", "Coll"); 707905Ssam if (tflag) 7132085Skarels printf(" %s", "Time"); 7234270Skarels if (dflag) 7334270Skarels printf(" %s", "Drop"); 747905Ssam putchar('\n'); 7521906Skarels ifaddraddr = 0; 7621906Skarels while (ifnetaddr || ifaddraddr) { 777905Ssam struct sockaddr_in *sin; 787905Ssam register char *cp; 7940839Ssklower int n, m; 807905Ssam 8121906Skarels if (ifaddraddr == 0) { 8253698Ssklower if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) || 8354761Ssklower kread((u_long)ifnet.if_name, name, 16)) 8453698Ssklower return; 8521906Skarels name[15] = '\0'; 8654761Ssklower ifnetaddr = (u_long) ifnet.if_next; 8721906Skarels if (interface != 0 && 8821906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 8921906Skarels continue; 9021906Skarels cp = index(name, '\0'); 9121906Skarels *cp++ = ifnet.if_unit + '0'; 9221906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 9321906Skarels *cp++ = '*'; 9421906Skarels *cp = '\0'; 9554761Ssklower ifaddraddr = (u_long)ifnet.if_addrlist; 9621906Skarels } 977905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 9821906Skarels if (ifaddraddr == 0) { 9932085Skarels printf("%-11.11s ", "none"); 10032085Skarels printf("%-15.15s ", "none"); 10121906Skarels } else { 10253698Ssklower if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) { 10353698Ssklower ifaddraddr = 0; 10453698Ssklower continue; 10553698Ssklower } 10639214Smarc #define CP(x) ((char *)(x)) 10739214Smarc cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 10839214Smarc CP(&ifaddr); sa = (struct sockaddr *)cp; 10939214Smarc switch (sa->sa_family) { 11021906Skarels case AF_UNSPEC: 11132085Skarels printf("%-11.11s ", "none"); 11232085Skarels printf("%-15.15s ", "none"); 11321906Skarels break; 11421906Skarels case AF_INET: 11539214Smarc sin = (struct sockaddr_in *)sa; 11621906Skarels #ifdef notdef 11721906Skarels /* can't use inet_makeaddr because kernel 11821906Skarels * keeps nets unshifted. 11921906Skarels */ 12021906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 12121906Skarels INADDR_ANY); 12253698Ssklower printf("%-11.11s ", netname(in.s_addr, 12353698Ssklower ifaddr.in.ia_subnetmask)); 12421906Skarels #else 12532085Skarels printf("%-11.11s ", 12653698Ssklower netname(htonl(ifaddr.in.ia_subnet), 12753698Ssklower ifaddr.in.ia_subnetmask)); 12821906Skarels #endif 12953698Ssklower printf("%-15.15s ", 13053698Ssklower routename(sin->sin_addr.s_addr)); 13121906Skarels break; 13223499Ssklower case AF_NS: 13323499Ssklower { 13423499Ssklower struct sockaddr_ns *sns = 13539214Smarc (struct sockaddr_ns *)sa; 13629746Skupfer u_long net; 13732085Skarels char netnum[8]; 13829746Skupfer 13927265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 14039214Smarc sprintf(netnum, "%lxH", ntohl(net)); 14132085Skarels upHex(netnum); 14232085Skarels printf("ns:%-8s ", netnum); 14353698Ssklower printf("%-15s ", 14453698Ssklower ns_phost((struct sockaddr *)sns)); 14523499Ssklower } 14623499Ssklower break; 14740839Ssklower case AF_LINK: 14840839Ssklower { 14940839Ssklower struct sockaddr_dl *sdl = 15040839Ssklower (struct sockaddr_dl *)sa; 15141185Ssklower cp = (char *)LLADDR(sdl); 15241185Ssklower n = sdl->sdl_alen; 15340839Ssklower } 15441185Ssklower m = printf("<Link>"); 15541185Ssklower goto hexprint; 15621906Skarels default: 15741185Ssklower m = printf("(%d)", sa->sa_family); 15841185Ssklower for (cp = sa->sa_len + (char *)sa; 15941185Ssklower --cp > sa->sa_data && (*cp == 0);) {} 16039214Smarc n = cp - sa->sa_data + 1; 16139214Smarc cp = sa->sa_data; 16240839Ssklower hexprint: 16341185Ssklower while (--n >= 0) 16441185Ssklower m += printf("%x%c", *cp++ & 0xff, 16541185Ssklower n > 0 ? '.' : ' '); 16641185Ssklower m = 28 - m; 16740839Ssklower while (m-- > 0) 16840839Ssklower putchar(' '); 16921906Skarels break; 17021906Skarels } 17154761Ssklower ifaddraddr = (u_long)ifaddr.ifa.ifa_next; 17221906Skarels } 17332085Skarels printf("%8d %5d %8d %5d %5d", 1747905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1757905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1767905Ssam ifnet.if_collisions); 1777905Ssam if (tflag) 17832085Skarels printf(" %3d", ifnet.if_timer); 17934270Skarels if (dflag) 18034270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1817905Ssam putchar('\n'); 1827905Ssam } 1837905Ssam } 1847905Ssam 1858331Ssam #define MAXIF 10 1868331Ssam struct iftot { 1878331Ssam char ift_name[16]; /* interface name */ 1888331Ssam int ift_ip; /* input packets */ 1898331Ssam int ift_ie; /* input errors */ 1908331Ssam int ift_op; /* output packets */ 1918331Ssam int ift_oe; /* output errors */ 1928331Ssam int ift_co; /* collisions */ 19334270Skarels int ift_dr; /* drops */ 1948331Ssam } iftot[MAXIF]; 1958331Ssam 19629746Skupfer u_char signalled; /* set if alarm goes off "early" */ 19729746Skupfer 1988331Ssam /* 1998331Ssam * Print a running summary of interface statistics. 20029746Skupfer * Repeat display every interval seconds, showing statistics 20129746Skupfer * collected over that interval. Assumes that interval is non-zero. 20229746Skupfer * First line printed at top of screen is always cumulative. 2038331Ssam */ 20453698Ssklower static void 2057905Ssam sidewaysintpr(interval, off) 20629746Skupfer unsigned interval; 20754761Ssklower u_long off; 2087905Ssam { 2097905Ssam struct ifnet ifnet; 21054761Ssklower u_long firstifnet; 2118331Ssam register struct iftot *ip, *total; 2128331Ssam register int line; 2138331Ssam struct iftot *lastif, *sum, *interesting; 21429746Skupfer int oldmask; 2157905Ssam 21654761Ssklower if (kread(off, (char *)&firstifnet, sizeof (u_long))) 21753698Ssklower return; 2188331Ssam lastif = iftot; 2198331Ssam sum = iftot + MAXIF - 1; 2208331Ssam total = sum - 1; 22117402Sedward interesting = iftot; 2228331Ssam for (off = firstifnet, ip = iftot; off;) { 2238331Ssam char *cp; 2247905Ssam 22553698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet)) 22653698Ssklower break; 2278331Ssam ip->ift_name[0] = '('; 22854761Ssklower if (kread((u_long)ifnet.if_name, ip->ift_name + 1, 15)) 22953698Ssklower break; 23017402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 23117402Sedward unit == ifnet.if_unit) 23217402Sedward interesting = ip; 2338331Ssam ip->ift_name[15] = '\0'; 2348331Ssam cp = index(ip->ift_name, '\0'); 2358331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2368331Ssam ip++; 2378331Ssam if (ip >= iftot + MAXIF - 2) 2388331Ssam break; 23954761Ssklower off = (u_long) ifnet.if_next; 2407905Ssam } 2418331Ssam lastif = ip; 24229746Skupfer 24329746Skupfer (void)signal(SIGALRM, catchalarm); 24429746Skupfer signalled = NO; 24529746Skupfer (void)alarm(interval); 2468331Ssam banner: 24734270Skarels printf(" input %-6.6s output ", interesting->ift_name); 24834270Skarels if (lastif - iftot > 0) { 24934270Skarels if (dflag) 25034270Skarels printf(" "); 25134270Skarels printf(" input (Total) output"); 25234270Skarels } 2538331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2548331Ssam ip->ift_ip = 0; 2558331Ssam ip->ift_ie = 0; 2568331Ssam ip->ift_op = 0; 2578331Ssam ip->ift_oe = 0; 2588331Ssam ip->ift_co = 0; 25934270Skarels ip->ift_dr = 0; 2608331Ssam } 2618331Ssam putchar('\n'); 26232085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2638331Ssam "packets", "errs", "packets", "errs", "colls"); 26434270Skarels if (dflag) 26534270Skarels printf("%5.5s ", "drops"); 2668331Ssam if (lastif - iftot > 0) 26734270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2688331Ssam "packets", "errs", "packets", "errs", "colls"); 26934270Skarels if (dflag) 27034270Skarels printf(" %5.5s", "drops"); 2718331Ssam putchar('\n'); 2728331Ssam fflush(stdout); 2738331Ssam line = 0; 2748331Ssam loop: 2758331Ssam sum->ift_ip = 0; 2768331Ssam sum->ift_ie = 0; 2778331Ssam sum->ift_op = 0; 2788331Ssam sum->ift_oe = 0; 2798331Ssam sum->ift_co = 0; 28034270Skarels sum->ift_dr = 0; 2818331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 28253698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet)) { 28353698Ssklower off = 0; 28453698Ssklower continue; 28553698Ssklower } 28634270Skarels if (ip == interesting) { 28734270Skarels printf("%8d %5d %8d %5d %5d", 2888331Ssam ifnet.if_ipackets - ip->ift_ip, 2898331Ssam ifnet.if_ierrors - ip->ift_ie, 2908331Ssam ifnet.if_opackets - ip->ift_op, 2918331Ssam ifnet.if_oerrors - ip->ift_oe, 2928331Ssam ifnet.if_collisions - ip->ift_co); 29334270Skarels if (dflag) 29434270Skarels printf(" %5d", 29534270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 29634270Skarels } 2978331Ssam ip->ift_ip = ifnet.if_ipackets; 2988331Ssam ip->ift_ie = ifnet.if_ierrors; 2998331Ssam ip->ift_op = ifnet.if_opackets; 3008331Ssam ip->ift_oe = ifnet.if_oerrors; 3018331Ssam ip->ift_co = ifnet.if_collisions; 30234270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 3038331Ssam sum->ift_ip += ip->ift_ip; 3048331Ssam sum->ift_ie += ip->ift_ie; 3058331Ssam sum->ift_op += ip->ift_op; 3068331Ssam sum->ift_oe += ip->ift_oe; 3078331Ssam sum->ift_co += ip->ift_co; 30834270Skarels sum->ift_dr += ip->ift_dr; 30954761Ssklower off = (u_long) ifnet.if_next; 3108331Ssam } 31134270Skarels if (lastif - iftot > 0) { 31234270Skarels printf(" %8d %5d %8d %5d %5d", 3138331Ssam sum->ift_ip - total->ift_ip, 3148331Ssam sum->ift_ie - total->ift_ie, 3158331Ssam sum->ift_op - total->ift_op, 3168331Ssam sum->ift_oe - total->ift_oe, 3178331Ssam sum->ift_co - total->ift_co); 31834270Skarels if (dflag) 31934270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 32034270Skarels } 3218331Ssam *total = *sum; 32232085Skarels putchar('\n'); 3238331Ssam fflush(stdout); 3248331Ssam line++; 32529746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 32629746Skupfer if (! signalled) { 32729746Skupfer sigpause(0); 32829746Skupfer } 32929746Skupfer sigsetmask(oldmask); 33029746Skupfer signalled = NO; 33129746Skupfer (void)alarm(interval); 3328331Ssam if (line == 21) 3338331Ssam goto banner; 3348331Ssam goto loop; 3358331Ssam /*NOTREACHED*/ 3367905Ssam } 33729746Skupfer 33829746Skupfer /* 33929746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 34029746Skupfer * Sets a flag to not wait for the alarm. 34129746Skupfer */ 34253698Ssklower static void 34329746Skupfer catchalarm() 34429746Skupfer { 34529746Skupfer signalled = YES; 34629746Skupfer } 347