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