Network statistics on OS X using the sysctl interface

sysctl offers read access to a couple of kernel structures that contain network statistics.

I am yet to figure out the difference in between the IP statistics as read from the "net.inet.ip.stats" sysctl value when compared to the values as read by netstat (as seen below, IP stats prints 114243 packets and netstat reports 116840).


cristi:tmp diciu$ ./a.out
IP packets received: 114243
IP packets generated here: 85251
TCP connection attempts: 3337
TCP total packets sent: 81779
TCP total packets received: 105700



cristi:tmp diciu$ netstat -bi
Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll
[..]
en0 1500 Link#4 xx:xx:xx:xx:xx:xx 116840 0 113745333 85202 0 13307330 0
[..]


Here's the C source for the sysctl reader:



#include <sys/types.h>
#include <sys/sysctl.h>

#include <stdlib.h>
#include <stdio.h>

#include <sys/socketvar.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_var.h>

int main()
{
void * oldp = malloc(1024);
size_t oldlen = sizeof(struct ipstat), newlen;
void * newp = NULL;

int retval = sysctlbyname("net.inet.ip.stats", oldp, &oldlen, newp, newlen);


struct ipstat * g = (struct ipstat *) oldp;
printf("IP packets received: %d\n", g->ips_total);
printf("IP packets generated here: %d\n", g->ips_localout);


struct tcpstat * t = (struct tcpstat *) oldp;
oldlen = sizeof(struct tcpstat);
retval = sysctlbyname("net.inet.tcp.stats", oldp, &oldlen, newp, newlen);
printf("TCP connection attempts: %d\n", t->tcps_connattempt);
printf("TCP total packets sent: %d\n", t->tcps_sndtotal);
printf("TCP total packets received: %d\n", t->tcps_rcvtotal);
}