2 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
3 * author: Ryan Wagoner and Thomas Bernard
4 * (c) 2006 Ryan Wagoner
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
10 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #if defined(__FreeBSD__) || defined(__DragonFly__)
15 #include <net/if_var.h>
17 #if defined(__DragonFly__)
18 #include <net/pf/pfvar.h>
20 #include <net/pfvar.h>
25 #include <sys/queue.h>
30 #include "../getifstats.h"
31 #include "../config.h"
33 static struct nlist list
[] = {
34 {"_ifnet", 0, 0, 0, 0},
39 getifstats(const char * ifname
, struct ifdata
* data
)
41 #if defined(__FreeBSD__) || defined(__DragonFly__)
43 #elif defined(__OpenBSD__) || defined(__NetBSD__)
44 struct ifnet_head ifh
;
46 #error "Dont know if I should use struct ifnethead or struct ifnet_head"
52 char errstr
[_POSIX2_LINE_MAX
];
53 #ifdef ENABLE_GETIFSTATS_CACHING
54 static time_t cache_timestamp
= 0;
55 static struct ifdata cache_data
;
60 data
->baudrate
= 4200000;
65 if(!ifname
|| ifname
[0]=='\0')
67 #ifdef ENABLE_GETIFSTATS_CACHING
68 current_time
= time(NULL
);
69 if(current_time
== ((time_t)-1)) {
70 syslog(LOG_ERR
, "getifstats() : time() error : %m");
72 if(current_time
< cache_timestamp
+ GETIFSTATS_CACHING_DURATION
) {
73 memcpy(data
, &cache_data
, sizeof(struct ifdata
));
79 /*kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);*/
80 kd
= kvm_openfiles(NULL
, NULL
, NULL
, O_RDONLY
, errstr
);
83 syslog (LOG_ERR
, "getifstats() : kvm_open(): %s", errstr
);
86 if(kvm_nlist(kd
, list
) < 0)
88 syslog(LOG_ERR
, "getifstats() : kvm_nlist(): FAILED");
93 syslog(LOG_ERR
, "getifstats() : n_value(): FAILED");
96 n
= kvm_read(kd
, list
[0].n_value
, &ifh
, sizeof(ifh
));
99 syslog(LOG_ERR
, "getifstats() : kvm_read(head): %s", kvm_geterr(kd
));
102 for(ifp
= TAILQ_FIRST(&ifh
); ifp
; ifp
= TAILQ_NEXT(&ifc
, if_list
))
104 n
= kvm_read(kd
, (u_long
)ifp
, &ifc
, sizeof(ifc
));
107 syslog(LOG_ERR
, "getifstats() : kvm_read(element): %s", kvm_geterr(kd
));
110 if(strcmp(ifname
, ifc
.if_xname
) == 0)
112 /* found the right interface */
113 data
->opackets
= ifc
.if_data
.ifi_opackets
;
114 data
->ipackets
= ifc
.if_data
.ifi_ipackets
;
115 data
->obytes
= ifc
.if_data
.ifi_obytes
;
116 data
->ibytes
= ifc
.if_data
.ifi_ibytes
;
117 data
->baudrate
= ifc
.if_data
.ifi_baudrate
;
120 #ifdef ENABLE_GETIFSTATS_CACHING
121 if(current_time
!=((time_t)-1)) {
122 cache_timestamp
= current_time
;
123 memcpy(&cache_data
, data
, sizeof(struct ifdata
));
131 return -1; /* not found or error */