How to get network adapter stats in linux/Mac OSX?

20,624

Solution 1

The Darwin netstat source code uses sysctl. Here's some code that prints the number of bytes in and out on OSX:

#import <Foundation/Foundation.h>
#include <sys/sysctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/route.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int mib[] = {
        CTL_NET,
        PF_ROUTE,
        0,
        0,
        NET_RT_IFLIST2,
        0
    };
    size_t len;
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        fprintf(stderr, "sysctl: %s\n", strerror(errno));
        exit(1);
    }
    char *buf = (char *)malloc(len);
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        fprintf(stderr, "sysctl: %s\n", strerror(errno));
        exit(1);
    }
    char *lim = buf + len;
    char *next = NULL;
    u_int64_t totalibytes = 0;
    u_int64_t totalobytes = 0;
    for (next = buf; next < lim; ) {
        struct if_msghdr *ifm = (struct if_msghdr *)next;
        next += ifm->ifm_msglen;
        if (ifm->ifm_type == RTM_IFINFO2) {
            struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
            totalibytes += if2m->ifm_data.ifi_ibytes;
            totalobytes += if2m->ifm_data.ifi_obytes;
        }
    }
    printf("total ibytes %qu\tobytes %qu\n", totalibytes, totalobytes);
    [pool drain];
    return 0;
}

Solution 2

I can't speak to OSX but on linux take a look at /proc/net/dev.

If you do 'cat /proc/net/dev' you should see statistics including 'bytes' - the total number of bytes of data transmitted or received by the interface. You can read the file within your own program.

EDIT:

I didn't read your whole question. This article should help you get started with /proc and has a section on /proc/net/dev.

Also, to list the interfaces you can call ioctl with the SIOCGIFCONF option. You can Google for a decent code example on how to loop through the returned data. Or you can simply pull it out of the /proc.net/dev data mentioned above, which should be easier.

Solution 3

on Linux:

  • low level: check /sys/class/net/eth0/statistics/
  • slightly higher level: ip -s link show eth0
  • graphical: iftop
  • interactive: iptraf
Share:
20,624
Admin
Author by

Admin

Updated on April 01, 2021

Comments

  • Admin
    Admin about 3 years

    I'm looking for a way to get hold of network stats in C on Linux and MacOSX. Specifically, I need to monitor the number of bytes uploaded and downloaded from each network adapter on the system - I don't need to do packet inspection, or differentiate between protocols, just a 'total bytes' counter which I can poll at intervals would be fine. In Windows I can do this using the iphlpapi.dll library via GetIfTable (to list the network adapters) and GetIfEntry (to read the stats), but I can't find the Linux/OSX equivalents. My knowledge of C is fairly basic so I would appreciate a solution that isn't too involved. Any help would be much appreciated!

  • Admin
    Admin about 12 years
    Or, as per Javier's answer, look at the files under /sys/class/net/{your network interface}/statistics, where {your network interface} is the name of the network interface you want to look at, e.g. eth0 for the first Ethernet interface. sysfs (on /sys) is newer than procfs (on /proc).
  • virata
    virata over 11 years
    This works fine on simulator. but gives error on device. error is- /Users/praveendala/Desktop/all in one3/app2/app2/main.m:13:10: fatal error: 'net/route.h' file not found.
  • virata
    virata over 11 years
    I know this is for OSX. but I need to run on ios devices.any idea?
  • Armand
    Armand almost 11 years
    Nicely done. I like you provide an Objective-C solution too.
  • Purrell
    Purrell almost 11 years
    Title of question is OSX. First two do not work on OSX. Bottom two are not suited to question either, being graphical and interactive.
  • nullException
    nullException over 10 years
    both the tile and the body of the question mention Linux and OSX. this is about the Linux part
  • noɥʇʎԀʎzɐɹƆ
    noɥʇʎԀʎzɐɹƆ almost 7 years
    How can I do this with bash?
  • Hal Canary
    Hal Canary about 3 years
    Thanks for this example! I converted it to C++ by changing the NSAutoreleasePool to a std::vector for the buffer.