121986Sdist /* 233451Skarels * 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 633451Skarels * provided that this notice is preserved and that due credit is given 733451Skarels * to the University of California at Berkeley. The name of the University 833451Skarels * may not be used to endorse or promote products derived from this 933451Skarels * software without specific prior written permission. This software 1033451Skarels * is provided ``as is'' without express or implied warranty. 1121986Sdist */ 1221986Sdist 137905Ssam #ifndef lint 14*34270Skarels static char sccsid[] = "@(#)if.c 5.7 (Berkeley) 05/14/88"; 1521986Sdist #endif not lint 167905Ssam 177905Ssam #include <sys/types.h> 187905Ssam #include <sys/socket.h> 199203Ssam 207905Ssam #include <net/if.h> 219203Ssam #include <netinet/in.h> 2221906Skarels #include <netinet/in_var.h> 2323499Ssklower #include <netns/ns.h> 249203Ssam 258331Ssam #include <stdio.h> 2629746Skupfer #include <signal.h> 277905Ssam 2829746Skupfer #define YES 1 2929746Skupfer #define NO 0 3029746Skupfer 317905Ssam extern int kmem; 327905Ssam extern int tflag; 33*34270Skarels extern int dflag; 347905Ssam extern int nflag; 3517402Sedward extern char *interface; 3617402Sedward extern int unit; 3729746Skupfer extern char *routename(), *netname(), *ns_phost(); 387905Ssam 397905Ssam /* 407905Ssam * Print a description of the network interfaces. 417905Ssam */ 427905Ssam intpr(interval, ifnetaddr) 437905Ssam int interval; 447905Ssam off_t ifnetaddr; 457905Ssam { 467905Ssam struct ifnet ifnet; 4721906Skarels union { 4821906Skarels struct ifaddr ifa; 4921906Skarels struct in_ifaddr in; 5021906Skarels } ifaddr; 5121906Skarels off_t ifaddraddr; 527905Ssam char name[16]; 537905Ssam 547905Ssam if (ifnetaddr == 0) { 557905Ssam printf("ifnet: symbol not defined\n"); 567905Ssam return; 577905Ssam } 587905Ssam if (interval) { 5929746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 607905Ssam return; 617905Ssam } 627905Ssam klseek(kmem, ifnetaddr, 0); 6329746Skupfer read(kmem, (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"); 70*34270Skarels if (dflag) 71*34270Skarels printf(" %s", "Drop"); 727905Ssam putchar('\n'); 7321906Skarels ifaddraddr = 0; 7421906Skarels while (ifnetaddr || ifaddraddr) { 757905Ssam struct sockaddr_in *sin; 767905Ssam register char *cp; 7721906Skarels int n; 787905Ssam char *index(); 7929746Skupfer struct in_addr inet_makeaddr(); 807905Ssam 8121906Skarels if (ifaddraddr == 0) { 8221906Skarels klseek(kmem, ifnetaddr, 0); 8329746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 8421906Skarels klseek(kmem, (off_t)ifnet.if_name, 0); 8521906Skarels read(kmem, name, 16); 8621906Skarels name[15] = '\0'; 8721906Skarels ifnetaddr = (off_t) ifnet.if_next; 8821906Skarels if (interface != 0 && 8921906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 9021906Skarels continue; 9121906Skarels cp = index(name, '\0'); 9221906Skarels *cp++ = ifnet.if_unit + '0'; 9321906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 9421906Skarels *cp++ = '*'; 9521906Skarels *cp = '\0'; 9621906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 9721906Skarels } 987905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 9921906Skarels if (ifaddraddr == 0) { 10032085Skarels printf("%-11.11s ", "none"); 10132085Skarels printf("%-15.15s ", "none"); 10221906Skarels } else { 10321906Skarels klseek(kmem, ifaddraddr, 0); 10429746Skupfer read(kmem, (char *)&ifaddr, sizeof ifaddr); 10521906Skarels ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 10621906Skarels switch (ifaddr.ifa.ifa_addr.sa_family) { 10721906Skarels case AF_UNSPEC: 10832085Skarels printf("%-11.11s ", "none"); 10932085Skarels printf("%-15.15s ", "none"); 11021906Skarels break; 11121906Skarels case AF_INET: 11221906Skarels sin = (struct sockaddr_in *)&ifaddr.in.ia_addr; 11321906Skarels #ifdef notdef 11421906Skarels /* can't use inet_makeaddr because kernel 11521906Skarels * keeps nets unshifted. 11621906Skarels */ 11721906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 11821906Skarels INADDR_ANY); 11932085Skarels printf("%-11.11s ", netname(in)); 12021906Skarels #else 12132085Skarels printf("%-11.11s ", 12221906Skarels netname(htonl(ifaddr.in.ia_subnet), 12321906Skarels ifaddr.in.ia_subnetmask)); 12421906Skarels #endif 12532085Skarels printf("%-15.15s ", routename(sin->sin_addr)); 12621906Skarels break; 12723499Ssklower case AF_NS: 12823499Ssklower { 12923499Ssklower struct sockaddr_ns *sns = 13023499Ssklower (struct sockaddr_ns *)&ifaddr.in.ia_addr; 13129746Skupfer u_long net; 13232085Skarels char netnum[8]; 13329746Skupfer char *ns_phost(); 13429746Skupfer 13527265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 13632085Skarels sprintf(netnum, "%lxH", ntohl(net)); 13732085Skarels upHex(netnum); 13832085Skarels printf("ns:%-8s ", netnum); 13932085Skarels printf("%-15s ", ns_phost(sns)); 14023499Ssklower } 14123499Ssklower break; 14221906Skarels default: 14321906Skarels printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family); 14421906Skarels for (cp = (char *)&ifaddr.ifa.ifa_addr + 14521906Skarels sizeof(struct sockaddr) - 1; 14621906Skarels cp >= ifaddr.ifa.ifa_addr.sa_data; --cp) 14721906Skarels if (*cp != 0) 14821906Skarels break; 14921906Skarels n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1; 15021906Skarels cp = (char *)ifaddr.ifa.ifa_addr.sa_data; 15132085Skarels if (n <= 7) 15221906Skarels while (--n) 15321906Skarels printf("%02d.", *cp++ & 0xff); 15421906Skarels else 15521906Skarels while (--n) 15621906Skarels printf("%02d", *cp++ & 0xff); 15721906Skarels printf("%02d ", *cp & 0xff); 15821906Skarels break; 15921906Skarels } 16021906Skarels } 16132085Skarels printf("%8d %5d %8d %5d %5d", 1627905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1637905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1647905Ssam ifnet.if_collisions); 1657905Ssam if (tflag) 16632085Skarels printf(" %3d", ifnet.if_timer); 167*34270Skarels if (dflag) 168*34270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1697905Ssam putchar('\n'); 1707905Ssam } 1717905Ssam } 1727905Ssam 1738331Ssam #define MAXIF 10 1748331Ssam struct iftot { 1758331Ssam char ift_name[16]; /* interface name */ 1768331Ssam int ift_ip; /* input packets */ 1778331Ssam int ift_ie; /* input errors */ 1788331Ssam int ift_op; /* output packets */ 1798331Ssam int ift_oe; /* output errors */ 1808331Ssam int ift_co; /* collisions */ 181*34270Skarels int ift_dr; /* drops */ 1828331Ssam } iftot[MAXIF]; 1838331Ssam 18429746Skupfer u_char signalled; /* set if alarm goes off "early" */ 18529746Skupfer 1868331Ssam /* 1878331Ssam * Print a running summary of interface statistics. 18829746Skupfer * Repeat display every interval seconds, showing statistics 18929746Skupfer * collected over that interval. Assumes that interval is non-zero. 19029746Skupfer * First line printed at top of screen is always cumulative. 1918331Ssam */ 1927905Ssam sidewaysintpr(interval, off) 19329746Skupfer unsigned interval; 1947905Ssam off_t off; 1957905Ssam { 1967905Ssam struct ifnet ifnet; 1978331Ssam off_t firstifnet; 1988331Ssam register struct iftot *ip, *total; 1998331Ssam register int line; 2008331Ssam struct iftot *lastif, *sum, *interesting; 20129746Skupfer int oldmask; 20229746Skupfer int catchalarm(); 2037905Ssam 2047905Ssam klseek(kmem, off, 0); 20529746Skupfer read(kmem, (char *)&firstifnet, sizeof (off_t)); 2068331Ssam lastif = iftot; 2078331Ssam sum = iftot + MAXIF - 1; 2088331Ssam total = sum - 1; 20917402Sedward interesting = iftot; 2108331Ssam for (off = firstifnet, ip = iftot; off;) { 2118331Ssam char *cp; 2127905Ssam 2137905Ssam klseek(kmem, off, 0); 21429746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 21529746Skupfer klseek(kmem, (off_t)ifnet.if_name, 0); 2168331Ssam ip->ift_name[0] = '('; 2178331Ssam read(kmem, ip->ift_name + 1, 15); 21817402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 21917402Sedward unit == ifnet.if_unit) 22017402Sedward interesting = ip; 2218331Ssam ip->ift_name[15] = '\0'; 2228331Ssam cp = index(ip->ift_name, '\0'); 2238331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2248331Ssam ip++; 2258331Ssam if (ip >= iftot + MAXIF - 2) 2268331Ssam break; 2277905Ssam off = (off_t) ifnet.if_next; 2287905Ssam } 2298331Ssam lastif = ip; 23029746Skupfer 23129746Skupfer (void)signal(SIGALRM, catchalarm); 23229746Skupfer signalled = NO; 23329746Skupfer (void)alarm(interval); 2348331Ssam banner: 235*34270Skarels printf(" input %-6.6s output ", interesting->ift_name); 236*34270Skarels if (lastif - iftot > 0) { 237*34270Skarels if (dflag) 238*34270Skarels printf(" "); 239*34270Skarels printf(" input (Total) output"); 240*34270Skarels } 2418331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2428331Ssam ip->ift_ip = 0; 2438331Ssam ip->ift_ie = 0; 2448331Ssam ip->ift_op = 0; 2458331Ssam ip->ift_oe = 0; 2468331Ssam ip->ift_co = 0; 247*34270Skarels ip->ift_dr = 0; 2488331Ssam } 2498331Ssam putchar('\n'); 25032085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2518331Ssam "packets", "errs", "packets", "errs", "colls"); 252*34270Skarels if (dflag) 253*34270Skarels printf("%5.5s ", "drops"); 2548331Ssam if (lastif - iftot > 0) 255*34270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2568331Ssam "packets", "errs", "packets", "errs", "colls"); 257*34270Skarels if (dflag) 258*34270Skarels printf(" %5.5s", "drops"); 2598331Ssam putchar('\n'); 2608331Ssam fflush(stdout); 2618331Ssam line = 0; 2628331Ssam loop: 2638331Ssam sum->ift_ip = 0; 2648331Ssam sum->ift_ie = 0; 2658331Ssam sum->ift_op = 0; 2668331Ssam sum->ift_oe = 0; 2678331Ssam sum->ift_co = 0; 268*34270Skarels sum->ift_dr = 0; 2698331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 2708331Ssam klseek(kmem, off, 0); 27129746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 272*34270Skarels if (ip == interesting) { 273*34270Skarels printf("%8d %5d %8d %5d %5d", 2748331Ssam ifnet.if_ipackets - ip->ift_ip, 2758331Ssam ifnet.if_ierrors - ip->ift_ie, 2768331Ssam ifnet.if_opackets - ip->ift_op, 2778331Ssam ifnet.if_oerrors - ip->ift_oe, 2788331Ssam ifnet.if_collisions - ip->ift_co); 279*34270Skarels if (dflag) 280*34270Skarels printf(" %5d", 281*34270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 282*34270Skarels } 2838331Ssam ip->ift_ip = ifnet.if_ipackets; 2848331Ssam ip->ift_ie = ifnet.if_ierrors; 2858331Ssam ip->ift_op = ifnet.if_opackets; 2868331Ssam ip->ift_oe = ifnet.if_oerrors; 2878331Ssam ip->ift_co = ifnet.if_collisions; 288*34270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 2898331Ssam sum->ift_ip += ip->ift_ip; 2908331Ssam sum->ift_ie += ip->ift_ie; 2918331Ssam sum->ift_op += ip->ift_op; 2928331Ssam sum->ift_oe += ip->ift_oe; 2938331Ssam sum->ift_co += ip->ift_co; 294*34270Skarels sum->ift_dr += ip->ift_dr; 2958331Ssam off = (off_t) ifnet.if_next; 2968331Ssam } 297*34270Skarels if (lastif - iftot > 0) { 298*34270Skarels printf(" %8d %5d %8d %5d %5d", 2998331Ssam sum->ift_ip - total->ift_ip, 3008331Ssam sum->ift_ie - total->ift_ie, 3018331Ssam sum->ift_op - total->ift_op, 3028331Ssam sum->ift_oe - total->ift_oe, 3038331Ssam sum->ift_co - total->ift_co); 304*34270Skarels if (dflag) 305*34270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 306*34270Skarels } 3078331Ssam *total = *sum; 30832085Skarels putchar('\n'); 3098331Ssam fflush(stdout); 3108331Ssam line++; 31129746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 31229746Skupfer if (! signalled) { 31329746Skupfer sigpause(0); 31429746Skupfer } 31529746Skupfer sigsetmask(oldmask); 31629746Skupfer signalled = NO; 31729746Skupfer (void)alarm(interval); 3188331Ssam if (line == 21) 3198331Ssam goto banner; 3208331Ssam goto loop; 3218331Ssam /*NOTREACHED*/ 3227905Ssam } 32329746Skupfer 32429746Skupfer /* 32529746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 32629746Skupfer * Sets a flag to not wait for the alarm. 32729746Skupfer */ 32829746Skupfer catchalarm() 32929746Skupfer { 33029746Skupfer signalled = YES; 33129746Skupfer } 332