121986Sdist /* 262144Sbostic * Copyright (c) 1983, 1988, 1993 362144Sbostic * The Regents of the University of California. All rights reserved. 433451Skarels * 542748Sbostic * %sccs.include.redist.c% 621986Sdist */ 721986Sdist 87905Ssam #ifndef lint 9*66219Sbostic static char sccsid[] = "@(#)if.c 8.2 (Berkeley) 02/21/94"; 1034902Sbostic #endif /* not lint */ 117905Ssam 127905Ssam #include <sys/types.h> 1353698Ssklower #include <sys/protosw.h> 147905Ssam #include <sys/socket.h> 15*66219Sbostic 167905Ssam #include <net/if.h> 1740839Ssklower #include <net/if_dl.h> 189203Ssam #include <netinet/in.h> 1921906Skarels #include <netinet/in_var.h> 2023499Ssklower #include <netns/ns.h> 2139214Smarc #include <netns/ns_if.h> 2243251Ssklower #include <netiso/iso.h> 2343251Ssklower #include <netiso/iso_var.h> 24*66219Sbostic #include <arpa/inet.h> 259203Ssam 26*66219Sbostic #include <signal.h> 278331Ssam #include <stdio.h> 2853698Ssklower #include <string.h> 2954721Ssklower #include <unistd.h> 30*66219Sbostic 3153698Ssklower #include "netstat.h" 327905Ssam 3329746Skupfer #define YES 1 3429746Skupfer #define NO 0 3529746Skupfer 36*66219Sbostic static void sidewaysintpr __P((u_int, u_long)); 37*66219Sbostic static void catchalarm __P((int)); 387905Ssam 397905Ssam /* 407905Ssam * Print a description of the network interfaces. 417905Ssam */ 4253698Ssklower void 437905Ssam intpr(interval, ifnetaddr) 447905Ssam int interval; 4554761Ssklower u_long ifnetaddr; 467905Ssam { 477905Ssam struct ifnet ifnet; 4821906Skarels union { 4921906Skarels struct ifaddr ifa; 5021906Skarels struct in_ifaddr in; 5139214Smarc struct ns_ifaddr ns; 5243251Ssklower struct iso_ifaddr iso; 5321906Skarels } ifaddr; 5454761Ssklower u_long ifaddraddr; 5539214Smarc struct sockaddr *sa; 567905Ssam char name[16]; 577905Ssam 587905Ssam if (ifnetaddr == 0) { 597905Ssam printf("ifnet: symbol not defined\n"); 607905Ssam return; 617905Ssam } 627905Ssam if (interval) { 6329746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 647905Ssam return; 657905Ssam } 6653698Ssklower if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr)) 6753698Ssklower return; 6832085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 697905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 707905Ssam "Opkts", "Oerrs"); 7132085Skarels printf(" %5s", "Coll"); 727905Ssam if (tflag) 7332085Skarels printf(" %s", "Time"); 7434270Skarels if (dflag) 7534270Skarels printf(" %s", "Drop"); 767905Ssam putchar('\n'); 7721906Skarels ifaddraddr = 0; 7821906Skarels while (ifnetaddr || ifaddraddr) { 797905Ssam struct sockaddr_in *sin; 807905Ssam register char *cp; 8140839Ssklower int n, m; 827905Ssam 8321906Skarels if (ifaddraddr == 0) { 8453698Ssklower if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) || 8554761Ssklower kread((u_long)ifnet.if_name, name, 16)) 8653698Ssklower return; 8721906Skarels name[15] = '\0'; 88*66219Sbostic ifnetaddr = (u_long)ifnet.if_next; 89*66219Sbostic if (interface != 0 && (strcmp(name, interface) != 0 || 90*66219Sbostic unit != ifnet.if_unit)) 9121906Skarels continue; 9221906Skarels cp = index(name, '\0'); 93*66219Sbostic cp += sprintf(cp, "%d", ifnet.if_unit); 9421906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 9521906Skarels *cp++ = '*'; 9621906Skarels *cp = '\0'; 9754761Ssklower ifaddraddr = (u_long)ifnet.if_addrlist; 9821906Skarels } 997905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 10021906Skarels if (ifaddraddr == 0) { 10132085Skarels printf("%-11.11s ", "none"); 10232085Skarels printf("%-15.15s ", "none"); 10321906Skarels } else { 10453698Ssklower if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) { 10553698Ssklower ifaddraddr = 0; 10653698Ssklower continue; 10753698Ssklower } 10839214Smarc #define CP(x) ((char *)(x)) 10939214Smarc cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 11039214Smarc CP(&ifaddr); sa = (struct sockaddr *)cp; 11139214Smarc switch (sa->sa_family) { 11221906Skarels case AF_UNSPEC: 11332085Skarels printf("%-11.11s ", "none"); 11432085Skarels printf("%-15.15s ", "none"); 11521906Skarels break; 11621906Skarels case AF_INET: 11739214Smarc sin = (struct sockaddr_in *)sa; 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); 12453698Ssklower printf("%-11.11s ", netname(in.s_addr, 12553698Ssklower ifaddr.in.ia_subnetmask)); 12621906Skarels #else 12732085Skarels printf("%-11.11s ", 12853698Ssklower netname(htonl(ifaddr.in.ia_subnet), 12953698Ssklower ifaddr.in.ia_subnetmask)); 13021906Skarels #endif 13153698Ssklower printf("%-15.15s ", 13253698Ssklower routename(sin->sin_addr.s_addr)); 13321906Skarels break; 13423499Ssklower case AF_NS: 13523499Ssklower { 13623499Ssklower struct sockaddr_ns *sns = 13739214Smarc (struct sockaddr_ns *)sa; 13829746Skupfer u_long net; 13932085Skarels char netnum[8]; 14029746Skupfer 14127265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 14239214Smarc sprintf(netnum, "%lxH", ntohl(net)); 14332085Skarels upHex(netnum); 14432085Skarels printf("ns:%-8s ", netnum); 14553698Ssklower printf("%-15s ", 14653698Ssklower ns_phost((struct sockaddr *)sns)); 14723499Ssklower } 14823499Ssklower break; 14940839Ssklower case AF_LINK: 15040839Ssklower { 15140839Ssklower struct sockaddr_dl *sdl = 15240839Ssklower (struct sockaddr_dl *)sa; 15341185Ssklower cp = (char *)LLADDR(sdl); 15441185Ssklower n = sdl->sdl_alen; 15540839Ssklower } 15641185Ssklower m = printf("<Link>"); 15741185Ssklower goto hexprint; 15821906Skarels default: 15941185Ssklower m = printf("(%d)", sa->sa_family); 16041185Ssklower for (cp = sa->sa_len + (char *)sa; 16141185Ssklower --cp > sa->sa_data && (*cp == 0);) {} 16239214Smarc n = cp - sa->sa_data + 1; 16339214Smarc cp = sa->sa_data; 16440839Ssklower hexprint: 16541185Ssklower while (--n >= 0) 16641185Ssklower m += printf("%x%c", *cp++ & 0xff, 16741185Ssklower n > 0 ? '.' : ' '); 16841185Ssklower m = 28 - m; 16940839Ssklower while (m-- > 0) 17040839Ssklower putchar(' '); 17121906Skarels break; 17221906Skarels } 17354761Ssklower ifaddraddr = (u_long)ifaddr.ifa.ifa_next; 17421906Skarels } 17532085Skarels printf("%8d %5d %8d %5d %5d", 1767905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1777905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1787905Ssam ifnet.if_collisions); 1797905Ssam if (tflag) 18032085Skarels printf(" %3d", ifnet.if_timer); 18134270Skarels if (dflag) 18234270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1837905Ssam putchar('\n'); 1847905Ssam } 1857905Ssam } 1867905Ssam 1878331Ssam #define MAXIF 10 1888331Ssam struct iftot { 1898331Ssam char ift_name[16]; /* interface name */ 1908331Ssam int ift_ip; /* input packets */ 1918331Ssam int ift_ie; /* input errors */ 1928331Ssam int ift_op; /* output packets */ 1938331Ssam int ift_oe; /* output errors */ 1948331Ssam int ift_co; /* collisions */ 19534270Skarels int ift_dr; /* drops */ 1968331Ssam } iftot[MAXIF]; 1978331Ssam 19829746Skupfer u_char signalled; /* set if alarm goes off "early" */ 19929746Skupfer 2008331Ssam /* 2018331Ssam * Print a running summary of interface statistics. 20229746Skupfer * Repeat display every interval seconds, showing statistics 20329746Skupfer * collected over that interval. Assumes that interval is non-zero. 20429746Skupfer * First line printed at top of screen is always cumulative. 2058331Ssam */ 20653698Ssklower static void 2077905Ssam sidewaysintpr(interval, off) 20829746Skupfer unsigned interval; 20954761Ssklower u_long off; 2107905Ssam { 2117905Ssam struct ifnet ifnet; 21254761Ssklower u_long firstifnet; 2138331Ssam register struct iftot *ip, *total; 2148331Ssam register int line; 2158331Ssam struct iftot *lastif, *sum, *interesting; 21629746Skupfer int oldmask; 2177905Ssam 21854761Ssklower if (kread(off, (char *)&firstifnet, sizeof (u_long))) 21953698Ssklower return; 2208331Ssam lastif = iftot; 2218331Ssam sum = iftot + MAXIF - 1; 2228331Ssam total = sum - 1; 22317402Sedward interesting = iftot; 2248331Ssam for (off = firstifnet, ip = iftot; off;) { 2258331Ssam char *cp; 2267905Ssam 22753698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet)) 22853698Ssklower break; 2298331Ssam ip->ift_name[0] = '('; 23054761Ssklower if (kread((u_long)ifnet.if_name, ip->ift_name + 1, 15)) 23153698Ssklower break; 23217402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 23317402Sedward unit == ifnet.if_unit) 23417402Sedward interesting = ip; 2358331Ssam ip->ift_name[15] = '\0'; 2368331Ssam cp = index(ip->ift_name, '\0'); 2378331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2388331Ssam ip++; 2398331Ssam if (ip >= iftot + MAXIF - 2) 2408331Ssam break; 24154761Ssklower off = (u_long) ifnet.if_next; 2427905Ssam } 2438331Ssam lastif = ip; 24429746Skupfer 24529746Skupfer (void)signal(SIGALRM, catchalarm); 24629746Skupfer signalled = NO; 24729746Skupfer (void)alarm(interval); 2488331Ssam banner: 24934270Skarels printf(" input %-6.6s output ", interesting->ift_name); 25034270Skarels if (lastif - iftot > 0) { 25134270Skarels if (dflag) 25234270Skarels printf(" "); 25334270Skarels printf(" input (Total) output"); 25434270Skarels } 2558331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2568331Ssam ip->ift_ip = 0; 2578331Ssam ip->ift_ie = 0; 2588331Ssam ip->ift_op = 0; 2598331Ssam ip->ift_oe = 0; 2608331Ssam ip->ift_co = 0; 26134270Skarels ip->ift_dr = 0; 2628331Ssam } 2638331Ssam putchar('\n'); 26432085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2658331Ssam "packets", "errs", "packets", "errs", "colls"); 26634270Skarels if (dflag) 26734270Skarels printf("%5.5s ", "drops"); 2688331Ssam if (lastif - iftot > 0) 26934270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2708331Ssam "packets", "errs", "packets", "errs", "colls"); 27134270Skarels if (dflag) 27234270Skarels printf(" %5.5s", "drops"); 2738331Ssam putchar('\n'); 2748331Ssam fflush(stdout); 2758331Ssam line = 0; 2768331Ssam loop: 2778331Ssam sum->ift_ip = 0; 2788331Ssam sum->ift_ie = 0; 2798331Ssam sum->ift_op = 0; 2808331Ssam sum->ift_oe = 0; 2818331Ssam sum->ift_co = 0; 28234270Skarels sum->ift_dr = 0; 2838331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 28453698Ssklower if (kread(off, (char *)&ifnet, sizeof ifnet)) { 28553698Ssklower off = 0; 28653698Ssklower continue; 28753698Ssklower } 28834270Skarels if (ip == interesting) { 28934270Skarels printf("%8d %5d %8d %5d %5d", 2908331Ssam ifnet.if_ipackets - ip->ift_ip, 2918331Ssam ifnet.if_ierrors - ip->ift_ie, 2928331Ssam ifnet.if_opackets - ip->ift_op, 2938331Ssam ifnet.if_oerrors - ip->ift_oe, 2948331Ssam ifnet.if_collisions - ip->ift_co); 29534270Skarels if (dflag) 29634270Skarels printf(" %5d", 29734270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 29834270Skarels } 2998331Ssam ip->ift_ip = ifnet.if_ipackets; 3008331Ssam ip->ift_ie = ifnet.if_ierrors; 3018331Ssam ip->ift_op = ifnet.if_opackets; 3028331Ssam ip->ift_oe = ifnet.if_oerrors; 3038331Ssam ip->ift_co = ifnet.if_collisions; 30434270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 3058331Ssam sum->ift_ip += ip->ift_ip; 3068331Ssam sum->ift_ie += ip->ift_ie; 3078331Ssam sum->ift_op += ip->ift_op; 3088331Ssam sum->ift_oe += ip->ift_oe; 3098331Ssam sum->ift_co += ip->ift_co; 31034270Skarels sum->ift_dr += ip->ift_dr; 31154761Ssklower off = (u_long) ifnet.if_next; 3128331Ssam } 31334270Skarels if (lastif - iftot > 0) { 31434270Skarels printf(" %8d %5d %8d %5d %5d", 3158331Ssam sum->ift_ip - total->ift_ip, 3168331Ssam sum->ift_ie - total->ift_ie, 3178331Ssam sum->ift_op - total->ift_op, 3188331Ssam sum->ift_oe - total->ift_oe, 3198331Ssam sum->ift_co - total->ift_co); 32034270Skarels if (dflag) 32134270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 32234270Skarels } 3238331Ssam *total = *sum; 32432085Skarels putchar('\n'); 3258331Ssam fflush(stdout); 3268331Ssam line++; 32729746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 32829746Skupfer if (! signalled) { 32929746Skupfer sigpause(0); 33029746Skupfer } 33129746Skupfer sigsetmask(oldmask); 33229746Skupfer signalled = NO; 33329746Skupfer (void)alarm(interval); 3348331Ssam if (line == 21) 3358331Ssam goto banner; 3368331Ssam goto loop; 3378331Ssam /*NOTREACHED*/ 3387905Ssam } 33929746Skupfer 34029746Skupfer /* 34129746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 34229746Skupfer * Sets a flag to not wait for the alarm. 34329746Skupfer */ 34453698Ssklower static void 345*66219Sbostic catchalarm(signo) 346*66219Sbostic int signo; 34729746Skupfer { 34829746Skupfer signalled = YES; 34929746Skupfer } 350