1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
$NetBSD: patch-aa,v 1.5 2012/08/11 17:20:23 marino Exp $
FreeBSD changes taken from FreeBSD ports
--- ioctl_stat.c.orig 2000-02-01 07:11:24.000000000 +0000
+++ ioctl_stat.c
@@ -30,6 +30,15 @@
#include <fcntl.h> /* open */
#include <sys/ioctl.h> /* ioctl */
#include <errno.h>
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#define __FreeFly__ 1
+#endif
+#if __FreeFly__
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_mib.h>
+#endif
#ifndef STREAMS /* Linux, FreeBSD, NetBSD, Ultrix */
# include <sys/socket.h> /* socket */
@@ -39,8 +48,10 @@
# include <linux/if_ppp.h>
# else /* most everything else */
# include <net/if.h>
+# ifndef __FreeFly__
# include <net/ppp_defs.h>
# include <net/if_ppp.h>
+# endif /* FreeBSD | DragonFly */
# endif /* linux && __GLIBC__ < 2 */
#else /* STREAMS */ /* Solaris, SunOS, OSF/1, SVR4 */
# include <net/ppp_defs.h>
@@ -61,7 +72,21 @@ void getsocket(if_data *ifd)
void ioctl_stat(if_data *ifd)
{
struct ifreq ifr;
+#if __FreeFly__
+ static int if_ix = -1;
+ struct ifmibdata ifmd;
+ size_t ifmd_sz = sizeof(ifmd);
+ int nr_ifs;
+ size_t nr_ifs_sz = sizeof(nr_ifs);
+ int name[6];
+ int i;
+#else
+#ifdef SIOCGIFDATA
+ struct ifdatareq ifdr;
+ struct if_data * const ifi = &ifdr.ifdr_data;
+#endif
struct ifpppstatsreq req;
+#endif /* FreeBSD | DragonFly */
if (!ifd->s) getsocket(ifd);
@@ -76,7 +101,9 @@ void ioctl_stat(if_data *ifd)
return;
}
+#ifndef __FreeFly__
memset(&req, 0, sizeof(req));
+#endif
#ifdef linux
req.stats_ptr = (caddr_t) &req.stats;
@@ -84,6 +111,60 @@ void ioctl_stat(if_data *ifd)
#define ifr_name ifr__name
#endif
+#ifdef __NetBSD__
+ strncpy(ifr.ifr_name, ifd->device, sizeof(ifr.ifr_name));
+ if (ioctl(ifd->s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0 ||
+ !(ifr.ifr_flags&IFF_UP))
+ {
+ /* invalid interface, or interface down */
+ ifd->in_bytes = 0UL;
+ ifd->out_bytes = 0UL;
+ return;
+ }
+#endif
+
+#if __FreeFly__
+ name[0] = CTL_NET;
+ name[1] = PF_LINK;
+ name[2] = NETLINK_GENERIC;
+ name[3] = IFMIB_IFDATA;
+ name[5] = IFDATA_GENERAL;
+
+ if (if_ix < 0) {
+ if (sysctlbyname("net.link.generic.system.ifcount", (void *) &nr_ifs, &nr_ifs_sz, (void *) 0, 0) < 0) {
+ return;
+ }
+ for (i = 1; i <= nr_ifs; i++) {
+ name[4] = i; /* row of the ifmib table */
+
+ if (sysctl(name, 6, (void *) &ifmd, &ifmd_sz, (void *) 0, 0) < 0) {
+ continue;
+ }
+ if (strncmp(ifmd.ifmd_name, ifr.ifr_name, strlen(ifr.ifr_name)) == 0) {
+ if_ix = i;
+ break;
+ }
+ }
+ }
+
+ name[4] = if_ix;
+ if (sysctl(name, 6, (void *) &ifmd, &ifmd_sz, (void *) 0, 0) >= 0) {
+ ifd->in_bytes = ifmd.ifmd_data.ifi_ibytes;
+ ifd->out_bytes = ifmd.ifmd_data.ifi_obytes;
+ }
+#elif defined(__NetBSD__) && defined(SIOCGIFDATA)
+ /* prefer the generic interface statistics over the PPP specific ones */
+ strncpy(ifdr.ifdr_name, ifd->device, sizeof(ifdr.ifdr_name));
+ if (ioctl(ifd->s, SIOCGIFDATA, &ifdr) == -1)
+ {
+ /* non-existent device? */
+ ifd->in_bytes = 0UL;
+ ifd->out_bytes = 0UL;
+ return;
+ }
+ ifd->in_bytes = ifi->ifi_ibytes;
+ ifd->out_bytes = ifi->ifi_obytes;
+#else
strncpy(req.ifr_name, ifd->device, sizeof(req.ifr_name));
if (ioctl(ifd->s, SIOCGPPPSTATS, &req) != 0)
{
@@ -95,6 +176,7 @@ void ioctl_stat(if_data *ifd)
ifd->in_bytes = (unsigned long)req.stats.p.ppp_ibytes;
ifd->out_bytes = (unsigned long)req.stats.p.ppp_obytes;
+#endif
return;
}
|