19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1983, 1988, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349b50d902SRodney W. Grimes #ifndef lint 3587669425SGarrett Wollman /* 3605ddff6eSPeter Wemm static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95"; 3787669425SGarrett Wollman */ 3887669425SGarrett Wollman static const char rcsid[] = 39c3aac50fSPeter Wemm "$FreeBSD$"; 409b50d902SRodney W. Grimes #endif /* not lint */ 419b50d902SRodney W. Grimes 429b50d902SRodney W. Grimes #include <sys/types.h> 439b50d902SRodney W. Grimes #include <sys/protosw.h> 449b50d902SRodney W. Grimes #include <sys/socket.h> 450024d1dbSLuigi Rizzo #include <sys/sysctl.h> 46628d2ac1SGarrett Wollman #include <sys/time.h> 479b50d902SRodney W. Grimes 489b50d902SRodney W. Grimes #include <net/if.h> 4987669425SGarrett Wollman #include <net/if_var.h> 509b50d902SRodney W. Grimes #include <net/if_dl.h> 51f6719675SBill Fenner #include <net/if_types.h> 520024d1dbSLuigi Rizzo #include <net/bridge.h> 5375fb8770SGarrett Wollman #include <net/ethernet.h> 549b50d902SRodney W. Grimes #include <netinet/in.h> 559b50d902SRodney W. Grimes #include <netinet/in_var.h> 56cc6a66f2SJulian Elischer #include <netipx/ipx.h> 57cc6a66f2SJulian Elischer #include <netipx/ipx_if.h> 58cbc17e71SGarrett Wollman #ifdef NS 599b50d902SRodney W. Grimes #include <netns/ns.h> 609b50d902SRodney W. Grimes #include <netns/ns_if.h> 61cbc17e71SGarrett Wollman #endif 620761cb29SGarrett Wollman #ifdef ISO 639b50d902SRodney W. Grimes #include <netiso/iso.h> 649b50d902SRodney W. Grimes #include <netiso/iso_var.h> 650761cb29SGarrett Wollman #endif 669b50d902SRodney W. Grimes #include <arpa/inet.h> 679b50d902SRodney W. Grimes 689b50d902SRodney W. Grimes #include <signal.h> 699b50d902SRodney W. Grimes #include <stdio.h> 70591c194aSGuido van Rooij #include <stdlib.h> 719b50d902SRodney W. Grimes #include <string.h> 729b50d902SRodney W. Grimes #include <unistd.h> 739b50d902SRodney W. Grimes 749b50d902SRodney W. Grimes #include "netstat.h" 759b50d902SRodney W. Grimes 769b50d902SRodney W. Grimes #define YES 1 779b50d902SRodney W. Grimes #define NO 0 789b50d902SRodney W. Grimes 799b50d902SRodney W. Grimes static void sidewaysintpr __P((u_int, u_long)); 809b50d902SRodney W. Grimes static void catchalarm __P((int)); 819b50d902SRodney W. Grimes 82cfa1ca9dSYoshinobu Inoue #ifdef INET6 83cfa1ca9dSYoshinobu Inoue char *netname6 __P((struct sockaddr_in6 *, struct in6_addr *)); 84cfa1ca9dSYoshinobu Inoue static char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */ 85cfa1ca9dSYoshinobu Inoue static int bdg_done; 86cfa1ca9dSYoshinobu Inoue #endif 87cfa1ca9dSYoshinobu Inoue 880024d1dbSLuigi Rizzo void 890024d1dbSLuigi Rizzo bdg_stats(u_long dummy, char *name) /* print bridge statistics */ 900024d1dbSLuigi Rizzo { 91890bc2a5SDoug Rabson int i; 92890bc2a5SDoug Rabson size_t slen ; 930024d1dbSLuigi Rizzo struct bdg_stats s ; 940024d1dbSLuigi Rizzo int mib[4] ; 950024d1dbSLuigi Rizzo 960024d1dbSLuigi Rizzo slen = sizeof(s); 970024d1dbSLuigi Rizzo 980024d1dbSLuigi Rizzo mib[0] = CTL_NET ; 990024d1dbSLuigi Rizzo mib[1] = PF_LINK ; 1000024d1dbSLuigi Rizzo mib[2] = IFT_ETHER ; 1010024d1dbSLuigi Rizzo mib[3] = PF_BDG ; 1020024d1dbSLuigi Rizzo if (sysctl(mib,4, &s,&slen,NULL,0)==-1) 1030024d1dbSLuigi Rizzo return ; /* no bridging */ 104cfa1ca9dSYoshinobu Inoue #ifdef INET6 105cfa1ca9dSYoshinobu Inoue if (bdg_done != 0) 106cfa1ca9dSYoshinobu Inoue return; 107cfa1ca9dSYoshinobu Inoue else 108cfa1ca9dSYoshinobu Inoue bdg_done = 1; 109cfa1ca9dSYoshinobu Inoue #endif 1100024d1dbSLuigi Rizzo printf("-- Bridging statistics (%s) --\n", name) ; 1110024d1dbSLuigi Rizzo printf( 1120024d1dbSLuigi Rizzo "Name In Out Forward Drop Bcast Mcast Local Unknown\n"); 1130024d1dbSLuigi Rizzo for (i = 0 ; i < 16 ; i++) { 1140024d1dbSLuigi Rizzo if (s.s[i].name[0]) 115f41f949dSMatthew Dillon printf("%-6s %9ld%9ld%9ld%9ld%9ld%9ld%9ld%9ld\n", 1160024d1dbSLuigi Rizzo s.s[i].name, 1170024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_IN], 1180024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_OUT], 1190024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_FORWARD], 1200024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_DROP], 1210024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_BCAST], 1220024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_MCAST], 1230024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_LOCAL], 1240024d1dbSLuigi Rizzo s.s[i].p_in[(int)BDG_UNKNOWN] ); 1250024d1dbSLuigi Rizzo } 1260024d1dbSLuigi Rizzo } 1270024d1dbSLuigi Rizzo 128445f17bbSJosef Karthauser 129445f17bbSJosef Karthauser 130445f17bbSJosef Karthauser 131445f17bbSJosef Karthauser /* 132445f17bbSJosef Karthauser * Display a formatted value, or a '-' in the same space. 133445f17bbSJosef Karthauser */ 134445f17bbSJosef Karthauser void 135445f17bbSJosef Karthauser show_stat(fmt, width, value, showvalue) 136445f17bbSJosef Karthauser char *fmt; 137445f17bbSJosef Karthauser int width; 138445f17bbSJosef Karthauser u_long value; 139445f17bbSJosef Karthauser short showvalue; 140445f17bbSJosef Karthauser { 141445f17bbSJosef Karthauser char newfmt[32]; 142445f17bbSJosef Karthauser 143445f17bbSJosef Karthauser /* Construct the format string */ 144445f17bbSJosef Karthauser if (showvalue) { 145445f17bbSJosef Karthauser sprintf(newfmt, "%%%d%s", width, fmt); 146445f17bbSJosef Karthauser printf(newfmt, value); 147445f17bbSJosef Karthauser } else { 148445f17bbSJosef Karthauser sprintf(newfmt, "%%%ds", width); 149445f17bbSJosef Karthauser printf(newfmt, "-"); 150445f17bbSJosef Karthauser } 151445f17bbSJosef Karthauser } 152445f17bbSJosef Karthauser 153445f17bbSJosef Karthauser 154445f17bbSJosef Karthauser 1559b50d902SRodney W. Grimes /* 1569b50d902SRodney W. Grimes * Print a description of the network interfaces. 1579b50d902SRodney W. Grimes */ 1589b50d902SRodney W. Grimes void 159cfa1ca9dSYoshinobu Inoue intpr(interval, ifnetaddr, pfunc) 1609b50d902SRodney W. Grimes int interval; 1619b50d902SRodney W. Grimes u_long ifnetaddr; 162cfa1ca9dSYoshinobu Inoue void (*pfunc)(char *); 1639b50d902SRodney W. Grimes { 1649b50d902SRodney W. Grimes struct ifnet ifnet; 1650e27dc05SGarrett Wollman struct ifnethead ifnethead; 1669b50d902SRodney W. Grimes union { 1679b50d902SRodney W. Grimes struct ifaddr ifa; 1689b50d902SRodney W. Grimes struct in_ifaddr in; 169cfa1ca9dSYoshinobu Inoue #ifdef INET6 170cfa1ca9dSYoshinobu Inoue struct in6_ifaddr in6; 171cfa1ca9dSYoshinobu Inoue #endif 172cc6a66f2SJulian Elischer struct ipx_ifaddr ipx; 173cbc17e71SGarrett Wollman #ifdef NS 1749b50d902SRodney W. Grimes struct ns_ifaddr ns; 175cbc17e71SGarrett Wollman #endif 1760761cb29SGarrett Wollman #ifdef ISO 1779b50d902SRodney W. Grimes struct iso_ifaddr iso; 1780761cb29SGarrett Wollman #endif 1799b50d902SRodney W. Grimes } ifaddr; 1809b50d902SRodney W. Grimes u_long ifaddraddr; 181f6719675SBill Fenner u_long ifaddrfound; 182f6719675SBill Fenner u_long ifnetfound; 1835da9f8faSJosef Karthauser u_long opackets; 1845da9f8faSJosef Karthauser u_long ipackets; 1855da9f8faSJosef Karthauser u_long obytes; 1865da9f8faSJosef Karthauser u_long ibytes; 1875da9f8faSJosef Karthauser u_long oerrors; 1885da9f8faSJosef Karthauser u_long ierrors; 1895da9f8faSJosef Karthauser u_long collisions; 1905da9f8faSJosef Karthauser short timer; 1915da9f8faSJosef Karthauser int drops; 192a97a9922SJulian Elischer struct sockaddr *sa = NULL; 1931b72e71cSDavid Greenman char name[32], tname[16]; 194445f17bbSJosef Karthauser short network_layer; 195445f17bbSJosef Karthauser short link_layer; 1969b50d902SRodney W. Grimes 1979b50d902SRodney W. Grimes if (ifnetaddr == 0) { 1989b50d902SRodney W. Grimes printf("ifnet: symbol not defined\n"); 1999b50d902SRodney W. Grimes return; 2009b50d902SRodney W. Grimes } 2019b50d902SRodney W. Grimes if (interval) { 2029b50d902SRodney W. Grimes sidewaysintpr((unsigned)interval, ifnetaddr); 2039b50d902SRodney W. Grimes return; 2049b50d902SRodney W. Grimes } 2050e27dc05SGarrett Wollman if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead)) 2069b50d902SRodney W. Grimes return; 2074d51ef63SPoul-Henning Kamp ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead); 2080e27dc05SGarrett Wollman if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet)) 2090e27dc05SGarrett Wollman return; 2100e27dc05SGarrett Wollman 2113cfac2c5SJohn Polstra if ((!sflag || iflag) && !pflag) { 212cc6a66f2SJulian Elischer printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s", 213e1e293a5SDavid Greenman "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs"); 214e1e293a5SDavid Greenman if (bflag) 215e1e293a5SDavid Greenman printf(" %10.10s","Ibytes"); 216e1e293a5SDavid Greenman printf(" %8.8s %5.5s", "Opkts", "Oerrs"); 217e1e293a5SDavid Greenman if (bflag) 218e1e293a5SDavid Greenman printf(" %10.10s","Obytes"); 2199b50d902SRodney W. Grimes printf(" %5s", "Coll"); 2209b50d902SRodney W. Grimes if (tflag) 2219b50d902SRodney W. Grimes printf(" %s", "Time"); 2229b50d902SRodney W. Grimes if (dflag) 2239b50d902SRodney W. Grimes printf(" %s", "Drop"); 2249b50d902SRodney W. Grimes putchar('\n'); 225cfa1ca9dSYoshinobu Inoue } 2269b50d902SRodney W. Grimes ifaddraddr = 0; 2279b50d902SRodney W. Grimes while (ifnetaddr || ifaddraddr) { 2289b50d902SRodney W. Grimes struct sockaddr_in *sin; 229cfa1ca9dSYoshinobu Inoue #ifdef INET6 230cfa1ca9dSYoshinobu Inoue struct sockaddr_in6 *sin6; 231cfa1ca9dSYoshinobu Inoue #endif 2329b50d902SRodney W. Grimes register char *cp; 2339b50d902SRodney W. Grimes int n, m; 2349b50d902SRodney W. Grimes 235445f17bbSJosef Karthauser network_layer = 0; 236445f17bbSJosef Karthauser link_layer = 0; 237445f17bbSJosef Karthauser 2389b50d902SRodney W. Grimes if (ifaddraddr == 0) { 239f6719675SBill Fenner ifnetfound = ifnetaddr; 2409b50d902SRodney W. Grimes if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) || 2411b72e71cSDavid Greenman kread((u_long)ifnet.if_name, tname, 16)) 2429b50d902SRodney W. Grimes return; 2431b72e71cSDavid Greenman tname[15] = '\0'; 2444d51ef63SPoul-Henning Kamp ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link); 2451b72e71cSDavid Greenman snprintf(name, 32, "%s%d", tname, ifnet.if_unit); 2461b72e71cSDavid Greenman if (interface != 0 && (strcmp(name, interface) != 0)) 2479b50d902SRodney W. Grimes continue; 2489b50d902SRodney W. Grimes cp = index(name, '\0'); 249cfa1ca9dSYoshinobu Inoue 250cfa1ca9dSYoshinobu Inoue if (pfunc) { 251cfa1ca9dSYoshinobu Inoue (*pfunc)(name); 252cfa1ca9dSYoshinobu Inoue continue; 253cfa1ca9dSYoshinobu Inoue } 254cfa1ca9dSYoshinobu Inoue 2559b50d902SRodney W. Grimes if ((ifnet.if_flags&IFF_UP) == 0) 2569b50d902SRodney W. Grimes *cp++ = '*'; 2579b50d902SRodney W. Grimes *cp = '\0'; 2584d51ef63SPoul-Henning Kamp ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead); 2599b50d902SRodney W. Grimes } 2607d56c0eeSAlexander Langer printf("%-5.5s %-5lu ", name, ifnet.if_mtu); 261f6719675SBill Fenner ifaddrfound = ifaddraddr; 2625da9f8faSJosef Karthauser 2635da9f8faSJosef Karthauser /* 2645da9f8faSJosef Karthauser * Get the interface stats. These may get 2655da9f8faSJosef Karthauser * overriden below on a per-interface basis. 2665da9f8faSJosef Karthauser */ 2675da9f8faSJosef Karthauser opackets = ifnet.if_opackets; 2685da9f8faSJosef Karthauser ipackets = ifnet.if_ipackets; 2695da9f8faSJosef Karthauser obytes = ifnet.if_obytes; 2705da9f8faSJosef Karthauser ibytes = ifnet.if_ibytes; 2715da9f8faSJosef Karthauser oerrors = ifnet.if_oerrors; 2725da9f8faSJosef Karthauser ierrors = ifnet.if_ierrors; 2735da9f8faSJosef Karthauser collisions = ifnet.if_collisions; 2745da9f8faSJosef Karthauser timer = ifnet.if_timer; 2755da9f8faSJosef Karthauser drops = ifnet.if_snd.ifq_drops; 2765da9f8faSJosef Karthauser 2779b50d902SRodney W. Grimes if (ifaddraddr == 0) { 278cc6a66f2SJulian Elischer printf("%-13.13s ", "none"); 2799b50d902SRodney W. Grimes printf("%-15.15s ", "none"); 2809b50d902SRodney W. Grimes } else { 2819b50d902SRodney W. Grimes if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) { 2829b50d902SRodney W. Grimes ifaddraddr = 0; 2839b50d902SRodney W. Grimes continue; 2849b50d902SRodney W. Grimes } 2859b50d902SRodney W. Grimes #define CP(x) ((char *)(x)) 2869b50d902SRodney W. Grimes cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 287a97a9922SJulian Elischer CP(&ifaddr); 288a97a9922SJulian Elischer sa = (struct sockaddr *)cp; 2899b50d902SRodney W. Grimes switch (sa->sa_family) { 2909b50d902SRodney W. Grimes case AF_UNSPEC: 291cc6a66f2SJulian Elischer printf("%-13.13s ", "none"); 2929b50d902SRodney W. Grimes printf("%-15.15s ", "none"); 2939b50d902SRodney W. Grimes break; 2949b50d902SRodney W. Grimes case AF_INET: 2959b50d902SRodney W. Grimes sin = (struct sockaddr_in *)sa; 2969b50d902SRodney W. Grimes #ifdef notdef 2979b50d902SRodney W. Grimes /* can't use inet_makeaddr because kernel 2989b50d902SRodney W. Grimes * keeps nets unshifted. 2999b50d902SRodney W. Grimes */ 3009b50d902SRodney W. Grimes in = inet_makeaddr(ifaddr.in.ia_subnet, 3019b50d902SRodney W. Grimes INADDR_ANY); 30209a67ffaSStefan Eßer printf("%-13.13s ", netname(in.s_addr, 3039b50d902SRodney W. Grimes ifaddr.in.ia_subnetmask)); 3049b50d902SRodney W. Grimes #else 30509a67ffaSStefan Eßer printf("%-13.13s ", 3069b50d902SRodney W. Grimes netname(htonl(ifaddr.in.ia_subnet), 3079b50d902SRodney W. Grimes ifaddr.in.ia_subnetmask)); 3089b50d902SRodney W. Grimes #endif 3099b50d902SRodney W. Grimes printf("%-15.15s ", 3109b50d902SRodney W. Grimes routename(sin->sin_addr.s_addr)); 311445f17bbSJosef Karthauser 312445f17bbSJosef Karthauser network_layer = 1; 3139b50d902SRodney W. Grimes break; 314cfa1ca9dSYoshinobu Inoue #ifdef INET6 315cfa1ca9dSYoshinobu Inoue case AF_INET6: 316cfa1ca9dSYoshinobu Inoue sin6 = (struct sockaddr_in6 *)sa; 317cfa1ca9dSYoshinobu Inoue printf("%-11.11s ", 318cfa1ca9dSYoshinobu Inoue netname6(&ifaddr.in6.ia_addr, 319cfa1ca9dSYoshinobu Inoue &ifaddr.in6.ia_prefixmask.sin6_addr)); 320cfa1ca9dSYoshinobu Inoue printf("%-17.17s ", 321cfa1ca9dSYoshinobu Inoue (char *)inet_ntop(AF_INET6, 322cfa1ca9dSYoshinobu Inoue &sin6->sin6_addr, 323cfa1ca9dSYoshinobu Inoue ntop_buf, sizeof(ntop_buf))); 324445f17bbSJosef Karthauser 325445f17bbSJosef Karthauser network_layer = 1; 326cfa1ca9dSYoshinobu Inoue break; 327cfa1ca9dSYoshinobu Inoue #endif /*INET6*/ 328cc6a66f2SJulian Elischer case AF_IPX: 329cc6a66f2SJulian Elischer { 330cc6a66f2SJulian Elischer struct sockaddr_ipx *sipx = 331cc6a66f2SJulian Elischer (struct sockaddr_ipx *)sa; 332cc6a66f2SJulian Elischer u_long net; 333cc6a66f2SJulian Elischer char netnum[10]; 334cc6a66f2SJulian Elischer 335cc6a66f2SJulian Elischer *(union ipx_net *) &net = sipx->sipx_addr.x_net; 33622694ebaSBruce Evans sprintf(netnum, "%lx", (u_long)ntohl(net)); 337cc6a66f2SJulian Elischer printf("ipx:%-8s ", netnum); 338cc6a66f2SJulian Elischer /* printf("ipx:%-8s ", netname(net, 0L)); */ 339cc6a66f2SJulian Elischer printf("%-15s ", 340cc6a66f2SJulian Elischer ipx_phost((struct sockaddr *)sipx)); 341cc6a66f2SJulian Elischer } 342cc6a66f2SJulian Elischer break; 3436ffcfd6cSJulian Elischer 3446ffcfd6cSJulian Elischer case AF_APPLETALK: 345a8d37845SJulian Elischer printf("atalk:%-12.12s ",atalk_print(sa,0x10) ); 346a8d37845SJulian Elischer printf("%-9.9s ",atalk_print(sa,0x0b) ); 3476ffcfd6cSJulian Elischer break; 348cbc17e71SGarrett Wollman #ifdef NS 3499b50d902SRodney W. Grimes case AF_NS: 3509b50d902SRodney W. Grimes { 3519b50d902SRodney W. Grimes struct sockaddr_ns *sns = 3529b50d902SRodney W. Grimes (struct sockaddr_ns *)sa; 3539b50d902SRodney W. Grimes u_long net; 354cc6a66f2SJulian Elischer char netnum[10]; 3559b50d902SRodney W. Grimes 3569b50d902SRodney W. Grimes *(union ns_net *) &net = sns->sns_addr.x_net; 3579b50d902SRodney W. Grimes sprintf(netnum, "%lxH", ntohl(net)); 3589b50d902SRodney W. Grimes upHex(netnum); 3599b50d902SRodney W. Grimes printf("ns:%-8s ", netnum); 3609b50d902SRodney W. Grimes printf("%-15s ", 3619b50d902SRodney W. Grimes ns_phost((struct sockaddr *)sns)); 3629b50d902SRodney W. Grimes } 3639b50d902SRodney W. Grimes break; 364cbc17e71SGarrett Wollman #endif 3659b50d902SRodney W. Grimes case AF_LINK: 3669b50d902SRodney W. Grimes { 3679b50d902SRodney W. Grimes struct sockaddr_dl *sdl = 3689b50d902SRodney W. Grimes (struct sockaddr_dl *)sa; 369cfa1ca9dSYoshinobu Inoue char linknum[10]; 3709b50d902SRodney W. Grimes cp = (char *)LLADDR(sdl); 3719b50d902SRodney W. Grimes n = sdl->sdl_alen; 372cfa1ca9dSYoshinobu Inoue sprintf(linknum, "<Link#%d>", sdl->sdl_index); 373cfa1ca9dSYoshinobu Inoue m = printf("%-11.11s ", linknum); 3749b50d902SRodney W. Grimes } 3759b50d902SRodney W. Grimes goto hexprint; 3769b50d902SRodney W. Grimes default: 3779b50d902SRodney W. Grimes m = printf("(%d)", sa->sa_family); 3789b50d902SRodney W. Grimes for (cp = sa->sa_len + (char *)sa; 3799b50d902SRodney W. Grimes --cp > sa->sa_data && (*cp == 0);) {} 3809b50d902SRodney W. Grimes n = cp - sa->sa_data + 1; 3819b50d902SRodney W. Grimes cp = sa->sa_data; 3829b50d902SRodney W. Grimes hexprint: 3839b50d902SRodney W. Grimes while (--n >= 0) 384541f2562SDavid Greenman m += printf("%02x%c", *cp++ & 0xff, 385e54ca68cSJordan K. Hubbard n > 0 ? ':' : ' '); 386cc6a66f2SJulian Elischer m = 30 - m; 3879b50d902SRodney W. Grimes while (m-- > 0) 3889b50d902SRodney W. Grimes putchar(' '); 389445f17bbSJosef Karthauser 390445f17bbSJosef Karthauser link_layer = 1; 3919b50d902SRodney W. Grimes break; 3929b50d902SRodney W. Grimes } 3935da9f8faSJosef Karthauser 3945da9f8faSJosef Karthauser /* 3955da9f8faSJosef Karthauser * Fixup the statistics for interfaces that 3965da9f8faSJosef Karthauser * update stats for their network addresses 3975da9f8faSJosef Karthauser */ 398445f17bbSJosef Karthauser if (network_layer) { 3995da9f8faSJosef Karthauser opackets = ifaddr.in.ia_ifa.if_opackets; 4005da9f8faSJosef Karthauser ipackets = ifaddr.in.ia_ifa.if_ipackets; 4015da9f8faSJosef Karthauser obytes = ifaddr.in.ia_ifa.if_obytes; 4025da9f8faSJosef Karthauser ibytes = ifaddr.in.ia_ifa.if_ibytes; 4035da9f8faSJosef Karthauser } 4045da9f8faSJosef Karthauser 4054d51ef63SPoul-Henning Kamp ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); 4069b50d902SRodney W. Grimes } 4075da9f8faSJosef Karthauser 408445f17bbSJosef Karthauser show_stat("lu", 8, ipackets, link_layer|network_layer); 409445f17bbSJosef Karthauser printf(" "); 410445f17bbSJosef Karthauser show_stat("lu", 5, ierrors, link_layer); 411445f17bbSJosef Karthauser printf(" "); 412445f17bbSJosef Karthauser if (bflag) { 413445f17bbSJosef Karthauser show_stat("lu", 10, ibytes, link_layer|network_layer); 414445f17bbSJosef Karthauser printf(" "); 415445f17bbSJosef Karthauser } 416445f17bbSJosef Karthauser show_stat("lu", 8, opackets, link_layer|network_layer); 417445f17bbSJosef Karthauser printf(" "); 418445f17bbSJosef Karthauser show_stat("lu", 5, oerrors, link_layer); 419445f17bbSJosef Karthauser printf(" "); 420445f17bbSJosef Karthauser if (bflag) { 421445f17bbSJosef Karthauser show_stat("lu", 10, obytes, link_layer|network_layer); 422445f17bbSJosef Karthauser printf(" "); 423445f17bbSJosef Karthauser } 424445f17bbSJosef Karthauser show_stat("lu", 5, collisions, link_layer); 425445f17bbSJosef Karthauser if (tflag) { 426445f17bbSJosef Karthauser printf(" "); 427445f17bbSJosef Karthauser show_stat("d", 3, timer, link_layer); 428445f17bbSJosef Karthauser } 429445f17bbSJosef Karthauser if (dflag) { 430445f17bbSJosef Karthauser printf(" "); 431445f17bbSJosef Karthauser show_stat("d", 3, drops, link_layer); 432445f17bbSJosef Karthauser } 4339b50d902SRodney W. Grimes putchar('\n'); 434f6719675SBill Fenner if (aflag && ifaddrfound) { 435f6719675SBill Fenner /* 436f6719675SBill Fenner * Print family's multicast addresses 437f6719675SBill Fenner */ 4384d51ef63SPoul-Henning Kamp struct ifmultiaddr *multiaddr; 43975fb8770SGarrett Wollman struct ifmultiaddr ifma; 44075fb8770SGarrett Wollman union { 44175fb8770SGarrett Wollman struct sockaddr sa; 44275fb8770SGarrett Wollman struct sockaddr_in in; 443cfa1ca9dSYoshinobu Inoue #ifdef INET6 444cfa1ca9dSYoshinobu Inoue struct sockaddr_in6 in6; 445cfa1ca9dSYoshinobu Inoue #endif /* INET6 */ 44675fb8770SGarrett Wollman struct sockaddr_dl dl; 44775fb8770SGarrett Wollman } msa; 44875fb8770SGarrett Wollman const char *fmt; 449f6719675SBill Fenner 4506817526dSPoul-Henning Kamp TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) { 4514d51ef63SPoul-Henning Kamp if (kread(*(u_long *)multiaddr, (char *)&ifma, 45275fb8770SGarrett Wollman sizeof ifma)) 453f6719675SBill Fenner break; 45475fb8770SGarrett Wollman if (kread((u_long)ifma.ifma_addr, (char *)&msa, 45575fb8770SGarrett Wollman sizeof msa)) 45675fb8770SGarrett Wollman break; 45775fb8770SGarrett Wollman if (msa.sa.sa_family != sa->sa_family) 45875fb8770SGarrett Wollman continue; 45975fb8770SGarrett Wollman 46075fb8770SGarrett Wollman fmt = 0; 46175fb8770SGarrett Wollman switch (msa.sa.sa_family) { 46275fb8770SGarrett Wollman case AF_INET: 46375fb8770SGarrett Wollman fmt = routename(msa.in.sin_addr.s_addr); 46475fb8770SGarrett Wollman break; 465cfa1ca9dSYoshinobu Inoue #ifdef INET6 466cfa1ca9dSYoshinobu Inoue case AF_INET6: 467cfa1ca9dSYoshinobu Inoue printf("%23s %-19.19s(refs: %d)\n", "", 468cfa1ca9dSYoshinobu Inoue inet_ntop(AF_INET6, 469cfa1ca9dSYoshinobu Inoue &msa.in6.sin6_addr, 470cfa1ca9dSYoshinobu Inoue ntop_buf, 471cfa1ca9dSYoshinobu Inoue sizeof(ntop_buf)), 472cfa1ca9dSYoshinobu Inoue ifma.ifma_refcount); 473cfa1ca9dSYoshinobu Inoue #endif /* INET6 */ 474f6719675SBill Fenner case AF_LINK: 475f6719675SBill Fenner switch (ifnet.if_type) { 476f6719675SBill Fenner case IFT_ETHER: 47775fb8770SGarrett Wollman case IFT_FDDI: 47875fb8770SGarrett Wollman fmt = ether_ntoa( 47975fb8770SGarrett Wollman (struct ether_addr *) 48075fb8770SGarrett Wollman LLADDR(&msa.dl)); 48175fb8770SGarrett Wollman break; 482f6719675SBill Fenner } 483f6719675SBill Fenner break; 484f6719675SBill Fenner } 48575fb8770SGarrett Wollman if (fmt) 48675fb8770SGarrett Wollman printf("%23s %s\n", "", fmt); 487f6719675SBill Fenner } 488f6719675SBill Fenner } 4899b50d902SRodney W. Grimes } 4909b50d902SRodney W. Grimes } 4919b50d902SRodney W. Grimes 4929b50d902SRodney W. Grimes struct iftot { 4934d51ef63SPoul-Henning Kamp SLIST_ENTRY(iftot) chain; 4949b50d902SRodney W. Grimes char ift_name[16]; /* interface name */ 495890bc2a5SDoug Rabson u_long ift_ip; /* input packets */ 496890bc2a5SDoug Rabson u_long ift_ie; /* input errors */ 497890bc2a5SDoug Rabson u_long ift_op; /* output packets */ 498890bc2a5SDoug Rabson u_long ift_oe; /* output errors */ 499890bc2a5SDoug Rabson u_long ift_co; /* collisions */ 500e1e293a5SDavid Greenman u_int ift_dr; /* drops */ 501890bc2a5SDoug Rabson u_long ift_ib; /* input bytes */ 502890bc2a5SDoug Rabson u_long ift_ob; /* output bytes */ 503591c194aSGuido van Rooij }; 5049b50d902SRodney W. Grimes 5059b50d902SRodney W. Grimes u_char signalled; /* set if alarm goes off "early" */ 5069b50d902SRodney W. Grimes 5079b50d902SRodney W. Grimes /* 5089b50d902SRodney W. Grimes * Print a running summary of interface statistics. 5099b50d902SRodney W. Grimes * Repeat display every interval seconds, showing statistics 5109b50d902SRodney W. Grimes * collected over that interval. Assumes that interval is non-zero. 5119b50d902SRodney W. Grimes * First line printed at top of screen is always cumulative. 5120e27dc05SGarrett Wollman * XXX - should be rewritten to use ifmib(4). 5139b50d902SRodney W. Grimes */ 5149b50d902SRodney W. Grimes static void 5159b50d902SRodney W. Grimes sidewaysintpr(interval, off) 5169b50d902SRodney W. Grimes unsigned interval; 5179b50d902SRodney W. Grimes u_long off; 5189b50d902SRodney W. Grimes { 5199b50d902SRodney W. Grimes struct ifnet ifnet; 5209b50d902SRodney W. Grimes u_long firstifnet; 5210e27dc05SGarrett Wollman struct ifnethead ifnethead; 522591c194aSGuido van Rooij struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting; 5239b50d902SRodney W. Grimes register int line; 5240b87c915SDavid Greenman int oldmask, first; 5250b87c915SDavid Greenman u_long interesting_off; 5269b50d902SRodney W. Grimes 5270e27dc05SGarrett Wollman if (kread(off, (char *)&ifnethead, sizeof ifnethead)) 5289b50d902SRodney W. Grimes return; 5294d51ef63SPoul-Henning Kamp firstifnet = (u_long)TAILQ_FIRST(&ifnethead); 5300e27dc05SGarrett Wollman 531591c194aSGuido van Rooij if ((iftot = malloc(sizeof(struct iftot))) == NULL) { 532591c194aSGuido van Rooij printf("malloc failed\n"); 533591c194aSGuido van Rooij exit(1); 534591c194aSGuido van Rooij } 535591c194aSGuido van Rooij memset(iftot, 0, sizeof(struct iftot)); 536591c194aSGuido van Rooij 5370b87c915SDavid Greenman interesting = NULL; 5380b87c915SDavid Greenman interesting_off = 0; 5399b50d902SRodney W. Grimes for (off = firstifnet, ip = iftot; off;) { 5401b72e71cSDavid Greenman char name[16], tname[16]; 5419b50d902SRodney W. Grimes 5429b50d902SRodney W. Grimes if (kread(off, (char *)&ifnet, sizeof ifnet)) 5439b50d902SRodney W. Grimes break; 5441b72e71cSDavid Greenman if (kread((u_long)ifnet.if_name, tname, 16)) 5459b50d902SRodney W. Grimes break; 5461b72e71cSDavid Greenman tname[15] = '\0'; 5471b72e71cSDavid Greenman snprintf(name, 16, "%s%d", tname, ifnet.if_unit); 5480b87c915SDavid Greenman if (interface && strcmp(name, interface) == 0) { 5499b50d902SRodney W. Grimes interesting = ip; 5500b87c915SDavid Greenman interesting_off = off; 5510b87c915SDavid Greenman } 5521b72e71cSDavid Greenman snprintf(ip->ift_name, 16, "(%s)", name);; 553591c194aSGuido van Rooij if ((ipn = malloc(sizeof(struct iftot))) == NULL) { 554591c194aSGuido van Rooij printf("malloc failed\n"); 555591c194aSGuido van Rooij exit(1); 556591c194aSGuido van Rooij } 557591c194aSGuido van Rooij memset(ipn, 0, sizeof(struct iftot)); 5584d51ef63SPoul-Henning Kamp SLIST_NEXT(ip, chain) = ipn; 559591c194aSGuido van Rooij ip = ipn; 5604d51ef63SPoul-Henning Kamp off = (u_long)TAILQ_NEXT(&ifnet, if_link); 5619b50d902SRodney W. Grimes } 562591c194aSGuido van Rooij if ((total = malloc(sizeof(struct iftot))) == NULL) { 563591c194aSGuido van Rooij printf("malloc failed\n"); 564591c194aSGuido van Rooij exit(1); 565591c194aSGuido van Rooij } 566591c194aSGuido van Rooij memset(total, 0, sizeof(struct iftot)); 567591c194aSGuido van Rooij if ((sum = malloc(sizeof(struct iftot))) == NULL) { 568591c194aSGuido van Rooij printf("malloc failed\n"); 569591c194aSGuido van Rooij exit(1); 570591c194aSGuido van Rooij } 571591c194aSGuido van Rooij memset(sum, 0, sizeof(struct iftot)); 572591c194aSGuido van Rooij 5739b50d902SRodney W. Grimes 5749b50d902SRodney W. Grimes (void)signal(SIGALRM, catchalarm); 5759b50d902SRodney W. Grimes signalled = NO; 5769b50d902SRodney W. Grimes (void)alarm(interval); 5770b87c915SDavid Greenman first = 1; 5780b87c915SDavid Greenman banner: 5790b87c915SDavid Greenman printf("%17s %14s %16s", "input", 5800b87c915SDavid Greenman interesting ? interesting->ift_name : "(Total)", "output"); 5819b50d902SRodney W. Grimes putchar('\n'); 5820b87c915SDavid Greenman printf("%10s %5s %10s %10s %5s %10s %5s", 5830b87c915SDavid Greenman "packets", "errs", "bytes", "packets", "errs", "bytes", "colls"); 5849b50d902SRodney W. Grimes if (dflag) 5859b50d902SRodney W. Grimes printf(" %5.5s", "drops"); 5869b50d902SRodney W. Grimes putchar('\n'); 5879b50d902SRodney W. Grimes fflush(stdout); 5889b50d902SRodney W. Grimes line = 0; 5899b50d902SRodney W. Grimes loop: 5900b87c915SDavid Greenman if (interesting != NULL) { 5910b87c915SDavid Greenman ip = interesting; 5920b87c915SDavid Greenman if (kread(interesting_off, (char *)&ifnet, sizeof ifnet)) { 5930b87c915SDavid Greenman printf("???\n"); 5940b87c915SDavid Greenman exit(1); 5950b87c915SDavid Greenman }; 5960b87c915SDavid Greenman if (!first) { 5977d56c0eeSAlexander Langer printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu", 5980b87c915SDavid Greenman ifnet.if_ipackets - ip->ift_ip, 5990b87c915SDavid Greenman ifnet.if_ierrors - ip->ift_ie, 6000b87c915SDavid Greenman ifnet.if_ibytes - ip->ift_ib, 6010b87c915SDavid Greenman ifnet.if_opackets - ip->ift_op, 6020b87c915SDavid Greenman ifnet.if_oerrors - ip->ift_oe, 6030b87c915SDavid Greenman ifnet.if_obytes - ip->ift_ob, 6040b87c915SDavid Greenman ifnet.if_collisions - ip->ift_co); 6050b87c915SDavid Greenman if (dflag) 6060b87c915SDavid Greenman printf(" %5u", ifnet.if_snd.ifq_drops - ip->ift_dr); 6070b87c915SDavid Greenman } 6080b87c915SDavid Greenman ip->ift_ip = ifnet.if_ipackets; 6090b87c915SDavid Greenman ip->ift_ie = ifnet.if_ierrors; 6100b87c915SDavid Greenman ip->ift_ib = ifnet.if_ibytes; 6110b87c915SDavid Greenman ip->ift_op = ifnet.if_opackets; 6120b87c915SDavid Greenman ip->ift_oe = ifnet.if_oerrors; 6130b87c915SDavid Greenman ip->ift_ob = ifnet.if_obytes; 6140b87c915SDavid Greenman ip->ift_co = ifnet.if_collisions; 6150b87c915SDavid Greenman ip->ift_dr = ifnet.if_snd.ifq_drops; 6160b87c915SDavid Greenman } else { 6179b50d902SRodney W. Grimes sum->ift_ip = 0; 6189b50d902SRodney W. Grimes sum->ift_ie = 0; 6190b87c915SDavid Greenman sum->ift_ib = 0; 6209b50d902SRodney W. Grimes sum->ift_op = 0; 6219b50d902SRodney W. Grimes sum->ift_oe = 0; 6220b87c915SDavid Greenman sum->ift_ob = 0; 6239b50d902SRodney W. Grimes sum->ift_co = 0; 6249b50d902SRodney W. Grimes sum->ift_dr = 0; 6254d51ef63SPoul-Henning Kamp for (off = firstifnet, ip = iftot; 6264d51ef63SPoul-Henning Kamp off && SLIST_NEXT(ip, chain) != NULL; 6274d51ef63SPoul-Henning Kamp ip = SLIST_NEXT(ip, chain)) { 6289b50d902SRodney W. Grimes if (kread(off, (char *)&ifnet, sizeof ifnet)) { 6299b50d902SRodney W. Grimes off = 0; 6309b50d902SRodney W. Grimes continue; 6319b50d902SRodney W. Grimes } 6320b87c915SDavid Greenman sum->ift_ip += ifnet.if_ipackets; 6330b87c915SDavid Greenman sum->ift_ie += ifnet.if_ierrors; 6340b87c915SDavid Greenman sum->ift_ib += ifnet.if_ibytes; 6350b87c915SDavid Greenman sum->ift_op += ifnet.if_opackets; 6360b87c915SDavid Greenman sum->ift_oe += ifnet.if_oerrors; 6370b87c915SDavid Greenman sum->ift_ob += ifnet.if_obytes; 6380b87c915SDavid Greenman sum->ift_co += ifnet.if_collisions; 6390b87c915SDavid Greenman sum->ift_dr += ifnet.if_snd.ifq_drops; 6404d51ef63SPoul-Henning Kamp off = (u_long)TAILQ_NEXT(&ifnet, if_link); 6419b50d902SRodney W. Grimes } 6420b87c915SDavid Greenman if (!first) { 643890bc2a5SDoug Rabson printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu", 6449b50d902SRodney W. Grimes sum->ift_ip - total->ift_ip, 6450b87c915SDavid Greenman sum->ift_ie - total->ift_ie, 6460b87c915SDavid Greenman sum->ift_ib - total->ift_ib, 6479b50d902SRodney W. Grimes sum->ift_op - total->ift_op, 6480b87c915SDavid Greenman sum->ift_oe - total->ift_oe, 6490b87c915SDavid Greenman sum->ift_ob - total->ift_ob, 6500b87c915SDavid Greenman sum->ift_co - total->ift_co); 6519b50d902SRodney W. Grimes if (dflag) 6523aa80b1dSDavid Greenman printf(" %5u", sum->ift_dr - total->ift_dr); 6539b50d902SRodney W. Grimes } 6549b50d902SRodney W. Grimes *total = *sum; 6550b87c915SDavid Greenman } 6560b87c915SDavid Greenman if (!first) 6579b50d902SRodney W. Grimes putchar('\n'); 6589b50d902SRodney W. Grimes fflush(stdout); 6599b50d902SRodney W. Grimes oldmask = sigblock(sigmask(SIGALRM)); 6609b50d902SRodney W. Grimes if (! signalled) { 6619b50d902SRodney W. Grimes sigpause(0); 6629b50d902SRodney W. Grimes } 6639b50d902SRodney W. Grimes sigsetmask(oldmask); 6649b50d902SRodney W. Grimes signalled = NO; 6659b50d902SRodney W. Grimes (void)alarm(interval); 6660b87c915SDavid Greenman line++; 6670b87c915SDavid Greenman first = 0; 6689b50d902SRodney W. Grimes if (line == 21) 6699b50d902SRodney W. Grimes goto banner; 6700b87c915SDavid Greenman else 6719b50d902SRodney W. Grimes goto loop; 6729b50d902SRodney W. Grimes /*NOTREACHED*/ 6739b50d902SRodney W. Grimes } 6749b50d902SRodney W. Grimes 6759b50d902SRodney W. Grimes /* 6769b50d902SRodney W. Grimes * Called if an interval expires before sidewaysintpr has completed a loop. 6779b50d902SRodney W. Grimes * Sets a flag to not wait for the alarm. 6789b50d902SRodney W. Grimes */ 6799b50d902SRodney W. Grimes static void 6809b50d902SRodney W. Grimes catchalarm(signo) 6819b50d902SRodney W. Grimes int signo; 6829b50d902SRodney W. Grimes { 6839b50d902SRodney W. Grimes signalled = YES; 6849b50d902SRodney W. Grimes } 685