View Single Post
  #5   (View Single Post)  
Old 12th June 2008
BSDfan666 BSDfan666 is offline
Real Name: N/A, this is the interweb.
Banned
 
Join Date: Apr 2008
Location: Ontario, Canada
Posts: 2,223
Default

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.

Last edited by BSDfan666; 12th June 2008 at 03:43 AM.
Reply With Quote