rename lq_route into olsr_spf
[olsrd.git] / lib / bmf / src / NetworkInterfaces.c
1 /*
2  * OLSR Basic Multicast Forwarding (BMF) plugin.
3  * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
4  * Written by Erik Tromp.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without 
8  * modification, are permitted provided that the following conditions 
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright 
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright 
14  *   notice, this list of conditions and the following disclaimer in 
15  *   the documentation and/or other materials provided with the 
16  *   distribution.
17  * * Neither the name of Thales, BMF nor the names of its 
18  *   contributors may be used to endorse or promote products derived 
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
24  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
28  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
29  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /* -------------------------------------------------------------------------
34  * File       : NetworkInterfaces.c
35  * Description: Functions to open and close sockets
36  * Created    : 29 Jun 2006
37  *
38  * ------------------------------------------------------------------------- */
39
40 #include "NetworkInterfaces.h"
41
42 /* System includes */
43 #include <stddef.h> /* NULL */
44 #include <syslog.h> /* syslog() */
45 #include <string.h> /* strerror(), strchr(), strcmp() */
46 #include <errno.h> /* errno */
47 #include <unistd.h> /* close() */
48 #include <sys/ioctl.h> /* ioctl() */
49 #include <fcntl.h> /* fcntl() */
50 #include <assert.h> /* assert() */
51 #include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
52 #include <netinet/in.h> /* htons() */
53 #include <linux/if_ether.h> /* ETH_P_IP */
54 #include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
55 #include <linux/if_tun.h> /* IFF_TAP */
56 #include <netinet/ip.h> /* struct ip */
57 #include <netinet/udp.h> /* SOL_UDP */
58
59 /* OLSRD includes */
60 #include "olsr.h" /* olsr_printf() */
61 #include "ipcalc.h"
62 #include "defs.h" /* olsr_cnf */
63 #include "link_set.h" /* get_link_set() */
64 #include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
65 #include "net_olsr.h" /* ipequal */
66 #include "lq_plugin.h"
67
68 /* Plugin includes */
69 #include "Packet.h" /* IFHWADDRLEN */
70 #include "Bmf.h" /* PLUGIN_NAME, MainAddressOf() */
71 #include "Address.h" /* IsMulticast() */
72
73 /* List of network interface objects used by BMF plugin */
74 struct TBmfInterface* BmfInterfaces = NULL;
75 struct TBmfInterface* LastBmfInterface = NULL;
76
77 /* Highest-numbered open socket file descriptor. To be used as first
78  * parameter in calls to select(...). */
79 int HighestSkfd = -1;
80
81 /* Set of socket file descriptors */
82 fd_set InputSet;
83
84 /* File descriptor of EtherTunTap interface */
85 int EtherTunTapFd = -1;
86
87 /* Network interface name of EtherTunTap interface. May be overruled by
88  * setting the plugin parameter "BmfInterface". */
89 char EtherTunTapIfName[IFNAMSIZ] = "bmf0";
90
91 /* The underlying mechanism to forward multicast packets. Either:
92  * - BM_BROADCAST: BMF uses the IP local broadcast as destination address
93  * - BM_UNICAST_PROMISCUOUS: BMF uses the IP address of the best neighbor as
94  *   destination address. The other neighbors listen promiscuously. */
95 enum TBmfMechanism BmfMechanism = BM_BROADCAST;
96
97 #define ETHERTUNTAPIPNOTSET 0
98
99 /* The IP address of the BMF network interface in host byte order.
100  * May be overruled by setting the plugin parameter "BmfInterfaceIp". */
101 u_int32_t EtherTunTapIp = ETHERTUNTAPIPNOTSET;
102
103 /* 255.255.255.255 in host byte order. May be overruled by
104  * setting the plugin parameter "BmfInterfaceIp". */
105 u_int32_t EtherTunTapIpMask = 0xFFFFFFFF;
106
107 /* The IP broadcast address of the BMF network interface in host byte order.
108  * May be overruled by setting the plugin parameter "BmfinterfaceIp". */
109 u_int32_t EtherTunTapIpBroadcast = ETHERTUNTAPIPNOTSET;
110
111 /* Whether or not the configuration has overruled the default IP
112  * configuration of the EtherTunTap interface */
113 int TunTapIpOverruled = 0;
114
115 /* Whether or not to capture packets on the OLSR-enabled
116  * interfaces (in promiscuous mode). May be overruled by setting the plugin
117  * parameter "CapturePacketsOnOlsrInterfaces" to "yes". */
118 int CapturePacketsOnOlsrInterfaces = 0;
119
120 /* -------------------------------------------------------------------------
121  * Function   : SetBmfInterfaceName
122  * Description: Overrule the default network interface name ("bmf0") of the
123  *              EtherTunTap interface
124  * Input      : ifname - network interface name (e.g. "mybmf0")
125  *              data - not used
126  *              addon - not used
127  * Output     : none
128  * Return     : success (0) or fail (1)
129  * Data Used  : EtherTunTapIfName
130  * ------------------------------------------------------------------------- */
131 int SetBmfInterfaceName(
132   const char* ifname,
133   void* data __attribute__((unused)),
134   set_plugin_parameter_addon addon __attribute__((unused)))
135 {
136   strncpy(EtherTunTapIfName, ifname, IFNAMSIZ - 1);
137   EtherTunTapIfName[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
138   return 0;
139 } /* SetBmfInterfaceName */
140
141 /* -------------------------------------------------------------------------
142  * Function   : SetBmfInterfaceIp
143  * Description: Overrule the default IP address and prefix length
144  *              ("10.255.255.253/30") of the EtherTunTap interface
145  * Input      : ip - IP address string, followed by '/' and prefix length
146  *              data - not used
147  *              addon - not used
148  * Output     : none
149  * Return     : success (0) or fail (1)
150  * Data Used  : EtherTunTapIp, EtherTunTapIpMask, EtherTunTapIpBroadcast,
151  *              TunTapIpOverruled
152  * ------------------------------------------------------------------------- */
153 int SetBmfInterfaceIp(
154   const char* ip,
155   void* data __attribute__((unused)),
156   set_plugin_parameter_addon addon __attribute__((unused)))
157 {
158 #define IPV4_MAX_ADDRLEN 16
159 #define IPV4_MAX_PREFIXLEN 32
160   char* slashAt;
161   char ipAddr[IPV4_MAX_ADDRLEN];
162   struct in_addr sinaddr;
163   int prefixLen;
164   int i;
165
166   /* Inspired by function str2prefix_ipv4 as found in Quagga source
167    * file lib/prefix.c */
168
169   /* Find slash inside string. */
170   slashAt = strchr(ip, '/');
171
172   /* String doesn't contain slash. */
173   if (slashAt == NULL || slashAt - ip >= IPV4_MAX_ADDRLEN)
174   {
175     /* No prefix length specified, or IP address too long */
176     return 1;
177   }
178
179   strncpy(ipAddr, ip, slashAt - ip);
180   *(ipAddr + (slashAt - ip)) = '\0';
181   if (inet_aton(ipAddr, &sinaddr) == 0)
182   {
183     /* Invalid address passed */
184     return 1;
185   }
186
187   EtherTunTapIp = ntohl(sinaddr.s_addr);
188
189   /* Get prefix length. */
190   prefixLen = atoi(++slashAt);
191   if (prefixLen <= 0 || prefixLen > IPV4_MAX_PREFIXLEN)
192   {
193     return 1;
194   }
195
196   /* Compose IP subnet mask in host byte order */
197   EtherTunTapIpMask = 0;
198   for (i = 0; i < prefixLen; i++)
199   {
200     EtherTunTapIpMask |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
201   }
202
203   /* Compose IP broadcast address in host byte order */
204   EtherTunTapIpBroadcast = EtherTunTapIp;
205   for (i = prefixLen; i < IPV4_MAX_PREFIXLEN; i++)
206   {
207     EtherTunTapIpBroadcast |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
208   }
209
210   TunTapIpOverruled = 1;
211
212   return 0;
213 } /* SetBmfInterfaceIp */
214
215 /* -------------------------------------------------------------------------
216  * Function   : SetCapturePacketsOnOlsrInterfaces
217  * Description: Overrule the default setting, enabling or disabling the
218  *              capturing of packets on OLSR-enabled interfaces.
219  * Input      : enable - either "yes" or "no"
220  *              data - not used
221  *              addon - not used
222  * Output     : none
223  * Return     : success (0) or fail (1)
224  * Data Used  : none
225  * ------------------------------------------------------------------------- */
226 int SetCapturePacketsOnOlsrInterfaces(
227   const char* enable,
228   void* data __attribute__((unused)),
229   set_plugin_parameter_addon addon __attribute__((unused)))
230 {
231   if (strcmp(enable, "yes") == 0)
232   {
233     CapturePacketsOnOlsrInterfaces = 1;
234     return 0;
235   }
236   else if (strcmp(enable, "no") == 0)
237   {
238     CapturePacketsOnOlsrInterfaces = 0;
239     return 0;
240   }
241
242   /* Value not recognized */
243   return 1;
244 } /* SetCapturePacketsOnOlsrInterfaces */
245
246 /* -------------------------------------------------------------------------
247  * Function   : SetBmfMechanism
248  * Description: Overrule the default BMF mechanism to either BM_BROADCAST or
249  *              BM_UNICAST_PROMISCUOUS.
250  * Input      : mechanism - either "Broadcast" or "UnicastPromiscuous"
251  *              data - not used
252  *              addon - not used
253  * Output     : none
254  * Return     : success (0) or fail (1)
255  * Data Used  : none
256  * ------------------------------------------------------------------------- */
257 int SetBmfMechanism(
258   const char* mechanism,
259   void* data __attribute__((unused)),
260   set_plugin_parameter_addon addon __attribute__((unused)))
261 {
262   if (strcmp(mechanism, "Broadcast") == 0)
263   {
264     BmfMechanism = BM_BROADCAST;
265     return 0;
266   }
267   else if (strcmp(mechanism, "UnicastPromiscuous") == 0)
268   {
269     BmfMechanism = BM_UNICAST_PROMISCUOUS;
270     return 0;
271   }
272
273   /* Value not recognized */
274   return 1;
275 } /* SetBmfMechanism */
276
277 /* -------------------------------------------------------------------------
278  * Function   : AddDescriptorToInputSet
279  * Description: Add a socket descriptor to the global set of socket file descriptors
280  * Input      : skfd - socket file descriptor
281  * Output     : none
282  * Return     : none
283  * Data Used  : HighestSkfd, InputSet
284  * Notes      : Keeps track of the highest-numbered descriptor
285  * ------------------------------------------------------------------------- */
286 static void AddDescriptorToInputSet(int skfd)
287 {
288   /* Keep the highest-numbered descriptor */
289   if (skfd > HighestSkfd)
290   {
291     HighestSkfd = skfd;
292   }
293
294   /* Add descriptor to input set */
295   FD_SET(skfd, &InputSet);
296 } /* AddDescriptorToInputSet */
297
298 /* To save the state of the IP spoof filter for the EtherTunTap interface */
299 static char EthTapSpoofState = '1';
300
301 /* -------------------------------------------------------------------------
302  * Function   : DeactivateSpoofFilter
303  * Description: Deactivates the Linux anti-spoofing filter for the tuntap
304  *              interface
305  * Input      : none
306  * Output     : none
307  * Return     : fail (0) or success (1)
308  * Data Used  : EtherTunTapIfName, EthTapSpoofState
309  * Notes      : Saves the current filter state for later restoring
310  * ------------------------------------------------------------------------- */
311 int DeactivateSpoofFilter(void)
312 {
313   FILE* procSpoof;
314   char procFile[FILENAME_MAX];
315
316   /* Generate the procfile name */
317   sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
318
319   /* Open procfile for reading */
320   procSpoof = fopen(procFile, "r");
321   if (procSpoof == NULL)
322   {
323     fprintf(
324       stderr,
325       "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
326       "Are you using the procfile filesystem?\n"
327       "Does your system support IPv4?\n"
328       "I will continue (in 3 sec) - but you should manually ensure that IP spoof\n"
329       "filtering is disabled!\n\n",
330       procFile);
331       
332     sleep(3);
333     return 0;
334   }
335
336   EthTapSpoofState = fgetc(procSpoof);
337   fclose(procSpoof);
338
339   /* Open procfile for writing */
340   procSpoof = fopen(procFile, "w");
341   if (procSpoof == NULL)
342   {
343     fprintf(stderr, "Could not open %s for writing!\n", procFile);
344     fprintf(
345       stderr,
346       "I will continue (in 3 sec) - but you should manually ensure that IP"
347       " spoof filtering is disabled!\n\n");
348     sleep(3);
349     return 0;
350   }
351
352   syslog(LOG_INFO, "Writing \"0\" to %s", procFile);
353   fputs("0", procSpoof);
354
355   fclose(procSpoof);
356
357   return 1;
358 } /* DeactivateSpoofFilter */
359
360 /* -------------------------------------------------------------------------
361  * Function   : RestoreSpoofFilter
362  * Description: Restores the Linux anti-spoofing filter setting for the tuntap
363  *              interface
364  * Input      : none
365  * Output     : none
366  * Return     : none
367  * Data Used  : EtherTunTapIfName, EthTapSpoofState
368  * ------------------------------------------------------------------------- */
369 void RestoreSpoofFilter(void)
370 {
371   FILE* procSpoof;
372   char procFile[FILENAME_MAX];
373
374   /* Generate the procfile name */
375   sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
376
377   /* Open procfile for writing */
378   procSpoof = fopen(procFile, "w");
379   if (procSpoof == NULL)
380   {
381     fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procFile);
382   }
383   else
384   {
385     syslog(LOG_INFO, "Resetting %s to %c\n", procFile, EthTapSpoofState);
386
387     fputc(EthTapSpoofState, procSpoof);
388     fclose(procSpoof);
389   }
390 } /* RestoreSpoofFilter */
391
392 /* -------------------------------------------------------------------------
393  * Function   : FindNeighbors
394  * Description: Find the neighbors on a network interface to forward a BMF
395  *              packet to
396  * Input      : intf - the network interface
397  *              source - the source IP address of the BMF packet 
398  *              forwardedBy - the IP address of the node that forwarded the BMF
399  *                packet
400  *              forwardedTo - the IP address of the node to which the BMF packet
401  *                was directed
402  * Output     : neighbors - list of (up to a number of 'FanOutLimit') neighbors.
403  *              bestNeighbor - the best neighbor (in terms of lowest cost or ETX
404  *                value)
405  *              nPossibleNeighbors - number of found possible neighbors
406  * Data Used  : FanOutLimit
407  * ------------------------------------------------------------------------- */
408 void FindNeighbors(
409   struct TBestNeighbors* neighbors,
410   struct link_entry** bestNeighbor,
411   struct TBmfInterface* intf,
412   union olsr_ip_addr* source,
413   union olsr_ip_addr* forwardedBy,
414   union olsr_ip_addr* forwardedTo,
415   int* nPossibleNeighbors)
416 {
417   int i;
418
419   /* Initialize */
420   *bestNeighbor = NULL;
421   for (i = 0; i < MAX_UNICAST_NEIGHBORS; i++)
422   {
423     neighbors->links[i] = NULL;
424   }
425   *nPossibleNeighbors = 0;
426
427   /* handle the non-LQ case */
428
429   if (olsr_cnf->lq_level == 0)
430   {
431     struct link_entry* walker;
432
433     OLSR_FOR_ALL_LINK_ENTRIES(walker) {
434 #ifndef NODEBUG
435       struct ipaddr_str buf;
436 #endif
437       union olsr_ip_addr* neighborMainIp;
438
439       /* Consider only links from the specified interface */
440       if (! ipequal(&intf->intAddr, &walker->local_iface_addr))
441       {
442         continue; /* for */
443       }
444
445       OLSR_PRINTF(
446         8,
447         "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
448         PLUGIN_NAME_SHORT,
449         intf->ifName,
450         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
451
452       neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
453
454       /* Consider only neighbors with an IP address that differs from the
455        * passed IP addresses (if passed). Rely on short-circuit boolean evaluation. */
456       if (source != NULL && ipequal(neighborMainIp, MainAddressOf(source)))
457       {
458 #ifndef NODEBUG
459         struct ipaddr_str buf;
460 #endif
461         OLSR_PRINTF(
462           9,
463           "%s: ----> Not forwarding to %s: is source of pkt\n",
464           PLUGIN_NAME_SHORT,
465           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
466
467         continue; /* for */
468       }
469
470       /* Rely on short-circuit boolean evaluation */
471       if (forwardedBy != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
472       {
473 #ifndef NODEBUG
474         struct ipaddr_str buf;
475 #endif
476         OLSR_PRINTF(
477           9,
478           "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
479           PLUGIN_NAME_SHORT,
480           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
481
482         continue; /* for */
483       }
484
485       /* Rely on short-circuit boolean evaluation */
486       if (forwardedTo != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
487       {
488 #ifndef NODEBUG
489         struct ipaddr_str buf;
490 #endif
491         OLSR_PRINTF(
492           9,
493           "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
494           PLUGIN_NAME_SHORT,
495           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
496
497         continue; /* for */
498       }
499
500       /* Found a candidate neighbor to direct our packet to */
501
502       /* In the non-LQ case, it is not possible to select neigbors
503        * by quality or cost. So just remember the first found link.
504        * TODO: come on, there must be something better than to simply
505        * select the first one found! */
506       if (*bestNeighbor == NULL)
507       {
508         *bestNeighbor = walker;
509       }
510
511       /* Fill the list with up to 'FanOutLimit' neighbors. If there
512        * are more neighbors, broadcast is used instead of unicast. In that
513        * case we do not need the list of neighbors. */
514       if (*nPossibleNeighbors < FanOutLimit)
515       {
516         neighbors->links[*nPossibleNeighbors] = walker;
517       }
518
519       *nPossibleNeighbors += 1;
520     } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
521
522   }
523   /* handle the LQ case */
524   else
525   {
526 #ifdef USING_THALES_LINK_COST_ROUTING
527
528     struct link_entry* walker;
529     float previousLinkCost = 2 * INFINITE_COST;
530     float bestLinkCost = 2 * INFINITE_COST;
531
532     if (forwardedBy != NULL)
533     {
534       /* Retrieve the cost of the link from 'forwardedBy' to myself */
535       struct link_entry* bestLinkFromForwarder = get_best_link_to_neighbor(forwardedBy);
536       if (bestLinkFromForwarder != NULL)
537       {
538         previousLinkCost = bestLinkFromForwarder->link_cost;
539       }
540     }
541
542     /* TODO: get_link_set() is not thread-safe! */
543     for (walker = get_link_set(); walker != NULL; walker = walker->next) 
544     {
545 #ifndef NODEBUG
546       struct ipaddr_str buf;
547 #endif
548       union olsr_ip_addr* neighborMainIp;
549       struct link_entry* bestLinkToNeighbor;
550       struct tc_entry* tcLastHop;
551
552       /* Consider only links from the specified interface */
553       if (! ipequal(&intf->intAddr, &walker->local_iface_addr))
554       {
555         continue; /* for */
556       }
557
558       OLSR_PRINTF(
559         9,
560         "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
561         PLUGIN_NAME_SHORT,
562         intf->ifName,
563         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
564
565       neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
566
567       /* Consider only neighbors with an IP address that differs from the
568        * passed IP addresses (if passed). Rely on short-circuit boolean evaluation. */
569       if (source != NULL && ipequal(neighborMainIp, MainAddressOf(source)))
570       {
571         OLSR_PRINTF(
572           9,
573           "%s: ----> Not forwarding to %s: is source of pkt\n",
574           PLUGIN_NAME_SHORT,
575           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
576
577         continue; /* for */
578       }
579
580       /* Rely on short-circuit boolean evaluation */
581       if (forwardedBy != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
582       {
583         OLSR_PRINTF(
584           9,
585           "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
586           PLUGIN_NAME_SHORT,
587           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
588
589         continue; /* for */
590       }
591
592       /* Rely on short-circuit boolean evaluation */
593       if (forwardedTo != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
594       {
595         OLSR_PRINTF(
596           9,
597           "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
598           PLUGIN_NAME_SHORT,
599           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
600
601         continue; /* for */
602       }
603
604       /* Found a candidate neighbor to direct our packet to */
605
606       if (walker->link_cost >= INFINITE_COST)
607       {
608         OLSR_PRINTF(
609           9,
610           "%s: ----> Not forwarding to %s: link is timing out\n",
611           PLUGIN_NAME_SHORT,
612           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
613
614         continue; /* for */
615       }
616
617       /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
618       OLSR_PRINTF(
619         9,
620         "%s: ----> Forwarding pkt to %s will cost %5.2f\n",
621         PLUGIN_NAME_SHORT,
622         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
623         walker->link_cost);
624
625       /* If the candidate neighbor is best reached via another interface, then skip 
626        * the candidate neighbor; the candidate neighbor has been / will be selected via that
627        * other interface.
628        * TODO: get_best_link_to_neighbor() is not thread-safe. */
629       bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
630
631       if (walker != bestLinkToNeighbor)
632       {
633         if (bestLinkToNeighbor == NULL)
634         {
635           OLSR_PRINTF(
636             9,
637             "%s: ----> Not forwarding to %s: no link found\n",
638             PLUGIN_NAME_SHORT,
639             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
640         }
641         else
642         {
643           struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
644
645           OLSR_PRINTF(
646             9,
647             "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %5.2f\n",
648             PLUGIN_NAME_SHORT,
649             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
650             bestIntf->int_name,
651             bestLinkToNeighbor->link_cost);
652         }
653
654         continue; /* for */
655       }
656
657       if (forwardedBy != NULL)
658       {
659 #ifndef NODEBUG
660         struct ipaddr_str forwardedByBuf, niaBuf;
661 #endif
662         OLSR_PRINTF(
663           9,
664           "%s: ----> 2-hop path from %s via me to %s will cost %5.2f\n",
665           PLUGIN_NAME_SHORT,
666           olsr_ip_to_string(&forwardedByBuf, forwardedBy),
667           olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
668           previousLinkCost + walker->link_cost);
669       }
670
671       /* Check the topology table whether the 'forwardedBy' node is itself a direct
672        * neighbor of the candidate neighbor, at a lower cost than the 2-hop route
673        * via myself. If so, we do not need to forward the BMF packet to the candidate
674        * neighbor, because the 'forwardedBy' node will forward the packet. */
675       if (forwardedBy != NULL)
676       {
677         /* TODO: olsr_lookup_tc_entry() is not thread-safe. */
678         tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
679         if (tcLastHop != NULL)
680         {
681           struct tc_edge_entry* tc_edge;
682
683           /* TODO: olsr_lookup_tc_edge() is not thread-safe. */
684           tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
685           
686           /* We are not interested in dead-end or dying edges. */
687           if (tc_edge != NULL && (tc_edge->flags & OLSR_TC_EDGE_DOWN) == 0)
688           {
689             if (previousLinkCost + walker->link_cost > tc_edge->link_cost)
690             {
691 #ifndef NODEBUG
692               struct ipaddr_str neighbor_iface_buf, forw_buf;
693               olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
694 #endif
695               OLSR_PRINTF(
696                 9,
697                 "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %5.2f\n",
698                 PLUGIN_NAME_SHORT,
699                 neighbor_iface_buf.buf,
700                 olsr_ip_to_string(&forw_buf, forwardedBy),
701                 neighbor_iface_buf.buf,
702                 tc_edge->link_cost);
703
704               continue; /* for */
705             } /* if */
706           } /* if */
707         } /* if */
708       } /* if */
709
710       /* Remember the best neighbor. If all are very bad, remember none. */
711       if (walker->link_cost < bestLinkCost)
712       {
713         *bestNeighbor = walker;
714         bestLinkCost = walker->link_cost;
715       }
716
717       /* Fill the list with up to 'FanOutLimit' neighbors. If there
718        * are more neighbors, broadcast is used instead of unicast. In that
719        * case we do not need the list of neighbors. */
720       if (*nPossibleNeighbors < FanOutLimit)
721       {
722         neighbors->links[*nPossibleNeighbors] = walker;
723       }
724
725       *nPossibleNeighbors += 1;
726
727     } /* for */
728
729 #else /* USING_THALES_LINK_COST_ROUTING */
730         
731     struct link_entry* walker;
732     olsr_linkcost previousLinkEtx = LINK_COST_BROKEN;
733     olsr_linkcost bestEtx = LINK_COST_BROKEN;
734
735     if (forwardedBy != NULL)
736     {
737       /* Retrieve the cost of the link from 'forwardedBy' to myself */
738       struct link_entry* bestLinkFromForwarder = get_best_link_to_neighbor(forwardedBy);
739       if (bestLinkFromForwarder != NULL)
740       {
741         previousLinkEtx = bestLinkFromForwarder->linkcost;
742       }
743     }
744
745     OLSR_FOR_ALL_LINK_ENTRIES(walker) {
746 #ifndef NODEBUG
747       struct ipaddr_str buf;
748 #endif
749       union olsr_ip_addr* neighborMainIp;
750       struct link_entry* bestLinkToNeighbor;
751       struct tc_entry* tcLastHop;
752       float currEtx;
753  
754       /* Consider only links from the specified interface */
755       if (! ipequal(&intf->intAddr, &walker->local_iface_addr))
756       {
757         continue; /* for */
758       }
759
760       OLSR_PRINTF(
761         9,
762         "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
763         PLUGIN_NAME_SHORT,
764         intf->ifName,
765         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
766
767       neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
768
769       /* Consider only neighbors with an IP address that differs from the
770        * passed IP addresses (if passed). Rely on short-circuit boolean evaluation. */
771       if (source != NULL && ipequal(neighborMainIp, MainAddressOf(source)))
772       {
773         OLSR_PRINTF(
774           9,
775           "%s: ----> Not forwarding to %s: is source of pkt\n",
776           PLUGIN_NAME_SHORT,
777           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
778
779         continue; /* for */
780       }
781
782       /* Rely on short-circuit boolean evaluation */
783       if (forwardedBy != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
784       {
785         OLSR_PRINTF(
786           9,
787           "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
788           PLUGIN_NAME_SHORT,
789           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
790
791         continue; /* for */
792       }
793
794       /* Rely on short-circuit boolean evaluation */
795       if (forwardedTo != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
796       {
797         OLSR_PRINTF(
798           9,
799           "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
800           PLUGIN_NAME_SHORT,
801           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
802
803         continue; /* for */
804       }
805
806       /* Found a candidate neighbor to direct our packet to */
807
808       /* Calculate the link quality (ETX) of the link to the found neighbor */
809       currEtx = walker->linkcost;
810  
811       if (currEtx < LINK_COST_BROKEN)
812       {
813         OLSR_PRINTF(
814           9,
815           "%s: ----> Not forwarding to %s: link is timing out\n",
816           PLUGIN_NAME_SHORT,
817           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
818
819         continue; /* for */
820       }
821
822       /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
823       OLSR_PRINTF(
824         9,
825         "%s: ----> Forwarding pkt to %s will cost ETX %5.2f\n",
826         PLUGIN_NAME_SHORT,
827         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
828         currEtx);
829
830       /* If the candidate neighbor is best reached via another interface, then skip 
831        * the candidate neighbor; the candidate neighbor has been / will be selected via that
832        * other interface.
833        * TODO: get_best_link_to_neighbor() is not thread-safe. */
834       bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
835
836       if (walker != bestLinkToNeighbor)
837       {
838         if (bestLinkToNeighbor == NULL)
839         {
840 #ifndef NODEBUG
841           struct ipaddr_str buf;
842 #endif
843           OLSR_PRINTF(
844             9,
845             "%s: ----> Not forwarding to %s: no link found\n",
846             PLUGIN_NAME_SHORT,
847             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
848         }
849         else
850         {
851 #ifndef NODEBUG
852           struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
853           struct ipaddr_str buf;
854           struct lqtextbuffer lqbuffer;
855 #endif
856           OLSR_PRINTF(
857             9,
858             "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
859             PLUGIN_NAME_SHORT,
860             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
861             bestIntf->int_name,
862             get_linkcost_text(bestLinkToNeighbor->linkcost, OLSR_FALSE, &lqbuffer));
863         }
864
865         continue; /* for */
866       }
867
868       if (forwardedBy != NULL)
869       {
870 #ifndef NODEBUG
871         struct ipaddr_str forwardedByBuf, niaBuf;
872         struct lqtextbuffer lqbuffer;
873 #endif
874         OLSR_PRINTF(
875           9,
876           "%s: ----> 2-hop path from %s via me to %s will cost ETX %s\n",
877           PLUGIN_NAME_SHORT,
878           olsr_ip_to_string(&forwardedByBuf, forwardedBy),
879           olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
880           get_linkcost_text(previousLinkEtx + currEtx, OLSR_TRUE, &lqbuffer));
881       }
882
883       /* Check the topology table whether the 'forwardedBy' node is itself a direct
884        * neighbor of the candidate neighbor, at a lower cost than the 2-hop route
885        * via myself. If so, we do not need to forward the BMF packet to the candidate
886        * neighbor, because the 'forwardedBy' node will forward the packet. */
887       if (forwardedBy != NULL)
888       {
889         /* TODO: olsr_lookup_tc_entry() is not thread-safe. */
890         tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
891         if (tcLastHop != NULL)
892         {
893           struct tc_edge_entry* tc_edge;
894
895           /* TODO: olsr_lookup_tc_edge() is not thread-safe. */
896           tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
897
898           /* We are not interested in dead-end edges. */
899           if (tc_edge) {
900             olsr_linkcost tcEtx = tc_edge->cost;
901
902             if (previousLinkEtx + currEtx > tcEtx)
903             {
904 #ifndef NODEBUG
905               struct ipaddr_str neighbor_iface_buf, forw_buf;
906               struct lqtextbuffer lqbuffer;
907               olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
908 #endif
909               OLSR_PRINTF(
910                 9,
911                 "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
912                 PLUGIN_NAME_SHORT,
913                 neighbor_iface_buf.buf,
914                 olsr_ip_to_string(&forw_buf, forwardedBy),
915                 neighbor_iface_buf.buf,
916                 get_linkcost_text(tcEtx, OLSR_FALSE, &lqbuffer));
917
918               continue; /* for */
919             } /* if */
920           } /* if */
921         } /* if */
922       } /* if */
923
924       /* Remember the best neighbor. If all are very bad, remember none. */
925       if (currEtx < bestEtx)
926       {
927         *bestNeighbor = walker;
928         bestEtx = currEtx;
929       }
930
931       /* Fill the list with up to 'FanOutLimit' neighbors. If there
932        * are more neighbors, broadcast is used instead of unicast. In that
933        * case we do not need the list of neighbors. */
934       if (*nPossibleNeighbors < FanOutLimit)
935       {
936         neighbors->links[*nPossibleNeighbors] = walker;
937       }
938
939       *nPossibleNeighbors += 1;
940     } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
941
942 #endif /* USING_THALES_LINK_COST_ROUTING */
943
944   } /* if */
945
946   /* Display the result of the neighbor search */
947   if (*nPossibleNeighbors == 0)
948   {
949     OLSR_PRINTF(
950       9,
951       "%s: ----> No suitable neighbor found to forward to on \"%s\"\n",
952       PLUGIN_NAME_SHORT,
953       intf->ifName);
954   }
955   else
956   {
957 #ifndef NODEBUG
958     struct ipaddr_str buf;
959 #endif
960     OLSR_PRINTF(
961       9,
962       "%s: ----> %d neighbors found on \"%s\"; best neighbor to forward to: %s\n",
963       PLUGIN_NAME_SHORT,
964       *nPossibleNeighbors,
965       intf->ifName,
966       olsr_ip_to_string(&buf, &(*bestNeighbor)->neighbor_iface_addr));
967   } /* if */
968
969 } /* FindNeighbors */
970
971 /* -------------------------------------------------------------------------
972  * Function   : CreateCaptureSocket
973  * Description: Create socket for promiscuously capturing multicast IP traffic
974  * Input      : ifname - network interface (e.g. "eth0")
975  * Output     : none
976  * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
977  * Data Used  : none
978  * Notes      : The socket is a cooked IP packet socket, bound to the specified
979  *              network interface
980  * ------------------------------------------------------------------------- */
981 static int CreateCaptureSocket(const char* ifName)
982 {
983   int ifIndex = if_nametoindex(ifName);
984   struct packet_mreq mreq;
985   struct ifreq req;
986   struct sockaddr_ll bindTo;
987
988   /* Open cooked IP packet socket */
989   int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
990   if (skfd < 0)
991   {
992     BmfPError("socket(PF_PACKET) error");
993     return -1;
994   }
995
996   /* Set interface to promiscuous mode */
997   memset(&mreq, 0, sizeof(struct packet_mreq));
998   mreq.mr_ifindex = ifIndex;
999   mreq.mr_type = PACKET_MR_PROMISC;
1000   if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
1001   {
1002     BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1003     close(skfd);
1004     return -1;
1005   }
1006
1007   /* Get hardware (MAC) address */
1008   memset(&req, 0, sizeof(struct ifreq));
1009   strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
1010   req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
1011   if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
1012   {
1013     BmfPError("error retrieving MAC address");
1014     close(skfd);
1015     return -1;
1016   }
1017    
1018   /* Bind the socket to the specified interface */
1019   memset(&bindTo, 0, sizeof(bindTo));
1020   bindTo.sll_family = AF_PACKET;
1021   bindTo.sll_protocol = htons(ETH_P_IP);
1022   bindTo.sll_ifindex = ifIndex;
1023   memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1024   bindTo.sll_halen = IFHWADDRLEN;
1025     
1026   if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1027   {
1028     BmfPError("bind() error");
1029     close(skfd);
1030     return -1;
1031   }
1032
1033   /* Set socket to blocking operation */
1034   if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1035   {
1036     BmfPError("fcntl() error");
1037     close(skfd);
1038     return -1;
1039   }
1040
1041   AddDescriptorToInputSet(skfd);
1042
1043   return skfd;
1044 } /* CreateCaptureSocket */
1045
1046 /* -------------------------------------------------------------------------
1047  * Function   : CreateListeningSocket
1048  * Description: Create socket for promiscuously listening to BMF packets.
1049  *              Used only when 'BmfMechanism' is BM_UNICAST_PROMISCUOUS
1050  * Input      : ifname - network interface (e.g. "eth0")
1051  * Output     : none
1052  * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
1053  * Data Used  : none
1054  * Notes      : The socket is a cooked IP packet socket, bound to the specified
1055  *              network interface
1056  * ------------------------------------------------------------------------- */
1057 static int CreateListeningSocket(const char* ifName)
1058 {
1059   int ifIndex = if_nametoindex(ifName);
1060   struct packet_mreq mreq;
1061   struct ifreq req;
1062   struct sockaddr_ll bindTo;
1063
1064   /* Open cooked IP packet socket */
1065   int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1066   if (skfd < 0)
1067   {
1068     BmfPError("socket(PF_PACKET) error");
1069     return -1;
1070   }
1071
1072   /* Set interface to promiscuous mode */
1073   memset(&mreq, 0, sizeof(struct packet_mreq));
1074   mreq.mr_ifindex = ifIndex;
1075   mreq.mr_type = PACKET_MR_PROMISC;
1076   if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
1077   {
1078     BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1079     close(skfd);
1080     return -1;
1081   }
1082
1083   /* Get hardware (MAC) address */
1084   memset(&req, 0, sizeof(struct ifreq));
1085   strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
1086   req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
1087   if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
1088   {
1089     BmfPError("error retrieving MAC address");
1090     close(skfd);
1091     return -1;
1092   }
1093
1094   /* Bind the socket to the specified interface */
1095   memset(&bindTo, 0, sizeof(bindTo));
1096   bindTo.sll_family = AF_PACKET;
1097   bindTo.sll_protocol = htons(ETH_P_IP);
1098   bindTo.sll_ifindex = ifIndex;
1099   memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1100   bindTo.sll_halen = IFHWADDRLEN;
1101     
1102   if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1103   {
1104     BmfPError("bind() error");
1105     close(skfd);
1106     return -1;
1107   }
1108
1109   /* Set socket to blocking operation */
1110   if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1111   {
1112     BmfPError("fcntl() error");
1113     close(skfd);
1114     return -1;
1115   }
1116
1117   AddDescriptorToInputSet(skfd);
1118
1119   return skfd;
1120 } /* CreateListeningSocket */
1121
1122 /* -------------------------------------------------------------------------
1123  * Function   : CreateEncapsulateSocket
1124  * Description: Create a socket for sending and receiving encapsulated
1125  *              multicast packets
1126  * Input      : ifname - network interface (e.g. "eth0")
1127  * Output     : none
1128  * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
1129  * Data Used  : none
1130  * Notes      : The socket is an UDP (datagram) over IP socket, bound to the
1131  *              specified network interface
1132  * ------------------------------------------------------------------------- */
1133 static int CreateEncapsulateSocket(const char* ifName)
1134 {
1135   int on = 1;
1136   struct sockaddr_in bindTo;
1137
1138   /* Open UDP-IP socket */
1139   int skfd = socket(PF_INET, SOCK_DGRAM, 0);
1140   if (skfd < 0)
1141   {
1142     BmfPError("socket(PF_INET) error");
1143     return -1;
1144   }
1145
1146   /* Enable sending to broadcast addresses */
1147   if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
1148   {
1149     BmfPError("setsockopt(SO_BROADCAST) error");
1150     close(skfd);
1151     return -1;
1152   }
1153         
1154   /* Bind to the specific network interfaces indicated by ifName. */
1155   /* When using Kernel 2.6 this must happer prior to the port binding! */
1156   if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0)
1157   {
1158     BmfPError("setsockopt(SO_BINDTODEVICE) error");
1159     close(skfd);
1160     return -1;
1161   }
1162
1163   /* Bind to BMF port */
1164   memset(&bindTo, 0, sizeof(bindTo));
1165   bindTo.sin_family = AF_INET;
1166   bindTo.sin_port = htons(BMF_ENCAP_PORT);
1167   bindTo.sin_addr.s_addr = htonl(INADDR_ANY);
1168       
1169   if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0) 
1170   {
1171     BmfPError("bind() error");
1172     close(skfd);
1173     return -1;
1174   }
1175
1176   /* Set socket to blocking operation */
1177   if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1178   {
1179     BmfPError("fcntl() error");
1180     close(skfd);
1181     return -1;
1182   }
1183
1184   AddDescriptorToInputSet(skfd);
1185
1186   return skfd;
1187 } /* CreateEncapsulateSocket */
1188
1189 /* -------------------------------------------------------------------------
1190  * Function   : CreateLocalEtherTunTap
1191  * Description: Creates and brings up an EtherTunTap interface
1192  * Input      : none
1193  * Output     : none
1194  * Return     : the socket file descriptor (>= 0), or -1 in case of failure
1195  * Data Used  : EtherTunTapIfName - name used for the tuntap interface (e.g.
1196  *                "bmf0")
1197  *              EtherTunTapIp
1198  *              EtherTunTapIpMask
1199  *              EtherTunTapIpBroadcast
1200  *              BmfInterfaces
1201  * Note       : Order dependency: call this function only if BmfInterfaces
1202  *              is filled with a list of network interfaces.
1203  * ------------------------------------------------------------------------- */
1204 static int CreateLocalEtherTunTap(void)
1205 {
1206   static const char deviceName[] = "/dev/net/tun";
1207   struct ifreq ifreq;
1208   int etfd;
1209   int ioctlSkfd;
1210   int ioctlres;
1211
1212   etfd = open(deviceName, O_RDWR | O_NONBLOCK);
1213   if (etfd < 0)
1214   {
1215     BmfPError("error opening %s", deviceName);
1216     return -1;
1217   }
1218
1219   memset(&ifreq, 0, sizeof(ifreq));
1220   strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1221   ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1222
1223   /* Specify the IFF_TUN flag for IP packets.
1224    * Specify IFF_NO_PI for not receiving extra meta packet information. */
1225   ifreq.ifr_flags = IFF_TUN;
1226   ifreq.ifr_flags |= IFF_NO_PI;
1227
1228   if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
1229   {
1230     BmfPError("ioctl(TUNSETIFF) error on %s", deviceName);
1231     close(etfd);
1232     return -1;
1233   }
1234
1235   memset(&ifreq, 0, sizeof(ifreq));
1236   strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1237   ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1238   ifreq.ifr_addr.sa_family = AF_INET;
1239
1240   ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1241   if (ioctlSkfd < 0)
1242   {
1243     BmfPError("socket(PF_INET) error on %s", deviceName);
1244     close(etfd);
1245     return -1;
1246   }
1247
1248   /* Give the EtherTunTap interface an IP address.
1249    * The default IP address is the address of the first OLSR interface;
1250    * the default netmask is 255.255.255.255 . Having an all-ones netmask prevents
1251    * automatic entry of the BMF network interface in the routing table. */
1252   if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
1253   {
1254     struct TBmfInterface* nextBmfIf = BmfInterfaces;
1255     while (nextBmfIf != NULL)
1256     {
1257       struct TBmfInterface* bmfIf = nextBmfIf;
1258       nextBmfIf = bmfIf->next;
1259
1260       if (bmfIf->olsrIntf != NULL)
1261       {
1262         EtherTunTapIp = ntohl(bmfIf->intAddr.v4.s_addr);
1263         EtherTunTapIpBroadcast = EtherTunTapIp;
1264       }
1265     }
1266   }
1267
1268   if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
1269   {
1270     /* No IP address configured for BMF network interface, and no OLSR interface found to
1271      * copy IP address from. Fall back to default: 10.255.255.253 . */
1272     EtherTunTapIp = ETHERTUNTAPDEFAULTIP;
1273   }
1274
1275   ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp);
1276   ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq);
1277   if (ioctlres >= 0)
1278   {
1279     /* Set net mask */
1280     ((struct sockaddr_in*)&ifreq.ifr_netmask)->sin_addr.s_addr = htonl(EtherTunTapIpMask);
1281     ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq);
1282     if (ioctlres >= 0)
1283     {
1284       /* Set broadcast IP */
1285       ((struct sockaddr_in*)&ifreq.ifr_broadaddr)->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast);
1286       ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq);
1287       if (ioctlres >= 0)
1288       {
1289         /* Bring EtherTunTap interface up (if not already) */
1290         ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1291         if (ioctlres >= 0)
1292         {
1293           ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_BROADCAST);
1294           ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1295         }
1296       }
1297     }
1298   }
1299
1300   if (ioctlres < 0)
1301   {
1302     /* Any of the above ioctl() calls failed */
1303     BmfPError("error bringing up EtherTunTap interface \"%s\"", EtherTunTapIfName);
1304
1305     close(etfd);
1306     close(ioctlSkfd);
1307     return -1;
1308   } /* if (ioctlres < 0) */
1309
1310   /* Set the multicast flag on the interface */
1311   memset(&ifreq, 0, sizeof(ifreq));
1312   strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1313   ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1314
1315   ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1316   if (ioctlres >= 0)
1317   {
1318     ifreq.ifr_flags |= IFF_MULTICAST;
1319     ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1320   }
1321   if (ioctlres < 0)
1322   {
1323     /* Any of the two above ioctl() calls failed */
1324     BmfPError("error setting multicast flag on EtherTunTap interface \"%s\"", EtherTunTapIfName);
1325
1326     /* Continue anyway */
1327   }
1328
1329   /* Use ioctl to make the tuntap persistent. Otherwise it will disappear
1330    * when this program exits. That is not desirable, since a multicast
1331    * daemon (e.g. mrouted) may be using the tuntap interface. */
1332   if (ioctl(etfd, TUNSETPERSIST, (void *)&ifreq) < 0)
1333   {
1334     BmfPError("error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName);
1335
1336     /* Continue anyway */
1337   }
1338
1339   OLSR_PRINTF(8, "%s: opened 1 socket on \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1340
1341   AddDescriptorToInputSet(etfd);
1342
1343   /* If the user configured a specific IP address for the BMF network interface,
1344    * help the user and advertise the IP address of the BMF network interface
1345    * on the OLSR network via HNA */
1346   if (TunTapIpOverruled != 0)
1347   {
1348     union olsr_ip_addr temp_net;
1349
1350     temp_net.v4.s_addr = htonl(EtherTunTapIp);
1351     ip_prefix_list_add(&olsr_cnf->hna_entries, &temp_net, 32);
1352   }
1353
1354   close(ioctlSkfd);
1355
1356   return etfd;
1357 } /* CreateLocalEtherTunTap */
1358
1359 /* -------------------------------------------------------------------------
1360  * Function   : CreateInterface
1361  * Description: Create a new TBmfInterface object and adds it to the global
1362  *              BmfInterfaces list
1363  * Input      : ifName - name of the network interface (e.g. "eth0")
1364  *            : olsrIntf - OLSR interface object of the network interface, or
1365  *                NULL if the network interface is not OLSR-enabled
1366  * Output     : none
1367  * Return     : the number of opened sockets
1368  * Data Used  : BmfInterfaces, LastBmfInterface
1369  * ------------------------------------------------------------------------- */
1370 static int CreateInterface(
1371   const char* ifName,
1372   struct interface* olsrIntf)
1373 {
1374   int capturingSkfd = -1;
1375   int encapsulatingSkfd = -1;
1376   int listeningSkfd = -1;
1377   int ioctlSkfd;
1378   struct ifreq ifr;
1379   int nOpened = 0;
1380   struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
1381
1382   assert(ifName != NULL);
1383
1384   if (newIf == NULL)
1385   {
1386     return 0;
1387   }
1388
1389   if (olsrIntf != NULL)
1390   {
1391     /* On OLSR-enabled interfaces, create socket for encapsulating and forwarding 
1392      * multicast packets */
1393     encapsulatingSkfd = CreateEncapsulateSocket(ifName);
1394     if (encapsulatingSkfd < 0)
1395     {
1396       free(newIf);
1397       return 0;
1398     }
1399     nOpened++;
1400   }
1401
1402   /* Create socket for capturing and sending of multicast packets on
1403    * non-OLSR interfaces, and on OLSR-interfaces if configured. */
1404   if ((olsrIntf == NULL) || (CapturePacketsOnOlsrInterfaces != 0))
1405   {
1406     capturingSkfd = CreateCaptureSocket(ifName);
1407     if (capturingSkfd < 0)
1408     {
1409       close(encapsulatingSkfd);
1410       free(newIf);
1411       return 0;
1412     }
1413
1414     nOpened++;
1415   }
1416
1417   /* Create promiscuous mode listening interface if BMF uses IP unicast
1418    * as underlying forwarding mechanism */
1419   if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
1420   {
1421     listeningSkfd = CreateListeningSocket(ifName);
1422     if (listeningSkfd < 0)
1423     {
1424       close(listeningSkfd);
1425       close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */
1426       free(newIf);
1427       return 0;
1428     }
1429
1430     nOpened++;
1431   }
1432
1433   /* For ioctl operations on the network interface, use either capturingSkfd
1434    * or encapsulatingSkfd, whichever is available */
1435   ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
1436
1437   /* Retrieve the MAC address of the interface. */
1438   memset(&ifr, 0, sizeof(struct ifreq));
1439   strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1440   ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1441   if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0)
1442   {
1443     BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
1444     close(capturingSkfd);
1445     close(encapsulatingSkfd);
1446     free(newIf);
1447     return 0;
1448   }
1449
1450   /* Copy data into TBmfInterface object */
1451   newIf->capturingSkfd = capturingSkfd;
1452   newIf->encapsulatingSkfd = encapsulatingSkfd;
1453   newIf->listeningSkfd = listeningSkfd;
1454   memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
1455   memcpy(newIf->ifName, ifName, IFNAMSIZ);
1456   newIf->olsrIntf = olsrIntf;
1457   if (olsrIntf != NULL)
1458   {
1459     /* For an OLSR-interface, copy the interface address and broadcast
1460      * address from the OLSR interface object. Downcast to correct sockaddr
1461      * subtype. */
1462     newIf->intAddr.v4 = ((struct sockaddr_in *)&olsrIntf->int_addr)->sin_addr;
1463     newIf->broadAddr.v4 = ((struct sockaddr_in *)&olsrIntf->int_broadaddr)->sin_addr;
1464   }
1465   else
1466   {
1467     /* For a non-OLSR interface, retrieve the IP address ourselves */
1468     memset(&ifr, 0, sizeof(struct ifreq));
1469     strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1470     ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1471     if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0) 
1472     {
1473       BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
1474
1475       newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
1476     }
1477     else
1478     {
1479       /* Downcast to correct sockaddr subtype */
1480       newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
1481     }
1482
1483     /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
1484     memset(&ifr, 0, sizeof(struct ifreq));
1485     strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1486     ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1487     if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0) 
1488     {
1489       BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
1490
1491       newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
1492     }
1493     else
1494     {
1495       /* Downcast to correct sockaddr subtype */
1496       newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
1497     }
1498   }
1499
1500   /* Initialize fragment history table */
1501   memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
1502   newIf->nextFragmentHistoryEntry = 0;
1503
1504   /* Reset counters */
1505   newIf->nBmfPacketsRx = 0;
1506   newIf->nBmfPacketsRxDup = 0;
1507   newIf->nBmfPacketsTx = 0;
1508
1509   /* Add new TBmfInterface object to global list. OLSR interfaces are
1510    * added at the front of the list, non-OLSR interfaces at the back. */
1511   if (BmfInterfaces == NULL)
1512   {
1513     /* First TBmfInterface object in list */
1514     BmfInterfaces = newIf;
1515     LastBmfInterface = newIf;
1516   }
1517   else if (olsrIntf != NULL)
1518   {
1519     /* Add new TBmfInterface object at front of list */
1520     newIf->next = BmfInterfaces;
1521     BmfInterfaces = newIf;
1522   }
1523   else
1524   {
1525     /* Add new TBmfInterface object at back of list */
1526     newIf->next = NULL;
1527     LastBmfInterface->next= newIf;
1528     LastBmfInterface = newIf;
1529   }
1530
1531   OLSR_PRINTF(
1532     8,
1533     "%s: opened %d socket%s on %s interface \"%s\"\n",
1534     PLUGIN_NAME_SHORT,
1535     nOpened,
1536     nOpened == 1 ? "" : "s",
1537     olsrIntf != NULL ? "OLSR" : "non-OLSR",
1538     ifName);
1539
1540   return nOpened;
1541 } /* CreateInterface */
1542
1543 /* -------------------------------------------------------------------------
1544  * Function   : CreateBmfNetworkInterfaces
1545  * Description: Create a list of TBmfInterface objects, one for each network
1546  *              interface on which BMF runs
1547  * Input      : skipThisIntf - network interface to skip, if seen
1548  * Output     : none
1549  * Return     : fail (-1) or success (0)
1550  * Data Used  : none
1551  * ------------------------------------------------------------------------- */
1552 int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
1553 {
1554   int skfd;
1555   struct ifconf ifc;
1556   int numreqs = 30;
1557   struct ifreq* ifr;
1558   int n;
1559   int nOpenedSockets = 0;
1560
1561   /* Clear input descriptor set */
1562   FD_ZERO(&InputSet);
1563
1564   skfd = socket(PF_INET, SOCK_DGRAM, 0);
1565   if (skfd < 0)
1566   {
1567     BmfPError("no inet socket available to retrieve interface list");
1568     return -1;
1569   }
1570
1571   /* Retrieve the network interface configuration list */
1572   ifc.ifc_buf = NULL;
1573   for (;;)
1574   {
1575     ifc.ifc_len = sizeof(struct ifreq) * numreqs;
1576     ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
1577
1578     if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
1579     {
1580       BmfPError("ioctl(SIOCGIFCONF) error");
1581
1582       close(skfd);
1583       free(ifc.ifc_buf);
1584       return -1;
1585     }
1586     if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
1587     {
1588       /* Assume it overflowed; double the space and try again */
1589       numreqs *= 2;
1590       assert(numreqs < 1024);
1591       continue; /* for (;;) */
1592     }
1593     break; /* for (;;) */
1594   } /* for (;;) */
1595
1596   close(skfd);
1597
1598   /* For each item in the interface configuration list... */
1599   ifr = ifc.ifc_req;
1600   for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++)
1601   {
1602     struct interface* olsrIntf;
1603     union olsr_ip_addr ipAddr;
1604
1605     /* Skip the BMF network interface itself */
1606     if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
1607     {
1608       continue; /* for (n = ...) */
1609     }
1610
1611     /* ...find the OLSR interface structure, if any */
1612     ipAddr.v4 =  ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr;
1613     olsrIntf = if_ifwithaddr(&ipAddr);
1614
1615     if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
1616     {
1617       continue; /* for (n = ...) */
1618     }
1619
1620     if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
1621     {
1622       /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
1623        * interface in the BMF plugin parameter list */
1624       continue; /* for (n = ...) */
1625     }
1626
1627     nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
1628
1629   } /* for (n = ...) */
1630
1631   free(ifc.ifc_buf);
1632   
1633   /* Create the BMF network interface */
1634   EtherTunTapFd = CreateLocalEtherTunTap();
1635   if (EtherTunTapFd >= 0)
1636   {
1637     nOpenedSockets++;
1638   }
1639
1640   if (BmfInterfaces == NULL)
1641   {
1642     olsr_printf(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
1643   }
1644   else
1645   {
1646     olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
1647   }
1648   return 0;
1649 } /* CreateBmfNetworkInterfaces */
1650
1651 /* -------------------------------------------------------------------------
1652  * Function   : AddInterface
1653  * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
1654  *              network interfaces
1655  * Input      : newIntf - network interface to add
1656  * Output     : none
1657  * Return     : none
1658  * Data Used  : none
1659  * ------------------------------------------------------------------------- */
1660 void AddInterface(struct interface* newIntf)
1661 {
1662   int nOpened;
1663
1664   assert(newIntf != NULL);
1665
1666   nOpened = CreateInterface(newIntf->int_name, newIntf);
1667
1668   olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
1669 } /* AddInterface */
1670
1671 /* -------------------------------------------------------------------------
1672  * Function   : CloseBmfNetworkInterfaces
1673  * Description: Closes every socket on each network interface used by BMF
1674  * Input      : none
1675  * Output     : none
1676  * Return     : none
1677  * Data Used  : none
1678  * Notes      : Closes
1679  *              - the local EtherTunTap interface (e.g. "tun0" or "tap0")
1680  *              - for each BMF-enabled interface, the socket used for
1681  *                capturing multicast packets
1682  *              - for each OLSR-enabled interface, the socket used for
1683  *                encapsulating packets
1684  *              Also restores the network state to the situation before BMF
1685  *              was started.
1686  * ------------------------------------------------------------------------- */
1687 void CloseBmfNetworkInterfaces(void)
1688 {
1689   int nClosed = 0;
1690   u_int32_t totalOlsrBmfPacketsRx = 0;
1691   u_int32_t totalOlsrBmfPacketsRxDup = 0;
1692   u_int32_t totalOlsrBmfPacketsTx = 0;
1693   u_int32_t totalNonOlsrBmfPacketsRx = 0;
1694   u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
1695   u_int32_t totalNonOlsrBmfPacketsTx = 0;
1696
1697   /* Close all opened sockets */
1698   struct TBmfInterface* nextBmfIf = BmfInterfaces;
1699   while (nextBmfIf != NULL) 
1700   {
1701     struct TBmfInterface* bmfIf = nextBmfIf;
1702     nextBmfIf = bmfIf->next;
1703
1704     if (bmfIf->capturingSkfd >= 0)
1705     {
1706       close(bmfIf->capturingSkfd);
1707       nClosed++;
1708     }
1709     if (bmfIf->encapsulatingSkfd >= 0) 
1710     {
1711       close(bmfIf->encapsulatingSkfd);
1712       nClosed++;
1713     }
1714
1715     OLSR_PRINTF(
1716       7,
1717       "%s: %s interface \"%s\": RX pkts %d (%d dups); TX pkts %d\n", 
1718       PLUGIN_NAME_SHORT,
1719       bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
1720       bmfIf->ifName,
1721       bmfIf->nBmfPacketsRx,
1722       bmfIf->nBmfPacketsRxDup,
1723       bmfIf->nBmfPacketsTx);
1724
1725     olsr_printf(
1726       1,
1727       "%s: closed %s interface \"%s\"\n", 
1728       PLUGIN_NAME_SHORT,
1729       bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
1730       bmfIf->ifName);
1731
1732     /* Add totals */
1733     if (bmfIf->olsrIntf != NULL)
1734     {
1735       totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1736       totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1737       totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1738     }
1739     else
1740     {
1741       totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1742       totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1743       totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1744     }
1745
1746     free(bmfIf);
1747   } /* while */
1748   
1749   if (EtherTunTapFd >= 0)
1750   {
1751     close(EtherTunTapFd);
1752     nClosed++;
1753
1754     OLSR_PRINTF(7, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1755   }
1756
1757   BmfInterfaces = NULL;
1758
1759   olsr_printf(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
1760
1761   OLSR_PRINTF(
1762     7,
1763     "%s: Total all OLSR interfaces    : RX pkts %d (%d dups); TX pkts %d\n",
1764     PLUGIN_NAME_SHORT,
1765     totalOlsrBmfPacketsRx,
1766     totalOlsrBmfPacketsRxDup,
1767     totalOlsrBmfPacketsTx);
1768   OLSR_PRINTF(
1769     7,
1770     "%s: Total all non-OLSR interfaces: RX pkts %d (%d dups); TX pkts %d\n",
1771     PLUGIN_NAME_SHORT,
1772     totalNonOlsrBmfPacketsRx,
1773     totalNonOlsrBmfPacketsRxDup,
1774     totalNonOlsrBmfPacketsTx);
1775 } /* CloseBmfNetworkInterfaces */
1776
1777 #define MAX_NON_OLSR_IFS 32
1778 static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
1779 static int nNonOlsrIfs = 0;
1780
1781 /* -------------------------------------------------------------------------
1782  * Function   : AddNonOlsrBmfIf
1783  * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
1784  *              network interfaces
1785  * Input      : ifName - network interface (e.g. "eth0")
1786  *              data - not used
1787  *              addon - not used
1788  * Output     : none
1789  * Return     : success (0) or fail (1)
1790  * Data Used  : NonOlsrIfNames
1791  * ------------------------------------------------------------------------- */
1792 int AddNonOlsrBmfIf(
1793   const char* ifName,
1794   void* data __attribute__((unused)),
1795   set_plugin_parameter_addon addon __attribute__((unused)))
1796 {
1797   assert(ifName != NULL);
1798
1799   if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
1800   {
1801     olsr_printf(
1802       1,
1803       "%s: too many non-OLSR interfaces specified, maximum is %d\n",
1804       PLUGIN_NAME,
1805       MAX_NON_OLSR_IFS);
1806     return 1;
1807   }
1808
1809   strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
1810   NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1811   nNonOlsrIfs++;
1812   return 0;
1813 } /* AddNonOlsrBmfIf */
1814
1815 /* -------------------------------------------------------------------------
1816  * Function   : IsNonOlsrBmfIf
1817  * Description: Checks if a network interface is OLSR-enabled
1818  * Input      : ifName - network interface (e.g. "eth0")
1819  * Output     : none
1820  * Return     : true (1) or false (0)
1821  * Data Used  : NonOlsrIfNames
1822  * ------------------------------------------------------------------------- */
1823 int IsNonOlsrBmfIf(const char* ifName)
1824 {
1825   int i;
1826
1827   assert(ifName != NULL);
1828
1829   for (i = 0; i < nNonOlsrIfs; i++)
1830   {
1831     if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
1832   }
1833   return 0;
1834 } /* IsNonOlsrBmfIf */
1835
1836 /* -------------------------------------------------------------------------
1837  * Function   : CheckAndUpdateLocalBroadcast
1838  * Description: For an IP packet, check if the destination address is not a
1839  *              multicast address. If it is not, the packet is assumed to be
1840  *              a local broadcast packet. In that case, set the destination
1841  *              address of the IP packet to the passed broadcast address.
1842  * Input      : ipPacket - the IP packet
1843  *              broadAddr - the broadcast address to fill in
1844  * Output     : none
1845  * Return     : none
1846  * Data Used  : none
1847  * Notes      : See also RFC1141
1848  * ------------------------------------------------------------------------- */
1849 void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr)
1850 {
1851   struct iphdr* iph;
1852   union olsr_ip_addr destIp;
1853
1854   assert(ipPacket != NULL && broadAddr != NULL);
1855
1856   iph = (struct iphdr*) ipPacket;
1857   destIp.v4.s_addr = iph->daddr;
1858   if (! IsMulticast(&destIp))
1859   {
1860     u_int32_t origDaddr, newDaddr;
1861     u_int32_t check;
1862
1863     origDaddr = ntohl(iph->daddr);
1864
1865     iph->daddr = broadAddr->v4.s_addr;
1866     newDaddr = ntohl(iph->daddr);
1867
1868     /* Re-calculate IP header checksum for new destination */
1869     check = ntohs(iph->check);
1870
1871     check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1872     check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1873
1874     /* Add carry */
1875     check = check + (check >> 16);
1876
1877     iph->check = htons(check);
1878
1879     if (iph->protocol == SOL_UDP)
1880     {
1881       /* Re-calculate UDP/IP checksum for new destination */
1882
1883       int ipHeaderLen = GetIpHeaderLength(ipPacket);
1884       struct udphdr* udph = (struct udphdr*) (ipPacket + ipHeaderLen);
1885
1886       /* RFC 1624, Eq. 3: HC' = ~(~HC - m + m') */
1887
1888       check = ntohs(udph->check);
1889
1890       check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1891       check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1892
1893       /* Add carry */
1894       check = check + (check >> 16);
1895
1896       udph->check = htons(check);
1897      } /* if */
1898   } /* if */
1899 } /* CheckAndUpdateLocalBroadcast */
1900
1901 /* -------------------------------------------------------------------------
1902  * Function   : AddMulticastRoute
1903  * Description: Insert a route to all multicast addresses in the kernel
1904  *              routing table. The route will be via the BMF network interface.
1905  * Input      : none
1906  * Output     : none
1907  * Return     : none
1908  * Data Used  : none
1909  * ------------------------------------------------------------------------- */
1910 void AddMulticastRoute(void)
1911 {
1912   struct rtentry kernel_route;
1913   int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1914   if (ioctlSkfd < 0)
1915   {
1916     BmfPError("socket(PF_INET) error");
1917     return;
1918   }
1919
1920   memset(&kernel_route, 0, sizeof(struct rtentry));
1921
1922   ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
1923   ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
1924   ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
1925
1926   /* 224.0.0.0/4 */
1927   ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
1928   ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
1929
1930   kernel_route.rt_metric = 0;
1931   kernel_route.rt_flags = RTF_UP;
1932
1933   kernel_route.rt_dev = EtherTunTapIfName;
1934
1935   if (ioctl(ioctlSkfd, SIOCADDRT, &kernel_route) < 0)
1936   {
1937     BmfPError("error setting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
1938
1939     /* Continue anyway */
1940   }
1941   close(ioctlSkfd);
1942 } /* AddMulticastRoute */
1943
1944 /* -------------------------------------------------------------------------
1945  * Function   : DeleteMulticastRoute
1946  * Description: Delete the route to all multicast addresses from the kernel
1947  *              routing table
1948  * Input      : none
1949  * Output     : none
1950  * Return     : none
1951  * Data Used  : none
1952  * ------------------------------------------------------------------------- */
1953 void DeleteMulticastRoute(void)
1954 {
1955   if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP)
1956   {
1957     struct rtentry kernel_route;
1958     int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1959     if (ioctlSkfd < 0)
1960     {
1961       BmfPError("socket(PF_INET) error");
1962       return;
1963     }
1964
1965     memset(&kernel_route, 0, sizeof(struct rtentry));
1966
1967     ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
1968     ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
1969     ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
1970
1971     /* 224.0.0.0/4 */
1972     ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
1973     ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
1974
1975     kernel_route.rt_metric = 0;
1976     kernel_route.rt_flags = RTF_UP;
1977
1978     kernel_route.rt_dev = EtherTunTapIfName;
1979
1980     if (ioctl(ioctlSkfd, SIOCDELRT, &kernel_route) < 0)
1981     {
1982       BmfPError("error deleting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
1983
1984       /* Continue anyway */
1985     }
1986     close(ioctlSkfd);
1987   } /* if */
1988 } /* DeleteMulticastRoute */