1/* MiniUPnP project
2 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
3 * author: Ryan Wagoner and Thomas Bernard
4 * (c) 2007 Darren Reed
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
7
8#include <syslog.h>
9#include <string.h>
10#include <stdlib.h>
11#include <ctype.h>
12#include <kstat.h>
13#include <sys/sysmacros.h>
14
15#include "../getifstats.h"
16
17int
18getifstats(const char * ifname, struct ifdata * data)
19{
20	char buffer[64], *s;
21	kstat_named_t *kn;
22	kstat_ctl_t *kc;
23	int instance;
24	kstat_t *ksp;
25	uint32_t cnt32;
26	void *ptr;
27
28	if (data == NULL)
29		goto error;
30
31	if (ifname == NULL || *ifname == '\0')
32		goto error;
33
34	s = (char *)ifname + strlen(ifname);
35	s--;
36	while ((s > ifname) && isdigit(*s))
37		s--;
38
39	s++;
40	instance = atoi(s);
41	strlcpy(buffer, ifname, MIN(s - ifname + 1, 64));
42
43	kc = kstat_open();
44	if (kc != NULL) {
45		ksp = kstat_lookup(kc, buffer, instance, (char *)ifname);
46		if (ksp && (kstat_read(kc, ksp, NULL) != -1)) {
47			/* found the right interface */
48			if (sizeof(long) == 8) {
49				uint64_t cnt64;
50				kn = kstat_data_lookup(ksp, "rbytes64");
51				if (kn != NULL) {
52					data->ibytes = kn->value.i64;
53				}
54				kn = kstat_data_lookup(ksp, "ipackets64");
55				if (kn != NULL) {
56					data->ipackets = kn->value.i64;
57				}
58				kn = kstat_data_lookup(ksp, "obytes64");
59				if (kn != NULL) {
60					data->obytes = kn->value.i64;
61				}
62				kn = kstat_data_lookup(ksp, "opackets64");
63				if (kn != NULL) {
64					data->opackets = kn->value.i64;
65				}
66			} else {
67				kn = kstat_data_lookup(ksp, "rbytes");
68				if (kn != NULL) {
69					data->ibytes = kn->value.i32;
70				}
71				kn = kstat_data_lookup(ksp, "ipackets");
72				if (kn != NULL) {
73					data->ipackets = kn->value.i32;
74				}
75				kn = kstat_data_lookup(ksp, "obytes");
76				if (kn != NULL) {
77					data->obytes = kn->value.i32;
78				}
79				kn = kstat_data_lookup(ksp, "opackets");
80				if (kn != NULL) {
81					data->ipackets = kn->value.i32;
82				}
83			}
84			kn = kstat_data_lookup(ksp, "ifspeed");
85			if (kn != NULL) {
86				data->baudrate = kn->value.i32;
87			}
88			kstat_close(kc);
89			return 0;	/* ok */
90		}
91		syslog(LOG_ERR, "kstat_lookup/read() failed: %m");
92		kstat_close(kc);
93		return -1;
94	} else {
95		syslog(LOG_ERR, "kstat_open() failed: %m");
96	}
97error:
98	return -1;	/* not found or error */
99}
100
101