summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2008-01-03 21:01:41 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2008-01-03 21:01:41 +0000
commit206b28b4f619d01b129ce54954bf46c28c0b36cc (patch)
treef1c786cc8ce966a2f1174b7d6641343c7e6fe829
parent1030fd4d4e2a61c5fcee1e899eaa59cc7aa25a72 (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.c736
-rw-r--r--usr.bin/netstat/main.c30
-rw-r--r--usr.bin/netstat/netstat.h4
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);