This is a raw extraction of the byte-counting code from the netstat command.. this may be useful to someone who's attempting to write their own application.
Code:
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
int
main(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;
int loop_index;
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
err(1, "sysctl");
if ((buf = (char *)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;
if (rtm->rtm_type == RTM_IFINFO) {
bcopy(next, &ifm, sizeof(ifm));
ifd = &ifm.ifm_data;
sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
for (loop_index = 0; loop_index < RTAX_MAX; loop_index++) {
if (ifm.ifm_addrs & (1 << loop_index)) {
rti_info[loop_index] = sa;
sa = (struct sockaddr *)((char *)(sa) +
roundup(sa->sa_len, sizeof(long)));
} else {
rti_info[loop_index] = NULL;
}
}
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(!strcmp(name, "rl0")) {
printf("%10llu %10llu\n", ifd->ifi_ibytes, ifd->ifi_obytes);
}
}
}
}
The second strcmp argument must be altered to match your Ethernet interface, any LAN traffic over the link is also recorded.
The equivalent command is:
$ netstat -ib
Take care.