GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
nt.c File Reference

LAN interface scanning to determine IPs in LAN. More...

#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for nt.c:

Go to the source code of this file.

Data Structures

struct  NT_Network
 We keep a list of our local networks so we can answer LAN vs. More...
 
struct  GNUNET_NT_InterfaceScanner
 Handle to the interface scanner. More...
 

Macros

#define INTERFACE_PROCESSING_INTERVAL
 How frequently do we scan the interfaces for changes to the addresses?
 

Functions

const char * GNUNET_NT_to_string (enum GNUNET_NetworkType net)
 Convert a enum GNUNET_NetworkType to a string.
 
static void delete_networks (struct GNUNET_NT_InterfaceScanner *is)
 Delete all entries from the current network list.
 
static int interface_proc (void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
 Function invoked for each interface found.
 
static void get_addresses (void *cls)
 Periodically get list of network addresses from our interfaces.
 
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type (struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
 Returns where the address is located: LAN or WAN or ...
 
struct GNUNET_NT_InterfaceScannerGNUNET_NT_scanner_init ()
 Initialize the interface scanner.
 
void GNUNET_NT_scanner_done (struct GNUNET_NT_InterfaceScanner *is)
 Client is done with the interface scanner, release resources.
 

Detailed Description

LAN interface scanning to determine IPs in LAN.

Author
Christian Grothoff
Matthias Wachs

Definition in file nt.c.

Macro Definition Documentation

◆ INTERFACE_PROCESSING_INTERVAL

#define INTERFACE_PROCESSING_INTERVAL
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

How frequently do we scan the interfaces for changes to the addresses?

Definition at line 32 of file nt.c.

37{
38 switch (net)
39 {
41 return "UNSPECIFIED";
42
44 return "LOOPBACK";
45
46 case GNUNET_NT_LAN:
47 return "LAN";
48
49 case GNUNET_NT_WAN:
50 return "WAN";
51
52 case GNUNET_NT_WLAN:
53 return "WLAN";
54
55 case GNUNET_NT_BT:
56 return "BLUETOOTH";
57
58 default:
59 return NULL;
60 }
61}
62
63
70struct NT_Network
71{
75 struct NT_Network *next;
76
80 struct NT_Network *prev;
81
85 struct sockaddr *network;
86
90 struct sockaddr *netmask;
91
95 socklen_t length;
96};
97
98
103{
107 struct NT_Network *net_head;
108
112 struct NT_Network *net_tail;
113
118};
119
120
126static void
128{
129 struct NT_Network *cur;
130
131 while (NULL != (cur = is->net_head))
132 {
134 is->net_tail,
135 cur);
136 GNUNET_free (cur);
137 }
138}
139
140
155static int
156interface_proc (void *cls,
157 const char *name,
158 int isDefault,
159 const struct sockaddr *addr,
160 const struct sockaddr *broadcast_addr,
161 const struct sockaddr *netmask,
162 socklen_t addrlen)
163{
164 struct GNUNET_NT_InterfaceScanner *is = cls;
165 /* Calculate network */
166 struct NT_Network *net = NULL;
167
168 (void) name;
169 (void) isDefault;
170 (void) broadcast_addr;
171
172 /* Skipping IPv4 loopback addresses since we have special check */
173 if (addr->sa_family == AF_INET)
174 {
175 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
176
177 if ((a4->sin_addr.s_addr & htonl (0xff000000)) == htonl (0x7f000000))
178 return GNUNET_OK;
179 }
180 /* Skipping IPv6 loopback addresses since we have special check */
181 if (addr->sa_family == AF_INET6)
182 {
183 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
184 if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr))
185 return GNUNET_OK;
186 }
187
188 if (addr->sa_family == AF_INET)
189 {
190 const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr;
191 const struct sockaddr_in *netmask4 = (const struct sockaddr_in *) netmask;
192 struct sockaddr_in *tmp;
193 struct sockaddr_in network4;
194
195 net = GNUNET_malloc (sizeof(struct NT_Network) + 2 * sizeof(struct
196 sockaddr_in));
197 tmp = (struct sockaddr_in *) &net[1];
198 net->network = (struct sockaddr *) &tmp[0];
199 net->netmask = (struct sockaddr *) &tmp[1];
200 net->length = addrlen;
201
202 memset (&network4,
203 0,
204 sizeof(network4));
205 network4.sin_family = AF_INET;
206#if HAVE_SOCKADDR_IN_SIN_LEN
207 network4.sin_len = sizeof(network4);
208#endif
209 network4.sin_addr.s_addr = (addr4->sin_addr.s_addr
210 & netmask4->sin_addr.s_addr);
211
212 GNUNET_memcpy (net->netmask,
213 netmask4,
214 sizeof(struct sockaddr_in));
215 GNUNET_memcpy (net->network,
216 &network4,
217 sizeof(struct sockaddr_in));
218 }
219
220 if (addr->sa_family == AF_INET6)
221 {
222 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
223 const struct sockaddr_in6 *netmask6 = (const struct sockaddr_in6 *) netmask;
224 struct sockaddr_in6 *tmp;
225 struct sockaddr_in6 network6;
226
227 net = GNUNET_malloc (sizeof(struct NT_Network) + 2 * sizeof(struct
228 sockaddr_in6));
229 tmp = (struct sockaddr_in6 *) &net[1];
230 net->network = (struct sockaddr *) &tmp[0];
231 net->netmask = (struct sockaddr *) &tmp[1];
232 net->length = addrlen;
233
234 memset (&network6, 0, sizeof(network6));
235 network6.sin6_family = AF_INET6;
236#if HAVE_SOCKADDR_IN_SIN_LEN
237 network6.sin6_len = sizeof(network6);
238#endif
239 {
240 unsigned int c;
241 uint32_t *addr_elem = (uint32_t *) &addr6->sin6_addr;
242 uint32_t *mask_elem = (uint32_t *) &netmask6->sin6_addr;
243 uint32_t *net_elem = (uint32_t *) &network6.sin6_addr;
244 for (c = 0; c < 4; c++)
245 net_elem[c] = addr_elem[c] & mask_elem[c];
246
247 GNUNET_memcpy (net->netmask,
248 netmask6,
249 sizeof(struct sockaddr_in6));
250 GNUNET_memcpy (net->network,
251 &network6,
252 sizeof(struct sockaddr_in6));
253 }
254 }
255 if (NULL == net)
256 return GNUNET_OK; /* odd / unsupported address family */
257
258 /* Store in list */
259#if VERBOSE_NT
260 char *netmask = GNUNET_strdup (GNUNET_a2s ((struct sockaddr *) net->netmask,
261 addrlen));
263 "nt",
264 "Adding network `%s', netmask `%s'\n",
265 GNUNET_a2s ((struct sockaddr *) net->network,
266 addrlen),
267 netmask);
268 GNUNET_free (netmask);
269#endif
271 is->net_tail,
272 net);
273
274 return GNUNET_OK;
275}
276
277
283static void
284get_addresses (void *cls)
285{
286 struct GNUNET_NT_InterfaceScanner *is = cls;
287
288 is->interface_task = NULL;
291 is);
292 is->interface_task = GNUNET_SCHEDULER_add_delayed (
295 is);
296}
297
298
309 const struct sockaddr *addr,
310 socklen_t addrlen)
311{
312 struct NT_Network *cur = is->net_head;
314
315 switch (addr->sa_family)
316 {
317 case AF_UNIX:
319 break;
320
321 case AF_INET:
322 {
323 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
324
325 if ((a4->sin_addr.s_addr & htonl (0xff000000)) == htonl (0x7f000000))
327 break;
328 }
329
330 case AF_INET6:
331 {
332 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
333
334 if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr))
336 break;
337 }
338
339 default:
340 GNUNET_break (0);
341 break;
342 }
343
344 /* Check local networks */
345 while ((NULL != cur) && (GNUNET_NT_UNSPECIFIED == type))
346 {
347 if (addrlen != cur->length)
348 {
349 cur = cur->next;
350 continue;
351 }
352 if (addr->sa_family == AF_INET)
353 {
354 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
355 const struct sockaddr_in *net4 = (const struct
356 sockaddr_in *) cur->network;
357 const struct sockaddr_in *mask4 = (const struct
358 sockaddr_in *) cur->netmask;
359
360 if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) ==
361 net4->sin_addr.s_addr)
363 }
364 if (addr->sa_family == AF_INET6)
365 {
366 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
367 const struct sockaddr_in6 *net6 = (const struct
368 sockaddr_in6 *) cur->network;
369 const struct sockaddr_in6 *mask6 = (const struct
370 sockaddr_in6 *) cur->netmask;
371
372 int res = GNUNET_YES;
373 int c = 0;
374 uint32_t *addr_elem = (uint32_t *) &a6->sin6_addr;
375 uint32_t *mask_elem = (uint32_t *) &mask6->sin6_addr;
376 uint32_t *net_elem = (uint32_t *) &net6->sin6_addr;
377 for (c = 0; c < 4; c++)
378 if ((addr_elem[c] & mask_elem[c]) != net_elem[c])
379 res = GNUNET_NO;
380
381 if (res == GNUNET_YES)
383 }
384 cur = cur->next;
385 }
386
387 /* no local network found for this address, default: WAN */
391 "nt-scanner-api",
392 "`%s' is in network `%s'\n",
393 GNUNET_a2s (addr,
394 addrlen),
396 return type;
397}
398
399
407{
409
412 is);
413 is->interface_task = GNUNET_SCHEDULER_add_delayed (
416 is);
417 return is;
418}
419
420
426void
428{
429 if (NULL != is->interface_task)
430 {
431 GNUNET_SCHEDULER_cancel (is->interface_task);
432 is->interface_task = NULL;
433 }
435 GNUNET_free (is);
436}
437
438
439/* end of nt.c */
static struct GNUNET_TESTING_Interpreter * is
static char * name
Name (label) of the records to list.
static char * res
Currently read line or NULL on EOF.
static uint32_t type
Type string converted to DNS type value.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_log_from(kind, comp,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Client is done with the interface scanner, release resources.
Definition nt.c:428
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init()
Initialize the interface scanner.
Definition nt.c:407
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: LAN or WAN or ...
Definition nt.c:309
const char * GNUNET_NT_to_string(enum GNUNET_NetworkType net)
Convert a enum GNUNET_NetworkType to a string.
Definition nt.c:37
@ GNUNET_NT_WLAN
Wireless LAN (i.e.
@ GNUNET_NT_WAN
Wide area network (i.e.
@ GNUNET_NT_UNSPECIFIED
Category of last resort.
@ GNUNET_NT_LAN
Local area network.
@ GNUNET_NT_LOOPBACK
Loopback (same host).
@ GNUNET_NT_BT
Bluetooth LAN.
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition os_network.c:397
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1277
static int interface_proc(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Function invoked for each interface found.
Definition nt.c:157
static void delete_networks(struct GNUNET_NT_InterfaceScanner *is)
Delete all entries from the current network list.
Definition nt.c:128
#define INTERFACE_PROCESSING_INTERVAL
How frequently do we scan the interfaces for changes to the addresses?
Definition nt.c:32
static void get_addresses(void *cls)
Periodically get list of network addresses from our interfaces.
Definition nt.c:285
Handle to the interface scanner.
Definition nt.c:104
struct NT_Network * net_head
Head of LAN networks list.
Definition nt.c:108
struct NT_Network * net_tail
Tail of LAN networks list.
Definition nt.c:113
struct GNUNET_SCHEDULER_Task * interface_task
Task for periodically refreshing our LAN network list.
Definition nt.c:118
Entry in list of pending tasks.
Definition scheduler.c:136
We keep a list of our local networks so we can answer LAN vs.
Definition nt.c:72
struct NT_Network * next
Kept in a DLL.
Definition nt.c:76
socklen_t length
How long are network and netmask?
Definition nt.c:96
struct sockaddr * network
Network address.
Definition nt.c:86
struct NT_Network * prev
Kept in a DLL.
Definition nt.c:81
struct sockaddr * netmask
Netmask to determine what is in the LAN.
Definition nt.c:91

Function Documentation

◆ delete_networks()

static void delete_networks ( struct GNUNET_NT_InterfaceScanner is)
static

Delete all entries from the current network list.

Parameters
isscanner to clean up

Definition at line 128 of file nt.c.

129{
130 struct NT_Network *cur;
131
132 while (NULL != (cur = is->net_head))
133 {
135 is->net_tail,
136 cur);
137 GNUNET_free (cur);
138 }
139}

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, and is.

Referenced by get_addresses(), and GNUNET_NT_scanner_done().

Here is the caller graph for this function:

◆ interface_proc()

static int interface_proc ( void *  cls,
const char *  name,
int  isDefault,
const struct sockaddr *  addr,
const struct sockaddr *  broadcast_addr,
const struct sockaddr *  netmask,
socklen_t  addrlen 
)
static

Function invoked for each interface found.

Adds the interface's network addresses to the respective DLL, so we can distinguish between LAN and WAN.

Parameters
clsclosure with the struct GNUNET_NT_InterfaceScanner
namename of the interface (can be NULL for unknown)
isDefaultis this presumably the default interface
addraddress of this interface (can be NULL for unknown or unassigned)
broadcast_addrthe broadcast address (can be NULL for unknown or unassigned)
netmaskthe network mask (can be NULL for unknown or unassigned)
addrlenlength of the address
Returns
GNUNET_OK to continue iteration

Definition at line 157 of file nt.c.

164{
165 struct GNUNET_NT_InterfaceScanner *is = cls;
166 /* Calculate network */
167 struct NT_Network *net = NULL;
168
169 (void) name;
170 (void) isDefault;
171 (void) broadcast_addr;
172
173 /* Skipping IPv4 loopback addresses since we have special check */
174 if (addr->sa_family == AF_INET)
175 {
176 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
177
178 if ((a4->sin_addr.s_addr & htonl (0xff000000)) == htonl (0x7f000000))
179 return GNUNET_OK;
180 }
181 /* Skipping IPv6 loopback addresses since we have special check */
182 if (addr->sa_family == AF_INET6)
183 {
184 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
185 if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr))
186 return GNUNET_OK;
187 }
188
189 if (addr->sa_family == AF_INET)
190 {
191 const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr;
192 const struct sockaddr_in *netmask4 = (const struct sockaddr_in *) netmask;
193 struct sockaddr_in *tmp;
194 struct sockaddr_in network4;
195
196 net = GNUNET_malloc (sizeof(struct NT_Network) + 2 * sizeof(struct
197 sockaddr_in));
198 tmp = (struct sockaddr_in *) &net[1];
199 net->network = (struct sockaddr *) &tmp[0];
200 net->netmask = (struct sockaddr *) &tmp[1];
201 net->length = addrlen;
202
203 memset (&network4,
204 0,
205 sizeof(network4));
206 network4.sin_family = AF_INET;
207#if HAVE_SOCKADDR_IN_SIN_LEN
208 network4.sin_len = sizeof(network4);
209#endif
210 network4.sin_addr.s_addr = (addr4->sin_addr.s_addr
211 & netmask4->sin_addr.s_addr);
212
213 GNUNET_memcpy (net->netmask,
214 netmask4,
215 sizeof(struct sockaddr_in));
216 GNUNET_memcpy (net->network,
217 &network4,
218 sizeof(struct sockaddr_in));
219 }
220
221 if (addr->sa_family == AF_INET6)
222 {
223 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
224 const struct sockaddr_in6 *netmask6 = (const struct sockaddr_in6 *) netmask;
225 struct sockaddr_in6 *tmp;
226 struct sockaddr_in6 network6;
227
228 net = GNUNET_malloc (sizeof(struct NT_Network) + 2 * sizeof(struct
229 sockaddr_in6));
230 tmp = (struct sockaddr_in6 *) &net[1];
231 net->network = (struct sockaddr *) &tmp[0];
232 net->netmask = (struct sockaddr *) &tmp[1];
233 net->length = addrlen;
234
235 memset (&network6, 0, sizeof(network6));
236 network6.sin6_family = AF_INET6;
237#if HAVE_SOCKADDR_IN_SIN_LEN
238 network6.sin6_len = sizeof(network6);
239#endif
240 {
241 unsigned int c;
242 uint32_t *addr_elem = (uint32_t *) &addr6->sin6_addr;
243 uint32_t *mask_elem = (uint32_t *) &netmask6->sin6_addr;
244 uint32_t *net_elem = (uint32_t *) &network6.sin6_addr;
245 for (c = 0; c < 4; c++)
246 net_elem[c] = addr_elem[c] & mask_elem[c];
247
248 GNUNET_memcpy (net->netmask,
249 netmask6,
250 sizeof(struct sockaddr_in6));
251 GNUNET_memcpy (net->network,
252 &network6,
253 sizeof(struct sockaddr_in6));
254 }
255 }
256 if (NULL == net)
257 return GNUNET_OK; /* odd / unsupported address family */
258
259 /* Store in list */
260#if VERBOSE_NT
261 char *netmask = GNUNET_strdup (GNUNET_a2s ((struct sockaddr *) net->netmask,
262 addrlen));
264 "nt",
265 "Adding network `%s', netmask `%s'\n",
266 GNUNET_a2s ((struct sockaddr *) net->network,
267 addrlen),
268 netmask);
269 GNUNET_free (netmask);
270#endif
272 is->net_tail,
273 net);
274
275 return GNUNET_OK;
276}

References GNUNET_a2s(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log_from, GNUNET_malloc, GNUNET_memcpy, GNUNET_OK, GNUNET_strdup, is, name, NT_Network::netmask, and NT_Network::network.

Referenced by get_addresses(), and GNUNET_NT_scanner_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_addresses()

static void get_addresses ( void *  cls)
static

Periodically get list of network addresses from our interfaces.

Parameters
clsclosure

Definition at line 285 of file nt.c.

286{
287 struct GNUNET_NT_InterfaceScanner *is = cls;
288
289 is->interface_task = NULL;
292 is);
293 is->interface_task = GNUNET_SCHEDULER_add_delayed (
296 is);
297}

References delete_networks(), get_addresses(), GNUNET_OS_network_interfaces_list(), GNUNET_SCHEDULER_add_delayed(), interface_proc(), INTERFACE_PROCESSING_INTERVAL, and is.

Referenced by get_addresses(), and GNUNET_NT_scanner_init().

Here is the call graph for this function:
Here is the caller graph for this function: