1/* MiniUPnP project
2 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
3 * author: Gleb Smirnoff <glebius@FreeBSD.org>
4 * (c) 2006 Ryan Wagoner
5 * (c) 2014 Gleb Smirnoff
6 * This software is subject to the conditions detailed
7 * in the LICENCE file provided within the distribution */
8
9#include <sys/types.h>
10#include <sys/socket.h>
11#include <net/if.h>
12#include <errno.h>
13#include <ifaddrs.h>
14#include <string.h>
15#include <syslog.h>
16
17#ifdef ENABLE_GETIFSTATS_CACHING
18#include <time.h>
19#endif
20
21#include "../getifstats.h"
22#include "../config.h"
23
24int
25getifstats(const char *ifname, struct ifdata *data)
26{
27	static struct ifaddrs *ifap, *ifa;
28#ifdef ENABLE_GETIFSTATS_CACHING
29	static time_t cache_timestamp;
30	time_t current_time;
31#endif
32	if(!data)
33		return -1;
34	data->baudrate = 4200000;
35	data->opackets = 0;
36	data->ipackets = 0;
37	data->obytes = 0;
38	data->ibytes = 0;
39	if(!ifname || ifname[0]=='\0')
40		return -1;
41
42#ifdef ENABLE_GETIFSTATS_CACHING
43	current_time = time(NULL);
44	if (ifap != NULL &&
45	    current_time < cache_timestamp + GETIFSTATS_CACHING_DURATION)
46		goto copy;
47#endif
48
49	if (ifap != NULL) {
50		freeifaddrs(ifap);
51		ifap = NULL;
52	}
53
54	if (getifaddrs(&ifap) != 0) {
55		syslog (LOG_ERR, "getifstats() : getifaddrs(): %s",
56		    strerror(errno));
57		return (-1);
58	}
59
60	for (ifa = ifap; ifa; ifa = ifa->ifa_next)
61		if (ifa->ifa_addr->sa_family == AF_LINK &&
62		    strcmp(ifa->ifa_name, ifname) == 0) {
63#ifdef ENABLE_GETIFSTATS_CACHING
64			cache_timestamp = current_time;
65copy:
66#endif
67#define	IFA_STAT(s)	(((struct if_data *)ifa->ifa_data)->ifi_ ## s)
68			data->opackets = IFA_STAT(opackets);
69			data->ipackets = IFA_STAT(ipackets);
70			data->obytes = IFA_STAT(obytes);
71			data->ibytes = IFA_STAT(ibytes);
72			data->baudrate = IFA_STAT(baudrate);
73			return (0);
74		}
75
76	return (-1);
77}
78