We determine if we're Linux by the absense of the sysctlbyname()
function. As the code introduced in this commit for getting MAC
addresses is specific to Linux, additional work will need to be
made to handle other operating systems (namely, OpenBSD and Solaris).
Conflicts:
libclamav/Makefile.in
... | ... |
@@ -178,6 +178,9 @@ |
178 | 178 |
/* Define to 1 if the system has the type `error_t'. */ |
179 | 179 |
#undef HAVE_ERROR_T |
180 | 180 |
|
181 |
+/* Define to 1 if you have the <fcntl.h> header file */ |
|
182 |
+#undef HAVE_FCNTL_H |
|
183 |
+ |
|
181 | 184 |
/* have working file descriptor passing support */ |
182 | 185 |
#undef HAVE_FD_PASSING |
183 | 186 |
|
... | ... |
@@ -187,6 +190,9 @@ |
187 | 187 |
/* have getaddrinfo() */ |
188 | 188 |
#undef HAVE_GETADDRINFO |
189 | 189 |
|
190 |
+/* Define to 1 if you have the `getifaddrs' function. */ |
|
191 |
+#undef HAVE_GETIFADDRS |
|
192 |
+ |
|
190 | 193 |
/* Define to 1 if getpagesize() is available */ |
191 | 194 |
#undef HAVE_GETPAGESIZE |
192 | 195 |
|
... | ... |
@@ -14427,6 +14427,25 @@ _ACEOF |
14427 | 14427 |
fi |
14428 | 14428 |
done |
14429 | 14429 |
|
14430 |
+for ac_func in getifaddrs |
|
14431 |
+do : |
|
14432 |
+ ac_fn_c_check_func "$LINENO" "getifaddrs" "ac_cv_func_getifaddrs" |
|
14433 |
+if test "x$ac_cv_func_getifaddrs" = xyes; then : |
|
14434 |
+ cat >>confdefs.h <<_ACEOF |
|
14435 |
+#define HAVE_GETIFADDRS 1 |
|
14436 |
+_ACEOF |
|
14437 |
+ |
|
14438 |
+fi |
|
14439 |
+done |
|
14440 |
+ |
|
14441 |
+ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" |
|
14442 |
+if test "x$ac_cv_header_fcntl_h" = xyes; then : |
|
14443 |
+ |
|
14444 |
+$as_echo "#define HAVE_FCNTL_H 1" >>confdefs.h |
|
14445 |
+ |
|
14446 |
+fi |
|
14447 |
+ |
|
14448 |
+ |
|
14430 | 14449 |
|
14431 | 14450 |
# Check whether --enable-experimental was given. |
14432 | 14451 |
if test "${enable_experimental+set}" = set; then : |
... | ... |
@@ -417,6 +417,8 @@ AC_COMPILE_CHECK_SIZEOF([long long]) |
417 | 417 |
AC_COMPILE_CHECK_SIZEOF([void *]) |
418 | 418 |
|
419 | 419 |
AC_CHECK_FUNCS([sysctlbyname]) |
420 |
+AC_CHECK_FUNCS([getifaddrs]) |
|
421 |
+AC_CHECK_HEADER([fcntl.h], AC_DEFINE([HAVE_FCNTL_H],1,[Define to 1 if you have the <fcntl.h> header file])) |
|
420 | 422 |
|
421 | 423 |
AC_ARG_ENABLE([experimental], |
422 | 424 |
[ --enable-experimental enable experimental code], |
3174 | 3176 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,187 @@ |
0 |
+#if HAVE_CONFIG_H |
|
1 |
+#include "clamav-config.h" |
|
2 |
+#endif |
|
3 |
+ |
|
4 |
+#include <stdio.h> |
|
5 |
+#include <stdlib.h> |
|
6 |
+#include <string.h> |
|
7 |
+#include <unistd.h> |
|
8 |
+ |
|
9 |
+#include <sys/types.h> |
|
10 |
+#include <sys/socket.h> |
|
11 |
+#include <netdb.h> |
|
12 |
+#include <sys/ioctl.h> |
|
13 |
+#include <fcntl.h> |
|
14 |
+ |
|
15 |
+#if defined(SIOCGIFHWADDR) |
|
16 |
+#include <net/if.h> |
|
17 |
+#include <ifaddrs.h> |
|
18 |
+#include <linux/sockios.h> |
|
19 |
+#endif |
|
20 |
+ |
|
21 |
+#include <errno.h> |
|
22 |
+ |
|
23 |
+#include "hostid.h" |
|
24 |
+#include "libclamav/md5.h" |
|
25 |
+ |
|
26 |
+struct device *get_device_entry(struct device *devices, size_t *ndevices, const char *name) |
|
27 |
+{ |
|
28 |
+ struct device *device; |
|
29 |
+ void *p; |
|
30 |
+ size_t i; |
|
31 |
+ |
|
32 |
+ if ((devices)) { |
|
33 |
+ int found = 0; |
|
34 |
+ |
|
35 |
+ for (device = devices; device < devices + *ndevices; device++) { |
|
36 |
+ if (!strcmp(device->name, name)) { |
|
37 |
+ found = 1; |
|
38 |
+ break; |
|
39 |
+ } |
|
40 |
+ } |
|
41 |
+ |
|
42 |
+ if (!found) { |
|
43 |
+ p = realloc(devices, sizeof(struct device) * (*ndevices + 1)); |
|
44 |
+ if (!(p)) { |
|
45 |
+ for (i=0; i < *ndevices; i++) |
|
46 |
+ free(devices[i].name); |
|
47 |
+ free(devices); |
|
48 |
+ return NULL; |
|
49 |
+ } |
|
50 |
+ |
|
51 |
+ devices = p; |
|
52 |
+ device = devices + *ndevices; |
|
53 |
+ (*ndevices)++; |
|
54 |
+ memset(device, 0x00, sizeof(struct device)); |
|
55 |
+ } |
|
56 |
+ } else { |
|
57 |
+ devices = calloc(1, sizeof(device)); |
|
58 |
+ if (!(devices)) |
|
59 |
+ return NULL; |
|
60 |
+ |
|
61 |
+ device = devices; |
|
62 |
+ *ndevices = 1; |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ if (!(device->name)) |
|
66 |
+ device->name = strdup(name); |
|
67 |
+ return devices; |
|
68 |
+} |
|
69 |
+ |
|
70 |
+#if HAVE_GETIFADDRS |
|
71 |
+struct device *get_devices(void) |
|
72 |
+{ |
|
73 |
+ struct ifaddrs *addrs, *addr; |
|
74 |
+ struct device *devices=NULL, *device=NULL; |
|
75 |
+ size_t ndevices=0, i; |
|
76 |
+ struct ifreq ifr; |
|
77 |
+ void *p; |
|
78 |
+ uint8_t *mac; |
|
79 |
+ int sock; |
|
80 |
+ |
|
81 |
+ if (getifaddrs(&addrs)) |
|
82 |
+ return NULL; |
|
83 |
+ |
|
84 |
+ for (addr = addrs; addr != NULL; addr = addr->ifa_next) { |
|
85 |
+ if (!(addr->ifa_addr)) |
|
86 |
+ continue; |
|
87 |
+ |
|
88 |
+ if (addr->ifa_addr->sa_family != AF_PACKET) |
|
89 |
+ continue; |
|
90 |
+ |
|
91 |
+ devices = get_device_entry(devices, &ndevices, addr->ifa_name); |
|
92 |
+ if (!(devices)) { |
|
93 |
+ freeifaddrs(addrs); |
|
94 |
+ return NULL; |
|
95 |
+ } |
|
96 |
+ } |
|
97 |
+ |
|
98 |
+ if (addrs) { |
|
99 |
+ freeifaddrs(addrs); |
|
100 |
+ addrs = NULL; |
|
101 |
+ } |
|
102 |
+ |
|
103 |
+ sock = socket(AF_INET, SOCK_DGRAM, 0); |
|
104 |
+ if (sock < 0) |
|
105 |
+ goto err; |
|
106 |
+ |
|
107 |
+#if defined(SIOCGIFHWADDR) |
|
108 |
+ for (device = devices; device < devices + (ndevices); device++) { |
|
109 |
+ memset(&ifr, 0x00, sizeof(struct ifreq)); |
|
110 |
+ strcpy(ifr.ifr_name, device->name); |
|
111 |
+ if (ioctl(sock, SIOCGIFHWADDR, &ifr)) { |
|
112 |
+ close(sock); |
|
113 |
+ goto err; |
|
114 |
+ } |
|
115 |
+ |
|
116 |
+ mac = ((uint8_t *)(ifr.ifr_ifru.ifru_hwaddr.sa_data)); |
|
117 |
+ for (i=0; i<6; i++) |
|
118 |
+ snprintf(device->mac+strlen(device->mac), sizeof(device->mac)-strlen(device->mac)-1, "%02x:", mac[i]); |
|
119 |
+ } |
|
120 |
+#endif |
|
121 |
+ |
|
122 |
+ close(sock); |
|
123 |
+ |
|
124 |
+ p = realloc(devices, sizeof(struct device) * (ndevices + 1)); |
|
125 |
+ if (!(p)) |
|
126 |
+ goto err; |
|
127 |
+ |
|
128 |
+ devices = p; |
|
129 |
+ devices[ndevices].name = NULL; |
|
130 |
+ memset(devices[ndevices].mac, 0x00, sizeof(devices[ndevices].mac)); |
|
131 |
+ |
|
132 |
+ return devices; |
|
133 |
+ |
|
134 |
+err: |
|
135 |
+ if (addrs) |
|
136 |
+ freeifaddrs(addrs); |
|
137 |
+ if (devices) { |
|
138 |
+ for (device = devices; device < devices + ndevices; device++) |
|
139 |
+ if (device->name) |
|
140 |
+ free(device->name); |
|
141 |
+ |
|
142 |
+ free(devices); |
|
143 |
+ } |
|
144 |
+ |
|
145 |
+ return NULL; |
|
146 |
+} |
|
147 |
+#else |
|
148 |
+struct device *get_devices(void) |
|
149 |
+{ |
|
150 |
+ return NULL; |
|
151 |
+} |
|
152 |
+#endif /* HAVE_GETIFADDRS */ |
|
153 |
+ |
|
154 |
+#if !HAVE_SYSCTLBYNAME && !defined(_WIN32) |
|
155 |
+char *internal_get_host_id(void) |
|
156 |
+{ |
|
157 |
+ size_t i; |
|
158 |
+ unsigned char raw_md5[16]; |
|
159 |
+ char *printable_md5; |
|
160 |
+ cli_md5_ctx ctx; |
|
161 |
+ struct device *devices; |
|
162 |
+ |
|
163 |
+ devices = get_devices(); |
|
164 |
+ if (!(devices)) |
|
165 |
+ return NULL; |
|
166 |
+ |
|
167 |
+ printable_md5 = calloc(1, 33); |
|
168 |
+ if (!(printable_md5)) |
|
169 |
+ return NULL; |
|
170 |
+ |
|
171 |
+ cli_md5_init(&ctx); |
|
172 |
+ for (i=0; devices[i].name != NULL; i++) |
|
173 |
+ cli_md5_update(&ctx, devices[i].mac, sizeof(devices[i].mac)); |
|
174 |
+ |
|
175 |
+ cli_md5_final(raw_md5, &ctx); |
|
176 |
+ |
|
177 |
+ for (i=0; devices[i].name != NULL; i++) |
|
178 |
+ free(devices[i].name); |
|
179 |
+ free(devices); |
|
180 |
+ |
|
181 |
+ for (i=0; i < sizeof(raw_md5); i++) |
|
182 |
+ sprintf(printable_md5+(i*2), "%02x", raw_md5[i]); |
|
183 |
+ |
|
184 |
+ return printable_md5; |
|
185 |
+} |
|
186 |
+#endif |
0 | 187 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,15 @@ |
0 |
+#if !defined(_LIBCLAMAV_HOSTID_H) |
|
1 |
+#define _LIBCLAMAV_HOSTID_H |
|
2 |
+ |
|
3 |
+struct device { |
|
4 |
+ char *name; |
|
5 |
+ char mac[19]; |
|
6 |
+}; |
|
7 |
+ |
|
8 |
+struct device *get_devices(void); |
|
9 |
+ |
|
10 |
+#if !HAVE_SYSCTLBYNAME |
|
11 |
+char *internal_get_host_id(void); |
|
12 |
+#endif |
|
13 |
+ |
|
14 |
+#endif |
... | ... |
@@ -23,6 +23,7 @@ |
23 | 23 |
#include "libclamav/clamav.h" |
24 | 24 |
#include "libclamav/json.h" |
25 | 25 |
#include "libclamav/stats.h" |
26 |
+#include "libclamav/hostid.h" |
|
26 | 27 |
|
27 | 28 |
static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type); |
28 | 29 |
void free_sample(cli_flagged_sample_t *sample); |
... | ... |
@@ -400,7 +401,10 @@ char *clamav_stats_get_hostid(void *cbdata) |
400 | 400 |
return buf; |
401 | 401 |
} |
402 | 402 |
#else |
403 |
+ buf = internal_get_host_id(); |
|
404 |
+ if (!(buf)) |
|
403 | 405 |
return strdup(STATS_ANON_UUID); |
406 |
+ return buf; |
|
404 | 407 |
#endif |
405 | 408 |
|
406 | 409 |
return strdup(STATS_ANON_UUID); |