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.