121986Sdist /* 234902Sbostic * 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 634902Sbostic * provided that the above copyright notice and this paragraph are 734902Sbostic * duplicated in all such forms and that any documentation, 834902Sbostic * advertising materials, and other materials related to such 934902Sbostic * distribution and use acknowledge that the software was developed 1034902Sbostic * by the University of California, Berkeley. The name of the 1134902Sbostic * University may not be used to endorse or promote products derived 1234902Sbostic * from this software without specific prior written permission. 1334902Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434902Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534902Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621986Sdist */ 1721986Sdist 187905Ssam #ifndef lint 19*39214Smarc static char sccsid[] = "@(#)if.c 5.10 (Berkeley) 09/25/89"; 2034902Sbostic #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> 29*39214Smarc #include <netns/ns_if.h> 309203Ssam 318331Ssam #include <stdio.h> 3229746Skupfer #include <signal.h> 337905Ssam 3429746Skupfer #define YES 1 3529746Skupfer #define NO 0 3629746Skupfer 377905Ssam extern int kmem; 387905Ssam extern int tflag; 3934270Skarels extern int dflag; 407905Ssam extern int nflag; 4117402Sedward extern char *interface; 4217402Sedward extern int unit; 4329746Skupfer extern char *routename(), *netname(), *ns_phost(); 447905Ssam 457905Ssam /* 467905Ssam * Print a description of the network interfaces. 477905Ssam */ 487905Ssam intpr(interval, ifnetaddr) 497905Ssam int interval; 507905Ssam off_t ifnetaddr; 517905Ssam { 527905Ssam struct ifnet ifnet; 5321906Skarels union { 5421906Skarels struct ifaddr ifa; 5521906Skarels struct in_ifaddr in; 56*39214Smarc struct ns_ifaddr ns; 5721906Skarels } ifaddr; 5821906Skarels off_t ifaddraddr; 59*39214Smarc struct sockaddr *sa; 607905Ssam char name[16]; 617905Ssam 627905Ssam if (ifnetaddr == 0) { 637905Ssam printf("ifnet: symbol not defined\n"); 647905Ssam return; 657905Ssam } 667905Ssam if (interval) { 6729746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 687905Ssam return; 697905Ssam } 707905Ssam klseek(kmem, ifnetaddr, 0); 7129746Skupfer read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr); 7232085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 737905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 747905Ssam "Opkts", "Oerrs"); 7532085Skarels printf(" %5s", "Coll"); 767905Ssam if (tflag) 7732085Skarels printf(" %s", "Time"); 7834270Skarels if (dflag) 7934270Skarels printf(" %s", "Drop"); 807905Ssam putchar('\n'); 8121906Skarels ifaddraddr = 0; 8221906Skarels while (ifnetaddr || ifaddraddr) { 837905Ssam struct sockaddr_in *sin; 847905Ssam register char *cp; 8521906Skarels int n; 86*39214Smarc char *index(); 87*39214Smarc struct in_addr inet_makeaddr(); 887905Ssam 8921906Skarels if (ifaddraddr == 0) { 9021906Skarels klseek(kmem, ifnetaddr, 0); 9129746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 9221906Skarels klseek(kmem, (off_t)ifnet.if_name, 0); 9321906Skarels read(kmem, name, 16); 9421906Skarels name[15] = '\0'; 9521906Skarels ifnetaddr = (off_t) ifnet.if_next; 9621906Skarels if (interface != 0 && 9721906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 9821906Skarels continue; 9921906Skarels cp = index(name, '\0'); 10021906Skarels *cp++ = ifnet.if_unit + '0'; 10121906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 10221906Skarels *cp++ = '*'; 10321906Skarels *cp = '\0'; 10421906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 10521906Skarels } 1067905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 10721906Skarels if (ifaddraddr == 0) { 10832085Skarels printf("%-11.11s ", "none"); 10932085Skarels printf("%-15.15s ", "none"); 11021906Skarels } else { 11121906Skarels klseek(kmem, ifaddraddr, 0); 11229746Skupfer read(kmem, (char *)&ifaddr, sizeof ifaddr); 113*39214Smarc #define CP(x) ((char *)(x)) 114*39214Smarc cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 115*39214Smarc CP(&ifaddr); sa = (struct sockaddr *)cp; 116*39214Smarc switch (sa->sa_family) { 11721906Skarels case AF_UNSPEC: 11832085Skarels printf("%-11.11s ", "none"); 11932085Skarels printf("%-15.15s ", "none"); 12021906Skarels break; 12121906Skarels case AF_INET: 122*39214Smarc sin = (struct sockaddr_in *)sa; 12321906Skarels #ifdef notdef 12421906Skarels /* can't use inet_makeaddr because kernel 12521906Skarels * keeps nets unshifted. 12621906Skarels */ 12721906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 12821906Skarels INADDR_ANY); 12932085Skarels printf("%-11.11s ", netname(in)); 13021906Skarels #else 13132085Skarels printf("%-11.11s ", 13221906Skarels netname(htonl(ifaddr.in.ia_subnet), 13321906Skarels ifaddr.in.ia_subnetmask)); 13421906Skarels #endif 13532085Skarels printf("%-15.15s ", routename(sin->sin_addr)); 13621906Skarels break; 13723499Ssklower case AF_NS: 13823499Ssklower { 13923499Ssklower struct sockaddr_ns *sns = 140*39214Smarc (struct sockaddr_ns *)sa; 14129746Skupfer u_long net; 14232085Skarels char netnum[8]; 14329746Skupfer char *ns_phost(); 14429746Skupfer 14527265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 146*39214Smarc sprintf(netnum, "%lxH", ntohl(net)); 14732085Skarels upHex(netnum); 14832085Skarels printf("ns:%-8s ", netnum); 14932085Skarels printf("%-15s ", ns_phost(sns)); 15023499Ssklower } 15123499Ssklower break; 15221906Skarels default: 153*39214Smarc printf("af%2d: ", sa->sa_family); 154*39214Smarc for (cp = sa->sa_data + sa->sa_len; 155*39214Smarc cp >= sa->sa_data; --cp) 15621906Skarels if (*cp != 0) 15721906Skarels break; 158*39214Smarc n = cp - sa->sa_data + 1; 159*39214Smarc cp = sa->sa_data; 16032085Skarels if (n <= 7) 16121906Skarels while (--n) 16221906Skarels printf("%02d.", *cp++ & 0xff); 16321906Skarels else 16421906Skarels while (--n) 16521906Skarels printf("%02d", *cp++ & 0xff); 16621906Skarels printf("%02d ", *cp & 0xff); 16721906Skarels break; 16821906Skarels } 169*39214Smarc ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 17021906Skarels } 17132085Skarels printf("%8d %5d %8d %5d %5d", 1727905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1737905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1747905Ssam ifnet.if_collisions); 1757905Ssam if (tflag) 17632085Skarels printf(" %3d", ifnet.if_timer); 17734270Skarels if (dflag) 17834270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1797905Ssam putchar('\n'); 1807905Ssam } 1817905Ssam } 1827905Ssam 1838331Ssam #define MAXIF 10 1848331Ssam struct iftot { 1858331Ssam char ift_name[16]; /* interface name */ 1868331Ssam int ift_ip; /* input packets */ 1878331Ssam int ift_ie; /* input errors */ 1888331Ssam int ift_op; /* output packets */ 1898331Ssam int ift_oe; /* output errors */ 1908331Ssam int ift_co; /* collisions */ 19134270Skarels int ift_dr; /* drops */ 1928331Ssam } iftot[MAXIF]; 1938331Ssam 19429746Skupfer u_char signalled; /* set if alarm goes off "early" */ 19529746Skupfer 1968331Ssam /* 1978331Ssam * Print a running summary of interface statistics. 19829746Skupfer * Repeat display every interval seconds, showing statistics 19929746Skupfer * collected over that interval. Assumes that interval is non-zero. 20029746Skupfer * First line printed at top of screen is always cumulative. 2018331Ssam */ 2027905Ssam sidewaysintpr(interval, off) 20329746Skupfer unsigned interval; 2047905Ssam off_t off; 2057905Ssam { 2067905Ssam struct ifnet ifnet; 2078331Ssam off_t firstifnet; 2088331Ssam register struct iftot *ip, *total; 2098331Ssam register int line; 2108331Ssam struct iftot *lastif, *sum, *interesting; 21129746Skupfer int oldmask; 21229746Skupfer int catchalarm(); 2137905Ssam 2147905Ssam klseek(kmem, off, 0); 21529746Skupfer read(kmem, (char *)&firstifnet, sizeof (off_t)); 2168331Ssam lastif = iftot; 2178331Ssam sum = iftot + MAXIF - 1; 2188331Ssam total = sum - 1; 21917402Sedward interesting = iftot; 2208331Ssam for (off = firstifnet, ip = iftot; off;) { 2218331Ssam char *cp; 2227905Ssam 2237905Ssam klseek(kmem, off, 0); 22429746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 22529746Skupfer klseek(kmem, (off_t)ifnet.if_name, 0); 2268331Ssam ip->ift_name[0] = '('; 2278331Ssam read(kmem, ip->ift_name + 1, 15); 22817402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 22917402Sedward unit == ifnet.if_unit) 23017402Sedward interesting = ip; 2318331Ssam ip->ift_name[15] = '\0'; 2328331Ssam cp = index(ip->ift_name, '\0'); 2338331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2348331Ssam ip++; 2358331Ssam if (ip >= iftot + MAXIF - 2) 2368331Ssam break; 2377905Ssam off = (off_t) ifnet.if_next; 2387905Ssam } 2398331Ssam lastif = ip; 24029746Skupfer 24129746Skupfer (void)signal(SIGALRM, catchalarm); 24229746Skupfer signalled = NO; 24329746Skupfer (void)alarm(interval); 2448331Ssam banner: 24534270Skarels printf(" input %-6.6s output ", interesting->ift_name); 24634270Skarels if (lastif - iftot > 0) { 24734270Skarels if (dflag) 24834270Skarels printf(" "); 24934270Skarels printf(" input (Total) output"); 25034270Skarels } 2518331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2528331Ssam ip->ift_ip = 0; 2538331Ssam ip->ift_ie = 0; 2548331Ssam ip->ift_op = 0; 2558331Ssam ip->ift_oe = 0; 2568331Ssam ip->ift_co = 0; 25734270Skarels ip->ift_dr = 0; 2588331Ssam } 2598331Ssam putchar('\n'); 26032085Skarels 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 if (lastif - iftot > 0) 26534270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2668331Ssam "packets", "errs", "packets", "errs", "colls"); 26734270Skarels if (dflag) 26834270Skarels printf(" %5.5s", "drops"); 2698331Ssam putchar('\n'); 2708331Ssam fflush(stdout); 2718331Ssam line = 0; 2728331Ssam loop: 2738331Ssam sum->ift_ip = 0; 2748331Ssam sum->ift_ie = 0; 2758331Ssam sum->ift_op = 0; 2768331Ssam sum->ift_oe = 0; 2778331Ssam sum->ift_co = 0; 27834270Skarels sum->ift_dr = 0; 2798331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 2808331Ssam klseek(kmem, off, 0); 28129746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 28234270Skarels if (ip == interesting) { 28334270Skarels printf("%8d %5d %8d %5d %5d", 2848331Ssam ifnet.if_ipackets - ip->ift_ip, 2858331Ssam ifnet.if_ierrors - ip->ift_ie, 2868331Ssam ifnet.if_opackets - ip->ift_op, 2878331Ssam ifnet.if_oerrors - ip->ift_oe, 2888331Ssam ifnet.if_collisions - ip->ift_co); 28934270Skarels if (dflag) 29034270Skarels printf(" %5d", 29134270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 29234270Skarels } 2938331Ssam ip->ift_ip = ifnet.if_ipackets; 2948331Ssam ip->ift_ie = ifnet.if_ierrors; 2958331Ssam ip->ift_op = ifnet.if_opackets; 2968331Ssam ip->ift_oe = ifnet.if_oerrors; 2978331Ssam ip->ift_co = ifnet.if_collisions; 29834270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 2998331Ssam sum->ift_ip += ip->ift_ip; 3008331Ssam sum->ift_ie += ip->ift_ie; 3018331Ssam sum->ift_op += ip->ift_op; 3028331Ssam sum->ift_oe += ip->ift_oe; 3038331Ssam sum->ift_co += ip->ift_co; 30434270Skarels sum->ift_dr += ip->ift_dr; 3058331Ssam off = (off_t) ifnet.if_next; 3068331Ssam } 30734270Skarels if (lastif - iftot > 0) { 30834270Skarels printf(" %8d %5d %8d %5d %5d", 3098331Ssam sum->ift_ip - total->ift_ip, 3108331Ssam sum->ift_ie - total->ift_ie, 3118331Ssam sum->ift_op - total->ift_op, 3128331Ssam sum->ift_oe - total->ift_oe, 3138331Ssam sum->ift_co - total->ift_co); 31434270Skarels if (dflag) 31534270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 31634270Skarels } 3178331Ssam *total = *sum; 31832085Skarels putchar('\n'); 3198331Ssam fflush(stdout); 3208331Ssam line++; 32129746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 32229746Skupfer if (! signalled) { 32329746Skupfer sigpause(0); 32429746Skupfer } 32529746Skupfer sigsetmask(oldmask); 32629746Skupfer signalled = NO; 32729746Skupfer (void)alarm(interval); 3288331Ssam if (line == 21) 3298331Ssam goto banner; 3308331Ssam goto loop; 3318331Ssam /*NOTREACHED*/ 3327905Ssam } 33329746Skupfer 33429746Skupfer /* 33529746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 33629746Skupfer * Sets a flag to not wait for the alarm. 33729746Skupfer */ 33829746Skupfer catchalarm() 33929746Skupfer { 34029746Skupfer signalled = YES; 34129746Skupfer } 342