Major Changes:
[olsrd.git] / lib / bmf / src / Bmf.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       : Bmf.c
35  * Description: Multicast forwarding functions
36  * Created    : 29 Jun 2006
37  *
38  * ------------------------------------------------------------------------- */
39
40 #define _MULTI_THREADED
41
42 #include "Bmf.h"
43
44 /* System includes */
45 #include <stddef.h> /* NULL */
46 #include <sys/types.h> /* ssize_t */
47 #include <string.h> /* strerror() */
48 #include <stdarg.h> /* va_list, va_start, va_end */
49 #include <errno.h> /* errno */
50 #include <assert.h> /* assert() */
51 #include <linux/if_ether.h> /* ETH_P_IP */
52 #include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
53 #include <pthread.h> /* pthread_t, pthread_create() */
54 #include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
55 #include <netinet/ip.h> /* struct ip */
56 #include <netinet/udp.h> /* struct udphdr */
57
58 /* OLSRD includes */
59 #include "defs.h" /* olsr_cnf, OLSR_PRINTF */
60 #include "ipcalc.h"
61 #include "olsr.h" /* olsr_printf */
62 #include "scheduler.h" /* olsr_register_scheduler_event */
63 #include "mid_set.h" /* mid_lookup_main_addr() */
64 #include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
65 #include "link_set.h" /* get_best_link_to_neighbor() */
66 #include "net_olsr.h" /* ipequal */
67
68 /* BMF includes */
69 #include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
70 #include "Address.h" /* IsMulticast() */
71 #include "Packet.h" /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
72 #include "PacketHistory.h" /* InitPacketHistory() */
73
74 static pthread_t BmfThread;
75 static int BmfThreadRunning = 0;
76
77 /* -------------------------------------------------------------------------
78  * Function   : BmfPError
79  * Description: Prints an error message at OLSR debug level 1.
80  *              First the plug-in name is printed. Then (if format is not NULL
81  *              and *format is not empty) the arguments are printed, followed
82  *              by a colon and a blank. Then the message and a new-line.
83  * Input      : format, arguments
84  * Output     : none
85  * Return     : none
86  * Data Used  : none
87  * ------------------------------------------------------------------------- */
88 void BmfPError(const char* format, ...)
89 {
90 #define MAX_STR_DESC 255
91   char* strErr = strerror(errno);
92   char strDesc[MAX_STR_DESC];
93
94   /* Rely on short-circuit boolean evaluation */
95   if (format == NULL || *format == '\0')
96   {
97     olsr_printf(1, "%s: %s\n", PLUGIN_NAME, strErr);
98   }
99   else
100   {
101     va_list arglist;
102
103     olsr_printf(1, "%s: ", PLUGIN_NAME);
104
105     va_start(arglist, format);
106     vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
107     va_end(arglist);
108
109     strDesc[MAX_STR_DESC - 1] = '\0'; /* Ensures null termination */
110
111     olsr_printf(1, "%s: %s\n", strDesc, strErr);
112   }
113 } /* BmfPError */
114
115 /* -------------------------------------------------------------------------
116  * Function   : MainAddressOf
117  * Description: Lookup the main address of a node
118  * Input      : ip - IP address of the node
119  * Output     : none
120  * Return     : The main IP address of the node
121  * Data Used  : none
122  * ------------------------------------------------------------------------- */
123 union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip)
124 {
125   union olsr_ip_addr* result;
126
127   /* TODO: mid_lookup_main_addr() is not thread-safe! */
128   result = mid_lookup_main_addr(ip);
129   if (result == NULL)
130   {
131     result = ip;
132   }
133   return result;
134 } /* MainAddressOf */
135
136 /* -------------------------------------------------------------------------
137  * Function   : EncapsulateAndForwardPacket
138  * Description: Encapsulate a captured raw IP packet and forward it
139  * Input      : intf - the network interface on which to forward the packet
140  *              encapsulationUdpData - The encapsulation header, followed by
141  *                the encapsulated IP packet
142  * Output     : none
143  * Return     : none
144  * Data Used  : none
145  * ------------------------------------------------------------------------- */
146 static void EncapsulateAndForwardPacket(
147   struct TBmfInterface* intf,
148   unsigned char* encapsulationUdpData)
149 {
150   /* The packet */
151   u_int16_t udpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
152
153   /* The next destination(s) */
154   struct TBestNeighbors bestNeighborLinks;
155   int nPossibleNeighbors;
156   struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
157
158   int nPacketsToSend;
159   int nBytesWritten;
160   int i;
161
162   /* Retrieve at most two best neigbors to forward the packet to */
163   GetBestTwoNeighbors(&bestNeighborLinks, intf, NULL, NULL, NULL, &nPossibleNeighbors);
164
165   if (nPossibleNeighbors <= 0)
166   {
167     OLSR_PRINTF(
168       8,
169       "%s: --> not encap-forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
170       PLUGIN_NAME_SHORT,
171       intf->ifName);
172     return;
173   }
174
175   /* Compose destination of encapsulation packet */
176
177   memset(&forwardTo, 0, sizeof(forwardTo));
178   forwardTo.sin_family = AF_INET;
179   forwardTo.sin_port = htons(BMF_ENCAP_PORT);
180
181   /* Start by filling in the local broadcast address */
182   //COPY_IP(&forwardTo.sin_addr.s_addr, &intf->broadAddr);
183   forwardTo.sin_addr = intf->broadAddr.v4;
184
185   /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
186    *   packet (to the best neighbor).
187    * - If the BMF mechanism is BM_BROADCAST,
188    *   - send one unicast packet if there is one possible neighbor,
189    *   - send two unicast packets if there are two possible neighbors, and
190    *   - only if there are more than two possible neighbors, then send an
191    *     (WLAN-air-expensive, less reliable) broadcast packet. */
192   if (BmfMechanism == BM_UNICAST_PROMISCUOUS || nPossibleNeighbors < 2)
193   {
194     nPacketsToSend = 1;
195   }
196   else /* BmfMechanism == BM_BROADCAST && nPossibleNeighbors >= 2 */
197   {
198     nPacketsToSend = 2;
199   }
200
201   for (i = 0; i < nPacketsToSend; i++)
202   {
203     if (BmfMechanism == BM_UNICAST_PROMISCUOUS || nPossibleNeighbors <= 2)
204     {
205       //COPY_IP(&forwardTo.sin_addr.s_addr, &bestNeighborLinks.links[i]->neighbor_iface_addr);
206       forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
207     }
208
209     /* Forward the BMF packet via the encapsulation socket */
210     nBytesWritten = sendto(
211       intf->encapsulatingSkfd,
212       encapsulationUdpData,
213       udpDataLen,
214       MSG_DONTROUTE,
215       (struct sockaddr*) &forwardTo,
216       sizeof(forwardTo));                   
217
218     /* Evaluate and display result */
219     if (nBytesWritten != udpDataLen)
220     {
221       BmfPError("sendto() error forwarding pkt on \"%s\"", intf->ifName);
222     }
223     else
224     {
225       /* Increase counter */
226       intf->nBmfPacketsTx++;
227
228       OLSR_PRINTF(
229         8,
230         "%s: --> encapsulated and forwarded on \"%s\" to %s\n",
231         PLUGIN_NAME_SHORT,
232         intf->ifName,
233         inet_ntoa(forwardTo.sin_addr));
234     } /* if (nBytesWritten != udpDataLen) */
235   } /* for */
236 } /* EncapsulateAndForwardPacket */
237
238 /* -------------------------------------------------------------------------
239  * Function   : BmfPacketCaptured
240  * Description: Handle a captured IP packet
241  * Input      : intf - the network interface on which the packet was captured
242  *              sllPkttype - the type of packet. Either PACKET_OUTGOING,
243  *                PACKET_BROADCAST or PACKET_MULTICAST.
244  *              encapsulationUdpData - space for the encapsulation header, followed by
245  *                the captured IP packet
246  * Output     : none
247  * Return     : none
248  * Data Used  : BmfInterfaces
249  * Notes      : The IP packet is assumed to be captured on a socket of family
250  *              PF_PACKET and type SOCK_DGRAM (cooked).
251  * ------------------------------------------------------------------------- */
252 static void BmfPacketCaptured(
253   struct TBmfInterface* intf,
254   unsigned char sllPkttype,
255   unsigned char* encapsulationUdpData)
256 {
257   union olsr_ip_addr src; /* Source IP address in captured packet */
258   union olsr_ip_addr dst; /* Destination IP address in captured packet */
259   union olsr_ip_addr* origIp; /* Main OLSR address of source of captured packet */
260   struct TBmfInterface* walker;
261   int isFromOlsrIntf;
262   int isFromOlsrNeighbor;
263   int iAmMpr;
264   unsigned char* ipPacket; /* The captured IP packet... */
265   u_int16_t ipPacketLen; /* ...and its length */
266   struct ip* ipHeader; /* The IP header inside the captured IP packet */
267   u_int32_t crc32;
268   struct TEncapHeader* encapHdr;
269 #ifndef NODEBUG
270   struct ipaddr_str srcBuf, dstBuf;
271 #endif
272   ipHeader = GetIpHeader(encapsulationUdpData);
273
274   //COPY_IP(&dst, &ipHeader->ip_dst);
275   dst.v4 = ipHeader->ip_dst;
276
277   /* Only forward multicast packets. If configured, also forward local broadcast packets */
278   if (IsMulticast(&dst) ||
279       (EnableLocalBroadcast != 0 && ipequal(&dst, &intf->broadAddr)))
280   {
281     /* continue */
282   }
283   else
284   {
285     return;
286   }
287
288   ipPacket = GetIpPacket(encapsulationUdpData);
289
290   /* Don't forward fragments of IP packets. Also, don't forward OLSR packets (UDP
291    * port 698) and BMF encapsulated packets */
292   if (IsIpFragment(ipPacket) || IsOlsrOrBmfPacket(ipPacket))
293   {
294     return;
295   }
296
297   /* Increase counter */
298   intf->nBmfPacketsRx++;
299
300   /* Check if the frame is captured on an OLSR-enabled interface */
301   isFromOlsrIntf = (intf->olsrIntf != NULL);
302
303   /* Retrieve the length of the captured packet */
304   ipPacketLen = GetIpTotalLength(ipPacket);
305
306   //COPY_IP(&src, &ipHeader->ip_src);
307   src.v4 = ipHeader->ip_src;
308
309   OLSR_PRINTF(
310     8,
311     "%s: %s pkt of %ld bytes captured on %s interface \"%s\": %s->%s\n",
312     PLUGIN_NAME_SHORT,
313     sllPkttype == PACKET_OUTGOING ? "outgoing" : "incoming",
314     (long)ipPacketLen,
315     isFromOlsrIntf ? "OLSR" : "non-OLSR",
316     intf->ifName,
317     olsr_ip_to_string(&srcBuf, &src),
318     olsr_ip_to_string(&dstBuf, &dst));
319
320   /* Lookup main address of source in the MID table of OLSR */
321   origIp = MainAddressOf(&src);
322
323   /* Calculate packet fingerprint */
324   crc32 = PacketCrc32(ipPacket, ipPacketLen);
325
326   /* Check if this packet was seen recently */
327   if (CheckAndMarkRecentPacket(crc32))
328   {
329     /* Increase counter */
330     intf->nBmfPacketsRxDup++;
331
332     OLSR_PRINTF(
333       8,
334       "%s: --> discarding: packet is duplicate\n",
335       PLUGIN_NAME_SHORT);
336     return;
337   }
338
339   /* Compose encapsulation header */
340   encapHdr = (struct TEncapHeader*) encapsulationUdpData;
341   memset (encapHdr, 0, ENCAP_HDR_LEN);
342   encapHdr->type = BMF_ENCAP_TYPE;
343   encapHdr->len = BMF_ENCAP_LEN;
344   encapHdr->reserved = 0;
345   encapHdr->crc32 = htonl(crc32);
346
347   /* Check if the frame is captured on an OLSR interface from an OLSR neighbor.
348    * TODO1: get_best_link_to_neighbor() is not thread-safe.
349    * TODO2: get_best_link_to_neighbor() may be very CPU-expensive, a simpler call
350    * would do here (something like 'get_any_link_to_neighbor()'). */
351   isFromOlsrNeighbor =
352     (isFromOlsrIntf /* The frame is captured on an OLSR interface... */
353     && get_best_link_to_neighbor(origIp) != NULL); /* ...from an OLSR neighbor */ 
354
355   /* Check with OLSR if I am MPR for that neighbor */
356   /* TODO: olsr_lookup_mprs_set() is not thread-safe! */
357   iAmMpr = olsr_lookup_mprs_set(origIp) != NULL;
358
359   /* Check with each network interface what needs to be done on it */
360   for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
361   {
362     /* Is the forwarding interface OLSR-enabled? */
363     int isToOlsrIntf = (walker->olsrIntf != NULL);
364
365     /* Depending on certain conditions, we decide whether or not to forward
366      * the packet, and if it is forwarded, in which form (encapsulated
367      * or not, TTL decreased or not). These conditions are:
368      * - is the packet is coming in on an OLSR interface or not? (isFromOlsrIntf)
369      * - is the packet going out on an OLSR interface or not? (isToOlsrIntf)
370      * - if the packet if coming in on an OLSR interface:
371      *   - is the node that forwarded the packet my OLSR-neighbor? (isFromOlsrNeighbor)
372      *   - has the node that forwarded the packet selected me as MPR? (iAmMpr)
373      *
374      * Based on these conditions, the following cases can be distinguished:
375      *
376      * - Case 1: Packet coming in on an OLSR interface. What to
377      *   do with it on an OLSR interface?
378      *   Answer:
379      *   - Case 1.1: If the forwarding node is an OLSR neighbor that has *not*
380      *     selected me as MPR: don't forward the packet.
381      *   - Case 1.2: If the forwarding node is an OLSR neighbor that has selected
382      *     me as MPR: encapsulate and forward the packet.
383      *   - Case 1.3: If the forwarding node is not an OLSR neighbor: encapsulate
384      *     and forward the packet.
385      *     NOTE: Case 1.3 is a special case. In the perfect world, we expect to
386      *     see only OLSR-neighbors on OLSR-enabled interfaces. Sometimes, however,
387      *     ignorant users will connect a host not running OLSR, to a LAN in
388      *     which there are hosts running OLSR. Of course these ignorant users,
389      *     expecting magic, want to see their multicast packets being forwarded
390      *     through the network.
391      *
392      * - Case 2: Packet coming in on an OLSR interface. What to do with it on a
393      *   non-OLSR interface?
394      *   Answer: Forward it.
395      *
396      * - Case 3: Packet coming in on a non-OLSR interface. What to
397      *   do with it on an OLSR interface?
398      *   Answer: Encapsulate and forward it.
399      *
400      * - Case 4: Packet coming in on non-OLSR interface. What to do with it on a
401      *   non-OLSR interface?
402      *   Answer 1: nothing. Multicast routing between non-OLSR interfaces
403      *   is to be done by other protocols (e.g. PIM, DVMRP).
404      *   Answer 2 (better): Forward it.
405      */
406
407     if (isFromOlsrIntf && isToOlsrIntf)
408     {
409       /* Case 1: Forward from an OLSR interface to an OLSR interface */
410
411       if (isFromOlsrNeighbor && !iAmMpr)
412       {
413         /* Case 1.1 */
414         {
415 #ifndef NODEBUG
416           struct ipaddr_str buf;
417 #endif
418           OLSR_PRINTF(
419             8,
420             "%s: --> not encap-forwarding on \"%s\": I am not selected as MPR by neighbor %s\n",
421             PLUGIN_NAME_SHORT,
422             walker->ifName,
423             olsr_ip_to_string(&buf, &src));
424         }    
425       }
426       else if (sllPkttype == PACKET_OUTGOING && intf == walker)
427       {
428         OLSR_PRINTF(
429           8,
430           "%s: --> not encap-forwarding on \"%s\": pkt was captured on that interface\n",
431           PLUGIN_NAME_SHORT,
432           walker->ifName);
433       }
434       else
435       {
436         /* Case 1.2 and 1.3 */
437         EncapsulateAndForwardPacket(walker, encapsulationUdpData);
438       }
439     } /* if (isFromOlsrIntf && isToOlsrIntf) */
440
441     else if (isFromOlsrIntf && !isToOlsrIntf)
442     {
443       /* Case 2: Forward from OLSR interface to non-OLSR interface */
444
445       int nBytesWritten;
446       struct sockaddr_ll dest;
447
448       /* If the encapsulated IP packet is a local broadcast packet,
449        * update its destination address to match the subnet of the network
450        * interface on which the packet is being sent. */
451       CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
452
453       memset(&dest, 0, sizeof(dest));
454       dest.sll_family = AF_PACKET;
455       dest.sll_protocol = htons(ETH_P_IP);
456       dest.sll_ifindex = if_nametoindex(walker->ifName);
457       dest.sll_halen = IFHWADDRLEN;
458
459       /* Use all-ones as destination MAC address. When the IP destination is
460        * a multicast address, the destination MAC address should normally also
461        * be a multicast address. E.g., when the destination IP is 224.0.0.1,
462        * the destination MAC should be 01:00:5e:00:00:01. However, it does not
463        * seem to matter when the destination MAC address is set to all-ones
464        * in that case. */
465       memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
466
467       nBytesWritten = sendto(
468         walker->capturingSkfd,
469         ipPacket,
470         ipPacketLen,
471         0,
472         (struct sockaddr*) &dest,
473         sizeof(dest));
474       if (nBytesWritten != ipPacketLen)
475       {
476         BmfPError("sendto() error forwarding pkt on \"%s\"", walker->ifName);
477       }
478       else
479       {
480         /* Increase counter */
481         walker->nBmfPacketsTx++;
482
483         OLSR_PRINTF(8, "%s: --> forwarded on \"%s\"\n", PLUGIN_NAME_SHORT, walker->ifName);
484       }
485     } /* else if (isFromOlsrIntf && !isToOlsrIntf) */
486
487     else if (!isFromOlsrIntf && isToOlsrIntf)
488     {
489       /* Case 3: Forward from a non-OLSR interface to an OLSR interface.
490        * Encapsulate and forward packet. */
491
492       EncapsulateAndForwardPacket(walker, encapsulationUdpData);
493     } /* else if (!isFromOlsrIntf && isToOlsrIntf) */
494
495     else
496     {
497       /* Case 4: Forward from non-OLSR interface to non-OLSR interface. */
498
499       /* Don't forward on interface on which packet was received */
500       if (intf == walker)
501       {
502         OLSR_PRINTF(
503           8,
504           "%s: --> not forwarding on \"%s\": pkt was captured on that interface\n",
505           PLUGIN_NAME_SHORT,
506           walker->ifName);
507       }
508
509       else
510       {
511         int nBytesWritten;
512         struct sockaddr_ll dest;
513
514         /* If the encapsulated IP packet is a local broadcast packet,
515          * update its destination address to match the subnet of the network
516          * interface on which the packet is being sent. */
517         CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
518
519         memset(&dest, 0, sizeof(dest));
520         dest.sll_family = AF_PACKET;
521         dest.sll_protocol = htons(ETH_P_IP);
522         dest.sll_ifindex = if_nametoindex(walker->ifName);
523         dest.sll_halen = IFHWADDRLEN;
524
525         /* Use all-ones as destination MAC address. When the IP destination is
526          * a multicast address, the destination MAC address should normally also
527          * be a multicast address. E.g., when the destination IP is 224.0.0.1,
528          * the destination MAC should be 01:00:5e:00:00:01. However, it does not
529          * seem to matter when the destination MAC address is set to all-ones
530          * in that case. */
531         memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
532
533         nBytesWritten = sendto(
534           walker->capturingSkfd,
535           ipPacket,
536           ipPacketLen,
537           0,
538           (struct sockaddr*) &dest,
539           sizeof(dest));
540         if (nBytesWritten != ipPacketLen)
541         {
542           BmfPError("sendto() error forwarding pkt on \"%s\"", walker->ifName);
543         }
544         else
545         {
546           /* Increase counter */
547           walker->nBmfPacketsTx++;
548
549           OLSR_PRINTF(
550             8,
551             "%s: --> forwarded from non-OLSR on non-OLSR \"%s\"\n",
552             PLUGIN_NAME_SHORT,
553             walker->ifName);
554         }
555       } /* if (intf == walker) */
556     } /* if */
557   } /* for */
558 } /* BmfPacketCaptured */
559
560 /* -------------------------------------------------------------------------
561  * Function   : BmfEncapsulationPacketReceived
562  * Description: Handle a received BMF-encapsulation packet
563  * Input      : intf - the network interface on which the packet was received
564  *              forwardedBy - the IP node that forwarded the packet to me
565  *              forwardedTo - the destination IP address of the encapsulation
566  *                packet, in case the packet was received promiscuously.
567  *                Pass NULL if the packet is received normally (unicast or
568  *                broadcast).
569  *              encapsulationUdpData - the encapsulating IP UDP data, containting
570  *                the BMF encapsulation header, followed by the encapsulated
571  *                IP packet
572  * Output     : none
573  * Return     : none
574  * Data Used  : BmfInterfaces
575  * ------------------------------------------------------------------------- */
576 static void BmfEncapsulationPacketReceived(
577   struct TBmfInterface* intf,
578   union olsr_ip_addr* forwardedBy,
579   union olsr_ip_addr* forwardedTo,
580   unsigned char* encapsulationUdpData)
581 {
582   int iAmMpr; /* True (1) if I am selected as MPR by 'forwardedBy' */
583   struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
584   unsigned char* ipPacket; /* The encapsulated IP packet */
585   u_int16_t ipPacketLen; /* Length of the encapsulated IP packet */
586   struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
587   union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
588   union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
589   struct TEncapHeader* encapsulationHdr;
590   u_int16_t encapsulationUdpDataLen;
591   struct TBmfInterface* walker;
592 #ifndef NODEBUG
593   struct ipaddr_str mcSrcBuf, mcDstBuf, forwardedByBuf, forwardedToBuf;
594 #endif
595   /* Are we talking to ourselves? */
596   if (if_ifwithaddr(forwardedBy) != NULL)
597   {
598     return;
599   }
600
601   /* Discard encapsulated packets received on a non-OLSR interface */
602   if (intf->olsrIntf == NULL)
603   {
604     return;
605   }
606
607   /* Retrieve details about the encapsulated IP packet */
608   ipPacket = GetIpPacket(encapsulationUdpData);
609   ipPacketLen = GetIpTotalLength(ipPacket);
610   ipHeader = GetIpHeader(encapsulationUdpData);
611
612   //COPY_IP(&mcSrc, &ipHeader->ip_src);
613   mcSrc.v4 = ipHeader->ip_src;
614   //COPY_IP(&mcDst, &ipHeader->ip_dst);
615   mcDst.v4 = ipHeader->ip_dst;
616
617   /* Increase counter */
618   intf->nBmfPacketsRx++;
619
620   /* Beware: not possible to call olsr_ip_to_string more than 4 times in same printf */
621   OLSR_PRINTF(
622     8,
623     "%s: encapsulated pkt of %ld bytes incoming on \"%s\": %s->%s, forwarded by %s to %s\n",
624     PLUGIN_NAME_SHORT,
625     (long)ipPacketLen,
626     intf->ifName,
627     olsr_ip_to_string(&mcSrcBuf, &mcSrc),
628     olsr_ip_to_string(&mcDstBuf, &mcDst),
629     olsr_ip_to_string(&forwardedByBuf, forwardedBy),
630     forwardedTo != NULL ? olsr_ip_to_string(&forwardedToBuf, forwardedTo) : "me");
631
632   /* Get encapsulation header */
633   encapsulationHdr = (struct TEncapHeader*) encapsulationUdpData;
634
635   /* Verify correct format of BMF encapsulation header */
636   if (encapsulationHdr->type != BMF_ENCAP_TYPE ||
637       encapsulationHdr->len != BMF_ENCAP_LEN ||
638       ntohs(encapsulationHdr->reserved != 0))
639   {
640     OLSR_PRINTF(
641       8,
642       "%s: --> discarding: format of BMF encapsulation header not recognized\n",
643       PLUGIN_NAME_SHORT);
644     return;
645   }
646
647   /* Check if this packet was seen recently */
648   if (CheckAndMarkRecentPacket(ntohl(encapsulationHdr->crc32)))
649   {
650     /* Increase counter */
651     intf->nBmfPacketsRxDup++;
652
653     OLSR_PRINTF(
654       8,
655       "%s: --> discarding: packet is duplicate\n",
656       PLUGIN_NAME_SHORT);
657     return;
658   }
659
660   if (EtherTunTapFd >= 0)
661   {
662     /* Unpack the encapsulated IP packet and deliver it locally, by sending
663      * a copy into the local IP stack via the EtherTunTap interface */
664
665     union olsr_ip_addr broadAddr;
666     int nBytesToWrite, nBytesWritten;
667     unsigned char* bufferToWrite;
668
669     /* If the encapsulated IP packet is a local broadcast packet,
670      * update its destination address to match the subnet of the EtherTunTap
671      * interface */
672     broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
673     CheckAndUpdateLocalBroadcast(ipPacket, &broadAddr);
674
675     bufferToWrite = ipPacket;
676     nBytesToWrite = ipPacketLen;
677
678     /* Write the packet into the EtherTunTap interface for local delivery */
679     nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);
680     if (nBytesWritten != nBytesToWrite)
681     {
682       BmfPError("write() error forwarding encapsulated pkt on \"%s\"", EtherTunTapIfName);
683     }
684     else
685     {
686       OLSR_PRINTF(
687         8,
688         "%s: --> unpacked and delivered locally on \"%s\"\n",
689         PLUGIN_NAME_SHORT,
690         EtherTunTapIfName);
691     }
692   } /* if (EtherTunTapFd >= 0) */
693
694   /* Check if I am MPR for the forwarder */
695   /* TODO: olsr_lookup_mprs_set() is not thread-safe! */
696   iAmMpr = (olsr_lookup_mprs_set(MainAddressOf(forwardedBy)) != NULL);
697
698   /* Compose destination address for next hop */
699   memset(&forwardTo, 0, sizeof(forwardTo));
700   forwardTo.sin_family = AF_INET;
701   forwardTo.sin_port = htons(BMF_ENCAP_PORT);
702
703   /* Retrieve the number of bytes to be forwarded via the encapsulation socket */
704   encapsulationUdpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
705
706   /* Check with each network interface what needs to be done on it */
707   for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
708   {
709     /* What to do with the packet on a non-OLSR interface? Unpack
710      * encapsulated packet, and forward it.
711      *
712      * What to do with the packet on an OLSR interface? Forward it only
713      * if the forwarding node has selected us as MPR (iAmMpr).
714      *
715      * Note that the packet is always coming in on an OLSR interface, because
716      * it is an encapsulated BMF packet. */
717
718     /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
719     if (walker->olsrIntf == NULL)
720     {
721       int nBytesWritten;
722       struct sockaddr_ll dest;
723
724       /* If the encapsulated IP packet is a local broadcast packet,
725        * update its destination address to match the subnet of the network
726        * interface on which the packet is being sent. */
727       CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
728
729       memset(&dest, 0, sizeof(dest));
730       dest.sll_family = AF_PACKET;
731       dest.sll_protocol = htons(ETH_P_IP);
732       dest.sll_ifindex = if_nametoindex(walker->ifName);
733       dest.sll_halen = IFHWADDRLEN;
734
735       /* Use all-ones as destination MAC address. When the IP destination is
736        * a multicast address, the destination MAC address should normally also
737        * be a multicast address. E.g., when the destination IP is 224.0.0.1,
738        * the destination MAC should be 01:00:5e:00:00:01. However, it does not
739        * seem to matter when the destination MAC address is set to all-ones
740        * in that case. */
741       memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
742
743       nBytesWritten = sendto(
744         walker->capturingSkfd,
745         ipPacket,
746         ipPacketLen,
747         0,
748         (struct sockaddr*) &dest,
749         sizeof(dest));
750       if (nBytesWritten != ipPacketLen)
751       {
752         BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
753       }
754       else
755       {
756         /* Increase counter */
757         walker->nBmfPacketsTx++;
758
759         OLSR_PRINTF(
760           8,
761           "%s: --> unpacked and forwarded on \"%s\"\n",
762           PLUGIN_NAME_SHORT,
763           walker->ifName);
764       }
765     } /* if (walker->olsrIntf == NULL) */
766
767     /* To an OLSR interface: forward the packet, but only if this node is
768      * selected as MPR by the forwarding node */
769     else if (iAmMpr)
770     {
771       struct TBestNeighbors bestNeighborLinks;
772       int nPossibleNeighbors;
773       int nBytesWritten;
774       int nPacketsToSend;
775       int i;
776
777       /* Retrieve at most two best neigbors to forward the packet to */
778       GetBestTwoNeighbors(
779         &bestNeighborLinks,
780         walker,
781         &mcSrc,
782         forwardedBy,
783         forwardedTo,
784         &nPossibleNeighbors);
785
786       if (nPossibleNeighbors <= 0)
787       {
788         OLSR_PRINTF(
789           8,
790           "%s: --> not forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
791           PLUGIN_NAME_SHORT,
792           walker->ifName);
793
794         continue; /* for */
795       }
796
797       /* Compose destination of encapsulation packet.
798        * Start by filling in the local broadcast address. */
799       //COPY_IP(&forwardTo.sin_addr.s_addr, &walker->broadAddr);
800       forwardTo.sin_addr = walker->broadAddr.v4;
801
802       /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
803        *   packet (to the best neighbor). Other neighbors listen promiscuously.
804        * - If the BMF mechanism is BM_BROADCAST,
805        *   - send one unicast packet if there is one possible neighbor,
806        *   - send two unicast packets if there are two possible neighbors, and
807        *   - only if there are more than two possible neighbors, then send an
808        *     (WLAN-air-expensive, less reliable) broadcast packet. */
809       if (BmfMechanism == BM_UNICAST_PROMISCUOUS || nPossibleNeighbors < 2)
810       {
811         nPacketsToSend = 1;
812       }
813       else /* BmfMechanism == BM_BROADCAST && nPossibleNeighbors >= 2 */
814       {
815         nPacketsToSend = 2;
816       }
817
818       for (i = 0; i < nPacketsToSend; i++)
819       {
820         if (BmfMechanism == BM_UNICAST_PROMISCUOUS || nPossibleNeighbors <= 2)
821         {
822           /* For unicast, overwrite the local broadcast address which was filled in
823            * above */
824           //COPY_IP(&forwardTo.sin_addr.s_addr, &bestNeighborLinks.links[i]->neighbor_iface_addr);
825           forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
826         }
827
828         /* Forward the BMF packet via the encapsulation socket */
829         nBytesWritten = sendto(
830           walker->encapsulatingSkfd,
831           encapsulationUdpData,
832           encapsulationUdpDataLen,
833           MSG_DONTROUTE,
834           (struct sockaddr*) &forwardTo,
835           sizeof(forwardTo));                   
836
837         /* Evaluate and display result */
838         if (nBytesWritten != encapsulationUdpDataLen)
839         {
840           BmfPError("sendto() error forwarding encapsulated pkt on \"%s\"", walker->ifName);
841         }
842         else
843         {
844           /* Increase counter */
845           walker->nBmfPacketsTx++;
846
847           OLSR_PRINTF(
848             8,
849             "%s: --> forwarded on \"%s\" to %s\n",
850             PLUGIN_NAME_SHORT,
851             walker->ifName,
852             inet_ntoa(forwardTo.sin_addr));
853         } /* if */
854       } /* for */
855     }  /* else if (iAmMpr) */
856
857     else /* walker->olsrIntf != NULL && !iAmMpr */
858     {
859 #ifndef NODEBUG
860       struct ipaddr_str buf;
861 #endif
862       /* 'walker' is an OLSR interface, but I am not selected as MPR. In that
863        * case, don't forward. */
864       OLSR_PRINTF(
865         8,
866         "%s: --> not forwarding on \"%s\": I am not selected as MPR by %s\n",
867         PLUGIN_NAME_SHORT,
868         walker->ifName,
869         olsr_ip_to_string(&buf, forwardedBy));
870     } /* else */
871   } /* for */
872 } /* BmfEncapsulationPacketReceived */
873
874 /* -------------------------------------------------------------------------
875  * Function   : BmfTunPacketCaptured
876  * Description: Handle an IP packet, captured outgoing on the tuntap interface
877  * Input      : encapsulationUdpData - space for the encapsulation header, followed by
878  *                the captured outgoing IP packet
879  * Output     : none
880  * Return     : none
881  * Data Used  : none
882  * Notes      : The packet is assumed to be captured on a socket of family
883  *              PF_PACKET and type SOCK_DGRAM (cooked).
884  * ------------------------------------------------------------------------- */
885 static void BmfTunPacketCaptured(unsigned char* encapsulationUdpData)
886 {
887   union olsr_ip_addr srcIp;
888   union olsr_ip_addr dstIp;
889   union olsr_ip_addr broadAddr;
890   struct TBmfInterface* walker;
891   unsigned char* ipPacket;
892   u_int16_t ipPacketLen;
893   struct ip* ipHeader;
894   u_int32_t crc32;
895   struct TEncapHeader* encapHdr;
896 #ifndef NODEBUG
897   struct ipaddr_str srcIpBuf, dstIpBuf;
898 #endif
899   ipPacket = GetIpPacket(encapsulationUdpData);
900   ipPacketLen = GetIpTotalLength(ipPacket);
901   ipHeader = GetIpHeader(encapsulationUdpData);
902
903   /* Only forward multicast packets. If configured, also forward local broadcast packets */
904   //COPY_IP(&dstIp, &ipHeader->ip_dst);
905   dstIp.v4 = ipHeader->ip_dst;
906
907   broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
908   if (IsMulticast(&dstIp) ||
909       (EnableLocalBroadcast != 0 && ipequal(&dstIp, &broadAddr)))
910   {
911     /* continue */
912   }
913   else
914   {
915     return;
916   }
917
918   //COPY_IP(&srcIp, &ipHeader->ip_src);
919   srcIp.v4 = ipHeader->ip_src;
920
921   OLSR_PRINTF(
922     8,
923     "%s: outgoing pkt of %ld bytes captured on tuntap interface \"%s\": %s->%s\n",
924     PLUGIN_NAME_SHORT,
925     (long)ipPacketLen,
926     EtherTunTapIfName,
927     olsr_ip_to_string(&srcIpBuf, &srcIp),
928     olsr_ip_to_string(&dstIpBuf, &dstIp));
929
930   /* Calculate packet fingerprint */
931   crc32 = PacketCrc32(ipPacket, ipPacketLen);
932
933   /* Check if this packet was seen recently */
934   if (CheckAndMarkRecentPacket(crc32))
935   {
936     OLSR_PRINTF(
937       8,
938       "%s: --> discarding: packet is duplicate\n",
939       PLUGIN_NAME_SHORT);
940     return;
941   }
942
943   /* Compose encapsulation header */
944   encapHdr = (struct TEncapHeader*) encapsulationUdpData;
945   memset (encapHdr, 0, ENCAP_HDR_LEN);
946   encapHdr->type = BMF_ENCAP_TYPE;
947   encapHdr->len = BMF_ENCAP_LEN;
948   encapHdr->reserved = 0;
949   encapHdr->crc32 = htonl(crc32);
950
951   /* Check with each network interface what needs to be done on it */
952   for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
953   {
954     /* Is the forwarding interface OLSR-enabled? */
955     if (walker->olsrIntf != NULL)
956     {
957       /* On an OLSR interface: encapsulate and forward packet. */
958
959       EncapsulateAndForwardPacket(walker, encapsulationUdpData);
960     }
961     else
962     {
963       /* On a non-OLSR interface: what to do?
964        * Answer 1: nothing. Multicast routing between non-OLSR interfaces
965        * is to be done by other protocols (e.g. PIM, DVMRP).
966        * Answer 2 (better): Forward it. */
967
968       int nBytesWritten;
969       struct sockaddr_ll dest;
970
971       /* If the encapsulated IP packet is a local broadcast packet,
972        * update its destination address to match the subnet of the network
973        * interface on which the packet is being sent. */
974       CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
975
976       memset(&dest, 0, sizeof(dest));
977       dest.sll_family = AF_PACKET;
978       dest.sll_protocol = htons(ETH_P_IP);
979       dest.sll_ifindex = if_nametoindex(walker->ifName);
980       dest.sll_halen = IFHWADDRLEN;
981
982       /* Use all-ones as destination MAC address. When the IP destination is
983        * a multicast address, the destination MAC address should normally also
984        * be a multicast address. E.g., when the destination IP is 224.0.0.1,
985        * the destination MAC should be 01:00:5e:00:00:01. However, it does not
986        * seem to matter when the destination MAC address is set to all-ones
987        * in that case. */
988       memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
989
990       nBytesWritten = sendto(
991         walker->capturingSkfd,
992         ipPacket,
993         ipPacketLen,
994         0,
995         (struct sockaddr*) &dest,
996         sizeof(dest));
997       if (nBytesWritten != ipPacketLen)
998       {
999         BmfPError("sendto() error forwarding pkt on \"%s\"", walker->ifName);
1000       }
1001       else
1002       {
1003         /* Increase counter */
1004         walker->nBmfPacketsTx++;
1005
1006         OLSR_PRINTF(
1007           8,
1008           "%s: --> forwarded from non-OLSR to non-OLSR \"%s\"\n",
1009           PLUGIN_NAME_SHORT,
1010           walker->ifName);
1011       } /* if */
1012     } /* if */
1013   } /* for */
1014 } /* BmfTunPacketCaptured */
1015
1016 /* -------------------------------------------------------------------------
1017  * Function   : DoBmf
1018  * Description: Wait (blocking) for IP packets, then call the handler for each
1019  *              received packet
1020  * Input      : none
1021  * Output     : none
1022  * Return     : none
1023  * Data Used  : BmfInterfaces
1024  * ------------------------------------------------------------------------- */
1025 static void DoBmf(void)
1026 {
1027   int nFdBitsSet;
1028   unsigned char rxBuffer[BMF_BUFFER_SIZE];
1029   fd_set rxFdSet;
1030
1031   assert(HighestSkfd >= 0);
1032
1033   /* Make a local copy of the set of file descriptors that select() can
1034    * modify to indicate which descriptors actually changed status */
1035   rxFdSet = InputSet;
1036
1037   /* Wait (blocking) for packets received on any of the sockets.
1038    * NOTE: don't use a timeout (last parameter). It causes a high system CPU load! */
1039   nFdBitsSet = select(HighestSkfd + 1, &rxFdSet, NULL, NULL, NULL);
1040   if (nFdBitsSet < 0)
1041   {
1042     if (errno != EINTR)
1043     {
1044       BmfPError("select() error");
1045     }
1046     return;
1047   }
1048
1049   while (nFdBitsSet > 0)
1050   {
1051     struct TBmfInterface* walker;
1052
1053     /* Check if a packet was received on the capturing socket (if any)
1054      * of each network interface */
1055     for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
1056     {
1057       int skfd = walker->capturingSkfd;
1058       if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))
1059       {
1060         struct sockaddr_ll pktAddr;
1061         socklen_t addrLen = sizeof(pktAddr);
1062         int nBytes;
1063         unsigned char* ipPacket;
1064
1065         /* A packet was captured. */
1066
1067         nFdBitsSet--;
1068
1069         /* Receive the captured Ethernet frame, leaving space for the BMF
1070          * encapsulation header */
1071         ipPacket = GetIpPacket(rxBuffer);
1072         nBytes = recvfrom(
1073           skfd,
1074           ipPacket,
1075           BMF_BUFFER_SIZE - ENCAP_HDR_LEN,
1076           0,
1077           (struct sockaddr*)&pktAddr,
1078           &addrLen);
1079         if (nBytes < 0)
1080         {
1081           BmfPError("recvfrom() error on \"%s\"", walker->ifName);
1082
1083           continue; /* for */
1084         } /* if (nBytes < 0) */
1085
1086         /* Check if the number of received bytes is large enough for an IP
1087          * packet which contains at least a minimum-size IP header.
1088          * Note: There is an apparent bug in the packet socket implementation in
1089          * combination with VLAN interfaces. On a VLAN interface, the value returned
1090          * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
1091          * returned on a non-VLAN interface, for the same ethernet frame. */
1092         if (nBytes < (int)sizeof(struct ip))
1093         {
1094           olsr_printf(
1095             1,
1096             "%s: captured frame too short (%d bytes) on \"%s\"\n",
1097             PLUGIN_NAME,
1098             nBytes,
1099             walker->ifName);
1100
1101           continue; /* for */
1102         }
1103
1104         if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
1105             pktAddr.sll_pkttype == PACKET_MULTICAST ||
1106             pktAddr.sll_pkttype == PACKET_BROADCAST)
1107         {
1108           /* A multicast or broadcast packet was captured */
1109
1110           BmfPacketCaptured(walker, pktAddr.sll_pkttype, rxBuffer);
1111
1112         } /* if (pktAddr.sll_pkttype == ...) */
1113       } /* if (skfd >= 0 && (FD_ISSET...)) */
1114     } /* for */
1115     
1116     /* Check if a BMF encapsulation packet was received on the listening
1117      * socket (if any) of each network interface */
1118     for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
1119     {
1120       int skfd = walker->listeningSkfd;
1121       if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))
1122       {
1123         struct sockaddr_ll pktAddr;
1124         socklen_t addrLen = sizeof(pktAddr);
1125         int nBytes;
1126         int minimumLength;
1127         struct ip* ipHeader;
1128         struct udphdr* udpHeader;
1129         u_int16_t destPort;
1130         union olsr_ip_addr forwardedBy;
1131         union olsr_ip_addr forwardedTo;
1132
1133         /* Heard a BMF packet */
1134
1135         nFdBitsSet--;
1136
1137         nBytes = recvfrom(
1138           skfd,
1139           rxBuffer,
1140           BMF_BUFFER_SIZE,
1141           0,
1142           (struct sockaddr*)&pktAddr,
1143           &addrLen);
1144         if (nBytes < 0)
1145         {
1146           BmfPError("recvfrom() error on \"%s\"", walker->ifName);
1147
1148           continue; /* for */
1149         } /* if (nBytes < 0) */
1150
1151         /* Check if the received packet is actually directed to another
1152          * node on the LAN */
1153         if (pktAddr.sll_pkttype != PACKET_OTHERHOST)
1154         {
1155           /* No, the packet is directed to this node. In that case it will
1156            * be, or will already have been received, via the encapsulating
1157            * socket. Discard it here. */
1158           continue; /* for */
1159         } /* if (pktAddr.sll_pkttype ...) */
1160
1161         /* Check if the received packet is UDP - BMF port */
1162         ipHeader = (struct ip*)rxBuffer;
1163         if (ipHeader->ip_p != SOL_UDP)
1164         {
1165           /* Not UDP */
1166           continue; /* for */
1167         }
1168
1169         udpHeader = (struct udphdr*)(rxBuffer + GetIpHeaderLength(rxBuffer));
1170         destPort = ntohs(udpHeader->dest);
1171         if (destPort != BMF_ENCAP_PORT)
1172         {
1173           /* Not BMF */
1174           continue; /* for */
1175         }
1176
1177         /* Check if the number of received bytes is large enough for a minimal BMF
1178          * encapsulation packet, at least:
1179          * - the IP header of the encapsulation IP packet
1180          * - the UDP header of the encapsulation IP packet
1181          * - the encapsulation header
1182          * - a minimum IP header inside the encapsulated packet
1183          * Note: on a VLAN interface, the value returned by 'recvfrom' may (but need
1184          * not) be 4 (bytes) larger than the value returned on a non-VLAN interface, for
1185          * the same ethernet frame. */
1186         minimumLength =
1187           GetIpHeaderLength(rxBuffer) +
1188           sizeof(struct udphdr) +
1189           ENCAP_HDR_LEN +
1190           sizeof(struct ip);
1191         if (nBytes < minimumLength)
1192         {
1193           olsr_printf(
1194             1,
1195             "%s: captured a too short encapsulation packet (%d bytes) on \"%s\"\n",
1196             PLUGIN_NAME,
1197             nBytes,
1198             walker->ifName);
1199
1200           continue; /* for */
1201         }
1202
1203         //COPY_IP(&forwardedBy, &ipHeader->ip_src);
1204         forwardedBy.v4 = ipHeader->ip_src;
1205         //COPY_IP(&forwardedTo, &ipHeader->ip_dst);
1206         forwardedTo.v4 = ipHeader->ip_dst;
1207         BmfEncapsulationPacketReceived(
1208           walker,
1209           &forwardedBy,
1210           &forwardedTo,
1211           rxBuffer + GetIpHeaderLength(rxBuffer) + sizeof(struct udphdr));
1212
1213       } /* if (skfd >= 0 && (FD_ISSET...)) */
1214     } /* for */
1215
1216     /* Check if a packet was received on the encapsulating socket (if any)
1217      * of each network interface */
1218     for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
1219     {
1220       int skfd = walker->encapsulatingSkfd;
1221       if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))
1222       {
1223         struct sockaddr_in from;
1224         socklen_t fromLen = sizeof(from);
1225         int nBytes;
1226         int minimumLength;
1227         union olsr_ip_addr forwardedBy;
1228
1229         /* An encapsulated packet was received */
1230
1231         nFdBitsSet--;
1232
1233         nBytes = recvfrom(
1234           skfd,
1235           rxBuffer,
1236           BMF_BUFFER_SIZE,
1237           0,
1238           (struct sockaddr*)&from,
1239           &fromLen);
1240         if (nBytes < 0)
1241         {
1242           BmfPError("recvfrom() error on \"%s\"", walker->ifName);
1243
1244           continue; /* for */
1245         } /* if (nBytes < 0) */
1246
1247         //COPY_IP(&forwardedBy, &from.sin_addr.s_addr);
1248         forwardedBy.v4 = from.sin_addr;
1249
1250         /* Check if the number of received bytes is large enough for a minimal BMF
1251          * encapsulation packet, at least:
1252          * - the encapsulation header
1253          * - a minimum IP header inside the encapsulated packet */
1254         minimumLength =
1255           ENCAP_HDR_LEN +
1256           sizeof(struct ip);
1257         if (nBytes < minimumLength)
1258         {
1259           struct ipaddr_str buf;
1260           olsr_printf(
1261             1,
1262             "%s: received a too short encapsulation packet (%d bytes) from %s on \"%s\"\n",
1263             PLUGIN_NAME,
1264             nBytes,
1265             olsr_ip_to_string(&buf, &forwardedBy),
1266             walker->ifName);
1267
1268           continue; /* for */
1269         }
1270
1271         /* Unfortunately, the recvfrom call does not return the destination
1272          * of the encapsulation packet (the destination may be either the
1273          * my unicast or my local broadcast address). Therefore we fill in 'NULL'
1274          * for the 'forwardedTo' parameter. */
1275         BmfEncapsulationPacketReceived(walker, &forwardedBy, NULL, rxBuffer);
1276
1277       } /* if (skfd >= 0 && (FD_ISSET...)) */
1278     } /* for */
1279
1280     if (nFdBitsSet > 0 && FD_ISSET(EtherTunTapFd, &rxFdSet))
1281     {
1282       /* Check if an application has sent a packet out via the tuntap
1283        * network interface */
1284
1285       int nBytes;
1286       unsigned char* ipPacket;
1287       unsigned char* bufferToRead;
1288       size_t nBytesToRead;
1289
1290       nFdBitsSet--;
1291
1292       /* Receive the packet, leaving space for the BMF encapsulation header */
1293       ipPacket = GetIpPacket(rxBuffer);
1294     
1295       bufferToRead = ipPacket;
1296       nBytesToRead = BMF_BUFFER_SIZE - ENCAP_HDR_LEN;
1297
1298       nBytes = read(EtherTunTapFd, bufferToRead, nBytesToRead);
1299
1300       if (nBytes < 0)
1301       {
1302         BmfPError("recvfrom() error on \"%s\"", EtherTunTapIfName);
1303       }
1304       else
1305       {
1306         /* Check if the number of received bytes is large enough for an IP
1307          * packet which contains at least a minimum-size IP header */
1308         if (nBytes < (int)sizeof(struct ip))
1309         {
1310           olsr_printf(
1311             1,
1312             "%s: captured packet too short (%d bytes) on \"%s\"\n",
1313             PLUGIN_NAME,
1314             nBytes,
1315             EtherTunTapIfName);
1316         }
1317         else
1318         {
1319           /* An outbound packet was captured */
1320
1321           BmfTunPacketCaptured(rxBuffer);
1322
1323         } /* if (nBytes < ... */
1324       } /* if (nBytes < 0) */
1325     } /* if (nFdBitsSet > 0 && ... */
1326   } /* while (nFdBitsSet > 0) */
1327 } /* DoBmf */
1328
1329 /* -------------------------------------------------------------------------
1330  * Function   : BmfSignalHandler
1331  * Description: Signal handler function
1332  * Input      : signo - signal being handled
1333  * Output     : none
1334  * Return     : none
1335  * Data Used  : BmfThreadRunning
1336  * ------------------------------------------------------------------------- */
1337 static void BmfSignalHandler(int signo __attribute__((unused)))
1338 {
1339   BmfThreadRunning = 0;
1340 } /* BmfSignalHandler */
1341
1342 /* -------------------------------------------------------------------------
1343  * Function   : BmfRun
1344  * Description: Receiver thread function
1345  * Input      : useless - not used
1346  * Output     : none
1347  * Return     : not used
1348  * Data Used  : BmfThreadRunning
1349  * Notes      : Another thread can gracefully stop this thread by sending
1350  *              a SIGALRM signal.
1351  * ------------------------------------------------------------------------- */
1352 static void* BmfRun(void* useless __attribute__((unused)))
1353 {
1354   /* Mask all signals except SIGALRM */
1355   sigset_t blockedSigs;
1356   sigfillset(&blockedSigs);
1357   sigdelset(&blockedSigs, SIGALRM);
1358   if (pthread_sigmask(SIG_BLOCK, &blockedSigs, NULL) != 0)
1359   {
1360     BmfPError("pthread_sigmask() error");
1361   }
1362
1363   /* Set up the signal handler for the process: use SIGALRM to terminate
1364    * the BMF thread. Only if a signal handler is specified, does a blocking
1365    * system call return with errno set to EINTR; if a signal hander is not
1366    * specified, any system call in which the thread may be waiting will not
1367    * return. Note that the BMF thread is usually blocked in the select()
1368    * function (see DoBmf()). */
1369   if (signal(SIGALRM, BmfSignalHandler) == SIG_ERR)
1370   {
1371     BmfPError("signal() error");
1372   }
1373
1374   /* Call the thread function until flagged to exit */
1375   while (BmfThreadRunning != 0)
1376   {
1377     DoBmf();
1378   }
1379
1380   return NULL;
1381 } /* BmfRun */
1382
1383 /* -------------------------------------------------------------------------
1384  * Function   : InterfaceChange
1385  * Description: Callback function passed to OLSRD for it to call whenever a
1386  *              network interface has been added, removed or updated
1387  * Input      : interf - the network interface to deal with
1388  *              action - indicates if the specified network interface was
1389  *                added, removed or updated.
1390  * Output     : none
1391  * Return     : always 0
1392  * Data Used  : none
1393  * ------------------------------------------------------------------------- */
1394 int InterfaceChange(struct interface* interf, int action)
1395 {
1396   switch (action)
1397   {
1398   case (IFCHG_IF_ADD):
1399     AddInterface(interf);
1400     olsr_printf(1, "%s: interface %s added\n", PLUGIN_NAME, interf->int_name);
1401     break;
1402
1403   case (IFCHG_IF_REMOVE):
1404     /* We cannot just remove the interface, because the receive-thread is likely
1405      * to be waiting in select(...) for packets coming in via the interface.
1406      * Therefore we first close BMF (CloseBmf()), interrupting and kiling the
1407      * receive-thread so that it is safe to remove this (and all other)
1408      * interfaces. After that, BMF is re-started (InitBmf(interf)). */
1409     CloseBmf();
1410     InitBmf(interf);
1411     olsr_printf(1, "%s: interface %s removed\n", PLUGIN_NAME, interf->int_name);
1412     break;
1413
1414   case (IFCHG_IF_UPDATE):
1415     olsr_printf(1, "%s: interface %s updated\n", PLUGIN_NAME, interf->int_name);
1416     break;
1417       
1418   default:
1419     olsr_printf(
1420       1,
1421       "%s: interface %s: error - unknown action (%d)\n",
1422       PLUGIN_NAME,
1423       interf->int_name, action);
1424     break;
1425   }
1426
1427   return 0;
1428 } /* InterfaceChange */
1429
1430 /* -------------------------------------------------------------------------
1431  * Function   : InitBmf
1432  * Description: Initialize the BMF plugin
1433  * Input      : skipThisIntf - specifies which network interface should not
1434  *              be enabled for BMF. Pass NULL if not applicable.
1435  * Output     : none
1436  * Return     : fail (0) or success (1)
1437  * Data Used  : BmfThreadRunning, BmfThread
1438  * ------------------------------------------------------------------------- */
1439 int InitBmf(struct interface* skipThisIntf)
1440 {
1441   CreateBmfNetworkInterfaces(skipThisIntf);
1442
1443   /* Start running the multicast packet processing thread */
1444   BmfThreadRunning = 1;
1445   if (pthread_create(&BmfThread, NULL, BmfRun, NULL) != 0)
1446   {
1447     BmfPError("pthread_create() error");
1448     return 0;
1449   }
1450
1451   if (EtherTunTapFd >= 0)
1452   {
1453     /* Deactivate IP spoof filter for EtherTunTap interface */
1454     DeactivateSpoofFilter();
1455
1456     /* If the BMF network interface has a sensible IP address, it is a good idea
1457      * to route all multicast traffic through that interface */
1458     if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP)
1459     {
1460       AddMulticastRoute();
1461     }
1462   }
1463
1464   return 1;
1465 } /* InitBmf */
1466
1467 /* -------------------------------------------------------------------------
1468  * Function   : CloseBmf
1469  * Description: Close the BMF plugin and clean up
1470  * Input      : none
1471  * Output     : none
1472  * Return     : none
1473  * Data Used  : BmfThread
1474  * ------------------------------------------------------------------------- */
1475 void CloseBmf(void)
1476 {
1477   if (EtherTunTapFd >= 0)
1478   {
1479     /* If there is a multicast route, try to delete it first */
1480     DeleteMulticastRoute();
1481
1482     /* Restore IP spoof filter for EtherTunTap interface */
1483     RestoreSpoofFilter();
1484   }
1485
1486   if (BmfThreadRunning)
1487   {
1488     /* Signal BmfThread to exit */
1489     /* Strangely enough, all running threads receive the SIGALRM signal. But only the
1490      * BMF thread is affected by this signal, having specified a handler for this
1491      * signal in its thread entry function BmfRun(...). */
1492     if (pthread_kill(BmfThread, SIGALRM) != 0)
1493     {
1494       BmfPError("pthread_kill() error");
1495     }
1496
1497     /* Wait for BmfThread to acknowledge */
1498     if (pthread_join(BmfThread, NULL) != 0)
1499     {
1500       BmfPError("pthread_join() error");
1501     }
1502   }
1503
1504   /* Clean up after the BmfThread has been killed */
1505   CloseBmfNetworkInterfaces();
1506 } /* CloseBmf */
1507