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