073800c2c7d9dfe166d2cccd1937d812a0600b5c
[olsrd.git] / lib / pud / src / networkInterfaces.c
1 #include "networkInterfaces.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5 #include "configuration.h"
6 #include "netTools.h"
7
8 /* OLSRD includes */
9 #include "olsr.h"
10
11 /* System includes */
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <ifaddrs.h>
15
16 /*
17  * Main IP MAC address
18  */
19
20 /** the MAC address of the main IP address */
21 static unsigned char mac[PUD_NODEIDTYPE_MAC_BYTES] = { 0 };
22
23 /** true when the MAC address of the main IP address has been retrieved */
24 static bool macSet = false;
25
26 /**
27  * @return
28  * the MAC address of the main IP address
29  */
30 unsigned char * getMainIpMacAddress(void) {
31         if (!macSet) {
32                 struct ifreq ifr;
33                 unsigned char * macInIfr;
34
35                 struct interface *mainInterface = if_ifwithaddr(&olsr_cnf->main_addr);
36                 if (!mainInterface) {
37                         pudError(true, "Could not get the main interface");
38                         return NULL;
39                 }
40                 macInIfr = getHardwareAddress(mainInterface->int_name, olsr_cnf->ip_version, &ifr);
41                 if (!macInIfr) {
42                         pudError(true, "Could not get the MAC address of the main interface");
43                         return NULL;
44                 }
45                 memcpy(&mac[0], &macInIfr[0], PUD_NODEIDTYPE_MAC_BYTES);
46                 macSet = true;
47         }
48
49         return &mac[0];
50 }
51
52 /*
53  * RX interfaces
54  */
55
56 /** The list of network interface objects, receiving GPS NMEA sentences */
57 static TRxTxNetworkInterface *rxNetworkInterfacesListHead = NULL;
58
59 /** Pointer to the last network interface object, receiving GPS NMEA sentences */
60 static TRxTxNetworkInterface *lastRxNetworkInterface = NULL;
61
62 /**
63  @return
64  The list of network interface objects, receiving GPS NMEA sentences
65  */
66 TRxTxNetworkInterface *getRxNetworkInterfaces(void) {
67         return rxNetworkInterfacesListHead;
68 }
69
70 /**
71  Create a receive socket for a network interface
72
73  @param networkInterface
74  The network interface object. This function expects it to be filled with all
75  information, except for the socket descriptor.
76  @param rxSocketHandlerFunction
77  The function that handles reception of data on the network interface
78  @param rxMcAddr
79  The receive multicast address (must have same IP version as networkInterface address)
80
81  @return
82  - the socket descriptor (>= 0)
83  - -1 if an error occurred
84  */
85 static int createRxSocket(TRxTxNetworkInterface * networkInterface,
86                 socket_handler_func rxSocketHandlerFunction, union olsr_sockaddr * rxMcAddr) {
87         int ipFamilySetting;
88         int ipProtoSetting;
89         int ipMcLoopSetting;
90         int ipAddMembershipSetting;
91
92         union olsr_sockaddr address;
93         struct sockaddr * addr;
94         size_t addrSize;
95
96         int rxSocket = -1;
97
98         int socketReuseFlagValue = 1;
99         int mcLoopValue = 1;
100
101         assert(networkInterface != NULL);
102         assert(rxSocketHandlerFunction != NULL);
103         assert(strncmp((char *) &networkInterface->name[0], "",
104                                         sizeof(networkInterface->name)) != 0);
105         assert(networkInterface->ipAddress.in.sa_family == rxMcAddr->in.sa_family);
106
107         memset(&address, 0, sizeof(address));
108         if (networkInterface->ipAddress.in.sa_family == AF_INET) {
109                 assert(networkInterface->ipAddress.in4.sin_addr.s_addr != INADDR_ANY);
110
111                 ipFamilySetting = AF_INET;
112                 ipProtoSetting = IPPROTO_IP;
113                 ipMcLoopSetting = IP_MULTICAST_LOOP;
114                 ipAddMembershipSetting = IP_ADD_MEMBERSHIP;
115
116                 address.in4.sin_family = ipFamilySetting;
117                 address.in4.sin_addr.s_addr = INADDR_ANY;
118                 address.in4.sin_port = getRxMcPort();
119                 addr = (struct sockaddr *)&address.in4;
120                 addrSize = sizeof(struct sockaddr_in);
121         } else {
122                 assert(networkInterface->ipAddress.in6.sin6_addr.s6_addr != in6addr_any.s6_addr);
123
124                 ipFamilySetting = AF_INET6;
125                 ipProtoSetting = IPPROTO_IPV6;
126                 ipMcLoopSetting = IPV6_MULTICAST_LOOP;
127                 ipAddMembershipSetting = IPV6_ADD_MEMBERSHIP;
128
129                 address.in6.sin6_family = ipFamilySetting;
130                 address.in6.sin6_addr = in6addr_any;
131                 address.in6.sin6_port = getRxMcPort();
132                 addr = (struct sockaddr *)&address.in6;
133                 addrSize = sizeof(struct sockaddr_in6);
134         }
135
136         /* Create a datagram socket on which to receive. */
137         errno = 0;
138         rxSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
139         if (rxSocket < 0) {
140                 pudError(true, "Could not create a receive socket for interface %s",
141                                 networkInterface->name);
142                 goto bail;
143         }
144
145         /* Enable SO_REUSEADDR to allow multiple applications to receive the same
146          * multicast messages */
147         errno = 0;
148         if (setsockopt(rxSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue,
149                         sizeof(socketReuseFlagValue)) < 0) {
150                 pudError(true, "Could not set the reuse flag on the receive socket for"
151                         " interface %s", networkInterface->name);
152                 goto bail;
153         }
154
155         /* Bind to the proper port number with the IP address INADDR_ANY
156          * (INADDR_ANY is really required here, do not change it) */
157         errno = 0;
158         if (bind(rxSocket, addr, addrSize) < 0) {
159                 pudError(true, "Could not bind the receive socket for interface"
160                         " %s to port %u", networkInterface->name, ntohs(getRxMcPort()));
161                 goto bail;
162         }
163
164         /* Enable multicast local loopback */
165         errno = 0;
166         if (setsockopt(rxSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
167                         sizeof(mcLoopValue)) < 0) {
168                 pudError(true, "Could not %s multicast loopback on the"
169                         " receive socket for interface %s", mcLoopValue ? "enable"
170                                 : "disable", networkInterface->name);
171                 goto bail;
172         }
173
174         /* Join the multicast group on the local interface. Note that this
175          * ADD_MEMBERSHIP option must be called for each local interface over
176          * which the multicast datagrams are to be received. */
177         if (ipFamilySetting == AF_INET) {
178                 struct ip_mreq mc_settings;
179                 (void) memset(&mc_settings, 0, sizeof(mc_settings));
180                 mc_settings.imr_multiaddr = rxMcAddr->in4.sin_addr;
181                 mc_settings.imr_interface = networkInterface->ipAddress.in4.sin_addr;
182                 errno = 0;
183                 if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
184                                 &mc_settings, sizeof(mc_settings)) < 0) {
185                         pudError(true, "Could not subscribe interface %s to the configured"
186                                 " multicast group", networkInterface->name);
187                         goto bail;
188                 }
189         } else {
190                 struct ipv6_mreq mc6_settings;
191                 (void) memset(&mc6_settings, 0, sizeof(mc6_settings));
192                 mc6_settings.ipv6mr_multiaddr = rxMcAddr->in6.sin6_addr;
193                 mc6_settings.ipv6mr_interface = if_nametoindex((char *)networkInterface->name);
194                 errno = 0;
195                 if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
196                                 &mc6_settings, sizeof(mc6_settings)) < 0) {
197                         pudError(true, "Could not subscribe interface %s to the configured"
198                                 " multicast group", networkInterface->name);
199                         goto bail;
200                 }
201         }
202
203         add_olsr_socket(rxSocket, rxSocketHandlerFunction, NULL, networkInterface,
204                         SP_PR_READ);
205
206         return rxSocket;
207
208         bail: if (rxSocket >= 0) {
209                 close(rxSocket);
210         }
211         return -1;
212
213 }
214
215 /**
216  Create a receive interface and add it to the list of receive network interface
217  objects
218
219  @param ifName
220  the network interface name
221  @param ipAddr
222  the IP address of the interface
223  @param rxSocketHandlerFunction
224  the function that handles reception of data on the network interface
225  @param rxMcAddr
226  The receive multicast address (must have same IP version as ipAddr)
227
228  @return
229  - true on success
230  - false on failure
231  */
232 static bool createRxInterface(const char * ifName, union olsr_sockaddr * ipAddr,
233                 socket_handler_func rxSocketHandlerFunction, union olsr_sockaddr * rxMcAddr) {
234         int socketFd = -1;
235         TRxTxNetworkInterface * networkInterface = NULL;
236
237         if (ifName == NULL) {
238                 goto bail;
239         }
240
241         networkInterface = olsr_malloc(sizeof(TRxTxNetworkInterface),
242                         "TRxTxNetworkInterface (PUD)");
243         if (networkInterface == NULL) {
244                 goto bail;
245         }
246
247         memcpy(networkInterface->name, ifName, sizeof(networkInterface->name));
248         networkInterface->name[IFNAMSIZ] = '\0';
249         networkInterface->ipAddress = *ipAddr;
250         networkInterface->handler = NULL;
251         networkInterface->next = NULL;
252
253         /* networkInterface needs to be filled in when calling createRxSocket */
254         socketFd = createRxSocket(networkInterface, rxSocketHandlerFunction, rxMcAddr);
255         if (socketFd < 0) {
256                 goto bail;
257         }
258         networkInterface->socketFd = socketFd;
259         networkInterface->handler = rxSocketHandlerFunction;
260
261         /* Add new object to the end of the global list. */
262         if (rxNetworkInterfacesListHead == NULL) {
263                 rxNetworkInterfacesListHead = networkInterface;
264                 lastRxNetworkInterface = networkInterface;
265         } else {
266                 lastRxNetworkInterface->next = networkInterface;
267                 lastRxNetworkInterface = networkInterface;
268         }
269
270         return true;
271
272         bail: if (networkInterface != NULL) {
273                 free(networkInterface);
274         }
275         return false;
276
277 }
278
279 /*
280  * TX interfaces
281  */
282
283 /** The list of network interface objects, sending our NMEA sentences */
284 static TRxTxNetworkInterface *txNetworkInterfacesListHead = NULL;
285
286 /** Pointer to the last network interface object, sending our NMEA sentences */
287 static TRxTxNetworkInterface *lastTxNetworkInterface = NULL;
288
289 /**
290  @return
291  The list of network interface objects, sending our NMEA sentences
292  */
293 TRxTxNetworkInterface *getTxNetworkInterfaces(void) {
294         return txNetworkInterfacesListHead;
295 }
296
297 /**
298  Create a transmit socket for a network interface
299
300  @param networkInterface
301  The network interface object. This function expects it to be filled with all
302  information, except for the socket descriptor.
303
304  @return
305  - the socket descriptor (>= 0)
306  - -1 if an error occurred
307  */
308 static int createTxSocket(TRxTxNetworkInterface * networkInterface) {
309         int ipFamilySetting;
310         int ipProtoSetting;
311         int ipMcLoopSetting;
312         int ipMcIfSetting;
313         int ipTtlSetting;
314         unsigned int index;
315
316         union olsr_sockaddr address;
317         void * addr;
318         size_t addrSize;
319
320         int txSocket = -1;
321
322         int mcLoopValue = 0;
323         int txTtl = getTxTtl();
324
325         assert(networkInterface != NULL);
326         assert(strncmp((char *) &networkInterface->name[0], "",
327                                         sizeof(networkInterface->name)) != 0);
328
329         memset(&address, 0, sizeof(address));
330         if (networkInterface->ipAddress.in.sa_family == AF_INET) {
331                 assert(networkInterface->ipAddress.in4.sin_addr.s_addr != INADDR_ANY);
332
333                 ipFamilySetting = AF_INET;
334                 ipProtoSetting = IPPROTO_IP;
335                 ipMcLoopSetting = IP_MULTICAST_LOOP;
336                 ipMcIfSetting = IP_MULTICAST_IF;
337                 ipTtlSetting = IP_MULTICAST_TTL;
338                 index = 0;
339
340                 address.in4.sin_family = ipFamilySetting;
341                 address.in4.sin_addr = networkInterface->ipAddress.in4.sin_addr;
342                 address.in4.sin_port = getTxMcPort();
343                 addr = &address.in4;
344                 addrSize = sizeof(struct sockaddr_in);
345         } else {
346                 assert(networkInterface->ipAddress.in6.sin6_addr.s6_addr != in6addr_any.s6_addr);
347
348                 ipFamilySetting = AF_INET6;
349                 ipProtoSetting = IPPROTO_IPV6;
350                 ipMcLoopSetting = IPV6_MULTICAST_LOOP;
351                 ipMcIfSetting = IPV6_MULTICAST_IF;
352                 ipTtlSetting = IPV6_MULTICAST_HOPS;
353                 index = if_nametoindex((char *)networkInterface->name);
354
355                 address.in6.sin6_family = ipFamilySetting;
356                 address.in6.sin6_addr = networkInterface->ipAddress.in6.sin6_addr;
357                 address.in6.sin6_port = getTxMcPort();
358                 addr = &index;
359                 addrSize = sizeof(index);
360         }
361
362         /*  Create a datagram socket on which to transmit */
363         errno = 0;
364         txSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
365         if (txSocket < 0) {
366                 pudError(true, "Could not create a transmit socket for interface %s",
367                                 networkInterface->name);
368                 goto bail;
369         }
370
371         /* Bind the socket to the desired interface */
372         errno = 0;
373         if (setsockopt(txSocket, ipProtoSetting, ipMcIfSetting, addr, addrSize) < 0) {
374                 pudError(true, "Could not set the multicast interface on the"
375                         " transmit socket to interface %s", networkInterface->name);
376                 goto bail;
377         }
378
379         /* Disable multicast local loopback */
380         errno = 0;
381         if (setsockopt(txSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
382                         sizeof(mcLoopValue)) < 0) {
383                 pudError(true, "Could not %s multicast loopback on the"
384                         " transmit socket for interface %s", mcLoopValue ? "enable"
385                                 : "disable", networkInterface->name);
386                 goto bail;
387         }
388
389         /* Set the TTL on the socket */
390         errno = 0;
391         if (setsockopt(txSocket, ipProtoSetting, ipTtlSetting, &txTtl,
392                         sizeof(txTtl)) < 0) {
393                 pudError(true, "Could not set TTL on the transmit socket"
394                         " for interface %s", networkInterface->name);
395                 goto bail;
396         }
397
398         /* Set the no delay option on the socket */
399         errno = 0;
400         if (fcntl(txSocket, F_SETFL, O_NDELAY) < 0) {
401                 pudError(true, "Could not set the no delay option on the"
402                         " transmit socket for interface %s", networkInterface->name);
403                 goto bail;
404         }
405
406         return txSocket;
407
408         bail: if (txSocket >= 0) {
409                 close(txSocket);
410         }
411         return -1;
412 }
413
414 /**
415  Create a transmit interface and add it to the list of transmit network
416  interface objects
417
418  @param ifName
419  the network interface name
420  @param ipAddr
421  the IP address of the interface
422
423  @return
424  - true on success
425  - false on failure
426  */
427 static bool createTxInterface(const char * ifName, union olsr_sockaddr * ipAddr) {
428         int socketFd = -1;
429         TRxTxNetworkInterface * networkInterface = NULL;
430
431         if (ifName == NULL) {
432                 goto bail;
433         }
434
435         networkInterface = olsr_malloc(sizeof(TRxTxNetworkInterface),
436                         "TRxTxNetworkInterface (PUD)");
437         if (networkInterface == NULL) {
438                 goto bail;
439         }
440
441         memcpy(networkInterface->name, ifName, sizeof(networkInterface->name));
442         networkInterface->name[IFNAMSIZ] = '\0';
443         networkInterface->ipAddress = *ipAddr;
444         networkInterface->handler = NULL;
445         networkInterface->next = NULL;
446
447         /* networkInterface needs to be filled in when calling createTxSocket */
448         socketFd = createTxSocket(networkInterface);
449         if (socketFd < 0) {
450                 goto bail;
451         }
452         networkInterface->socketFd = socketFd;
453
454         /* Add new object to the end of the global list. */
455         if (txNetworkInterfacesListHead == NULL) {
456                 txNetworkInterfacesListHead = networkInterface;
457                 lastTxNetworkInterface = networkInterface;
458         } else {
459                 lastTxNetworkInterface->next = networkInterface;
460                 lastTxNetworkInterface = networkInterface;
461         }
462
463         return true;
464
465         bail: if (networkInterface != NULL) {
466                 free(networkInterface);
467         }
468         return false;
469 }
470
471 /*
472  * Downlink interface
473  */
474
475 /** The socket fd, receiving downlinked messages */
476 static int downlinkSocketFd = -1;
477
478 /** the downlink handler function */
479 static socket_handler_func downlinkHandler = NULL;
480
481
482 /**
483  @return
484  The downlink socket fd. -1 when not valid.
485  */
486 int getDownlinkSocketFd(void) {
487         return downlinkSocketFd;
488 }
489
490 /**
491  Create an downlink socket
492
493  @param ipVersion
494  The IP version (AF_INET or AF_INET6) for the socket
495  @param rxSocketHandlerFunction
496  The socket handler function
497
498  @return
499  - the socket descriptor (>= 0)
500  - -1 if an error occurred
501  */
502 static int createDownlinkSocket(int ipVersion, socket_handler_func rxSocketHandlerFunction) {
503         union olsr_sockaddr address;
504         struct sockaddr * addr;
505         size_t addrSize;
506
507         int downlinkSocket = -1;
508
509         int socketReuseFlagValue = 1;
510
511         memset(&address, 0, sizeof(address));
512         if (ipVersion == AF_INET) {
513                 address.in4.sin_family = AF_INET;
514                 address.in4.sin_addr.s_addr = INADDR_ANY;
515                 address.in4.sin_port = getDownlinkPort();
516                 addr = (struct sockaddr *)&address.in4;
517                 addrSize = sizeof(struct sockaddr_in);
518         } else {
519                 address.in6.sin6_family = AF_INET6;
520                 address.in6.sin6_addr = in6addr_any;
521                 address.in6.sin6_port = getDownlinkPort();
522                 addr = (struct sockaddr *)&address.in6;
523                 addrSize = sizeof(struct sockaddr_in6);
524         }
525
526         /*  Create a datagram socket on which to receive */
527         errno = 0;
528         downlinkSocket = socket(ipVersion, SOCK_DGRAM, 0);
529         if (downlinkSocket < 0) {
530                 pudError(true, "Could not create the downlink socket");
531                 goto bail;
532         }
533
534         /* Enable SO_REUSEADDR to allow multiple applications to receive the same
535          * messages */
536         errno = 0;
537         if (setsockopt(downlinkSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue,
538                         sizeof(socketReuseFlagValue)) < 0) {
539                 pudError(true, "Could not set REUSE option on the downlink socket");
540                 goto bail;
541         }
542
543         /* Bind to the proper port number with the IP address INADDR_ANY
544          * (INADDR_ANY is really required here, do not change it) */
545         errno = 0;
546         if (bind(downlinkSocket, addr, addrSize)) {
547                 pudError(true, "Could not bind downlink socket to port %d",
548                                 getDownlinkPort());
549                 goto bail;
550         }
551
552         add_olsr_socket(downlinkSocket, rxSocketHandlerFunction, NULL, NULL,
553                         SP_PR_READ);
554
555         downlinkHandler = rxSocketHandlerFunction;
556
557         return downlinkSocket;
558
559         bail: if (downlinkSocket >= 0) {
560                 close(downlinkSocket);
561         }
562         return -1;
563 }
564
565 /*
566  * OLSR interfaces
567  */
568
569 /** The list of OLSR network interface objects */
570 static TOLSRNetworkInterface *olsrNetworkInterfacesListHead = NULL;
571
572 /** Pointer to the last OLSR network interface object */
573 static TOLSRNetworkInterface *lastOlsrNetworkInterface = NULL;
574
575 /**
576  Get the OLSR interface structure for a certain OLSR interface. Note that
577  pointer comparison is performed to compare the OLSR interfaces.
578
579  @param olsrIntf
580  a pointer to an OLSR interface
581
582  @return
583  - a pointer to the OLSR interface structure
584  - NULL when not found
585  */
586 TOLSRNetworkInterface * getOlsrNetworkInterface(struct interface *olsrIntf) {
587         TOLSRNetworkInterface * retval = olsrNetworkInterfacesListHead;
588
589         while ((retval->olsrIntf != olsrIntf) && (retval != NULL)) {
590                 retval = retval->next;
591         }
592
593         return retval;
594 }
595
596 /**
597  Create an OLSR interface and add it to the list of OLSR network interface
598  objects
599
600  @param olsrIntf
601  a pointer to the OLSR interface
602
603  @return
604  - true on success
605  - false on failure
606  */
607 static int createOlsrInterface(struct interface *olsrIntf) {
608         TOLSRNetworkInterface * networkInterface = NULL;
609
610         networkInterface = olsr_malloc(sizeof(TOLSRNetworkInterface),
611                         "TOLSRNetworkInterface (PUD)");
612         if (networkInterface == NULL) {
613                 goto bail;
614         }
615
616         networkInterface->olsrIntf = olsrIntf;
617         networkInterface->next = NULL;
618
619         /* Add new object to the end of the global list. */
620         if (olsrNetworkInterfacesListHead == NULL) {
621                 olsrNetworkInterfacesListHead = networkInterface;
622                 lastOlsrNetworkInterface = networkInterface;
623         } else {
624                 lastOlsrNetworkInterface->next = networkInterface;
625                 lastOlsrNetworkInterface = networkInterface;
626         }
627
628         return true;
629
630         bail: if (networkInterface != NULL) {
631                 free(networkInterface);
632         }
633         return false;
634 }
635
636 /*
637  * Interface Functions
638  */
639
640 /**
641  Creates receive and transmit sockets and register the receive sockets with
642  the OLSR stack
643
644  @param rxSocketHandlerFunction
645  The function to call upon reception of data on a receive socket
646  @param rxSocketHandlerFunctionDownlink
647  The function to call upon reception of data on a downlink receive socket
648
649  @return
650  - true on success
651  - false on failure
652  */
653 bool createNetworkInterfaces(socket_handler_func rxSocketHandlerFunction,
654                 socket_handler_func rxSocketHandlerFunctionDownlink) {
655         int retval = false;
656         struct ifaddrs *ifAddrs = NULL;
657         struct ifaddrs *ifAddr = NULL;
658         union olsr_sockaddr * rxMcAddr = getRxMcAddr();
659         union olsr_sockaddr * txMcAddr = getTxMcAddr();
660
661         errno = 0;
662         if (getifaddrs(&ifAddrs) != 0) {
663                 pudError(true, "Could not get list of interfaces and their addresses");
664                 return retval;
665         }
666
667         /* loop over all interfaces */
668         for (ifAddr = ifAddrs; ifAddr != NULL; ifAddr = ifAddr->ifa_next) {
669                 union olsr_sockaddr * addr = (union olsr_sockaddr *)ifAddr->ifa_addr;
670                 if ((addr != NULL) && ((addr->in.sa_family == AF_INET) || (addr->in.sa_family == AF_INET6))) {
671                         char * ifName = ifAddr->ifa_name;
672
673                         struct interface * olsrIntf = ((addr->in.sa_family != olsr_cnf->ip_version) ?
674                                         NULL :
675                                         if_ifwithaddr((addr->in.sa_family == AF_INET) ?
676                                                         (union olsr_ip_addr *)&addr->in4.sin_addr :
677                                                         (union olsr_ip_addr *)&addr->in6.sin6_addr));
678                         bool isOlsrIf = (olsrIntf != NULL);
679
680                         /* determine whether the iterated interface is configured as a
681                          * non-OLSR interface in the plugin parameter list */
682                         bool isRxNonOlsrIf = isRxNonOlsrInterface(ifName) && (addr->in.sa_family == rxMcAddr->in.sa_family);
683                         bool isTxNonOlsrIf = isTxNonOlsrInterface(ifName) && (addr->in.sa_family == txMcAddr->in.sa_family);
684
685                         bool isNonOlsrIf = isRxNonOlsrIf || isTxNonOlsrIf;
686
687                         if (!isOlsrIf && !isNonOlsrIf) {
688                                 /* Interface is not an OLSR interface AND interface is not
689                                  * configured as non-OLSR interface: skip */
690                                 continue;
691                         }
692
693                         if (isOlsrIf && !createOlsrInterface(olsrIntf)) {
694                                 /* creating an OLSR interface failed */
695                                 goto end;
696                         }
697
698                         if (!isNonOlsrIf) {
699                                 /* interface is not configured as non-OLSR interface: skip */
700                                 continue;
701                         }
702
703                         if (isRxNonOlsrIf && !createRxInterface(ifName, addr, rxSocketHandlerFunction, rxMcAddr)) {
704                                 /* creating a receive interface failed */
705                                 goto end;
706                         }
707
708                         if (isTxNonOlsrIf && !createTxInterface(ifName, addr)) {
709                                 /* creating a transmit interface failed */
710                                 goto end;
711                         }
712                 }
713         }
714
715         if (isUplinkAddrSet()) {
716                 downlinkSocketFd = createDownlinkSocket(getUplinkAddr()->in.sa_family, rxSocketHandlerFunctionDownlink);
717                 if (downlinkSocketFd == -1) {
718                         goto end;
719                 }
720         } else {
721                 downlinkSocketFd = -1;
722         }
723
724         retval = true;
725
726         end: freeifaddrs(ifAddrs);
727         return retval;
728 }
729
730 /**
731  Cleanup the OLSR network interfaces in the given list
732
733  @param networkInterface
734  the list of network interface to close and clean up
735  */
736 static void cleanupOlsrInterfaces(TOLSRNetworkInterface * networkInterface) {
737         TOLSRNetworkInterface * nextNetworkInterface = networkInterface;
738         while (nextNetworkInterface != NULL) {
739                 TOLSRNetworkInterface * iteratedNetworkInterface = nextNetworkInterface;
740                 nextNetworkInterface = iteratedNetworkInterface->next;
741                 iteratedNetworkInterface->next = NULL;
742                 free(iteratedNetworkInterface);
743         }
744 }
745
746 /**
747  Close and cleanup the network interfaces in the given list
748
749  @param networkInterface
750  the list of network interface to close and clean up
751  */
752 static void closeInterfaces(TRxTxNetworkInterface * networkInterface) {
753         TRxTxNetworkInterface * nextNetworkInterface = networkInterface;
754         while (nextNetworkInterface != NULL) {
755                 TRxTxNetworkInterface * iteratedNetworkInterface = nextNetworkInterface;
756                 if (iteratedNetworkInterface->socketFd >= 0) {
757                         if (iteratedNetworkInterface->handler) {
758                                 remove_olsr_socket(iteratedNetworkInterface->socketFd,
759                                                 iteratedNetworkInterface->handler, NULL);
760                         }
761                         close(iteratedNetworkInterface->socketFd);
762                         iteratedNetworkInterface->socketFd = -1;
763                 }
764                 nextNetworkInterface = iteratedNetworkInterface->next;
765                 iteratedNetworkInterface->next = NULL;
766                 free(iteratedNetworkInterface);
767         }
768 }
769
770 /**
771  Close and cleanup all receive and transmit network interfaces
772  */
773 void closeNetworkInterfaces(void) {
774         if (rxNetworkInterfacesListHead != NULL) {
775                 closeInterfaces(rxNetworkInterfacesListHead);
776                 rxNetworkInterfacesListHead = NULL;
777         }
778
779         if (txNetworkInterfacesListHead != NULL) {
780                 closeInterfaces(txNetworkInterfacesListHead);
781                 txNetworkInterfacesListHead = NULL;
782         }
783
784         if (olsrNetworkInterfacesListHead != NULL) {
785                 cleanupOlsrInterfaces(olsrNetworkInterfacesListHead);
786                 olsrNetworkInterfacesListHead = NULL;
787         }
788
789         if (downlinkSocketFd != -1 ) {
790                 if (downlinkHandler) {
791                         remove_olsr_socket (downlinkSocketFd, downlinkHandler, NULL);
792                         downlinkHandler = NULL;
793                 }
794                 close(downlinkSocketFd);
795                 downlinkSocketFd = -1;
796         }
797 }