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*41185Ssklower static char sccsid[] = "@(#)if.c 5.12 (Berkeley) 05/01/90"; 2034902Sbostic #endif /* not lint */ 217905Ssam 227905Ssam #include <sys/types.h> 237905Ssam #include <sys/socket.h> 249203Ssam 257905Ssam #include <net/if.h> 2640839Ssklower #include <net/if_dl.h> 279203Ssam #include <netinet/in.h> 2821906Skarels #include <netinet/in_var.h> 2923499Ssklower #include <netns/ns.h> 3039214Smarc #include <netns/ns_if.h> 319203Ssam 328331Ssam #include <stdio.h> 3329746Skupfer #include <signal.h> 347905Ssam 3529746Skupfer #define YES 1 3629746Skupfer #define NO 0 3729746Skupfer 387905Ssam extern int kmem; 397905Ssam extern int tflag; 4034270Skarels extern int dflag; 417905Ssam extern int nflag; 4217402Sedward extern char *interface; 4317402Sedward extern int unit; 4429746Skupfer extern char *routename(), *netname(), *ns_phost(); 457905Ssam 467905Ssam /* 477905Ssam * Print a description of the network interfaces. 487905Ssam */ 497905Ssam intpr(interval, ifnetaddr) 507905Ssam int interval; 517905Ssam off_t ifnetaddr; 527905Ssam { 537905Ssam struct ifnet ifnet; 5421906Skarels union { 5521906Skarels struct ifaddr ifa; 5621906Skarels struct in_ifaddr in; 5739214Smarc struct ns_ifaddr ns; 5821906Skarels } ifaddr; 5921906Skarels off_t ifaddraddr; 6039214Smarc struct sockaddr *sa; 617905Ssam char name[16]; 627905Ssam 637905Ssam if (ifnetaddr == 0) { 647905Ssam printf("ifnet: symbol not defined\n"); 657905Ssam return; 667905Ssam } 677905Ssam if (interval) { 6829746Skupfer sidewaysintpr((unsigned)interval, ifnetaddr); 697905Ssam return; 707905Ssam } 717905Ssam klseek(kmem, ifnetaddr, 0); 7229746Skupfer read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr); 7332085Skarels printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", 747905Ssam "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", 757905Ssam "Opkts", "Oerrs"); 7632085Skarels printf(" %5s", "Coll"); 777905Ssam if (tflag) 7832085Skarels printf(" %s", "Time"); 7934270Skarels if (dflag) 8034270Skarels printf(" %s", "Drop"); 817905Ssam putchar('\n'); 8221906Skarels ifaddraddr = 0; 8321906Skarels while (ifnetaddr || ifaddraddr) { 847905Ssam struct sockaddr_in *sin; 857905Ssam register char *cp; 8640839Ssklower int n, m; 8739214Smarc char *index(); 8839214Smarc struct in_addr inet_makeaddr(); 897905Ssam 9021906Skarels if (ifaddraddr == 0) { 9121906Skarels klseek(kmem, ifnetaddr, 0); 9229746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 9321906Skarels klseek(kmem, (off_t)ifnet.if_name, 0); 9421906Skarels read(kmem, name, 16); 9521906Skarels name[15] = '\0'; 9621906Skarels ifnetaddr = (off_t) ifnet.if_next; 9721906Skarels if (interface != 0 && 9821906Skarels (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) 9921906Skarels continue; 10021906Skarels cp = index(name, '\0'); 10121906Skarels *cp++ = ifnet.if_unit + '0'; 10221906Skarels if ((ifnet.if_flags&IFF_UP) == 0) 10321906Skarels *cp++ = '*'; 10421906Skarels *cp = '\0'; 10521906Skarels ifaddraddr = (off_t)ifnet.if_addrlist; 10621906Skarels } 1077905Ssam printf("%-5.5s %-5d ", name, ifnet.if_mtu); 10821906Skarels if (ifaddraddr == 0) { 10932085Skarels printf("%-11.11s ", "none"); 11032085Skarels printf("%-15.15s ", "none"); 11121906Skarels } else { 11221906Skarels klseek(kmem, ifaddraddr, 0); 11329746Skupfer read(kmem, (char *)&ifaddr, sizeof ifaddr); 11439214Smarc #define CP(x) ((char *)(x)) 11539214Smarc cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 11639214Smarc CP(&ifaddr); sa = (struct sockaddr *)cp; 11739214Smarc switch (sa->sa_family) { 11821906Skarels case AF_UNSPEC: 11932085Skarels printf("%-11.11s ", "none"); 12032085Skarels printf("%-15.15s ", "none"); 12121906Skarels break; 12221906Skarels case AF_INET: 12339214Smarc sin = (struct sockaddr_in *)sa; 12421906Skarels #ifdef notdef 12521906Skarels /* can't use inet_makeaddr because kernel 12621906Skarels * keeps nets unshifted. 12721906Skarels */ 12821906Skarels in = inet_makeaddr(ifaddr.in.ia_subnet, 12921906Skarels INADDR_ANY); 13032085Skarels printf("%-11.11s ", netname(in)); 13121906Skarels #else 13232085Skarels printf("%-11.11s ", 13321906Skarels netname(htonl(ifaddr.in.ia_subnet), 13421906Skarels ifaddr.in.ia_subnetmask)); 13521906Skarels #endif 13632085Skarels printf("%-15.15s ", routename(sin->sin_addr)); 13721906Skarels break; 13823499Ssklower case AF_NS: 13923499Ssklower { 14023499Ssklower struct sockaddr_ns *sns = 14139214Smarc (struct sockaddr_ns *)sa; 14229746Skupfer u_long net; 14332085Skarels char netnum[8]; 14429746Skupfer char *ns_phost(); 14529746Skupfer 14627265Skarels *(union ns_net *) &net = sns->sns_addr.x_net; 14739214Smarc sprintf(netnum, "%lxH", ntohl(net)); 14832085Skarels upHex(netnum); 14932085Skarels printf("ns:%-8s ", netnum); 15032085Skarels printf("%-15s ", ns_phost(sns)); 15123499Ssklower } 15223499Ssklower break; 15340839Ssklower case AF_LINK: 15440839Ssklower { 15540839Ssklower struct sockaddr_dl *sdl = 15640839Ssklower (struct sockaddr_dl *)sa; 157*41185Ssklower cp = (char *)LLADDR(sdl); 158*41185Ssklower n = sdl->sdl_alen; 15940839Ssklower } 160*41185Ssklower m = printf("<Link>"); 161*41185Ssklower goto hexprint; 16221906Skarels default: 163*41185Ssklower m = printf("(%d)", sa->sa_family); 164*41185Ssklower for (cp = sa->sa_len + (char *)sa; 165*41185Ssklower --cp > sa->sa_data && (*cp == 0);) {} 16639214Smarc n = cp - sa->sa_data + 1; 16739214Smarc cp = sa->sa_data; 16840839Ssklower hexprint: 169*41185Ssklower while (--n >= 0) 170*41185Ssklower m += printf("%x%c", *cp++ & 0xff, 171*41185Ssklower n > 0 ? '.' : ' '); 172*41185Ssklower m = 28 - m; 17340839Ssklower while (m-- > 0) 17440839Ssklower putchar(' '); 17521906Skarels break; 17621906Skarels } 17739214Smarc ifaddraddr = (off_t)ifaddr.ifa.ifa_next; 17821906Skarels } 17932085Skarels printf("%8d %5d %8d %5d %5d", 1807905Ssam ifnet.if_ipackets, ifnet.if_ierrors, 1817905Ssam ifnet.if_opackets, ifnet.if_oerrors, 1827905Ssam ifnet.if_collisions); 1837905Ssam if (tflag) 18432085Skarels printf(" %3d", ifnet.if_timer); 18534270Skarels if (dflag) 18634270Skarels printf(" %3d", ifnet.if_snd.ifq_drops); 1877905Ssam putchar('\n'); 1887905Ssam } 1897905Ssam } 1907905Ssam 1918331Ssam #define MAXIF 10 1928331Ssam struct iftot { 1938331Ssam char ift_name[16]; /* interface name */ 1948331Ssam int ift_ip; /* input packets */ 1958331Ssam int ift_ie; /* input errors */ 1968331Ssam int ift_op; /* output packets */ 1978331Ssam int ift_oe; /* output errors */ 1988331Ssam int ift_co; /* collisions */ 19934270Skarels int ift_dr; /* drops */ 2008331Ssam } iftot[MAXIF]; 2018331Ssam 20229746Skupfer u_char signalled; /* set if alarm goes off "early" */ 20329746Skupfer 2048331Ssam /* 2058331Ssam * Print a running summary of interface statistics. 20629746Skupfer * Repeat display every interval seconds, showing statistics 20729746Skupfer * collected over that interval. Assumes that interval is non-zero. 20829746Skupfer * First line printed at top of screen is always cumulative. 2098331Ssam */ 2107905Ssam sidewaysintpr(interval, off) 21129746Skupfer unsigned interval; 2127905Ssam off_t off; 2137905Ssam { 2147905Ssam struct ifnet ifnet; 2158331Ssam off_t firstifnet; 2168331Ssam register struct iftot *ip, *total; 2178331Ssam register int line; 2188331Ssam struct iftot *lastif, *sum, *interesting; 21929746Skupfer int oldmask; 22029746Skupfer int catchalarm(); 2217905Ssam 2227905Ssam klseek(kmem, off, 0); 22329746Skupfer read(kmem, (char *)&firstifnet, sizeof (off_t)); 2248331Ssam lastif = iftot; 2258331Ssam sum = iftot + MAXIF - 1; 2268331Ssam total = sum - 1; 22717402Sedward interesting = iftot; 2288331Ssam for (off = firstifnet, ip = iftot; off;) { 2298331Ssam char *cp; 2307905Ssam 2317905Ssam klseek(kmem, off, 0); 23229746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 23329746Skupfer klseek(kmem, (off_t)ifnet.if_name, 0); 2348331Ssam ip->ift_name[0] = '('; 2358331Ssam read(kmem, ip->ift_name + 1, 15); 23617402Sedward if (interface && strcmp(ip->ift_name + 1, interface) == 0 && 23717402Sedward unit == ifnet.if_unit) 23817402Sedward interesting = ip; 2398331Ssam ip->ift_name[15] = '\0'; 2408331Ssam cp = index(ip->ift_name, '\0'); 2418331Ssam sprintf(cp, "%d)", ifnet.if_unit); 2428331Ssam ip++; 2438331Ssam if (ip >= iftot + MAXIF - 2) 2448331Ssam break; 2457905Ssam off = (off_t) ifnet.if_next; 2467905Ssam } 2478331Ssam lastif = ip; 24829746Skupfer 24929746Skupfer (void)signal(SIGALRM, catchalarm); 25029746Skupfer signalled = NO; 25129746Skupfer (void)alarm(interval); 2528331Ssam banner: 25334270Skarels printf(" input %-6.6s output ", interesting->ift_name); 25434270Skarels if (lastif - iftot > 0) { 25534270Skarels if (dflag) 25634270Skarels printf(" "); 25734270Skarels printf(" input (Total) output"); 25834270Skarels } 2598331Ssam for (ip = iftot; ip < iftot + MAXIF; ip++) { 2608331Ssam ip->ift_ip = 0; 2618331Ssam ip->ift_ie = 0; 2628331Ssam ip->ift_op = 0; 2638331Ssam ip->ift_oe = 0; 2648331Ssam ip->ift_co = 0; 26534270Skarels ip->ift_dr = 0; 2668331Ssam } 2678331Ssam putchar('\n'); 26832085Skarels printf("%8.8s %5.5s %8.8s %5.5s %5.5s ", 2698331Ssam "packets", "errs", "packets", "errs", "colls"); 27034270Skarels if (dflag) 27134270Skarels printf("%5.5s ", "drops"); 2728331Ssam if (lastif - iftot > 0) 27334270Skarels printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 2748331Ssam "packets", "errs", "packets", "errs", "colls"); 27534270Skarels if (dflag) 27634270Skarels printf(" %5.5s", "drops"); 2778331Ssam putchar('\n'); 2788331Ssam fflush(stdout); 2798331Ssam line = 0; 2808331Ssam loop: 2818331Ssam sum->ift_ip = 0; 2828331Ssam sum->ift_ie = 0; 2838331Ssam sum->ift_op = 0; 2848331Ssam sum->ift_oe = 0; 2858331Ssam sum->ift_co = 0; 28634270Skarels sum->ift_dr = 0; 2878331Ssam for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { 2888331Ssam klseek(kmem, off, 0); 28929746Skupfer read(kmem, (char *)&ifnet, sizeof ifnet); 29034270Skarels if (ip == interesting) { 29134270Skarels printf("%8d %5d %8d %5d %5d", 2928331Ssam ifnet.if_ipackets - ip->ift_ip, 2938331Ssam ifnet.if_ierrors - ip->ift_ie, 2948331Ssam ifnet.if_opackets - ip->ift_op, 2958331Ssam ifnet.if_oerrors - ip->ift_oe, 2968331Ssam ifnet.if_collisions - ip->ift_co); 29734270Skarels if (dflag) 29834270Skarels printf(" %5d", 29934270Skarels ifnet.if_snd.ifq_drops - ip->ift_dr); 30034270Skarels } 3018331Ssam ip->ift_ip = ifnet.if_ipackets; 3028331Ssam ip->ift_ie = ifnet.if_ierrors; 3038331Ssam ip->ift_op = ifnet.if_opackets; 3048331Ssam ip->ift_oe = ifnet.if_oerrors; 3058331Ssam ip->ift_co = ifnet.if_collisions; 30634270Skarels ip->ift_dr = ifnet.if_snd.ifq_drops; 3078331Ssam sum->ift_ip += ip->ift_ip; 3088331Ssam sum->ift_ie += ip->ift_ie; 3098331Ssam sum->ift_op += ip->ift_op; 3108331Ssam sum->ift_oe += ip->ift_oe; 3118331Ssam sum->ift_co += ip->ift_co; 31234270Skarels sum->ift_dr += ip->ift_dr; 3138331Ssam off = (off_t) ifnet.if_next; 3148331Ssam } 31534270Skarels if (lastif - iftot > 0) { 31634270Skarels printf(" %8d %5d %8d %5d %5d", 3178331Ssam sum->ift_ip - total->ift_ip, 3188331Ssam sum->ift_ie - total->ift_ie, 3198331Ssam sum->ift_op - total->ift_op, 3208331Ssam sum->ift_oe - total->ift_oe, 3218331Ssam sum->ift_co - total->ift_co); 32234270Skarels if (dflag) 32334270Skarels printf(" %5d", sum->ift_dr - total->ift_dr); 32434270Skarels } 3258331Ssam *total = *sum; 32632085Skarels putchar('\n'); 3278331Ssam fflush(stdout); 3288331Ssam line++; 32929746Skupfer oldmask = sigblock(sigmask(SIGALRM)); 33029746Skupfer if (! signalled) { 33129746Skupfer sigpause(0); 33229746Skupfer } 33329746Skupfer sigsetmask(oldmask); 33429746Skupfer signalled = NO; 33529746Skupfer (void)alarm(interval); 3368331Ssam if (line == 21) 3378331Ssam goto banner; 3388331Ssam goto loop; 3398331Ssam /*NOTREACHED*/ 3407905Ssam } 34129746Skupfer 34229746Skupfer /* 34329746Skupfer * Called if an interval expires before sidewaysintpr has completed a loop. 34429746Skupfer * Sets a flag to not wait for the alarm. 34529746Skupfer */ 34629746Skupfer catchalarm() 34729746Skupfer { 34829746Skupfer signalled = YES; 34929746Skupfer } 350