121986Sdist /* 2*33451Skarels * Copyright (c) 1983,1988 Regents of the University of California. 3*33451Skarels * All rights reserved. 4*33451Skarels * 5*33451Skarels * Redistribution and use in source and binary forms are permitted 6*33451Skarels * provided that this notice is preserved and that due credit is given 7*33451Skarels * to the University of California at Berkeley. The name of the University 8*33451Skarels * may not be used to endorse or promote products derived from this 9*33451Skarels * software without specific prior written permission. This software 10*33451Skarels * is provided ``as is'' without express or implied warranty. 1121986Sdist */ 1221986Sdist 137905Ssam #ifndef lint 14*33451Skarels static char sccsid[] = "@(#)if.c 5.6 (Berkeley) 02/07/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; 337905Ssam extern int nflag; 3417402Sedward extern char *interface; 3517402Sedward extern int unit; 3629746Skupfer extern char *routename(), *netname(), *ns_phost(); 377905Ssam 387905Ssam /* 397905Ssam * Print a description of the network interfaces. 407905Ssam */ 417905Ssam intpr(interval, ifnetaddr) 427905Ssam int interval; 437905Ssam off_t ifnetaddr; 447905Ssam { 457905Ssam struct ifnet ifnet; 4621906Skarels union { 4721906Skarels struct ifaddr ifa; 4821906Skarels struct in_ifaddr in; 4921906Skarels } ifaddr; 5021906Skarels off_t ifaddraddr; 517905Ssam char name[16]; 527905Ssam 537905Ssam if (ifnetaddr == 0) { 547905Ssam printf("ifnet: symbol not defined\n"); 557905Ssam return; 567905Ssam } 577905Ssam if (interval) { 5829746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 597905Ssam return; 607905Ssam } 617905Ssam klseek(kmem, ifnetaddr, 0); 6229746Skupfer read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr); 6332085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 647905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 657905Ssam "Opkts", "Oerrs"); 6632085Skarels printf(" %5s", "Coll"); 677905Ssam if (tflag) 6832085Skarels printf(" %s", "Time"); 697905Ssam putchar('\n'); 7021906Skarels ifaddraddr = 0; 7121906Skarels while (ifnetaddr || ifaddraddr) { 727905Ssam struct sockaddr_in *sin; 737905Ssam register char *cp; 7421906Skarels int n; 757905Ssam char *index(); 7629746Skupfer struct in_addr inet_makeaddr(); 777905Ssam 7821906Skarels if (ifaddraddr == 0) { 7921906Skarels klseek(kmem, ifnetaddr, 0); 8029746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 8121906Skarels klseek(kmem, (off_t)ifnet.if_name, 0); 8221906Skarels read(kmem, name, 16); 8321906Skarels name[15] = '\0'; 8421906Skarels ifnetaddr = (off_t) ifnet.if_next; 8521906Skarels if (interface != 0 && 8621906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 8721906Skarels continue; 8821906Skarels cp = index(name, '\0'); 8921906Skarels *cp++ = ifnet.if_unit + '0'; 9021906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 9121906Skarels *cp++ = '*'; 9221906Skarels *cp = '\0'; 9321906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 9421906Skarels } 957905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 9621906Skarels if (ifaddraddr == 0) { 9732085Skarels printf("%-11.11s ", "none"); 9832085Skarels printf("%-15.15s ", "none"); 9921906Skarels } else { 10021906Skarels klseek(kmem, ifaddraddr, 0); 10129746Skupfer read(kmem, (char *)&ifaddr, sizeof ifaddr); 10221906Skarels ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 10321906Skarels switch (ifaddr.ifa.ifa_addr.sa_family) { 10421906Skarels case AF_UNSPEC: 10532085Skarels printf("%-11.11s ", "none"); 10632085Skarels printf("%-15.15s ", "none"); 10721906Skarels break; 10821906Skarels case AF_INET: 10921906Skarels sin = (struct sockaddr_in *)&ifaddr.in.ia_addr; 11021906Skarels #ifdef notdef 11121906Skarels /* can't use inet_makeaddr because kernel 11221906Skarels * keeps nets unshifted. 11321906Skarels */ 11421906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 11521906Skarels INADDR_ANY); 11632085Skarels printf("%-11.11s ", netname(in)); 11721906Skarels #else 11832085Skarels printf("%-11.11s ", 11921906Skarels netname(htonl(ifaddr.in.ia_subnet), 12021906Skarels ifaddr.in.ia_subnetmask)); 12121906Skarels #endif 12232085Skarels printf("%-15.15s ", routename(sin->sin_addr)); 12321906Skarels break; 12423499Ssklower case AF_NS: 12523499Ssklower { 12623499Ssklower struct sockaddr_ns *sns = 12723499Ssklower (struct sockaddr_ns *)&ifaddr.in.ia_addr; 12829746Skupfer u_long net; 12932085Skarels char netnum[8]; 13029746Skupfer char *ns_phost(); 13129746Skupfer 13227265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 13332085Skarels sprintf(netnum, "%lxH", ntohl(net)); 13432085Skarels upHex(netnum); 13532085Skarels printf("ns:%-8s ", netnum); 13632085Skarels printf("%-15s ", ns_phost(sns)); 13723499Ssklower } 13823499Ssklower break; 13921906Skarels default: 14021906Skarels printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family); 14121906Skarels for (cp = (char *)&ifaddr.ifa.ifa_addr + 14221906Skarels sizeof(struct sockaddr) - 1; 14321906Skarels cp >= ifaddr.ifa.ifa_addr.sa_data; --cp) 14421906Skarels if (*cp != 0) 14521906Skarels break; 14621906Skarels n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1; 14721906Skarels cp = (char *)ifaddr.ifa.ifa_addr.sa_data; 14832085Skarels if (n <= 7) 14921906Skarels while (--n) 15021906Skarels printf("%02d.", *cp++ & 0xff); 15121906Skarels else 15221906Skarels while (--n) 15321906Skarels printf("%02d", *cp++ & 0xff); 15421906Skarels printf("%02d ", *cp & 0xff); 15521906Skarels break; 15621906Skarels } 15721906Skarels } 15832085Skarels printf("%8d %5d %8d %5d %5d", 1597905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1607905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1617905Ssam ifnet.if_collisions); 1627905Ssam if (tflag) 16332085Skarels printf(" %3d", ifnet.if_timer); 1647905Ssam putchar('\n'); 1657905Ssam } 1667905Ssam } 1677905Ssam 1688331Ssam #define MAXIF 10 1698331Ssam struct iftot { 1708331Ssam char ift_name[16]; /* interface name */ 1718331Ssam int ift_ip; /* input packets */ 1728331Ssam int ift_ie; /* input errors */ 1738331Ssam int ift_op; /* output packets */ 1748331Ssam int ift_oe; /* output errors */ 1758331Ssam int ift_co; /* collisions */ 1768331Ssam } iftot[MAXIF]; 1778331Ssam 17829746Skupfer u_char signalled; /* set if alarm goes off "early" */ 17929746Skupfer 1808331Ssam /* 1818331Ssam * Print a running summary of interface statistics. 18229746Skupfer * Repeat display every interval seconds, showing statistics 18329746Skupfer * collected over that interval. Assumes that interval is non-zero. 18429746Skupfer * First line printed at top of screen is always cumulative. 1858331Ssam */ 1867905Ssam sidewaysintpr(interval, off) 18729746Skupfer unsigned interval; 1887905Ssam off_t off; 1897905Ssam { 1907905Ssam struct ifnet ifnet; 1918331Ssam off_t firstifnet; 1928331Ssam register struct iftot *ip, *total; 1938331Ssam register int line; 1948331Ssam struct iftot *lastif, *sum, *interesting; 19529746Skupfer int oldmask; 19629746Skupfer int catchalarm(); 1977905Ssam 1987905Ssam klseek(kmem, off, 0); 19929746Skupfer read(kmem, (char *)&firstifnet, sizeof (off_t)); 2008331Ssam lastif = iftot; 2018331Ssam sum = iftot + MAXIF - 1; 2028331Ssam total = sum - 1; 20317402Sedward interesting = iftot; 2048331Ssam for (off = firstifnet, ip = iftot; off;) { 2058331Ssam char *cp; 2067905Ssam 2077905Ssam klseek(kmem, off, 0); 20829746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 20929746Skupfer klseek(kmem, (off_t)ifnet.if_name, 0); 2108331Ssam ip->ift_name[0] = '('; 2118331Ssam read(kmem, ip->ift_name + 1, 15); 21217402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 21317402Sedward unit == ifnet.if_unit) 21417402Sedward interesting = ip; 2158331Ssam ip->ift_name[15] = '\0'; 2168331Ssam cp = index(ip->ift_name, '\0'); 2178331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2188331Ssam ip++; 2198331Ssam if (ip >= iftot + MAXIF - 2) 2208331Ssam break; 2217905Ssam off = (off_t) ifnet.if_next; 2227905Ssam } 2238331Ssam lastif = ip; 22429746Skupfer 22529746Skupfer (void)signal(SIGALRM, catchalarm); 22629746Skupfer signalled = NO; 22729746Skupfer (void)alarm(interval); 2288331Ssam banner: 2298331Ssam printf(" input %-6.6s output ", interesting->ift_name); 2308331Ssam if (lastif - iftot > 0) 23132085Skarels printf(" input (Total) output"); 2328331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2338331Ssam ip->ift_ip = 0; 2348331Ssam ip->ift_ie = 0; 2358331Ssam ip->ift_op = 0; 2368331Ssam ip->ift_oe = 0; 2378331Ssam ip->ift_co = 0; 2388331Ssam } 2398331Ssam putchar('\n'); 24032085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2418331Ssam "packets", "errs", "packets", "errs", "colls"); 2428331Ssam if (lastif - iftot > 0) 24332085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2448331Ssam "packets", "errs", "packets", "errs", "colls"); 2458331Ssam putchar('\n'); 2468331Ssam fflush(stdout); 2478331Ssam line = 0; 2488331Ssam loop: 2498331Ssam sum->ift_ip = 0; 2508331Ssam sum->ift_ie = 0; 2518331Ssam sum->ift_op = 0; 2528331Ssam sum->ift_oe = 0; 2538331Ssam sum->ift_co = 0; 2548331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 2558331Ssam klseek(kmem, off, 0); 25629746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 2578331Ssam if (ip == interesting) 25832085Skarels printf("%8d %5d %8d %5d %5d ", 2598331Ssam ifnet.if_ipackets - ip->ift_ip, 2608331Ssam ifnet.if_ierrors - ip->ift_ie, 2618331Ssam ifnet.if_opackets - ip->ift_op, 2628331Ssam ifnet.if_oerrors - ip->ift_oe, 2638331Ssam ifnet.if_collisions - ip->ift_co); 2648331Ssam ip->ift_ip = ifnet.if_ipackets; 2658331Ssam ip->ift_ie = ifnet.if_ierrors; 2668331Ssam ip->ift_op = ifnet.if_opackets; 2678331Ssam ip->ift_oe = ifnet.if_oerrors; 2688331Ssam ip->ift_co = ifnet.if_collisions; 2698331Ssam sum->ift_ip += ip->ift_ip; 2708331Ssam sum->ift_ie += ip->ift_ie; 2718331Ssam sum->ift_op += ip->ift_op; 2728331Ssam sum->ift_oe += ip->ift_oe; 2738331Ssam sum->ift_co += ip->ift_co; 2748331Ssam off = (off_t) ifnet.if_next; 2758331Ssam } 2768331Ssam if (lastif - iftot > 0) 27732085Skarels printf("%8d %5d %8d %5d %5d ", 2788331Ssam sum->ift_ip - total->ift_ip, 2798331Ssam sum->ift_ie - total->ift_ie, 2808331Ssam sum->ift_op - total->ift_op, 2818331Ssam sum->ift_oe - total->ift_oe, 2828331Ssam sum->ift_co - total->ift_co); 2838331Ssam *total = *sum; 28432085Skarels putchar('\n'); 2858331Ssam fflush(stdout); 2868331Ssam line++; 28729746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 28829746Skupfer if (! signalled) { 28929746Skupfer sigpause(0); 29029746Skupfer } 29129746Skupfer sigsetmask(oldmask); 29229746Skupfer signalled = NO; 29329746Skupfer (void)alarm(interval); 2948331Ssam if (line == 21) 2958331Ssam goto banner; 2968331Ssam goto loop; 2978331Ssam /*NOTREACHED*/ 2987905Ssam } 29929746Skupfer 30029746Skupfer /* 30129746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 30229746Skupfer * Sets a flag to not wait for the alarm. 30329746Skupfer */ 30429746Skupfer catchalarm() 30529746Skupfer { 30629746Skupfer signalled = YES; 30729746Skupfer } 308