1: /* $Id: getifstats.c,v 1.1.1.3 2013/07/22 00:32:35 misho Exp $ */
2: /* MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4: * (c) 2006-2012 Thomas Bernard
5: * This software is subject to the conditions detailed
6: * in the LICENCE file provided within the distribution */
7:
8: #include <stdio.h>
9: #include <stdlib.h>
10: #include <syslog.h>
11: #include <string.h>
12: #include <time.h>
13:
14: #include "../config.h"
15: #include "../getifstats.h"
16:
17: int
18: getifstats(const char * ifname, struct ifdata * data)
19: {
20: FILE *f;
21: char line[512];
22: char * p;
23: int i;
24: int r = -1;
25: char fname[64];
26: #ifdef ENABLE_GETIFSTATS_CACHING
27: static time_t cache_timestamp = 0;
28: static struct ifdata cache_data;
29: time_t current_time;
30: #endif
31: if(!data)
32: return -1;
33: data->baudrate = 4200000; /* that is the answer */
34: data->opackets = 0;
35: data->ipackets = 0;
36: data->obytes = 0;
37: data->ibytes = 0;
38: if(!ifname || ifname[0]=='\0')
39: return -1;
40: #ifdef ENABLE_GETIFSTATS_CACHING
41: current_time = time(NULL);
42: if(current_time == ((time_t)-1)) {
43: syslog(LOG_ERR, "getifstats() : time() error : %m");
44: } else {
45: if(current_time < cache_timestamp + GETIFSTATS_CACHING_DURATION) {
46: /* return cached data */
47: memcpy(data, &cache_data, sizeof(struct ifdata));
48: return 0;
49: }
50: }
51: #endif
52: f = fopen("/proc/net/dev", "r");
53: if(!f) {
54: syslog(LOG_ERR, "getifstats() : cannot open /proc/net/dev : %m");
55: return -1;
56: }
57: /* discard the two header lines */
58: if(!fgets(line, sizeof(line), f) || !fgets(line, sizeof(line), f)) {
59: syslog(LOG_ERR, "getifstats() : error reading /proc/net/dev : %m");
60: }
61: while(fgets(line, sizeof(line), f)) {
62: p = line;
63: while(*p==' ') p++;
64: i = 0;
65: while(ifname[i] == *p) {
66: p++; i++;
67: }
68: /* TODO : how to handle aliases ? */
69: if(ifname[i] || *p != ':')
70: continue;
71: p++;
72: while(*p==' ') p++;
73: data->ibytes = strtoul(p, &p, 0);
74: while(*p==' ') p++;
75: data->ipackets = strtoul(p, &p, 0);
76: /* skip 6 columns */
77: for(i=6; i>0 && *p!='\0'; i--) {
78: while(*p==' ') p++;
79: while(*p!=' ' && *p) p++;
80: }
81: while(*p==' ') p++;
82: data->obytes = strtoul(p, &p, 0);
83: while(*p==' ') p++;
84: data->opackets = strtoul(p, &p, 0);
85: r = 0;
86: break;
87: }
88: fclose(f);
89: /* get interface speed */
90: snprintf(fname, sizeof(fname), "/sys/class/net/%s/speed", ifname);
91: f = fopen(fname, "r");
92: if(f) {
93: if(fgets(line, sizeof(line), f)) {
94: i = atoi(line); /* 65535 means unknown */
95: if(i > 0 && i < 65535)
96: data->baudrate = 1000000*i;
97: }
98: fclose(f);
99: } else {
100: syslog(LOG_WARNING, "cannot read %s file : %m", fname);
101: }
102: #ifdef ENABLE_GETIFSTATS_CACHING
103: if(r==0 && current_time!=((time_t)-1)) {
104: /* cache the new data */
105: cache_timestamp = current_time;
106: memcpy(&cache_data, data, sizeof(struct ifdata));
107: }
108: #endif
109: return r;
110: }
111:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>