diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2008-01-03 21:01:41 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2008-01-03 21:01:41 +0000 |
commit | 206b28b4f619d01b129ce54954bf46c28c0b36cc (patch) | |
tree | f1c786cc8ce966a2f1174b7d6641343c7e6fe829 | |
parent | 1030fd4d4e2a61c5fcee1e899eaa59cc7aa25a72 (diff) |
Make if.c kvm free by fetching the interface stats via sysctl like in systat
and ospfd. What is not yet covered is the -d and -t flags to show interface
queue drops and the if_timer.
OK deraadt@
-rw-r--r-- | usr.bin/netstat/if.c | 736 | ||||
-rw-r--r-- | usr.bin/netstat/main.c | 30 | ||||
-rw-r--r-- | usr.bin/netstat/netstat.h | 4 |
3 files changed, 406 insertions, 364 deletions
diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c index d97cdd26231..5116457262c 100644 --- a/usr.bin/netstat/if.c +++ b/usr.bin/netstat/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.55 2007/12/19 01:47:00 deraadt Exp $ */ +/* $OpenBSD: if.c,v 1.56 2008/01/03 21:01:40 claudio Exp $ */ /* $NetBSD: if.c,v 1.16.4.2 1996/06/07 21:46:46 thorpej Exp $ */ /* @@ -30,13 +30,16 @@ * SUCH DAMAGE. */ +#include <sys/param.h> #include <sys/types.h> #include <sys/protosw.h> #include <sys/socket.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> +#include <net/route.h> #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/if_ether.h> @@ -51,11 +54,11 @@ #include "netstat.h" -#define YES 1 -#define NO 0 - -static void sidewaysintpr(u_int, u_long); +static void print_addr(struct sockaddr *, struct sockaddr **, struct if_data *); +static void sidewaysintpr(u_int); static void catchalarm(int); +static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); +static void fetchifs(void); /* * Print a description of the network interfaces. @@ -63,37 +66,31 @@ static void catchalarm(int); * which is a TAILQ_HEAD. */ void -intpr(int interval, u_long ifnetaddr) +intpr(int interval) { - struct ifnet ifnet; - union { - struct ifaddr ifa; - struct in_ifaddr in; - struct in6_ifaddr in6; - } ifaddr; - u_int64_t total; - u_long ifaddraddr; - struct sockaddr *sa; - struct ifnet_head ifhead; /* TAILQ_HEAD */ - char name[IFNAMSIZ]; + struct if_msghdr ifm; + int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + char name[IFNAMSIZ + 1]; /* + 1 for the '*' */ + char *buf, *next, *lim, *cp; + struct rt_msghdr *rtm; + struct ifa_msghdr *ifam; + struct if_data *ifd; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_dl *sdl; + u_int64_t total = 0; + size_t len; - if (ifnetaddr == 0) { - printf("ifnet: symbol not defined\n"); - return; - } if (interval) { - sidewaysintpr((unsigned)interval, ifnetaddr); + sidewaysintpr((unsigned)interval); return; } - /* - * Find the pointer to the first ifnet structure. Replace - * the pointer to the TAILQ_HEAD with the actual pointer - * to the first list element. - */ - if (kread(ifnetaddr, &ifhead, sizeof ifhead)) - return; - ifnetaddr = (u_long)TAILQ_FIRST(&ifhead); + if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) + err(1, "sysctl"); + if ((buf = malloc(len)) == NULL) + err(1, NULL); + if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) + err(1, "sysctl"); printf("%-7.7s %-5.5s %-11.11s %-17.17s ", "Name", "Mtu", "Network", "Address"); @@ -107,212 +104,226 @@ intpr(int interval, u_long ifnetaddr) if (dflag) printf(" %s", "Drop"); putchar('\n'); - ifaddraddr = 0; - while (ifnetaddr || ifaddraddr) { - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; - char *cp; - int n, m; - - if (ifaddraddr == 0) { - if (kread(ifnetaddr, &ifnet, sizeof ifnet)) - return; - bcopy(ifnet.if_xname, name, IFNAMSIZ); - name[IFNAMSIZ - 1] = '\0'; /* sanity */ - ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_list); + + lim = buf + len; + for (next = buf; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + if (rtm->rtm_version != RTM_VERSION) + continue; + switch (rtm->rtm_type) { + case RTM_IFINFO: + total = 0; + bcopy(next, &ifm, sizeof ifm); + ifd = &ifm.ifm_data; + + sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); + get_rtaddrs(ifm.ifm_addrs, sa, rti_info); + + sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP]; + if (sdl == NULL || sdl->sdl_family != AF_LINK) + continue; + bzero(name, sizeof(name)); + if (sdl->sdl_nlen >= IFNAMSIZ) + memcpy(name, sdl->sdl_data, IFNAMSIZ - 1); + else if (sdl->sdl_nlen > 0) + memcpy(name, sdl->sdl_data, sdl->sdl_nlen); + if (interface != 0 && strcmp(name, interface) != 0) continue; + + /* mark inactive interfaces with a '*' */ cp = strchr(name, '\0'); - if ((ifnet.if_flags & IFF_UP) == 0) + if ((ifm.ifm_flags & IFF_UP) == 0) *cp++ = '*'; *cp = '\0'; - ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrlist); - } - if (qflag) { - total = ifnet.if_ibytes + ifnet.if_obytes + - ifnet.if_ipackets + ifnet.if_ierrors + - ifnet.if_opackets + ifnet.if_oerrors + - ifnet.if_collisions; - if (tflag) - total += ifnet.if_timer; - if (dflag) - total += ifnet.if_snd.ifq_drops; - if (total == 0) { - ifaddraddr = 0; - continue; + if (qflag) { + total = ifd->ifi_ibytes + ifd->ifi_obytes + + ifd->ifi_ipackets + ifd->ifi_ierrors + + ifd->ifi_opackets + ifd->ifi_oerrors + + ifd->ifi_collisions; + if (tflag) + total += 0; // XXX ifnet.if_timer; + if (dflag) + total += 0; // XXX ifnet.if_snd.ifq_drops; + if (total == 0) + continue; } - } - printf("%-7s %-5ld ", name, ifnet.if_mtu); - if (ifaddraddr == 0) { - printf("%-11.11s ", "none"); - printf("%-17.17s ", "none"); - } else { - if (kread(ifaddraddr, &ifaddr, sizeof ifaddr)) { - ifaddraddr = 0; + printf("%-7s %-5ld ", name, ifd->ifi_mtu); + print_addr(rti_info[RTAX_IFP], rti_info, ifd); + break; + case RTM_NEWADDR: + if (qflag && total == 0) continue; - } -#define CP(x) ((char *)(x)) - cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + - CP(&ifaddr); sa = (struct sockaddr *)cp; - switch (sa->sa_family) { - case AF_UNSPEC: - printf("%-11.11s ", "none"); - printf("%-17.17s ", "none"); + ifam = (struct ifa_msghdr *)next; + if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA | + RTA_BRD)) == 0) break; - case AF_INET: - sin = (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); - cp = netname4(in.s_addr, - ifaddr.in.ia_subnetmask); -#else - cp = netname4(ifaddr.in.ia_subnet, - ifaddr.in.ia_subnetmask); + + sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); + get_rtaddrs(ifam->ifam_addrs, sa, rti_info); + + printf("%-7s %-5ld ", name, ifd->ifi_mtu); + print_addr(rti_info[RTAX_IFA], rti_info, ifd); + break; + } + } +} + +static void +print_addr(struct sockaddr *sa, struct sockaddr **rtinfo, struct if_data *ifd) +{ + struct sockaddr_dl *sdl; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + char *cp; + int m, n; + + switch (sa->sa_family) { + case AF_UNSPEC: + printf("%-11.11s ", "none"); + printf("%-17.17s ", "none"); + break; + case AF_INET: + sin = (struct sockaddr_in *)sa; + cp = netname4(sin->sin_addr.s_addr, + ((struct sockaddr_in *)rtinfo[RTAX_NETMASK])->sin_addr.s_addr); + if (vflag) + n = strlen(cp) < 11 ? 11 : strlen(cp); + else + n = 11; + printf("%-*.*s ", n, n, cp); + cp = routename4(sin->sin_addr.s_addr); + if (vflag) + n = strlen(cp) < 17 ? 17 : strlen(cp); + else + n = 17; + printf("%-*.*s ", n, n, cp); + +#if 0 + if (aflag) { + u_long multiaddr; + struct in_multi inm; + + multiaddr = (u_long)LIST_FIRST(&ifaddr.in.ia_multiaddrs); + while (multiaddr != 0) { + kread(multiaddr, &inm, sizeof inm); + printf("\n%25s %-17.17s ", "", + routename4(inm.inm_addr.s_addr)); + multiaddr = (u_long)LIST_NEXT(&inm, inm_list); + } + } #endif - if (vflag) - n = strlen(cp) < 11 ? 11 : strlen(cp); - else - n = 11; - printf("%-*.*s ", n, n, cp); - cp = routename4(sin->sin_addr.s_addr); - if (vflag) - n = strlen(cp) < 17 ? 17 : strlen(cp); - else - n = 17; - printf("%-*.*s ", n, n, cp); - - if (aflag) { - u_long multiaddr; - struct in_multi inm; - - multiaddr = (u_long)LIST_FIRST(&ifaddr.in.ia_multiaddrs); - while (multiaddr != 0) { - kread(multiaddr, &inm, sizeof inm); - printf("\n%25s %-17.17s ", "", - routename4(inm.inm_addr.s_addr)); - multiaddr = (u_long)LIST_NEXT(&inm, inm_list); - } - } - break; - case AF_INET6: - sin6 = (struct sockaddr_in6 *)sa; + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)sa; #ifdef __KAME__ - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - sin6->sin6_scope_id = + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + sin6->sin6_scope_id = + ntohs(*(u_int16_t *) + &sin6->sin6_addr.s6_addr[2]); + sin6->sin6_addr.s6_addr[2] = 0; + sin6->sin6_addr.s6_addr[3] = 0; + } +#endif + cp = netname6(sin6, + (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK]); + if (vflag) + n = strlen(cp) < 11 ? 11 : strlen(cp); + else + n = 11; + printf("%-*.*s ", n, n, cp); + cp = routename6(sin6); + if (vflag) + n = strlen(cp) < 17 ? 17 : strlen(cp); + else + n = 17; + printf("%-*.*s ", n, n, cp); +#if 0 + if (aflag) { + u_long multiaddr; + struct in6_multi inm; + struct sockaddr_in6 m6; + + multiaddr = (u_long)LIST_FIRST(&ifaddr.in6.ia6_multiaddrs); + while (multiaddr != 0) { + kread(multiaddr, &inm, sizeof inm); + memset(&m6, 0, sizeof(m6)); + m6.sin6_len = sizeof(struct sockaddr_in6); + m6.sin6_family = AF_INET6; + m6.sin6_addr = inm.in6m_addr; +#ifdef __KAME__ + if (IN6_IS_ADDR_MC_LINKLOCAL(&m6.sin6_addr) || + IN6_IS_ADDR_MC_INTFACELOCAL(&m6.sin6_addr)) { + m6.sin6_scope_id = ntohs(*(u_int16_t *) - &sin6->sin6_addr.s6_addr[2]); - sin6->sin6_addr.s6_addr[2] = 0; - sin6->sin6_addr.s6_addr[3] = 0; + &m6.sin6_addr.s6_addr[2]); + m6.sin6_addr.s6_addr[2] = 0; + m6.sin6_addr.s6_addr[3] = 0; } #endif - cp = netname6(&ifaddr.in6.ia_addr, - &ifaddr.in6.ia_prefixmask); - if (vflag) - n = strlen(cp) < 11 ? 11 : strlen(cp); - else - n = 11; - printf("%-*.*s ", n, n, cp); - cp = routename6(sin6); + cp = routename6(&m6); if (vflag) n = strlen(cp) < 17 ? 17 : strlen(cp); else n = 17; - printf("%-*.*s ", n, n, cp); - if (aflag) { - u_long multiaddr; - struct in6_multi inm; - struct sockaddr_in6 m6; - - multiaddr = (u_long)LIST_FIRST(&ifaddr.in6.ia6_multiaddrs); - while (multiaddr != 0) { - kread(multiaddr, &inm, sizeof inm); - memset(&m6, 0, sizeof(m6)); - m6.sin6_len = sizeof(struct sockaddr_in6); - m6.sin6_family = AF_INET6; - m6.sin6_addr = inm.in6m_addr; -#ifdef __KAME__ - if (IN6_IS_ADDR_MC_LINKLOCAL(&m6.sin6_addr) || - IN6_IS_ADDR_MC_INTFACELOCAL(&m6.sin6_addr)) { - m6.sin6_scope_id = - ntohs(*(u_int16_t *) - &m6.sin6_addr.s6_addr[2]); - m6.sin6_addr.s6_addr[2] = 0; - m6.sin6_addr.s6_addr[3] = 0; - } -#endif - cp = routename6(&m6); - if (vflag) - n = strlen(cp) < 17 ? 17 : strlen(cp); - else - n = 17; - printf("\n%25s %-*.*s ", "", - n, n, cp); - multiaddr = (u_long)LIST_NEXT(&inm, in6m_entry); - } - } - break; - case AF_APPLETALK: - printf("atlk:%-12s",atalk_print(sa,0x10) ); - printf("%-12s ",atalk_print(sa,0x0b) ); - break; - case AF_LINK: - { - struct sockaddr_dl *sdl = - (struct sockaddr_dl *)sa; - m = printf("%-11.11s ", "<Link>"); - if (sdl->sdl_type == IFT_ETHER || - sdl->sdl_type == IFT_CARP || - sdl->sdl_type == IFT_FDDI || - sdl->sdl_type == IFT_ISO88025) - printf("%-17.17s ", - ether_ntoa((struct ether_addr *)LLADDR(sdl))); - else { - cp = (char *)LLADDR(sdl); - n = sdl->sdl_alen; - goto hexprint; - } - } - break; - 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("%x%c", *cp++ & 0xff, - n > 0 ? '.' : ' '); - m = 30 - m; - while (m-- > 0) - putchar(' '); - break; + printf("\n%25s %-*.*s ", "", + n, n, cp); + multiaddr = (u_long)LIST_NEXT(&inm, in6m_entry); } - ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_list); } - if (bflag) - printf("%10llu %10llu", - ifnet.if_ibytes, ifnet.if_obytes); - else - printf("%8llu %5llu %8llu %5llu %5llu", - ifnet.if_ipackets, ifnet.if_ierrors, - ifnet.if_opackets, ifnet.if_oerrors, - ifnet.if_collisions); - if (tflag) - printf(" %4d", ifnet.if_timer); - if (dflag) - printf(" %4d", ifnet.if_snd.ifq_drops); - putchar('\n'); +#endif + break; + case AF_APPLETALK: + printf("atlk:%-12s",atalk_print(sa,0x10) ); + printf("%-12s ",atalk_print(sa,0x0b) ); + break; + case AF_LINK: + sdl = (struct sockaddr_dl *)sa; + m = printf("%-11.11s ", "<Link>"); + if (sdl->sdl_type == IFT_ETHER || + sdl->sdl_type == IFT_CARP || + sdl->sdl_type == IFT_FDDI || + sdl->sdl_type == IFT_ISO88025) + printf("%-17.17s ", + ether_ntoa((struct ether_addr *)LLADDR(sdl))); + else { + cp = (char *)LLADDR(sdl); + n = sdl->sdl_alen; + goto hexprint; + } + break; + 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("%x%c", *cp++ & 0xff, + n > 0 ? '.' : ' '); + m = 30 - m; + while (m-- > 0) + putchar(' '); + break; } + if (bflag) + printf("%10llu %10llu", + ifd->ifi_ibytes, ifd->ifi_obytes); + else + printf("%8llu %5llu %8llu %5llu %5llu", + ifd->ifi_ipackets, ifd->ifi_ierrors, + ifd->ifi_opackets, ifd->ifi_oerrors, + ifd->ifi_collisions); + if (tflag) + printf(" %4d", 0 /* XXX ifnet.if_timer */); + if (dflag) + printf(" %4d", 0 /* XXX ifnet.if_snd.ifq_drops */); + putchar('\n'); } -#define MAXIF 100 struct iftot { char ift_name[IFNAMSIZ]; /* interface name */ u_int64_t ift_ip; /* input packets */ @@ -323,7 +334,7 @@ struct iftot { u_int64_t ift_oe; /* output errors */ u_int64_t ift_co; /* collisions */ u_int64_t ift_dr; /* drops */ -} iftot[MAXIF]; +} ip_cur, ip_old, sum_cur, sum_old; volatile sig_atomic_t signalled; /* set if alarm goes off "early" */ @@ -334,82 +345,42 @@ volatile sig_atomic_t signalled; /* set if alarm goes off "early" */ * First line printed at top of screen is always cumulative. */ static void -sidewaysintpr(unsigned int interval, u_long off) +sidewaysintpr(unsigned int interval) { struct ifnet ifnet; - u_long firstifnet; - struct iftot *ip, *total; - int line; - struct iftot *lastif, *sum, *interesting; - struct ifnet_head ifhead; /* TAILQ_HEAD */ sigset_t emptyset; + int line; - /* - * Find the pointer to the first ifnet structure. Replace - * the pointer to the TAILQ_HEAD with the actual pointer - * to the first list element. - */ - if (kread(off, &ifhead, sizeof ifhead)) - return; - firstifnet = (u_long)TAILQ_FIRST(&ifhead); - - lastif = iftot; - sum = iftot + MAXIF - 1; - total = sum - 1; - interesting = (interface == NULL) ? iftot : NULL; - for (off = firstifnet, ip = iftot; off;) { - if (kread(off, &ifnet, sizeof ifnet)) - break; - bzero(ip->ift_name, sizeof(ip->ift_name)); - snprintf(ip->ift_name, IFNAMSIZ, "%s", ifnet.if_xname); - if (interface && strcmp(ifnet.if_xname, interface) == 0) - interesting = ip; - ip++; - if (ip >= iftot + MAXIF - 2) - break; - off = (u_long)TAILQ_NEXT(&ifnet, if_list); - } - if (interesting == NULL) { + fetchifs(); + if (ip_cur.ift_name[0] == '\0') { fprintf(stderr, "%s: %s: unknown interface\n", __progname, interface); exit(1); } - lastif = ip; (void)signal(SIGALRM, catchalarm); - signalled = NO; + signalled = 0; (void)alarm(interval); banner: if (bflag) printf("%7.7s in %8.8s %6.6s out %5.5s", - interesting->ift_name, " ", - interesting->ift_name, " "); + ip_cur.ift_name, " ", + ip_cur.ift_name, " "); else printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", - interesting->ift_name, " ", - interesting->ift_name, " ", " "); + ip_cur.ift_name, " ", + ip_cur.ift_name, " ", " "); + if (dflag) + printf(" %5.5s", " "); + + if (bflag) + printf(" %7.7s in %8.8s %6.6s out %5.5s", + "total", " ", "total", " "); + else + printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", + "total", " ", "total", " ", " "); if (dflag) printf(" %5.5s", " "); - if (lastif - iftot > 0) { - if (bflag) - printf(" %7.7s in %8.8s %6.6s out %5.5s", - "total", " ", "total", " "); - else - printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", - "total", " ", "total", " ", " "); - if (dflag) - printf(" %5.5s", " "); - } - for (ip = iftot; ip < iftot + MAXIF; ip++) { - ip->ift_ip = 0; - ip->ift_ib = 0; - ip->ift_ie = 0; - ip->ift_op = 0; - ip->ift_ob = 0; - ip->ift_oe = 0; - ip->ift_co = 0; - ip->ift_dr = 0; - } putchar('\n'); if (bflag) printf("%10.10s %8.8s %10.10s %5.5s", @@ -419,90 +390,66 @@ banner: "packets", "errs", "packets", "errs", "colls"); if (dflag) printf(" %5.5s", "drops"); - if (lastif - iftot > 0) { - if (bflag) - printf(" %10.10s %8.8s %10.10s %5.5s", - "bytes", " ", "bytes", " "); - else - printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", - "packets", "errs", "packets", "errs", "colls"); - if (dflag) - printf(" %5.5s", "drops"); - } + + if (bflag) + printf(" %10.10s %8.8s %10.10s %5.5s", + "bytes", " ", "bytes", " "); + else + printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", + "packets", "errs", "packets", "errs", "colls"); + if (dflag) + printf(" %5.5s", "drops"); putchar('\n'); fflush(stdout); line = 0; + bzero(&ip_old, sizeof(ip_old)); + bzero(&sum_old, sizeof(sum_old)); loop: - sum->ift_ip = 0; - sum->ift_ib = 0; - sum->ift_ie = 0; - sum->ift_op = 0; - sum->ift_ob = 0; - sum->ift_oe = 0; - sum->ift_co = 0; - sum->ift_dr = 0; - for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { - if (kread(off, &ifnet, sizeof ifnet)) { - off = 0; - continue; - } - if (ip == interesting) { - if (bflag) - printf("%10llu %8.8s %10llu %5.5s", - ifnet.if_ibytes - ip->ift_ib, " ", - ifnet.if_obytes - ip->ift_ob, " "); - else - printf("%8llu %5llu %8llu %5llu %5llu", - ifnet.if_ipackets - ip->ift_ip, - ifnet.if_ierrors - ip->ift_ie, - ifnet.if_opackets - ip->ift_op, - ifnet.if_oerrors - ip->ift_oe, - ifnet.if_collisions - ip->ift_co); - if (dflag) - printf(" %5llu", - ifnet.if_snd.ifq_drops - ip->ift_dr); - } - ip->ift_ip = ifnet.if_ipackets; - ip->ift_ib = ifnet.if_ibytes; - ip->ift_ie = ifnet.if_ierrors; - ip->ift_op = ifnet.if_opackets; - ip->ift_ob = ifnet.if_obytes; - ip->ift_oe = ifnet.if_oerrors; - ip->ift_co = ifnet.if_collisions; - ip->ift_dr = ifnet.if_snd.ifq_drops; - sum->ift_ip += ip->ift_ip; - sum->ift_ib += ip->ift_ib; - sum->ift_ie += ip->ift_ie; - sum->ift_op += ip->ift_op; - sum->ift_ob += ip->ift_ob; - sum->ift_oe += ip->ift_oe; - sum->ift_co += ip->ift_co; - sum->ift_dr += ip->ift_dr; - off = (u_long)TAILQ_NEXT(&ifnet, if_list); - } - if (lastif - iftot > 0) { - if (bflag) - printf(" %10llu %8.8s %10llu %5.5s", - sum->ift_ib - total->ift_ib, " ", - sum->ift_ob - total->ift_ob, " "); - else - printf(" %8llu %5llu %8llu %5llu %5llu", - sum->ift_ip - total->ift_ip, - sum->ift_ie - total->ift_ie, - sum->ift_op - total->ift_op, - sum->ift_oe - total->ift_oe, - sum->ift_co - total->ift_co); - if (dflag) - printf(" %5llu", sum->ift_dr - total->ift_dr); - } - *total = *sum; + bzero(&sum_cur, sizeof(sum_cur)); + + fetchifs(); + + if (bflag) + printf("%10llu %8.8s %10llu %5.5s", + ip_cur.ift_ib - ip_old.ift_ib, " ", + ip_cur.ift_ob - ip_old.ift_ob, " "); + else + printf("%8llu %5llu %8llu %5llu %5llu", + ip_cur.ift_ip - ip_old.ift_ip, + ip_cur.ift_ie - ip_old.ift_ie, + ip_cur.ift_op - ip_old.ift_op, + ip_cur.ift_oe - ip_old.ift_oe, + ip_cur.ift_co - ip_old.ift_co); + if (dflag) + printf(" %5llu", + /* XXX ifnet.if_snd.ifq_drops - ip->ift_dr); */ + 0); + + ip_old = ip_cur; + + if (bflag) + printf(" %10llu %8.8s %10llu %5.5s", + sum_cur.ift_ib - sum_old.ift_ib, " ", + sum_cur.ift_ob - sum_old.ift_ob, " "); + else + printf(" %8llu %5llu %8llu %5llu %5llu", + sum_cur.ift_ip - sum_old.ift_ip, + sum_cur.ift_ie - sum_old.ift_ie, + sum_cur.ift_op - sum_old.ift_op, + sum_cur.ift_oe - sum_old.ift_oe, + sum_cur.ift_co - sum_old.ift_co); + if (dflag) + printf(" %5llu", sum_cur.ift_dr - sum_old.ift_dr); + + sum_old = sum_cur; + putchar('\n'); fflush(stdout); line++; sigemptyset(&emptyset); if (!signalled) sigsuspend(&emptyset); - signalled = NO; + signalled = 0; (void)alarm(interval); if (line == 21) goto banner; @@ -518,5 +465,102 @@ loop: static void catchalarm(int signo) { - signalled = YES; + signalled = 1; +} + +static void +get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) +{ + int i; + + for (i = 0; i < RTAX_MAX; i++) { + if (addrs & (1 << i)) { + rti_info[i] = sa; + sa = (struct sockaddr *)((char *)(sa) + + roundup(sa->sa_len, sizeof(long))); + } else + rti_info[i] = NULL; + } +} + +static void +fetchifs(void) +{ + struct if_msghdr ifm; + int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + struct rt_msghdr *rtm; + struct if_data *ifd; + struct sockaddr *sa, *rti_info[RTAX_MAX]; + struct sockaddr_dl *sdl; + char *buf, *next, *lim; + char name[IFNAMSIZ]; + size_t len; + + if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) + err(1, "sysctl"); + if ((buf = malloc(len)) == NULL) + err(1, NULL); + if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) + err(1, "sysctl"); + + lim = buf + len; + for (next = buf; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + if (rtm->rtm_version != RTM_VERSION) + continue; + switch (rtm->rtm_type) { + case RTM_IFINFO: + bcopy(next, &ifm, sizeof ifm); + ifd = &ifm.ifm_data; + + sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); + get_rtaddrs(ifm.ifm_addrs, sa, rti_info); + + sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP]; + if (sdl == NULL || sdl->sdl_family != AF_LINK) + continue; + bzero(name, sizeof(name)); + if (sdl->sdl_nlen >= IFNAMSIZ) + memcpy(name, sdl->sdl_data, IFNAMSIZ - 1); + else if (sdl->sdl_nlen > 0) + memcpy(name, sdl->sdl_data, sdl->sdl_nlen); + + if (interface != 0 && !strcmp(name, interface)) { + strlcpy(ip_cur.ift_name, name, + sizeof(ip_cur.ift_name)); + ip_cur.ift_ip = ifd->ifi_ipackets; + ip_cur.ift_ib = ifd->ifi_ibytes; + ip_cur.ift_ie = ifd->ifi_ierrors; + ip_cur.ift_op = ifd->ifi_opackets; + ip_cur.ift_ob = ifd->ifi_obytes; + ip_cur.ift_oe = ifd->ifi_oerrors; + ip_cur.ift_co = ifd->ifi_collisions; + ip_cur.ift_dr = 0; + /* XXX ifnet.if_snd.ifq_drops */ + } + + sum_cur.ift_ip += ifd->ifi_ipackets; + sum_cur.ift_ib += ifd->ifi_ibytes; + sum_cur.ift_ie += ifd->ifi_ierrors; + sum_cur.ift_op += ifd->ifi_opackets; + sum_cur.ift_ob += ifd->ifi_obytes; + sum_cur.ift_oe += ifd->ifi_oerrors; + sum_cur.ift_co += ifd->ifi_collisions; + sum_cur.ift_dr += 0; /* XXX ifnet.if_snd.ifq_drops */ + break; + } + } + if (interface == NULL) { + strlcpy(ip_cur.ift_name, name, + sizeof(ip_cur.ift_name)); + ip_cur.ift_ip = ifd->ifi_ipackets; + ip_cur.ift_ib = ifd->ifi_ibytes; + ip_cur.ift_ie = ifd->ifi_ierrors; + ip_cur.ift_op = ifd->ifi_opackets; + ip_cur.ift_ob = ifd->ifi_obytes; + ip_cur.ift_oe = ifd->ifi_oerrors; + ip_cur.ift_co = ifd->ifi_collisions; + ip_cur.ift_dr = 0; + /* XXX ifnet.if_snd.ifq_drops */ + } } diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 038df34494e..59694aec8b2 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.73 2007/12/19 08:49:23 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.74 2008/01/03 21:01:40 claudio Exp $ */ /* $NetBSD: main.c,v 1.9 1996/05/07 02:55:02 thorpej Exp $ */ /* @@ -59,35 +59,33 @@ struct nlist nl[] = { { "_udbtable" }, #define N_DDPCB 2 { "_ddpcb"}, -#define N_IFNET 3 - { "_ifnet" }, -#define N_UNIXSW 4 +#define N_UNIXSW 3 { "_unixsw" }, -#define N_MFCHASHTBL 5 +#define N_MFCHASHTBL 4 { "_mfchashtbl" }, -#define N_MFCHASH 6 +#define N_MFCHASH 5 { "_mfchash" }, -#define N_VIFTABLE 7 +#define N_VIFTABLE 6 { "_viftable" }, -#define N_MF6CTABLE 8 +#define N_MF6CTABLE 7 { "_mf6ctable" }, -#define N_MIF6TABLE 9 +#define N_MIF6TABLE 8 { "_mif6table" }, -#define N_RTREE 10 +#define N_RTREE 9 { "_rt_tables"}, -#define N_RTMASK 11 +#define N_RTMASK 10 { "_mask_rnhead" }, -#define N_AF2RTAFIDX 12 +#define N_AF2RTAFIDX 11 { "_af2rtafidx" }, -#define N_RTBLIDMAX 13 +#define N_RTBLIDMAX 12 { "_rtbl_id_max" }, -#define N_RAWIPTABLE 14 +#define N_RAWIPTABLE 13 { "_rawcbtable" }, -#define N_RAWIP6TABLE 15 +#define N_RAWIP6TABLE 14 { "_rawin6pcbtable" }, { ""} @@ -366,7 +364,7 @@ main(int argc, char *argv[]) setnetent(1); if (iflag) { - intpr(interval, nl[N_IFNET].n_value); + intpr(interval); exit(0); } if (rflag) { diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index 37b57699af2..4b417bb5ab1 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: netstat.h,v 1.46 2007/12/19 08:49:23 claudio Exp $ */ +/* $OpenBSD: netstat.h,v 1.47 2008/01/03 21:01:40 claudio Exp $ */ /* $NetBSD: netstat.h,v 1.6 1996/05/07 02:55:05 thorpej Exp $ */ /* @@ -128,7 +128,7 @@ void routepr(u_long, u_long, u_long, u_long); void nsprotopr(u_long, char *); -void intpr(int, u_long); +void intpr(int); void unixpr(u_long); |