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