summaryrefslogtreecommitdiff
path: root/src/nt/nt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nt/nt.c')
-rw-r--r--src/nt/nt.c392
1 files changed, 203 insertions, 189 deletions
diff --git a/src/nt/nt.c b/src/nt/nt.c
index 696088b5b..98653f641 100644
--- a/src/nt/nt.c
+++ b/src/nt/nt.c
@@ -30,7 +30,8 @@
30/** 30/**
31 * How frequently do we scan the interfaces for changes to the addresses? 31 * How frequently do we scan the interfaces for changes to the addresses?
32 */ 32 */
33#define INTERFACE_PROCESSING_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 33#define INTERFACE_PROCESSING_INTERVAL GNUNET_TIME_relative_multiply ( \
34 GNUNET_TIME_UNIT_MINUTES, 2)
34 35
35 36
36/** 37/**
@@ -40,31 +41,31 @@
40 * @return a string or NULL if invalid 41 * @return a string or NULL if invalid
41 */ 42 */
42const char * 43const char *
43GNUNET_NT_to_string(enum GNUNET_NetworkType net) 44GNUNET_NT_to_string (enum GNUNET_NetworkType net)
44{ 45{
45 switch (net) 46 switch (net)
46 { 47 {
47 case GNUNET_NT_UNSPECIFIED: 48 case GNUNET_NT_UNSPECIFIED:
48 return "UNSPECIFIED"; 49 return "UNSPECIFIED";
49 50
50 case GNUNET_NT_LOOPBACK: 51 case GNUNET_NT_LOOPBACK:
51 return "LOOPBACK"; 52 return "LOOPBACK";
52 53
53 case GNUNET_NT_LAN: 54 case GNUNET_NT_LAN:
54 return "LAN"; 55 return "LAN";
55 56
56 case GNUNET_NT_WAN: 57 case GNUNET_NT_WAN:
57 return "WAN"; 58 return "WAN";
58 59
59 case GNUNET_NT_WLAN: 60 case GNUNET_NT_WLAN:
60 return "WLAN"; 61 return "WLAN";
61 62
62 case GNUNET_NT_BT: 63 case GNUNET_NT_BT:
63 return "BLUETOOTH"; 64 return "BLUETOOTH";
64 65
65 default: 66 default:
66 return NULL; 67 return NULL;
67 } 68 }
68} 69}
69 70
70 71
@@ -74,7 +75,8 @@ GNUNET_NT_to_string(enum GNUNET_NetworkType net)
74 * (maybe we can do that heuristically based on interface 75 * (maybe we can do that heuristically based on interface
75 * name in the future?). 76 * name in the future?).
76 */ 77 */
77struct NT_Network { 78struct NT_Network
79{
78 /** 80 /**
79 * Kept in a DLL. 81 * Kept in a DLL.
80 */ 82 */
@@ -105,7 +107,8 @@ struct NT_Network {
105/** 107/**
106 * Handle to the interface scanner. 108 * Handle to the interface scanner.
107 */ 109 */
108struct GNUNET_NT_InterfaceScanner { 110struct GNUNET_NT_InterfaceScanner
111{
109 /** 112 /**
110 * Head of LAN networks list. 113 * Head of LAN networks list.
111 */ 114 */
@@ -129,17 +132,17 @@ struct GNUNET_NT_InterfaceScanner {
129 * @param is scanner to clean up 132 * @param is scanner to clean up
130 */ 133 */
131static void 134static void
132delete_networks(struct GNUNET_NT_InterfaceScanner *is) 135delete_networks (struct GNUNET_NT_InterfaceScanner *is)
133{ 136{
134 struct NT_Network *cur; 137 struct NT_Network *cur;
135 138
136 while (NULL != (cur = is->net_head)) 139 while (NULL != (cur = is->net_head))
137 { 140 {
138 GNUNET_CONTAINER_DLL_remove(is->net_head, 141 GNUNET_CONTAINER_DLL_remove (is->net_head,
139 is->net_tail, 142 is->net_tail,
140 cur); 143 cur);
141 GNUNET_free(cur); 144 GNUNET_free (cur);
142 } 145 }
143} 146}
144 147
145 148
@@ -158,117 +161,121 @@ delete_networks(struct GNUNET_NT_InterfaceScanner *is)
158 * @return #GNUNET_OK to continue iteration 161 * @return #GNUNET_OK to continue iteration
159 */ 162 */
160static int 163static int
161interface_proc(void *cls, 164interface_proc (void *cls,
162 const char *name, 165 const char *name,
163 int isDefault, 166 int isDefault,
164 const struct sockaddr *addr, 167 const struct sockaddr *addr,
165 const struct sockaddr *broadcast_addr, 168 const struct sockaddr *broadcast_addr,
166 const struct sockaddr *netmask, 169 const struct sockaddr *netmask,
167 socklen_t addrlen) 170 socklen_t addrlen)
168{ 171{
169 struct GNUNET_NT_InterfaceScanner *is = cls; 172 struct GNUNET_NT_InterfaceScanner *is = cls;
170 /* Calculate network */ 173 /* Calculate network */
171 struct NT_Network *net = NULL; 174 struct NT_Network *net = NULL;
172 175
173 (void)name; 176 (void) name;
174 (void)isDefault; 177 (void) isDefault;
175 (void)broadcast_addr; 178 (void) broadcast_addr;
176 179
177 /* Skipping IPv4 loopback addresses since we have special check */ 180 /* Skipping IPv4 loopback addresses since we have special check */
178 if (addr->sa_family == AF_INET) 181 if (addr->sa_family == AF_INET)
179 { 182 {
180 const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr; 183 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
181 184
182 if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl(0x7f000000)) 185 if ((a4->sin_addr.s_addr & htonl (0xff000000)) == htonl (0x7f000000))
183 return GNUNET_OK; 186 return GNUNET_OK;
184 } 187 }
185 /* Skipping IPv6 loopback addresses since we have special check */ 188 /* Skipping IPv6 loopback addresses since we have special check */
186 if (addr->sa_family == AF_INET6) 189 if (addr->sa_family == AF_INET6)
187 { 190 {
188 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr; 191 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
189 if (IN6_IS_ADDR_LOOPBACK(&a6->sin6_addr)) 192 if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr))
190 return GNUNET_OK; 193 return GNUNET_OK;
191 } 194 }
192 195
193 if (addr->sa_family == AF_INET) 196 if (addr->sa_family == AF_INET)
194 { 197 {
195 const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr; 198 const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr;
196 const struct sockaddr_in *netmask4 = (const struct sockaddr_in *)netmask; 199 const struct sockaddr_in *netmask4 = (const struct sockaddr_in *) netmask;
197 struct sockaddr_in *tmp; 200 struct sockaddr_in *tmp;
198 struct sockaddr_in network4; 201 struct sockaddr_in network4;
199 202
200 net = GNUNET_malloc(sizeof(struct NT_Network) + 2 * sizeof(struct sockaddr_in)); 203 net = GNUNET_malloc (sizeof(struct NT_Network) + 2 * sizeof(struct
201 tmp = (struct sockaddr_in *)&net[1]; 204 sockaddr_in));
202 net->network = (struct sockaddr *)&tmp[0]; 205 tmp = (struct sockaddr_in *) &net[1];
203 net->netmask = (struct sockaddr *)&tmp[1]; 206 net->network = (struct sockaddr *) &tmp[0];
204 net->length = addrlen; 207 net->netmask = (struct sockaddr *) &tmp[1];
205 208 net->length = addrlen;
206 memset(&network4, 209
207 0, 210 memset (&network4,
208 sizeof(network4)); 211 0,
209 network4.sin_family = AF_INET; 212 sizeof(network4));
213 network4.sin_family = AF_INET;
210#if HAVE_SOCKADDR_IN_SIN_LEN 214#if HAVE_SOCKADDR_IN_SIN_LEN
211 network4.sin_len = sizeof(network4); 215 network4.sin_len = sizeof(network4);
212#endif 216#endif
213 network4.sin_addr.s_addr = (addr4->sin_addr.s_addr & netmask4->sin_addr.s_addr); 217 network4.sin_addr.s_addr = (addr4->sin_addr.s_addr
214 218 & netmask4->sin_addr.s_addr);
215 GNUNET_memcpy(net->netmask, 219
216 netmask4, 220 GNUNET_memcpy (net->netmask,
217 sizeof(struct sockaddr_in)); 221 netmask4,
218 GNUNET_memcpy(net->network, 222 sizeof(struct sockaddr_in));
219 &network4, 223 GNUNET_memcpy (net->network,
220 sizeof(struct sockaddr_in)); 224 &network4,
221 } 225 sizeof(struct sockaddr_in));
226 }
222 227
223 if (addr->sa_family == AF_INET6) 228 if (addr->sa_family == AF_INET6)
224 { 229 {
225 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; 230 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
226 const struct sockaddr_in6 *netmask6 = (const struct sockaddr_in6 *)netmask; 231 const struct sockaddr_in6 *netmask6 = (const struct sockaddr_in6 *) netmask;
227 struct sockaddr_in6 * tmp; 232 struct sockaddr_in6 *tmp;
228 struct sockaddr_in6 network6; 233 struct sockaddr_in6 network6;
229 234
230 net = GNUNET_malloc(sizeof(struct NT_Network) + 2 * sizeof(struct sockaddr_in6)); 235 net = GNUNET_malloc (sizeof(struct NT_Network) + 2 * sizeof(struct
231 tmp = (struct sockaddr_in6 *)&net[1]; 236 sockaddr_in6));
232 net->network = (struct sockaddr *)&tmp[0]; 237 tmp = (struct sockaddr_in6 *) &net[1];
233 net->netmask = (struct sockaddr *)&tmp[1]; 238 net->network = (struct sockaddr *) &tmp[0];
234 net->length = addrlen; 239 net->netmask = (struct sockaddr *) &tmp[1];
235 240 net->length = addrlen;
236 memset(&network6, 0, sizeof(network6)); 241
237 network6.sin6_family = AF_INET6; 242 memset (&network6, 0, sizeof(network6));
243 network6.sin6_family = AF_INET6;
238#if HAVE_SOCKADDR_IN_SIN_LEN 244#if HAVE_SOCKADDR_IN_SIN_LEN
239 network6.sin6_len = sizeof(network6); 245 network6.sin6_len = sizeof(network6);
240#endif 246#endif
241 unsigned int c = 0; 247 unsigned int c = 0;
242 uint32_t *addr_elem = (uint32_t *)&addr6->sin6_addr; 248 uint32_t *addr_elem = (uint32_t *) &addr6->sin6_addr;
243 uint32_t *mask_elem = (uint32_t *)&netmask6->sin6_addr; 249 uint32_t *mask_elem = (uint32_t *) &netmask6->sin6_addr;
244 uint32_t *net_elem = (uint32_t *)&network6.sin6_addr; 250 uint32_t *net_elem = (uint32_t *) &network6.sin6_addr;
245 for (c = 0; c < 4; c++) 251 for (c = 0; c < 4; c++)
246 net_elem[c] = addr_elem[c] & mask_elem[c]; 252 net_elem[c] = addr_elem[c] & mask_elem[c];
247 253
248 GNUNET_memcpy(net->netmask, 254 GNUNET_memcpy (net->netmask,
249 netmask6, 255 netmask6,
250 sizeof(struct sockaddr_in6)); 256 sizeof(struct sockaddr_in6));
251 GNUNET_memcpy(net->network, 257 GNUNET_memcpy (net->network,
252 &network6, 258 &network6,
253 sizeof(struct sockaddr_in6)); 259 sizeof(struct sockaddr_in6));
254 } 260 }
255 if (NULL == net) 261 if (NULL == net)
256 return GNUNET_OK; /* odd / unsupported address family */ 262 return GNUNET_OK; /* odd / unsupported address family */
257 263
258 /* Store in list */ 264 /* Store in list */
259#if VERBOSE_NT 265#if VERBOSE_NT
260 char * netmask = GNUNET_strdup(GNUNET_a2s((struct sockaddr *)net->netmask, addrlen)); 266 char *netmask = GNUNET_strdup (GNUNET_a2s ((struct sockaddr *) net->netmask,
261 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, 267 addrlen));
262 "nt", 268 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
263 "Adding network `%s', netmask `%s'\n", 269 "nt",
264 GNUNET_a2s((struct sockaddr *)net->network, 270 "Adding network `%s', netmask `%s'\n",
265 addrlen), 271 GNUNET_a2s ((struct sockaddr *) net->network,
266 netmask); 272 addrlen),
267 GNUNET_free(netmask); 273 netmask);
274 GNUNET_free (netmask);
268#endif 275#endif
269 GNUNET_CONTAINER_DLL_insert(is->net_head, 276 GNUNET_CONTAINER_DLL_insert (is->net_head,
270 is->net_tail, 277 is->net_tail,
271 net); 278 net);
272 279
273 return GNUNET_OK; 280 return GNUNET_OK;
274} 281}
@@ -280,17 +287,18 @@ interface_proc(void *cls,
280 * @param cls closure 287 * @param cls closure
281 */ 288 */
282static void 289static void
283get_addresses(void *cls) 290get_addresses (void *cls)
284{ 291{
285 struct GNUNET_NT_InterfaceScanner *is = cls; 292 struct GNUNET_NT_InterfaceScanner *is = cls;
286 293
287 is->interface_task = NULL; 294 is->interface_task = NULL;
288 delete_networks(is); 295 delete_networks (is);
289 GNUNET_OS_network_interfaces_list(&interface_proc, 296 GNUNET_OS_network_interfaces_list (&interface_proc,
290 is); 297 is);
291 is->interface_task = GNUNET_SCHEDULER_add_delayed(INTERFACE_PROCESSING_INTERVAL, 298 is->interface_task = GNUNET_SCHEDULER_add_delayed (
292 &get_addresses, 299 INTERFACE_PROCESSING_INTERVAL,
293 is); 300 &get_addresses,
301 is);
294} 302}
295 303
296 304
@@ -303,89 +311,94 @@ get_addresses(void *cls)
303 * @return type of the network the address belongs to 311 * @return type of the network the address belongs to
304 */ 312 */
305enum GNUNET_NetworkType 313enum GNUNET_NetworkType
306GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, 314GNUNET_NT_scanner_get_type (struct GNUNET_NT_InterfaceScanner *is,
307 const struct sockaddr *addr, 315 const struct sockaddr *addr,
308 socklen_t addrlen) 316 socklen_t addrlen)
309{ 317{
310 struct NT_Network *cur = is->net_head; 318 struct NT_Network *cur = is->net_head;
311 enum GNUNET_NetworkType type = GNUNET_NT_UNSPECIFIED; 319 enum GNUNET_NetworkType type = GNUNET_NT_UNSPECIFIED;
312 320
313 switch (addr->sa_family) 321 switch (addr->sa_family)
314 { 322 {
315 case AF_UNIX: 323 case AF_UNIX:
316 type = GNUNET_NT_LOOPBACK; 324 type = GNUNET_NT_LOOPBACK;
317 break; 325 break;
318 326
319 case AF_INET: 327 case AF_INET:
320 { 328 {
321 const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr; 329 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
322 330
323 if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl(0x7f000000)) 331 if ((a4->sin_addr.s_addr & htonl (0xff000000)) == htonl (0x7f000000))
324 type = GNUNET_NT_LOOPBACK; 332 type = GNUNET_NT_LOOPBACK;
325 break; 333 break;
326 } 334 }
327 335
328 case AF_INET6: 336 case AF_INET6:
329 { 337 {
330 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr; 338 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
331 339
332 if (IN6_IS_ADDR_LOOPBACK(&a6->sin6_addr)) 340 if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr))
333 type = GNUNET_NT_LOOPBACK; 341 type = GNUNET_NT_LOOPBACK;
334 break; 342 break;
335 } 343 }
336 344
337 default: 345 default:
338 GNUNET_break(0); 346 GNUNET_break (0);
339 break; 347 break;
340 } 348 }
341 349
342 /* Check local networks */ 350 /* Check local networks */
343 while ((NULL != cur) && (GNUNET_NT_UNSPECIFIED == type)) 351 while ((NULL != cur) && (GNUNET_NT_UNSPECIFIED == type))
352 {
353 if (addrlen != cur->length)
344 { 354 {
345 if (addrlen != cur->length)
346 {
347 cur = cur->next;
348 continue;
349 }
350 if (addr->sa_family == AF_INET)
351 {
352 const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr;
353 const struct sockaddr_in *net4 = (const struct sockaddr_in *)cur->network;
354 const struct sockaddr_in *mask4 = (const struct sockaddr_in *)cur->netmask;
355
356 if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr)
357 type = GNUNET_NT_LAN;
358 }
359 if (addr->sa_family == AF_INET6)
360 {
361 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr;
362 const struct sockaddr_in6 *net6 = (const struct sockaddr_in6 *)cur->network;
363 const struct sockaddr_in6 *mask6 = (const struct sockaddr_in6 *)cur->netmask;
364
365 int res = GNUNET_YES;
366 int c = 0;
367 uint32_t *addr_elem = (uint32_t *)&a6->sin6_addr;
368 uint32_t *mask_elem = (uint32_t *)&mask6->sin6_addr;
369 uint32_t *net_elem = (uint32_t *)&net6->sin6_addr;
370 for (c = 0; c < 4; c++)
371 if ((addr_elem[c] & mask_elem[c]) != net_elem[c])
372 res = GNUNET_NO;
373
374 if (res == GNUNET_YES)
375 type = GNUNET_NT_LAN;
376 }
377 cur = cur->next; 355 cur = cur->next;
356 continue;
357 }
358 if (addr->sa_family == AF_INET)
359 {
360 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
361 const struct sockaddr_in *net4 = (const struct
362 sockaddr_in *) cur->network;
363 const struct sockaddr_in *mask4 = (const struct
364 sockaddr_in *) cur->netmask;
365
366 if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) ==
367 net4->sin_addr.s_addr)
368 type = GNUNET_NT_LAN;
378 } 369 }
370 if (addr->sa_family == AF_INET6)
371 {
372 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
373 const struct sockaddr_in6 *net6 = (const struct
374 sockaddr_in6 *) cur->network;
375 const struct sockaddr_in6 *mask6 = (const struct
376 sockaddr_in6 *) cur->netmask;
377
378 int res = GNUNET_YES;
379 int c = 0;
380 uint32_t *addr_elem = (uint32_t *) &a6->sin6_addr;
381 uint32_t *mask_elem = (uint32_t *) &mask6->sin6_addr;
382 uint32_t *net_elem = (uint32_t *) &net6->sin6_addr;
383 for (c = 0; c < 4; c++)
384 if ((addr_elem[c] & mask_elem[c]) != net_elem[c])
385 res = GNUNET_NO;
386
387 if (res == GNUNET_YES)
388 type = GNUNET_NT_LAN;
389 }
390 cur = cur->next;
391 }
379 392
380 /* no local network found for this address, default: WAN */ 393 /* no local network found for this address, default: WAN */
381 if (type == GNUNET_NT_UNSPECIFIED) 394 if (type == GNUNET_NT_UNSPECIFIED)
382 type = GNUNET_NT_WAN; 395 type = GNUNET_NT_WAN;
383 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, 396 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
384 "nt-scanner-api", 397 "nt-scanner-api",
385 "`%s' is in network `%s'\n", 398 "`%s' is in network `%s'\n",
386 GNUNET_a2s(addr, 399 GNUNET_a2s (addr,
387 addrlen), 400 addrlen),
388 GNUNET_NT_to_string(type)); 401 GNUNET_NT_to_string (type));
389 return type; 402 return type;
390} 403}
391 404
@@ -396,16 +409,17 @@ GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is,
396 * @return interface scanner 409 * @return interface scanner
397 */ 410 */
398struct GNUNET_NT_InterfaceScanner * 411struct GNUNET_NT_InterfaceScanner *
399GNUNET_NT_scanner_init() 412GNUNET_NT_scanner_init ()
400{ 413{
401 struct GNUNET_NT_InterfaceScanner *is; 414 struct GNUNET_NT_InterfaceScanner *is;
402 415
403 is = GNUNET_new(struct GNUNET_NT_InterfaceScanner); 416 is = GNUNET_new (struct GNUNET_NT_InterfaceScanner);
404 GNUNET_OS_network_interfaces_list(&interface_proc, 417 GNUNET_OS_network_interfaces_list (&interface_proc,
405 is); 418 is);
406 is->interface_task = GNUNET_SCHEDULER_add_delayed(INTERFACE_PROCESSING_INTERVAL, 419 is->interface_task = GNUNET_SCHEDULER_add_delayed (
407 &get_addresses, 420 INTERFACE_PROCESSING_INTERVAL,
408 is); 421 &get_addresses,
422 is);
409 return is; 423 return is;
410} 424}
411 425
@@ -416,15 +430,15 @@ GNUNET_NT_scanner_init()
416 * @param is handle to release 430 * @param is handle to release
417 */ 431 */
418void 432void
419GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is) 433GNUNET_NT_scanner_done (struct GNUNET_NT_InterfaceScanner *is)
420{ 434{
421 if (NULL != is->interface_task) 435 if (NULL != is->interface_task)
422 { 436 {
423 GNUNET_SCHEDULER_cancel(is->interface_task); 437 GNUNET_SCHEDULER_cancel (is->interface_task);
424 is->interface_task = NULL; 438 is->interface_task = NULL;
425 } 439 }
426 delete_networks(is); 440 delete_networks (is);
427 GNUNET_free(is); 441 GNUNET_free (is);
428} 442}
429 443
430 444