Annotation of embedaddon/miniupnpd/mac/getifstats.c, revision 1.1.1.1
1.1 misho 1: /*
2: * MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4: * (c) 2009 Jarder Weyrich
5: * This software is subject to the conditions detailed
6: * in the LICENCE file provided within the distribution
7: */
8:
9: #include <syslog.h>
10: #include <sys/sysctl.h>
11: #include <sys/types.h>
12: #include <netinet/in.h>
13: #include <net/if.h>
14: #include <net/if_types.h>
15: #include <net/route.h>
16: #include <nlist.h>
17: #include <stdio.h>
18: #include <stdlib.h>
19: #include <string.h>
20:
21: #include "../getifstats.h"
22: #include "../config.h"
23:
24: int getifstats(const char * ifname, struct ifdata * data) {
25: int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, if_nametoindex(ifname) };
26: const size_t mib_len = sizeof(mib) / sizeof(mib[0]);
27: size_t needed;
28: char *buf, *end;
29: struct if_msghdr *ifm;
30: struct if_data ifdata;
31: #ifdef ENABLE_GETIFSTATS_CACHING
32: static time_t cache_timestamp = 0;
33: static struct ifdata cache_data;
34: time_t current_time;
35: #endif
36:
37: if (data == NULL || ifname == NULL || ifname[0] == '\0')
38: return -1; // error
39:
40: data->baudrate = 4200000;
41: data->opackets = 0;
42: data->ipackets = 0;
43: data->obytes = 0;
44: data->ibytes = 0;
45:
46: #ifdef ENABLE_GETIFSTATS_CACHING
47: current_time = time(NULL);
48: if (current_time == ((time_t)-1)) {
49: syslog(LOG_ERR, "getifstats() : time() error : %m");
50: } else {
51: if (current_time < cache_timestamp + GETIFSTATS_CACHING_DURATION) {
52: memcpy(data, &cache_data, sizeof(struct ifdata));
53: return 0;
54: }
55: }
56: #endif
57:
58: if (sysctl(mib, mib_len, NULL, &needed, NULL, 0) == -1) {
59: syslog(LOG_ERR, "sysctl(): %m");
60: return -1;
61: }
62: buf = (char *) malloc(needed);
63: if (buf == NULL)
64: return -1; // error
65: if (sysctl(mib, mib_len, buf, &needed, NULL, 0) == -1) {
66: syslog(LOG_ERR, "sysctl(): %m");
67: free(buf);
68: return -1; // error
69: } else {
70: for (end = buf + needed; buf < end; buf += ifm->ifm_msglen) {
71: ifm = (struct if_msghdr *) buf;
72: if (ifm->ifm_type == RTM_IFINFO && ifm->ifm_data.ifi_type == IFT_ETHER) {
73: ifdata = ifm->ifm_data;
74: data->opackets = ifdata.ifi_opackets;
75: data->ipackets = ifdata.ifi_ipackets;
76: data->obytes = ifdata.ifi_obytes;
77: data->ibytes = ifdata.ifi_ibytes;
78: data->baudrate = ifdata.ifi_baudrate;
79: free(buf);
80: #ifdef ENABLE_GETIFSTATS_CACHING
81: if (current_time!=((time_t)-1)) {
82: cache_timestamp = current_time;
83: memcpy(&cache_data, data, sizeof(struct ifdata));
84: }
85: #endif
86: return 0; // found, ok
87: }
88: }
89: }
90: free(buf);
91: return -1; // not found or error
92: }
93:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>