121986Sdist /* 221986Sdist * Copyright (c) 1983 Regents of the University of California. 321986Sdist * All rights reserved. The Berkeley software License Agreement 421986Sdist * specifies the terms and conditions for redistribution. 521986Sdist */ 621986Sdist 77905Ssam #ifndef lint 8*32085Skarels static char sccsid[] = "@(#)if.c 5.5 (Berkeley) 08/31/87"; 921986Sdist #endif not lint 107905Ssam 117905Ssam #include <sys/types.h> 127905Ssam #include <sys/socket.h> 139203Ssam 147905Ssam #include <net/if.h> 159203Ssam #include <netinet/in.h> 1621906Skarels #include <netinet/in_var.h> 1723499Ssklower #include <netns/ns.h> 189203Ssam 198331Ssam #include <stdio.h> 2029746Skupfer #include <signal.h> 217905Ssam 2229746Skupfer #define YES 1 2329746Skupfer #define NO 0 2429746Skupfer 257905Ssam extern int kmem; 267905Ssam extern int tflag; 277905Ssam extern int nflag; 2817402Sedward extern char *interface; 2917402Sedward extern int unit; 3029746Skupfer extern char *routename(), *netname(), *ns_phost(); 317905Ssam 327905Ssam /* 337905Ssam * Print a description of the network interfaces. 347905Ssam */ 357905Ssam intpr(interval, ifnetaddr) 367905Ssam int interval; 377905Ssam off_t ifnetaddr; 387905Ssam { 397905Ssam struct ifnet ifnet; 4021906Skarels union { 4121906Skarels struct ifaddr ifa; 4221906Skarels struct in_ifaddr in; 4321906Skarels } ifaddr; 4421906Skarels off_t ifaddraddr; 457905Ssam char name[16]; 467905Ssam 477905Ssam if (ifnetaddr == 0) { 487905Ssam printf("ifnet: symbol not defined\n"); 497905Ssam return; 507905Ssam } 517905Ssam if (interval) { 5229746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 537905Ssam return; 547905Ssam } 557905Ssam klseek(kmem, ifnetaddr, 0); 5629746Skupfer read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr); 57*32085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 587905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 597905Ssam "Opkts", "Oerrs"); 60*32085Skarels printf(" %5s", "Coll"); 617905Ssam if (tflag) 62*32085Skarels printf(" %s", "Time"); 637905Ssam putchar('\n'); 6421906Skarels ifaddraddr = 0; 6521906Skarels while (ifnetaddr || ifaddraddr) { 667905Ssam struct sockaddr_in *sin; 677905Ssam register char *cp; 6821906Skarels int n; 697905Ssam char *index(); 7029746Skupfer struct in_addr inet_makeaddr(); 717905Ssam 7221906Skarels if (ifaddraddr == 0) { 7321906Skarels klseek(kmem, ifnetaddr, 0); 7429746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 7521906Skarels klseek(kmem, (off_t)ifnet.if_name, 0); 7621906Skarels read(kmem, name, 16); 7721906Skarels name[15] = '\0'; 7821906Skarels ifnetaddr = (off_t) ifnet.if_next; 7921906Skarels if (interface != 0 && 8021906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 8121906Skarels continue; 8221906Skarels cp = index(name, '\0'); 8321906Skarels *cp++ = ifnet.if_unit + '0'; 8421906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 8521906Skarels *cp++ = '*'; 8621906Skarels *cp = '\0'; 8721906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 8821906Skarels } 897905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 9021906Skarels if (ifaddraddr == 0) { 91*32085Skarels printf("%-11.11s ", "none"); 92*32085Skarels printf("%-15.15s ", "none"); 9321906Skarels } else { 9421906Skarels klseek(kmem, ifaddraddr, 0); 9529746Skupfer read(kmem, (char *)&ifaddr, sizeof ifaddr); 9621906Skarels ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 9721906Skarels switch (ifaddr.ifa.ifa_addr.sa_family) { 9821906Skarels case AF_UNSPEC: 99*32085Skarels printf("%-11.11s ", "none"); 100*32085Skarels printf("%-15.15s ", "none"); 10121906Skarels break; 10221906Skarels case AF_INET: 10321906Skarels sin = (struct sockaddr_in *)&ifaddr.in.ia_addr; 10421906Skarels #ifdef notdef 10521906Skarels /* can't use inet_makeaddr because kernel 10621906Skarels * keeps nets unshifted. 10721906Skarels */ 10821906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 10921906Skarels INADDR_ANY); 110*32085Skarels printf("%-11.11s ", netname(in)); 11121906Skarels #else 112*32085Skarels printf("%-11.11s ", 11321906Skarels netname(htonl(ifaddr.in.ia_subnet), 11421906Skarels ifaddr.in.ia_subnetmask)); 11521906Skarels #endif 116*32085Skarels printf("%-15.15s ", routename(sin->sin_addr)); 11721906Skarels break; 11823499Ssklower case AF_NS: 11923499Ssklower { 12023499Ssklower struct sockaddr_ns *sns = 12123499Ssklower (struct sockaddr_ns *)&ifaddr.in.ia_addr; 12229746Skupfer u_long net; 123*32085Skarels char netnum[8]; 12429746Skupfer char *ns_phost(); 12529746Skupfer 12627265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 127*32085Skarels sprintf(netnum, "%lxH", ntohl(net)); 128*32085Skarels upHex(netnum); 129*32085Skarels printf("ns:%-8s ", netnum); 130*32085Skarels printf("%-15s ", ns_phost(sns)); 13123499Ssklower } 13223499Ssklower break; 13321906Skarels default: 13421906Skarels printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family); 13521906Skarels for (cp = (char *)&ifaddr.ifa.ifa_addr + 13621906Skarels sizeof(struct sockaddr) - 1; 13721906Skarels cp >= ifaddr.ifa.ifa_addr.sa_data; --cp) 13821906Skarels if (*cp != 0) 13921906Skarels break; 14021906Skarels n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1; 14121906Skarels cp = (char *)ifaddr.ifa.ifa_addr.sa_data; 142*32085Skarels if (n <= 7) 14321906Skarels while (--n) 14421906Skarels printf("%02d.", *cp++ & 0xff); 14521906Skarels else 14621906Skarels while (--n) 14721906Skarels printf("%02d", *cp++ & 0xff); 14821906Skarels printf("%02d ", *cp & 0xff); 14921906Skarels break; 15021906Skarels } 15121906Skarels } 152*32085Skarels printf("%8d %5d %8d %5d %5d", 1537905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1547905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1557905Ssam ifnet.if_collisions); 1567905Ssam if (tflag) 157*32085Skarels printf(" %3d", ifnet.if_timer); 1587905Ssam putchar('\n'); 1597905Ssam } 1607905Ssam } 1617905Ssam 1628331Ssam #define MAXIF 10 1638331Ssam struct iftot { 1648331Ssam char ift_name[16]; /* interface name */ 1658331Ssam int ift_ip; /* input packets */ 1668331Ssam int ift_ie; /* input errors */ 1678331Ssam int ift_op; /* output packets */ 1688331Ssam int ift_oe; /* output errors */ 1698331Ssam int ift_co; /* collisions */ 1708331Ssam } iftot[MAXIF]; 1718331Ssam 17229746Skupfer u_char signalled; /* set if alarm goes off "early" */ 17329746Skupfer 1748331Ssam /* 1758331Ssam * Print a running summary of interface statistics. 17629746Skupfer * Repeat display every interval seconds, showing statistics 17729746Skupfer * collected over that interval. Assumes that interval is non-zero. 17829746Skupfer * First line printed at top of screen is always cumulative. 1798331Ssam */ 1807905Ssam sidewaysintpr(interval, off) 18129746Skupfer unsigned interval; 1827905Ssam off_t off; 1837905Ssam { 1847905Ssam struct ifnet ifnet; 1858331Ssam off_t firstifnet; 1868331Ssam register struct iftot *ip, *total; 1878331Ssam register int line; 1888331Ssam struct iftot *lastif, *sum, *interesting; 18929746Skupfer int oldmask; 19029746Skupfer int catchalarm(); 1917905Ssam 1927905Ssam klseek(kmem, off, 0); 19329746Skupfer read(kmem, (char *)&firstifnet, sizeof (off_t)); 1948331Ssam lastif = iftot; 1958331Ssam sum = iftot + MAXIF - 1; 1968331Ssam total = sum - 1; 19717402Sedward interesting = iftot; 1988331Ssam for (off = firstifnet, ip = iftot; off;) { 1998331Ssam char *cp; 2007905Ssam 2017905Ssam klseek(kmem, off, 0); 20229746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 20329746Skupfer klseek(kmem, (off_t)ifnet.if_name, 0); 2048331Ssam ip->ift_name[0] = '('; 2058331Ssam read(kmem, ip->ift_name + 1, 15); 20617402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 20717402Sedward unit == ifnet.if_unit) 20817402Sedward interesting = ip; 2098331Ssam ip->ift_name[15] = '\0'; 2108331Ssam cp = index(ip->ift_name, '\0'); 2118331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2128331Ssam ip++; 2138331Ssam if (ip >= iftot + MAXIF - 2) 2148331Ssam break; 2157905Ssam off = (off_t) ifnet.if_next; 2167905Ssam } 2178331Ssam lastif = ip; 21829746Skupfer 21929746Skupfer (void)signal(SIGALRM, catchalarm); 22029746Skupfer signalled = NO; 22129746Skupfer (void)alarm(interval); 2228331Ssam banner: 2238331Ssam printf(" input %-6.6s output ", interesting->ift_name); 2248331Ssam if (lastif - iftot > 0) 225*32085Skarels printf(" input (Total) output"); 2268331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2278331Ssam ip->ift_ip = 0; 2288331Ssam ip->ift_ie = 0; 2298331Ssam ip->ift_op = 0; 2308331Ssam ip->ift_oe = 0; 2318331Ssam ip->ift_co = 0; 2328331Ssam } 2338331Ssam putchar('\n'); 234*32085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2358331Ssam "packets", "errs", "packets", "errs", "colls"); 2368331Ssam if (lastif - iftot > 0) 237*32085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2388331Ssam "packets", "errs", "packets", "errs", "colls"); 2398331Ssam putchar('\n'); 2408331Ssam fflush(stdout); 2418331Ssam line = 0; 2428331Ssam loop: 2438331Ssam sum->ift_ip = 0; 2448331Ssam sum->ift_ie = 0; 2458331Ssam sum->ift_op = 0; 2468331Ssam sum->ift_oe = 0; 2478331Ssam sum->ift_co = 0; 2488331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 2498331Ssam klseek(kmem, off, 0); 25029746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 2518331Ssam if (ip == interesting) 252*32085Skarels printf("%8d %5d %8d %5d %5d ", 2538331Ssam ifnet.if_ipackets - ip->ift_ip, 2548331Ssam ifnet.if_ierrors - ip->ift_ie, 2558331Ssam ifnet.if_opackets - ip->ift_op, 2568331Ssam ifnet.if_oerrors - ip->ift_oe, 2578331Ssam ifnet.if_collisions - ip->ift_co); 2588331Ssam ip->ift_ip = ifnet.if_ipackets; 2598331Ssam ip->ift_ie = ifnet.if_ierrors; 2608331Ssam ip->ift_op = ifnet.if_opackets; 2618331Ssam ip->ift_oe = ifnet.if_oerrors; 2628331Ssam ip->ift_co = ifnet.if_collisions; 2638331Ssam sum->ift_ip += ip->ift_ip; 2648331Ssam sum->ift_ie += ip->ift_ie; 2658331Ssam sum->ift_op += ip->ift_op; 2668331Ssam sum->ift_oe += ip->ift_oe; 2678331Ssam sum->ift_co += ip->ift_co; 2688331Ssam off = (off_t) ifnet.if_next; 2698331Ssam } 2708331Ssam if (lastif - iftot > 0) 271*32085Skarels printf("%8d %5d %8d %5d %5d ", 2728331Ssam sum->ift_ip - total->ift_ip, 2738331Ssam sum->ift_ie - total->ift_ie, 2748331Ssam sum->ift_op - total->ift_op, 2758331Ssam sum->ift_oe - total->ift_oe, 2768331Ssam sum->ift_co - total->ift_co); 2778331Ssam *total = *sum; 278*32085Skarels putchar('\n'); 2798331Ssam fflush(stdout); 2808331Ssam line++; 28129746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 28229746Skupfer if (! signalled) { 28329746Skupfer sigpause(0); 28429746Skupfer } 28529746Skupfer sigsetmask(oldmask); 28629746Skupfer signalled = NO; 28729746Skupfer (void)alarm(interval); 2888331Ssam if (line == 21) 2898331Ssam goto banner; 2908331Ssam goto loop; 2918331Ssam /*NOTREACHED*/ 2927905Ssam } 29329746Skupfer 29429746Skupfer /* 29529746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 29629746Skupfer * Sets a flag to not wait for the alarm. 29729746Skupfer */ 29829746Skupfer catchalarm() 29929746Skupfer { 30029746Skupfer signalled = YES; 30129746Skupfer } 302