I have a problem where I need to know how much traffic has passed on a
given interface.  I don't need it broken down by IPs, protocols or
whatever of the sort.

After a bit of research I discovered the SIOCGIFDATA ioctl that seems
to do what I want.

I built myself a little test application to try it out (see at the end
of the mail for the code).  The number it reports for my egress
interface are weird though:

$ ./ifbw pppoe0
bandwidth: 802865637b up 1907983523b down
reduced: 765.67MiB up 1.78GiB down

I am certain I downloaded at least 2.6GB in the last few days and
uploaded at least 3.2GB.  Also, for the outbound traffic shaping queue
I have over this interface pftop reports 33Gb of traffic.

So I have questions for the network gurus.  Am I doing something
incorrectly with my code below?
If not, are the counters just out of whack and it's normal?

Also, if anybody knows a better way to do this, please tell me.

Arnaud

The test code:

#include <sys/types.h>

#include <sys/ioctl.h>

#include <sys/socket.h>

#include <net/if.h>

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

static struct if_data data;
int sd;

#define MAX_UNIT 9
static const char *sizes[MAX_UNIT] =
{ "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" };

void reduce_size(double size, float *res, const char **unit) {
   unsigned short unit_idx = 0;
   while (size >= 1024 && unit_idx < MAX_UNIT) {
        size /= 1024.0;
        unit_idx++;
   }
   *res = size;
   *unit = sizes[unit_idx];
}

static struct if_data *get_if_data(char *name) {
   struct ifreq ifr;

   strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   ifr.ifr_data = (caddr_t) &data;
   if (ioctl(sd, SIOCGIFDATA, (char *) &ifr) < 0) return NULL;
   return &data;
}

int main(int argc, char **argv) {
   float val;
   const char *unit;

   if (argc != 2) {
        fprintf(stderr, "usage:\n");
        fprintf(stderr, "\tifbw ifname\n");
        exit(2);
   }

   sd = socket(AF_INET, SOCK_DGRAM, 0);
   if (sd == -1) err(1, "socket");
   if (get_if_data(argv[1]) == NULL) err(1, "ioctl");
   printf("bandwidth: %lub up %lub down\n", data.ifi_obytes, data.ifi_ibytes);
   reduce_size(data.ifi_obytes, &val, &unit);
   printf("reduced: %.2f%s up", val, unit);
   reduce_size(data.ifi_ibytes, &val, &unit);
   printf(" %.2f%s down\n", val, unit);
   return 0;
}


--
No, we're keeping them for 4.2 Ultimate Edition which will be
available for the low low price of $595.00. -- dlg@, talking about the
hackaton network changes.

Reply via email to