Date: Sun, 10 Jul 2005 06:50:12 GMT From: soc-anders <soc-anders@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 79896 for review Message-ID: <200507100650.j6A6oCXF034652@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=79896 Change 79896 by soc-anders@soc-anders_gimli on 2005/07/10 06:49:17 Interface information now exclusivly uses sysctl to obtain information and if_var.h references have been removed. Certain Issues remain: * No watchdog timer information is available (drop -t?) * Per address if_data information is not available * Multicast address are not displayed Affected files ... .. //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#3 edit Differences ... ==== //depot/projects/soc2005/ifcleanup/src/src/usr.bin/netstat/if.c#3 (text+ko) ==== @@ -47,15 +47,14 @@ #include <sys/time.h> #include <net/if.h> -#include <net/if_var.h> #include <net/if_dl.h> #include <net/if_types.h> #include <net/bridge.h> #include <net/ethernet.h> #include <netinet/in.h> -#include <netinet/in_var.h> +/*#include <netinet/in_var.h>*/ #include <netipx/ipx.h> -#include <netipx/ipx_if.h> +/*#include <netipx/ipx_if.h>*/ #include <arpa/inet.h> #include <signal.h> @@ -68,6 +67,7 @@ #ifdef IFCLEANUP #include <net/if_mib.h> +#include <net/route.h> #endif #include "netstat.h" @@ -153,19 +153,6 @@ void intpr(int _interval, u_long ifnetaddr, void (*pfunc)(char *)) { - struct ifnet ifnet; - struct ifnethead ifnethead; - union { - struct ifaddr ifa; - struct in_ifaddr in; -#ifdef INET6 - struct in6_ifaddr in6; -#endif - struct ipx_ifaddr ipx; - } ifaddr; - u_long ifaddraddr; - u_long ifaddrfound; - u_long ifnetfound; u_long opackets; u_long ipackets; u_long obytes; @@ -175,27 +162,36 @@ u_long oerrors; u_long ierrors; u_long collisions; - short timer; - int drops; + /* short timer; */ + u_long drops; struct sockaddr *sa = NULL; char name[IFNAMSIZ]; short network_layer; short link_layer; + int mib[6] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; + size_t len; + char *buf, *cur, *end; + struct if_msghdr *ifm; + struct ifa_msghdr *ifam; + struct sockaddr *addr, *mask, *brd; + u_long mtu; + if (_interval) { sidewaysintpr((unsigned)_interval, ifnetaddr); return; } - else if (ifnetaddr == 0) { - printf("ifnet: symbol not defined\n"); + + if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) + return; + if ((buf = malloc(len)) == NULL) { + printf("malloc\n"); return; } - - if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead)) + if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { + free(buf); return; - ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead); - if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet)) - return; + } if (!pfunc) { if (Wflag) @@ -216,186 +212,206 @@ printf(" %s", "Drop"); putchar('\n'); } - ifaddraddr = 0; - while (ifnetaddr || ifaddraddr) { + cur = buf; + end = cur + len; + while (cur < end) { struct sockaddr_in *sockin; + struct sockaddr_in *inmask; #ifdef INET6 struct sockaddr_in6 *sockin6; + struct sockaddr_in6 *in6mask; #endif char *cp; int n, m; network_layer = 0; link_layer = 0; + ifm = (struct if_msghdr *)cur; + ifam = NULL; + + if (ifm->ifm_type == RTM_IFINFO) { + struct sockaddr_dl *sdl; + if (!(ifm->ifm_addrs & RTA_IFP)) { + printf("Missing IFP\n"); + exit(1); + } + sa = (struct sockaddr *)(cur + sizeof(*ifm)); + addr = sa; + sdl = (struct sockaddr_dl *)sa; + strlcpy(name, sdl->sdl_data, sdl->sdl_nlen+1); + cur += ifm->ifm_msglen; + if (interface != 0 && (strcmp(name, interface) != 0)) + continue; + if ((ifm->ifm_flags & IFF_UP) == 0) { + cp = index(name, '\0'); + *cp++ = '*'; + *cp = '\0'; + } + mtu = ifm->ifm_data.ifi_mtu; - if (ifaddraddr == 0) { - ifnetfound = ifnetaddr; - if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet)) - return; - strlcpy(name, ifnet.if_xname, sizeof(name)); - ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link); - if (interface != 0 && (strcmp(name, interface) != 0)) - continue; - cp = index(name, '\0'); + } else if (ifm->ifm_type == RTM_NEWADDR) { + int addrs = ifm->ifm_addrs; + ifam = (struct ifa_msghdr *)cur; + cur += sizeof(*ifam); - if (pfunc) { - (*pfunc)(name); - continue; + while (addrs != 0) { + sa = (struct sockaddr *)cur; + cur += SA_SIZE(sa); + if (sa->sa_len == 0) + continue; + + if (addrs & RTA_NETMASK) { + mask = sa; + addrs &= ~RTA_NETMASK; + } else if (addrs & RTA_IFA) { + addr = sa; + addrs &= ~RTA_IFA; + } else if (addrs & RTA_BRD) { + brd = sa; + addrs &= ~RTA_BRD; + } } - - if ((ifnet.if_flags&IFF_UP) == 0) - *cp++ = '*'; - *cp = '\0'; - ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead); + } else { + printf("Unknown message type: %d\n", ifm->ifm_type); + cur += ifm->ifm_msglen; + continue; } - ifaddrfound = ifaddraddr; /* * Get the interface stats. These may get * overriden below on a per-interface basis. */ - opackets = ifnet.if_opackets; - ipackets = ifnet.if_ipackets; - obytes = ifnet.if_obytes; - ibytes = ifnet.if_ibytes; - omcasts = ifnet.if_omcasts; - imcasts = ifnet.if_imcasts; - oerrors = ifnet.if_oerrors; - ierrors = ifnet.if_ierrors; - collisions = ifnet.if_collisions; - timer = ifnet.if_timer; - drops = ifnet.if_snd.ifq_drops; + if (ifm->ifm_type == RTM_IFINFO) { + opackets = ifm->ifm_data.ifi_opackets; + ipackets = ifm->ifm_data.ifi_ipackets; + obytes = ifm->ifm_data.ifi_obytes; + ibytes = ifm->ifm_data.ifi_ibytes; + omcasts = ifm->ifm_data.ifi_omcasts; + imcasts = ifm->ifm_data.ifi_imcasts; + oerrors = ifm->ifm_data.ifi_oerrors; + ierrors = ifm->ifm_data.ifi_ierrors; + collisions = ifm->ifm_data.ifi_collisions; + /* IFCLEANUP + * Timer info not available in if_data + * timer = ifnet.if_timer; + */ + drops = ifm->ifm_data.ifi_iqdrops; + } - if (ifaddraddr == 0) { - if (Wflag) - printf("%-7.7s", name); - else - printf("%-5.5s", name); - printf(" %5lu ", ifnet.if_mtu); + if (af != AF_UNSPEC && sa->sa_family != af) + continue; + + if (Wflag) + printf("%-7.7s", name); + else + printf("%-5.5s", name); + printf(" %5lu ", mtu); + switch (addr->sa_family) { + case AF_UNSPEC: printf("%-13.13s ", "none"); - printf("%-17.17s ", "none"); - } else { - if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) { - ifaddraddr = 0; - continue; - } -#define CP(x) ((char *)(x)) - cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + - CP(&ifaddr); - sa = (struct sockaddr *)cp; - if (af != AF_UNSPEC && sa->sa_family != af) { - ifaddraddr = - (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); - continue; - } - if (Wflag) - printf("%-7.7s", name); - else - printf("%-5.5s", name); - printf(" %5lu ", ifnet.if_mtu); - switch (sa->sa_family) { - case AF_UNSPEC: - printf("%-13.13s ", "none"); - printf("%-15.15s ", "none"); - break; - case AF_INET: - sockin = (struct sockaddr_in *)sa; -#ifdef notdef - /* can't use inet_makeaddr because kernel - * keeps nets unshifted. - */ - in = inet_makeaddr(ifaddr.in.ia_subnet, - INADDR_ANY); - printf("%-13.13s ", netname(in.s_addr, - ifaddr.in.ia_subnetmask)); -#else - printf("%-13.13s ", - netname(htonl(ifaddr.in.ia_subnet), - ifaddr.in.ia_subnetmask)); -#endif - printf("%-17.17s ", - routename(sockin->sin_addr.s_addr)); + printf("%-15.15s ", "none"); + break; + case AF_INET: + inmask = (struct sockaddr_in *)mask; + sockin = (struct sockaddr_in *)addr; + + /* IFCLEANUP + * netname expects a network address and its mask + */ + printf("%-13.13s ", + netname(sockin->sin_addr.s_addr & + inmask->sin_addr.s_addr, + ntohl(inmask->sin_addr.s_addr))); + printf("%-17.17s ", + routename(sockin->sin_addr.s_addr)); - network_layer = 1; - break; -#ifdef INET6 - case AF_INET6: - sockin6 = (struct sockaddr_in6 *)sa; - printf("%-13.13s ", - netname6(&ifaddr.in6.ia_addr, - &ifaddr.in6.ia_prefixmask.sin6_addr)); - printf("%-17.17s ", - inet_ntop(AF_INET6, - &sockin6->sin6_addr, - ntop_buf, sizeof(ntop_buf))); + network_layer = 1; + break; +#ifdef INET6 + case AF_INET6: + in6mask = (struct sockaddr_in6 *)mask; + sockin6 = (struct sockaddr_in6 *)addr; - network_layer = 1; - break; + printf("%-13.13s ", + netname6(sockin6, &in6mask->sin6_addr)); + printf("%-17.17s ", + inet_ntop(AF_INET6, + &sockin6->sin6_addr, + ntop_buf, sizeof(ntop_buf))); + + network_layer = 1; + break; #endif /*INET6*/ - case AF_IPX: - { - struct sockaddr_ipx *sipx = - (struct sockaddr_ipx *)sa; - u_long net; - char netnum[10]; + case AF_IPX: + { + struct sockaddr_ipx *sipx = + (struct sockaddr_ipx *)addr; + u_long net; + char netnum[10]; + + *(union ipx_net *) &net = sipx->sipx_addr.x_net; + sprintf(netnum, "%lx", (u_long)ntohl(net)); + printf("ipx:%-8s ", netnum); + /* printf("ipx:%-8s ", netname(net, 0L)); */ + printf("%-17s ", + ipx_phost((struct sockaddr *)sipx)); + } - *(union ipx_net *) &net = sipx->sipx_addr.x_net; - sprintf(netnum, "%lx", (u_long)ntohl(net)); - printf("ipx:%-8s ", netnum); -/* printf("ipx:%-8s ", netname(net, 0L)); */ - printf("%-17s ", - ipx_phost((struct sockaddr *)sipx)); - } + network_layer = 1; + break; - network_layer = 1; - break; - - case AF_APPLETALK: - printf("atalk:%-12.12s ",atalk_print(sa,0x10) ); - printf("%-11.11s ",atalk_print(sa,0x0b) ); - break; - case AF_LINK: - { - struct sockaddr_dl *sdl = - (struct sockaddr_dl *)sa; - char linknum[10]; - cp = (char *)LLADDR(sdl); - n = sdl->sdl_alen; - sprintf(linknum, "<Link#%d>", sdl->sdl_index); - m = printf("%-13.13s ", linknum); - } - goto hexprint; - default: - m = printf("(%d)", sa->sa_family); - for (cp = sa->sa_len + (char *)sa; - --cp > sa->sa_data && (*cp == 0);) {} - n = cp - sa->sa_data + 1; - cp = sa->sa_data; - hexprint: - while (--n >= 0) - m += printf("%02x%c", *cp++ & 0xff, + case AF_APPLETALK: + printf("atalk:%-12.12s ",atalk_print(sa,0x10) ); + printf("%-11.11s ",atalk_print(sa,0x0b) ); + break; + case AF_LINK: + { + struct sockaddr_dl *sdl = + (struct sockaddr_dl *)addr; + char linknum[10]; + cp = (char *)LLADDR(sdl); + n = sdl->sdl_alen; + sprintf(linknum, "<Link#%d>", sdl->sdl_index); + m = printf("%-13.13s ", linknum); + } + goto hexprint; + default: + m = printf("(%d)", sa->sa_family); + for (cp = sa->sa_len + (char *)sa; + --cp > sa->sa_data && (*cp == 0);) {} + n = cp - sa->sa_data + 1; + cp = sa->sa_data; + hexprint: + while (--n >= 0) + m += printf("%02x%c", *cp++ & 0xff, n > 0 ? ':' : ' '); - m = 32 - m; - while (m-- > 0) - putchar(' '); - - link_layer = 1; - break; - } - - /* - * Fixup the statistics for interfaces that - * update stats for their network addresses - */ - if (network_layer) { - opackets = ifaddr.in.ia_ifa.if_opackets; - ipackets = ifaddr.in.ia_ifa.if_ipackets; - obytes = ifaddr.in.ia_ifa.if_obytes; - ibytes = ifaddr.in.ia_ifa.if_ibytes; - } - - ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); + m = 32 - m; + while (m-- > 0) + putchar(' '); + + link_layer = 1; + break; } + + /* + * Fixup the statistics for interfaces that + * update stats for their network addresses + */ + + /* IFCLEANUP + * Cannot handle this yet; ifa_msghdr does not + * contain socket if_data info. + */ + /* + if (network_layer) { + opackets = ifaddr.in.ia_ifa.if_opackets; + ipackets = ifaddr.in.ia_ifa.if_ipackets; + obytes = ifaddr.in.ia_ifa.if_obytes; + ibytes = ifaddr.in.ia_ifa.if_ibytes; + } + */ + + show_stat("lu", 8, ipackets, link_layer|network_layer); printf(" "); @@ -414,15 +430,24 @@ printf(" "); } show_stat("lu", 5, collisions, link_layer); + /* IFCLEANUP + * timer info not availble in if_data + */ + /* if (tflag) { printf(" "); show_stat("d", 3, timer, link_layer); } + */ if (dflag) { printf(" "); show_stat("d", 3, drops, link_layer); } putchar('\n'); + /* IFCLEANUP + * Skip mcast for now + */ +#if 0 if (aflag && ifaddrfound) { /* * Print family's multicast addresses @@ -490,6 +515,7 @@ } } } +#endif /* if 0 */ } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507100650.j6A6oCXF034652>