1 /* $Id: getifstats.c,v 1.13 2015/06/09 15:33:24 nanard Exp $ */
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006-2013 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
14 #include "../config.h"
15 #include "../getifstats.h"
17 #ifdef GET_WIRELESS_STATS
19 #include <sys/ioctl.h>
20 #include <arpa/inet.h>
21 #include <linux/wireless.h>
22 #endif /* GET_WIRELESS_STATS */
24 /* that is the answer */
25 #define BAUDRATE_DEFAULT 4200000
28 getifstats(const char * ifname
, struct ifdata
* data
)
36 #ifdef ENABLE_GETIFSTATS_CACHING
37 static time_t cache_timestamp
= 0;
38 static struct ifdata cache_data
;
40 #endif /* ENABLE_GETIFSTATS_CACHING */
43 data
->baudrate
= BAUDRATE_DEFAULT
;
48 if(!ifname
|| ifname
[0]=='\0')
50 #ifdef ENABLE_GETIFSTATS_CACHING
51 current_time
= time(NULL
);
52 if(current_time
== ((time_t)-1)) {
53 syslog(LOG_ERR
, "getifstats() : time() error : %m");
55 if(current_time
< cache_timestamp
+ GETIFSTATS_CACHING_DURATION
) {
56 /* return cached data */
57 memcpy(data
, &cache_data
, sizeof(struct ifdata
));
61 #endif /* ENABLE_GETIFSTATS_CACHING */
62 f
= fopen("/proc/net/dev", "r");
64 syslog(LOG_ERR
, "getifstats() : cannot open /proc/net/dev : %m");
67 /* discard the two header lines */
68 if(!fgets(line
, sizeof(line
), f
) || !fgets(line
, sizeof(line
), f
)) {
69 syslog(LOG_ERR
, "getifstats() : error reading /proc/net/dev : %m");
71 while(fgets(line
, sizeof(line
), f
)) {
75 while(ifname
[i
] == *p
) {
78 /* TODO : how to handle aliases ? */
79 if(ifname
[i
] || *p
!= ':')
83 data
->ibytes
= strtoul(p
, &p
, 0);
85 data
->ipackets
= strtoul(p
, &p
, 0);
87 for(i
=6; i
>0 && *p
!='\0'; i
--) {
89 while(*p
!=' ' && *p
) p
++;
92 data
->obytes
= strtoul(p
, &p
, 0);
94 data
->opackets
= strtoul(p
, &p
, 0);
99 /* get interface speed */
100 snprintf(fname
, sizeof(fname
), "/sys/class/net/%s/speed", ifname
);
101 f
= fopen(fname
, "r");
103 if(fgets(line
, sizeof(line
), f
)) {
104 i
= atoi(line
); /* 65535 means unknown */
105 if(i
> 0 && i
< 65535)
106 data
->baudrate
= 1000000*i
;
110 syslog(LOG_INFO
, "cannot read %s file : %m", fname
);
112 #ifdef GET_WIRELESS_STATS
113 if(data
->baudrate
== BAUDRATE_DEFAULT
) {
116 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
118 strncpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
119 if(ioctl(s
, SIOCGIWRATE
, &iwr
) >= 0) {
120 data
->baudrate
= iwr
.u
.bitrate
.value
;
125 #endif /* GET_WIRELESS_STATS */
126 #ifdef ENABLE_GETIFSTATS_CACHING
127 if(r
==0 && current_time
!=((time_t)-1)) {
128 /* cache the new data */
129 cache_timestamp
= current_time
;
130 memcpy(&cache_data
, data
, sizeof(struct ifdata
));
132 #endif /* ENABLE_GETIFSTATS_CACHING */