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