contrib/package: bump to olsrd 0.5.6-r6 plus most recent fixes
[project/luci.git] / contrib / package / olsrd-luci / patches / 160-add-mdns.patch
1 --- a/Makefile
2 +++ b/Makefile
3 @@ -154,7 +154,7 @@
4  # nameservice: no regex
5  SUBDIRS := bmf dot_draw dyn_gw_plain httpinfo mini quagga secure tas txtinfo watchdog
6  else
7 -SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo mini nameservice pgraph secure txtinfo watchdog
8 +SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo mini nameservice pgraph secure txtinfo watchdog mdns
9  endif
10  endif
11  endif
12 @@ -241,6 +241,11 @@
13                 $(MAKECMD) -C lib/watchdog
14                 $(MAKECMD) -C lib/watchdog DESTDIR=$(DESTDIR) install
15  
16 +mdns:
17 +               $(MAKECMD) -C lib/mdns clean
18 +               $(MAKECMD) -C lib/mdns
19 +               $(MAKECMD) -C lib/mdns DESTDIR=$(DESTDIR) install
20 +
21  build_all:     all switch libs
22  install_all:   install install_libs
23  clean_all:     uberclean clean_libs
24 --- /dev/null
25 +++ b/lib/mdns/Makefile
26 @@ -0,0 +1,66 @@
27 +#
28 +# OLSR Basic Multicast Forwarding (BMF) plugin.
29 +# Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
30 +# Written by Erik Tromp.
31 +# All rights reserved.
32 +#
33 +# Redistribution and use in source and binary forms, with or without
34 +# modification, are permitted provided that the following conditions
35 +# are met:
36 +#
37 +# * Redistributions of source code must retain the above copyright
38 +#   notice, this list of conditions and the following disclaimer.
39 +# * Redistributions in binary form must reproduce the above copyright
40 +#   notice, this list of conditions and the following disclaimer in
41 +#   the documentation and/or other materials provided with the
42 +#   distribution.
43 +# * Neither the name of Thales, BMF nor the names of its
44 +#   contributors may be used to endorse or promote products derived
45 +#   from this software without specific prior written permission.
46 +#
47 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
50 +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
51 +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
52 +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
53 +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
55 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
57 +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58 +# POSSIBILITY OF SUCH DAMAGE.
59 +#
60 +
61 +OLSRD_PLUGIN = true
62 +PLUGIN_NAME =  olsrd_mdns
63 +PLUGIN_VER =   1.0.0
64 +
65 +TOPDIR = ../..
66 +include $(TOPDIR)/Makefile.inc
67 +
68 +LIBS +=        $(OS_LIB_PTHREAD)
69 +
70 +# Must be specified along with -lpthread on linux
71 +CPPFLAGS += $(OS_CFLAG_PTHREAD)
72 +
73 +ifneq ($(OS),linux)
74 +
75 +default_target install clean:
76 +       @echo "*** BMF Plugin only supported on Linux, sorry!"
77 +
78 +else
79 +
80 +default_target: $(PLUGIN_FULLNAME)
81 +
82 +$(PLUGIN_FULLNAME): $(OBJS) version-script.txt
83 +               $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
84 +
85 +install:       $(PLUGIN_FULLNAME)
86 +               $(STRIP) $(PLUGIN_FULLNAME)
87 +               $(INSTALL_LIB)
88 +
89 +clean:
90 +               rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
91 +
92 +endif
93 --- /dev/null
94 +++ b/lib/mdns/src/Address.c
95 @@ -0,0 +1,164 @@
96 +/*
97 + * OLSR Basic Multicast Forwarding (BMF) plugin.
98 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
99 + * Written by Erik Tromp.
100 + * All rights reserved.
101 + *
102 + * Redistribution and use in source and binary forms, with or without
103 + * modification, are permitted provided that the following conditions
104 + * are met:
105 + *
106 + * * Redistributions of source code must retain the above copyright
107 + *   notice, this list of conditions and the following disclaimer.
108 + * * Redistributions in binary form must reproduce the above copyright
109 + *   notice, this list of conditions and the following disclaimer in
110 + *   the documentation and/or other materials provided with the
111 + *   distribution.
112 + * * Neither the name of Thales, BMF nor the names of its
113 + *   contributors may be used to endorse or promote products derived
114 + *   from this software without specific prior written permission.
115 + *
116 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
117 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
119 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
120 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
121 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
122 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
123 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
124 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
125 + * OF THE POSSIBILITY OF SUCH DAMAGE.
126 + */
127 +
128 +/* -------------------------------------------------------------------------
129 + * File       : Address.c
130 + * Description: IP packet characterization functions
131 + * Created    : 29 Jun 2006
132 + *
133 + * ------------------------------------------------------------------------- */
134 +
135 +#include "Address.h"
136 +
137 +/* System includes */
138 +#include <stddef.h> /* NULL */
139 +#include <string.h> /* strcmp */
140 +#include <assert.h> /* assert() */
141 +#include <netinet/ip.h> /* struct ip */
142 +#include <netinet/udp.h> /* struct udphdr */
143 +
144 +/* OLSRD includes */
145 +#include "defs.h" /* ipequal */
146 +#include "olsr_protocol.h" /* OLSRPORT */
147 +
148 +/* Plugin includes */
149 +#include "mdns.h" /* BMF_ENCAP_PORT */
150 +#include "NetworkInterfaces.h" /* TBmfInterface */
151 +
152 +/* Whether or not to flood local broadcast packets (e.g. packets with IP
153 + * destination 192.168.1.255). May be overruled by setting the plugin
154 + * parameter "DoLocalBroadcast" to "no" */
155 +int EnableLocalBroadcast = 1;
156 +
157 +/* -------------------------------------------------------------------------
158 + * Function   : DoLocalBroadcast
159 + * Description: Overrule the default setting, enabling or disabling the
160 + *              flooding of local broadcast packets
161 + * Input      : enable - either "yes" or "no"
162 + *              data - not used
163 + *              addon - not used
164 + * Output     : none
165 + * Return     : success (0) or fail (1)
166 + * Data Used  : none
167 + * ------------------------------------------------------------------------- */
168 +int DoLocalBroadcast(
169 +  const char* enable,
170 +  void* data __attribute__((unused)),
171 +  set_plugin_parameter_addon addon __attribute__((unused)))
172 +{
173 +  if (strcmp(enable, "yes") == 0)
174 +  {
175 +    EnableLocalBroadcast = 1;
176 +    return 0;
177 +  }
178 +  else if (strcmp(enable, "no") == 0)
179 +  {
180 +    EnableLocalBroadcast = 0;
181 +    return 0;
182 +  }
183 +
184 +  /* Value not recognized */
185 +  return 1;
186 +}
187 +
188 +/* -------------------------------------------------------------------------
189 + * Function   : IsMulticast
190 + * Description: Check if an IP address is a multicast address
191 + * Input      : ipAddress
192 + * Output     : none
193 + * Return     : true (1) or false (0)
194 + * Data Used  : none
195 + * ------------------------------------------------------------------------- */
196 +int IsMulticast(union olsr_ip_addr* ipAddress)
197 +{
198 +  assert(ipAddress != NULL);
199 +
200 +  return (ntohl(ipAddress->v4.s_addr) & 0xF0000000) == 0xE0000000;
201 +}
202 +
203 +/* -------------------------------------------------------------------------
204 + * Function   : IsOlsrOrBmfPacket
205 + * Description: Check if an IP packet is either an OLSR packet or a BMF packet
206 + * Input      : ipPacket
207 + * Output     : none
208 + * Return     : true (1) or false (0)
209 + * Data Used  : none
210 + * ------------------------------------------------------------------------- */
211 +//int IsOlsrOrBmfPacket(unsigned char* ipPacket)
212 +//{//MODIFICATA
213 +//  struct ip* ipHeader;
214 +//  unsigned int ipHeaderLen;
215 +//  struct udphdr* udpHeader;
216 +//  u_int16_t destPort;
217 +//
218 +//  assert(ipPacket != NULL);
219 +//
220 +//  /* OLSR packets are UDP - port 698
221 +//   * OLSR-BMF packets are UDP - port 50698
222 +//   * OLSR-Autodetect probe packets are UDP - port 51698 */
223 +//
224 +//  /* Check if UDP */
225 +//  ipHeader = (struct ip*) ipPacket;
226 +//  if (ipHeader->ip_p != SOL_UDP)
227 +//  {
228 +//    /* Not UDP */
229 +//    return 0;
230 +//  }
231 +//
232 +//  /* The total length must be at least large enough to store the UDP header */
233 +//  ipHeaderLen = GetIpHeaderLength(ipPacket);
234 +//  if (GetIpTotalLength(ipPacket) < ipHeaderLen + sizeof(struct udphdr))
235 +//  {
236 +//    /* Not long enough */
237 +//    return 0;
238 +//  }
239 +//
240 +//  /* Go into the UDP header and check port number */
241 +//  udpHeader = (struct udphdr*) (ipPacket + ipHeaderLen);
242 +//  destPort = ntohs(udpHeader->dest);
243 +//
244 +//  //if (destPort == OLSRPORT || destPort == BMF_ENCAP_PORT || destPort == 51698)
245 +//  if (destPort == 5353)
246 +//      /* TODO: #define for 51698 */
247 +//  {
248 +//    return 1;
249 +//  }
250 +//
251 +//  return 0;
252 +//}
253 +//
254 +/*
255 + * Local Variables:
256 + * c-basic-offset: 2
257 + * indent-tabs-mode: nil
258 + * End:
259 + */
260 --- /dev/null
261 +++ b/lib/mdns/src/Address.h
262 @@ -0,0 +1,62 @@
263 +#ifndef _BMF_ADDRESS_H
264 +#define _BMF_ADDRESS_H
265 +
266 +/*
267 + * OLSR Basic Multicast Forwarding (BMF) plugin.
268 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
269 + * Written by Erik Tromp.
270 + * All rights reserved.
271 + *
272 + * Redistribution and use in source and binary forms, with or without
273 + * modification, are permitted provided that the following conditions
274 + * are met:
275 + *
276 + * * Redistributions of source code must retain the above copyright
277 + *   notice, this list of conditions and the following disclaimer.
278 + * * Redistributions in binary form must reproduce the above copyright
279 + *   notice, this list of conditions and the following disclaimer in
280 + *   the documentation and/or other materials provided with the
281 + *   distribution.
282 + * * Neither the name of Thales, BMF nor the names of its
283 + *   contributors may be used to endorse or promote products derived
284 + *   from this software without specific prior written permission.
285 + *
286 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
287 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
288 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
289 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
290 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
291 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
292 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
293 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
294 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
295 + * OF THE POSSIBILITY OF SUCH DAMAGE.
296 + */
297 +
298 +/* -------------------------------------------------------------------------
299 + * File       : Address.h
300 + * Description: IP packet characterization functions
301 + * Created    : 29 Jun 2006
302 + *
303 + * ------------------------------------------------------------------------- */
304 +
305 +#include "olsr_types.h" /* olsr_ip_addr */
306 +#include "olsrd_plugin.h"     /* union set_plugin_parameter_addon */
307 +#include "interfaces.h" /* struct interface */
308 +
309 +struct TBmfInterface;
310 +
311 +extern int EnableLocalBroadcast;
312 +
313 +int DoLocalBroadcast(const char* enable, void* data, set_plugin_parameter_addon addon);
314 +int IsMulticast(union olsr_ip_addr* ipAddress);
315 +int IsOlsrOrBmfPacket(unsigned char* ipPacket);
316 +
317 +#endif /* _BMF_ADDRESS_H */
318 +
319 +/*
320 + * Local Variables:
321 + * c-basic-offset: 2
322 + * indent-tabs-mode: nil
323 + * End:
324 + */
325 --- /dev/null
326 +++ b/lib/mdns/src/NetworkInterfaces.c
327 @@ -0,0 +1,1703 @@
328 +/*
329 + * OLSR Basic Multicast Forwarding (BMF) plugin.
330 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
331 + * Written by Erik Tromp.
332 + * All rights reserved.
333 + *
334 + * Redistribution and use in source and binary forms, with or without
335 + * modification, are permitted provided that the following conditions
336 + * are met:
337 + *
338 + * * Redistributions of source code must retain the above copyright
339 + *   notice, this list of conditions and the following disclaimer.
340 + * * Redistributions in binary form must reproduce the above copyright
341 + *   notice, this list of conditions and the following disclaimer in
342 + *   the documentation and/or other materials provided with the
343 + *   distribution.
344 + * * Neither the name of Thales, BMF nor the names of its
345 + *   contributors may be used to endorse or promote products derived
346 + *   from this software without specific prior written permission.
347 + *
348 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
349 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
350 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
351 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
352 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
353 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
354 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
355 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
356 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
357 + * OF THE POSSIBILITY OF SUCH DAMAGE.
358 + */
359 +
360 +/* -------------------------------------------------------------------------
361 + * File       : NetworkInterfaces.c
362 + * Description: Functions to open and close sockets
363 + * Created    : 29 Jun 2006
364 + *
365 + * ------------------------------------------------------------------------- */
366 +
367 +#include "NetworkInterfaces.h"
368 +
369 +/* System includes */
370 +#include <stddef.h> /* NULL */
371 +#include <syslog.h> /* syslog() */
372 +#include <string.h> /* strerror(), strchr(), strcmp() */
373 +#include <errno.h> /* errno */
374 +#include <unistd.h> /* close() */
375 +#include <sys/ioctl.h> /* ioctl() */
376 +#include <fcntl.h> /* fcntl() */
377 +#include <assert.h> /* assert() */
378 +#include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
379 +#include <netinet/in.h> /* htons() */
380 +#include <linux/if_ether.h> /* ETH_P_IP */
381 +#include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
382 +#include <linux/if_tun.h> /* IFF_TAP */
383 +#include <netinet/ip.h> /* struct ip */
384 +#include <netinet/udp.h> /* SOL_UDP */
385 +#include <stdlib.h> /* atoi, malloc */
386 +
387 +/* OLSRD includes */
388 +#include "olsr.h" /* OLSR_PRINTF() */
389 +#include "ipcalc.h"
390 +#include "defs.h" /* olsr_cnf */
391 +#include "link_set.h" /* get_link_set() */
392 +#include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
393 +#include "net_olsr.h" /* ipequal */
394 +#include "lq_plugin.h"
395 +
396 +
397 +/* Plugin includes */
398 +#include "Packet.h" /* IFHWADDRLEN */
399 +#include "mdns.h" /* PLUGIN_NAME, MainAddressOf() */
400 +#include "Address.h" /* IsMulticast() */
401 +
402 +/* List of network interface objects used by BMF plugin */
403 +struct TBmfInterface* BmfInterfaces = NULL;
404 +struct TBmfInterface* LastBmfInterface = NULL;
405 +
406 +/* Highest-numbered open socket file descriptor. To be used as first
407 + * parameter in calls to select(...). */
408 +int HighestSkfd = -1;
409 +
410 +/* Set of socket file descriptors */
411 +fd_set InputSet;
412 +
413 +/* File descriptor of EtherTunTap interface */
414 +int EtherTunTapFd = -1;
415 +
416 +/* Network interface name of EtherTunTap interface. May be overruled by
417 + * setting the plugin parameter "BmfInterface". */
418 +char EtherTunTapIfName[IFNAMSIZ] = "bmf0";
419 +
420 +/* The underlying mechanism to forward multicast packets. Either:
421 + * - BM_BROADCAST: BMF uses the IP local broadcast as destination address
422 + * - BM_UNICAST_PROMISCUOUS: BMF uses the IP address of the best neighbor as
423 + *   destination address. The other neighbors listen promiscuously. */
424 +enum TBmfMechanism BmfMechanism = BM_BROADCAST;
425 +
426 +#define ETHERTUNTAPIPNOTSET 0
427 +
428 +/* The IP address of the BMF network interface in host byte order.
429 + * May be overruled by setting the plugin parameter "BmfInterfaceIp". */
430 +u_int32_t EtherTunTapIp = ETHERTUNTAPIPNOTSET;
431 +
432 +/* 255.255.255.255 in host byte order. May be overruled by
433 + * setting the plugin parameter "BmfInterfaceIp". */
434 +u_int32_t EtherTunTapIpMask = 0xFFFFFFFF;
435 +
436 +/* The IP broadcast address of the BMF network interface in host byte order.
437 + * May be overruled by setting the plugin parameter "BmfinterfaceIp". */
438 +u_int32_t EtherTunTapIpBroadcast = ETHERTUNTAPIPNOTSET;
439 +
440 +/* Whether or not the configuration has overruled the default IP
441 + * configuration of the EtherTunTap interface */
442 +int TunTapIpOverruled = 0;
443 +
444 +/* Whether or not to capture packets on the OLSR-enabled
445 + * interfaces (in promiscuous mode). May be overruled by setting the plugin
446 + * parameter "CapturePacketsOnOlsrInterfaces" to "yes". */
447 +int CapturePacketsOnOlsrInterfaces = 0;
448 +
449 +/* -------------------------------------------------------------------------
450 + * Function   : SetBmfInterfaceName
451 + * Description: Overrule the default network interface name ("bmf0") of the
452 + *              EtherTunTap interface
453 + * Input      : ifname - network interface name (e.g. "mybmf0")
454 + *              data - not used
455 + *              addon - not used
456 + * Output     : none
457 + * Return     : success (0) or fail (1)
458 + * Data Used  : EtherTunTapIfName
459 + * ------------------------------------------------------------------------- */
460 +int SetBmfInterfaceName(
461 +  const char* ifname,
462 +  void* data __attribute__((unused)),
463 +  set_plugin_parameter_addon addon __attribute__((unused)))
464 +{
465 +  strncpy(EtherTunTapIfName, ifname, IFNAMSIZ - 1);
466 +  EtherTunTapIfName[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
467 +  return 0;
468 +} /* SetBmfInterfaceName */
469 +
470 +/* -------------------------------------------------------------------------
471 + * Function   : SetBmfInterfaceIp
472 + * Description: Overrule the default IP address and prefix length
473 + *              ("10.255.255.253/30") of the EtherTunTap interface
474 + * Input      : ip - IP address string, followed by '/' and prefix length
475 + *              data - not used
476 + *              addon - not used
477 + * Output     : none
478 + * Return     : success (0) or fail (1)
479 + * Data Used  : EtherTunTapIp, EtherTunTapIpMask, EtherTunTapIpBroadcast,
480 + *              TunTapIpOverruled
481 + * ------------------------------------------------------------------------- */
482 +int SetBmfInterfaceIp(
483 +  const char* ip,
484 +  void* data __attribute__((unused)),
485 +  set_plugin_parameter_addon addon __attribute__((unused)))
486 +{
487 +#define IPV4_MAX_ADDRLEN 16
488 +#define IPV4_MAX_PREFIXLEN 32
489 +  char* slashAt;
490 +  char ipAddr[IPV4_MAX_ADDRLEN];
491 +  struct in_addr sinaddr;
492 +  int prefixLen;
493 +  int i;
494 +
495 +  /* Inspired by function str2prefix_ipv4 as found in Quagga source
496 +   * file lib/prefix.c */
497 +
498 +  /* Find slash inside string. */
499 +  slashAt = strchr(ip, '/');
500 +
501 +  /* String doesn't contain slash. */
502 +  if (slashAt == NULL || slashAt - ip >= IPV4_MAX_ADDRLEN)
503 +  {
504 +    /* No prefix length specified, or IP address too long */
505 +    return 1;
506 +  }
507 +
508 +  strncpy(ipAddr, ip, slashAt - ip);
509 +  *(ipAddr + (slashAt - ip)) = '\0';
510 +  if (inet_aton(ipAddr, &sinaddr) == 0)
511 +  {
512 +    /* Invalid address passed */
513 +    return 1;
514 +  }
515 +
516 +  EtherTunTapIp = ntohl(sinaddr.s_addr);
517 +
518 +  /* Get prefix length. */
519 +  prefixLen = atoi(++slashAt);
520 +  if (prefixLen <= 0 || prefixLen > IPV4_MAX_PREFIXLEN)
521 +  {
522 +    return 1;
523 +  }
524 +
525 +  /* Compose IP subnet mask in host byte order */
526 +  EtherTunTapIpMask = 0;
527 +  for (i = 0; i < prefixLen; i++)
528 +  {
529 +    EtherTunTapIpMask |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
530 +  }
531 +
532 +  /* Compose IP broadcast address in host byte order */
533 +  EtherTunTapIpBroadcast = EtherTunTapIp;
534 +  for (i = prefixLen; i < IPV4_MAX_PREFIXLEN; i++)
535 +  {
536 +    EtherTunTapIpBroadcast |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
537 +  }
538 +
539 +  TunTapIpOverruled = 1;
540 +
541 +  return 0;
542 +} /* SetBmfInterfaceIp */
543 +
544 +/* -------------------------------------------------------------------------
545 + * Function   : SetCapturePacketsOnOlsrInterfaces
546 + * Description: Overrule the default setting, enabling or disabling the
547 + *              capturing of packets on OLSR-enabled interfaces.
548 + * Input      : enable - either "yes" or "no"
549 + *              data - not used
550 + *              addon - not used
551 + * Output     : none
552 + * Return     : success (0) or fail (1)
553 + * Data Used  : none
554 + * ------------------------------------------------------------------------- */
555 +int SetCapturePacketsOnOlsrInterfaces(
556 +  const char* enable,
557 +  void* data __attribute__((unused)),
558 +  set_plugin_parameter_addon addon __attribute__((unused)))
559 +{
560 +  if (strcmp(enable, "yes") == 0)
561 +  {
562 +    CapturePacketsOnOlsrInterfaces = 1;
563 +    return 0;
564 +  }
565 +  else if (strcmp(enable, "no") == 0)
566 +  {
567 +    CapturePacketsOnOlsrInterfaces = 0;
568 +    return 0;
569 +  }
570 +
571 +  /* Value not recognized */
572 +  return 1;
573 +} /* SetCapturePacketsOnOlsrInterfaces */
574 +
575 +/* -------------------------------------------------------------------------
576 + * Function   : SetBmfMechanism
577 + * Description: Overrule the default BMF mechanism to either BM_BROADCAST or
578 + *              BM_UNICAST_PROMISCUOUS.
579 + * Input      : mechanism - either "Broadcast" or "UnicastPromiscuous"
580 + *              data - not used
581 + *              addon - not used
582 + * Output     : none
583 + * Return     : success (0) or fail (1)
584 + * Data Used  : none
585 + * ------------------------------------------------------------------------- */
586 +int SetBmfMechanism(
587 +  const char* mechanism,
588 +  void* data __attribute__((unused)),
589 +  set_plugin_parameter_addon addon __attribute__((unused)))
590 +{
591 +  if (strcmp(mechanism, "Broadcast") == 0)
592 +  {
593 +    BmfMechanism = BM_BROADCAST;
594 +    return 0;
595 +  }
596 +  else if (strcmp(mechanism, "UnicastPromiscuous") == 0)
597 +  {
598 +    BmfMechanism = BM_UNICAST_PROMISCUOUS;
599 +    return 0;
600 +  }
601 +
602 +  /* Value not recognized */
603 +  return 1;
604 +} /* SetBmfMechanism */
605 +
606 +/* -------------------------------------------------------------------------
607 + * Function   : AddDescriptorToInputSet
608 + * Description: Add a socket descriptor to the global set of socket file descriptors
609 + * Input      : skfd - socket file descriptor
610 + * Output     : none
611 + * Return     : none
612 + * Data Used  : HighestSkfd, InputSet
613 + * Notes      : Keeps track of the highest-numbered descriptor
614 + * ------------------------------------------------------------------------- */
615 +static void AddDescriptorToInputSet(int skfd)
616 +{
617 +  /* Keep the highest-numbered descriptor */
618 +  if (skfd > HighestSkfd)
619 +  {
620 +    HighestSkfd = skfd;
621 +  }
622 +
623 +  /* Add descriptor to input set */
624 +  FD_SET(skfd, &InputSet);
625 +} /* AddDescriptorToInputSet */
626 +
627 +/* To save the state of the IP spoof filter for the EtherTunTap interface */
628 +static char EthTapSpoofState = '1';
629 +
630 +/* -------------------------------------------------------------------------
631 + * Function   : DeactivateSpoofFilter
632 + * Description: Deactivates the Linux anti-spoofing filter for the tuntap
633 + *              interface
634 + * Input      : none
635 + * Output     : none
636 + * Return     : fail (0) or success (1)
637 + * Data Used  : EtherTunTapIfName, EthTapSpoofState
638 + * Notes      : Saves the current filter state for later restoring
639 + * ------------------------------------------------------------------------- */
640 +int DeactivateSpoofFilter(void)
641 +{
642 +  FILE* procSpoof;
643 +  char procFile[FILENAME_MAX];
644 +
645 +  /* Generate the procfile name */
646 +  sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
647 +
648 +  /* Open procfile for reading */
649 +  procSpoof = fopen(procFile, "r");
650 +  if (procSpoof == NULL)
651 +  {
652 +    fprintf(
653 +      stderr,
654 +      "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
655 +      "Are you using the procfile filesystem?\n"
656 +      "Does your system support IPv4?\n"
657 +      "I will continue (in 3 sec) - but you should manually ensure that IP spoof\n"
658 +      "filtering is disabled!\n\n",
659 +      procFile);
660 +
661 +    sleep(3);
662 +    return 0;
663 +  }
664 +
665 +  EthTapSpoofState = fgetc(procSpoof);
666 +  fclose(procSpoof);
667 +
668 +  /* Open procfile for writing */
669 +  procSpoof = fopen(procFile, "w");
670 +  if (procSpoof == NULL)
671 +  {
672 +    fprintf(stderr, "Could not open %s for writing!\n", procFile);
673 +    fprintf(
674 +      stderr,
675 +      "I will continue (in 3 sec) - but you should manually ensure that IP"
676 +      " spoof filtering is disabled!\n\n");
677 +    sleep(3);
678 +    return 0;
679 +  }
680 +
681 +  syslog(LOG_INFO, "Writing \"0\" to %s", procFile);
682 +  fputs("0", procSpoof);
683 +
684 +  fclose(procSpoof);
685 +
686 +  return 1;
687 +} /* DeactivateSpoofFilter */
688 +
689 +/* -------------------------------------------------------------------------
690 + * Function   : RestoreSpoofFilter
691 + * Description: Restores the Linux anti-spoofing filter setting for the tuntap
692 + *              interface
693 + * Input      : none
694 + * Output     : none
695 + * Return     : none
696 + * Data Used  : EtherTunTapIfName, EthTapSpoofState
697 + * ------------------------------------------------------------------------- */
698 +void RestoreSpoofFilter(void)
699 +{
700 +  FILE* procSpoof;
701 +  char procFile[FILENAME_MAX];
702 +
703 +  /* Generate the procfile name */
704 +  sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
705 +
706 +  /* Open procfile for writing */
707 +  procSpoof = fopen(procFile, "w");
708 +  if (procSpoof == NULL)
709 +  {
710 +    fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procFile);
711 +  }
712 +  else
713 +  {
714 +    syslog(LOG_INFO, "Resetting %s to %c\n", procFile, EthTapSpoofState);
715 +
716 +    fputc(EthTapSpoofState, procSpoof);
717 +    fclose(procSpoof);
718 +  }
719 +} /* RestoreSpoofFilter */
720 +
721 +/* -------------------------------------------------------------------------
722 + * Function   : FindNeighbors
723 + * Description: Find the neighbors on a network interface to forward a BMF
724 + *              packet to
725 + * Input      : intf - the network interface
726 + *              source - the source IP address of the BMF packet
727 + *              forwardedBy - the IP address of the node that forwarded the BMF
728 + *                packet
729 + *              forwardedTo - the IP address of the node to which the BMF packet
730 + *                was directed
731 + * Output     : neighbors - list of (up to a number of 'FanOutLimit') neighbors.
732 + *              bestNeighbor - the best neighbor (in terms of lowest cost or ETX
733 + *                value)
734 + *              nPossibleNeighbors - number of found possible neighbors
735 + * Data Used  : FanOutLimit
736 + * ------------------------------------------------------------------------- */
737 +//void FindNeighbors(
738 +//  struct TBestNeighbors* neighbors,
739 +//  struct link_entry** bestNeighbor,
740 +//  struct TBmfInterface* intf,
741 +//  union olsr_ip_addr* source,
742 +//  union olsr_ip_addr* forwardedBy,
743 +//  union olsr_ip_addr* forwardedTo,
744 +//  int* nPossibleNeighbors)
745 +//{
746 +//  struct link_entry* walker;
747 +//  olsr_linkcost previousLinkEtx = LINK_COST_BROKEN;
748 +//  olsr_linkcost bestEtx = LINK_COST_BROKEN;
749 +//
750 +//  int i;
751 +//
752 +//  /* Initialize */
753 +//  *bestNeighbor = NULL;
754 +//  for (i = 0; i < MAX_UNICAST_NEIGHBORS; i++)
755 +//  {
756 +//    neighbors->links[i] = NULL;
757 +//  }
758 +//  *nPossibleNeighbors = 0;
759 +//
760 +//  if (forwardedBy != NULL)
761 +//  {
762 +//    /* Retrieve the cost of the link from 'forwardedBy' to myself */
763 +//    struct link_entry* bestLinkFromForwarder = get_best_link_to_neighbor(forwardedBy);
764 +//    if (bestLinkFromForwarder != NULL)
765 +//    {
766 +//      previousLinkEtx = bestLinkFromForwarder->linkcost;
767 +//    }
768 +//  }
769 +//
770 +//  OLSR_FOR_ALL_LINK_ENTRIES(walker) {
771 +//    struct ipaddr_str buf;
772 +//    union olsr_ip_addr* neighborMainIp;
773 +//    struct link_entry* bestLinkToNeighbor;
774 +//    struct tc_entry* tcLastHop;
775 +//    float currEtx;
776 +//
777 +//    /* Consider only links from the specified interface */
778 +//    if (! olsr_ipequal(&intf->intAddr, &walker->local_iface_addr))
779 +//    {
780 +//      continue; /* for */
781 +//    }
782 +//
783 +//    OLSR_PRINTF(
784 +//      9,
785 +//      "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
786 +//      PLUGIN_NAME_SHORT,
787 +//      intf->ifName,
788 +//      olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
789 +//
790 +//    neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
791 +//
792 +//    /* Consider only neighbors with an IP address that differs from the
793 +//     * passed IP addresses (if passed). Rely on short-circuit boolean evaluation. */
794 +//    if (source != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(source)))
795 +//    {
796 +//      OLSR_PRINTF(
797 +//        9,
798 +//        "%s: ----> Not forwarding to %s: is source of pkt\n",
799 +//        PLUGIN_NAME_SHORT,
800 +//        olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
801 +//
802 +//      continue; /* for */
803 +//    }
804 +//
805 +//    /* Rely on short-circuit boolean evaluation */
806 +//    if (forwardedBy != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
807 +//    {
808 +//      OLSR_PRINTF(
809 +//        9,
810 +//        "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
811 +//        PLUGIN_NAME_SHORT,
812 +//        olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
813 +//
814 +//      continue; /* for */
815 +//    }
816 +//
817 +//    /* Rely on short-circuit boolean evaluation */
818 +//    if (forwardedTo != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
819 +//    {
820 +//      OLSR_PRINTF(
821 +//        9,
822 +//        "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
823 +//        PLUGIN_NAME_SHORT,
824 +//        olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
825 +//
826 +//      continue; /* for */
827 +//    }
828 +//
829 +//    /* Found a candidate neighbor to direct our packet to */
830 +//
831 +//    /* Calculate the link quality (ETX) of the link to the found neighbor */
832 +//    currEtx = walker->linkcost;
833 +//
834 +//    if (currEtx >= LINK_COST_BROKEN)
835 +//    {
836 +//      OLSR_PRINTF(
837 +//        9,
838 +//        "%s: ----> Not forwarding to %s: link is timing out\n",
839 +//        PLUGIN_NAME_SHORT,
840 +//        olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
841 +//
842 +//      continue; /* for */
843 +//    }
844 +//
845 +//    /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
846 +//    OLSR_PRINTF(
847 +//      9,
848 +//      "%s: ----> Forwarding pkt to %s will cost ETX %5.2f\n",
849 +//      PLUGIN_NAME_SHORT,
850 +//      olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
851 +//      currEtx);
852 +//
853 +//    /*
854 +//     * If the candidate neighbor is best reached via another interface, then skip
855 +//     * the candidate neighbor; the candidate neighbor has been / will be selected via that
856 +//     * other interface.
857 +//     */
858 +//    bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
859 +//
860 +//    if (walker != bestLinkToNeighbor)
861 +//    {
862 +//      if (bestLinkToNeighbor == NULL)
863 +//      {
864 +//        OLSR_PRINTF(
865 +//          9,
866 +//          "%s: ----> Not forwarding to %s: no link found\n",
867 +//          PLUGIN_NAME_SHORT,
868 +//          olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
869 +//      }
870 +//      else
871 +//      {
872 +//#ifndef NODEBUG
873 +//        struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
874 +//        struct lqtextbuffer lqbuffer;
875 +//#endif
876 +//        OLSR_PRINTF(
877 +//          9,
878 +//          "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
879 +//          PLUGIN_NAME_SHORT,
880 +//          olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
881 +//          bestIntf->int_name,
882 +//          get_linkcost_text(bestLinkToNeighbor->linkcost, 0, &lqbuffer));
883 +//      }
884 +//
885 +//      continue; /* for */
886 +//    }
887 +//
888 +//    if (forwardedBy != NULL)
889 +//    {
890 +//#ifndef NODEBUG
891 +//      struct ipaddr_str forwardedByBuf, niaBuf;
892 +//      struct lqtextbuffer lqbuffer;
893 +//#endif
894 +//      OLSR_PRINTF(
895 +//        9,
896 +//        "%s: ----> 2-hop path from %s via me to %s will cost ETX %s\n",
897 +//        PLUGIN_NAME_SHORT,
898 +//        olsr_ip_to_string(&forwardedByBuf, forwardedBy),
899 +//        olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
900 +//        get_linkcost_text(previousLinkEtx + currEtx, 1, &lqbuffer));
901 +//    }
902 +//
903 +//    /* Check the topology table whether the 'forwardedBy' node is itself a direct
904 +//     * neighbor of the candidate neighbor, at a lower cost than the 2-hop route
905 +//     * via myself. If so, we do not need to forward the BMF packet to the candidate
906 +//     * neighbor, because the 'forwardedBy' node will forward the packet. */
907 +//    if (forwardedBy != NULL)
908 +//    {
909 +//      tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
910 +//      if (tcLastHop != NULL)
911 +//      {
912 +//        struct tc_edge_entry* tc_edge;
913 +//
914 +//        tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
915 +//
916 +//        /* We are not interested in dead-end edges. */
917 +//        if (tc_edge) {
918 +//          olsr_linkcost tcEtx = tc_edge->cost;
919 +//
920 +//          if (previousLinkEtx + currEtx > tcEtx)
921 +//          {
922 +//#ifndef NODEBUG
923 +//            struct ipaddr_str neighbor_iface_buf, forw_buf;
924 +//            struct lqtextbuffer lqbuffer;
925 +//            olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
926 +//#endif
927 +//            OLSR_PRINTF(
928 +//              9,
929 +//              "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
930 +//              PLUGIN_NAME_SHORT,
931 +//              neighbor_iface_buf.buf,
932 +//              olsr_ip_to_string(&forw_buf, forwardedBy),
933 +//              neighbor_iface_buf.buf,
934 +//              get_linkcost_text(tcEtx, 0, &lqbuffer));
935 +//
936 +//            continue; /* for */
937 +//          } /* if */
938 +//        } /* if */
939 +//      } /* if */
940 +//    } /* if */
941 +//
942 +//    /* Remember the best neighbor. If all are very bad, remember none. */
943 +//    if (currEtx < bestEtx)
944 +//    {
945 +//      *bestNeighbor = walker;
946 +//      bestEtx = currEtx;
947 +//    }
948 +//
949 +//    /* Fill the list with up to 'FanOutLimit' neighbors. If there
950 +//     * are more neighbors, broadcast is used instead of unicast. In that
951 +//     * case we do not need the list of neighbors. */
952 +//    if (*nPossibleNeighbors < FanOutLimit)
953 +//    {
954 +//      neighbors->links[*nPossibleNeighbors] = walker;
955 +//    }
956 +//
957 +//    *nPossibleNeighbors += 1;
958 +//  } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
959 +//
960 +//  /* Display the result of the neighbor search */
961 +//  if (*nPossibleNeighbors == 0)
962 +//  {
963 +//    OLSR_PRINTF(
964 +//      9,
965 +//      "%s: ----> No suitable neighbor found to forward to on \"%s\"\n",
966 +//      PLUGIN_NAME_SHORT,
967 +//      intf->ifName);
968 +//  }
969 +//  else
970 +//  {
971 +//    struct ipaddr_str buf;
972 +//    OLSR_PRINTF(
973 +//      9,
974 +//      "%s: ----> %d neighbors found on \"%s\"; best neighbor to forward to: %s\n",
975 +//      PLUGIN_NAME_SHORT,
976 +//      *nPossibleNeighbors,
977 +//      intf->ifName,
978 +//      olsr_ip_to_string(&buf, &(*bestNeighbor)->neighbor_iface_addr));
979 +//  } /* if */
980 +//
981 +//} /* FindNeighbors */
982 +
983 +/* -------------------------------------------------------------------------
984 + * Function   : CreateCaptureSocket
985 + * Description: Create socket for promiscuously capturing multicast IP traffic
986 + * Input      : ifname - network interface (e.g. "eth0")
987 + * Output     : none
988 + * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
989 + * Data Used  : none
990 + * Notes      : The socket is a cooked IP packet socket, bound to the specified
991 + *              network interface
992 + * ------------------------------------------------------------------------- */
993 +static int CreateCaptureSocket(const char* ifName)
994 +{
995 +  int ifIndex = if_nametoindex(ifName);
996 +  struct packet_mreq mreq;
997 +  struct ifreq req;
998 +  struct sockaddr_ll bindTo;
999 +  int skfd = 0;
1000 +  /* Open cooked IP packet socket */
1001 +  if (olsr_cnf->ip_version == AF_INET){
1002 +  skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1003 +  }
1004 +  else {
1005 +  skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
1006 +  }
1007 +  if (skfd < 0)
1008 +  {
1009 +    BmfPError("socket(PF_PACKET) error");
1010 +    return -1;
1011 +  }
1012 +
1013 +  /* Set interface to promiscuous mode */
1014 +  memset(&mreq, 0, sizeof(struct packet_mreq));
1015 +  mreq.mr_ifindex = ifIndex;
1016 +  mreq.mr_type = PACKET_MR_PROMISC;
1017 +  if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
1018 +  {
1019 +    BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1020 +    close(skfd);
1021 +    return -1;
1022 +  }
1023 +
1024 +  /* Get hardware (MAC) address */
1025 +  memset(&req, 0, sizeof(struct ifreq));
1026 +  strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
1027 +  req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
1028 +  if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
1029 +  {
1030 +    BmfPError("error retrieving MAC address");
1031 +    close(skfd);
1032 +    return -1;
1033 +  }
1034 +
1035 +  /* Bind the socket to the specified interface */
1036 +  memset(&bindTo, 0, sizeof(bindTo));
1037 +  bindTo.sll_family = AF_PACKET;
1038 +  if (olsr_cnf->ip_version == AF_INET){
1039 +  bindTo.sll_protocol = htons(ETH_P_IP);
1040 +  }
1041 +  else{
1042 +  bindTo.sll_protocol = htons(ETH_P_IPV6);
1043 +  }
1044 +  bindTo.sll_ifindex = ifIndex;
1045 +  memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1046 +  bindTo.sll_halen = IFHWADDRLEN;
1047 +
1048 +  if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1049 +  {
1050 +    BmfPError("bind() error");
1051 +    close(skfd);
1052 +    return -1;
1053 +  }
1054 +
1055 +  /* Set socket to blocking operation */
1056 +  if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1057 +  {
1058 +    BmfPError("fcntl() error");
1059 +    close(skfd);
1060 +    return -1;
1061 +  }
1062 +
1063 +  AddDescriptorToInputSet(skfd);
1064 +  add_olsr_socket(skfd,&DoMDNS);
1065 +
1066 +  return skfd;
1067 +} /* CreateCaptureSocket */
1068 +
1069 +/* -------------------------------------------------------------------------
1070 + * Function   : CreateListeningSocket
1071 + * Description: Create socket for promiscuously listening to BMF packets.
1072 + *              Used only when 'BmfMechanism' is BM_UNICAST_PROMISCUOUS
1073 + * Input      : ifname - network interface (e.g. "eth0")
1074 + * Output     : none
1075 + * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
1076 + * Data Used  : none
1077 + * Notes      : The socket is a cooked IP packet socket, bound to the specified
1078 + *              network interface
1079 + * ------------------------------------------------------------------------- */
1080 +//static int CreateListeningSocket(const char* ifName)
1081 +//{
1082 +//  int ifIndex = if_nametoindex(ifName);
1083 +//  struct packet_mreq mreq;
1084 +//  struct ifreq req;
1085 +//  struct sockaddr_ll bindTo;
1086 +//
1087 +//  /* Open cooked IP packet socket */
1088 +//  int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1089 +//  if (skfd < 0)
1090 +//  {
1091 +//    BmfPError("socket(PF_PACKET) error");
1092 +//    return -1;
1093 +//  }
1094 +//
1095 +//  /* Set interface to promiscuous mode */
1096 +//  memset(&mreq, 0, sizeof(struct packet_mreq));
1097 +//  mreq.mr_ifindex = ifIndex;
1098 +//  mreq.mr_type = PACKET_MR_PROMISC;
1099 +//  if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
1100 +//  {
1101 +//    BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1102 +//    close(skfd);
1103 +//    return -1;
1104 +//  }
1105 +//
1106 +//  /* Get hardware (MAC) address */
1107 +//  memset(&req, 0, sizeof(struct ifreq));
1108 +//  strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
1109 +//  req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
1110 +//  if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
1111 +//  {
1112 +//    BmfPError("error retrieving MAC address");
1113 +//    close(skfd);
1114 +//    return -1;
1115 +//  }
1116 +//
1117 +//  /* Bind the socket to the specified interface */
1118 +//  memset(&bindTo, 0, sizeof(bindTo));
1119 +//  bindTo.sll_family = AF_PACKET;
1120 +//  bindTo.sll_protocol = htons(ETH_P_IP);
1121 +//  bindTo.sll_ifindex = ifIndex;
1122 +//  memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1123 +//  bindTo.sll_halen = IFHWADDRLEN;
1124 +//
1125 +//  if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1126 +//  {
1127 +//    BmfPError("bind() error");
1128 +//    close(skfd);
1129 +//    return -1;
1130 +//  }
1131 +//
1132 +//  /* Set socket to blocking operation */
1133 +//  if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1134 +//  {
1135 +//    BmfPError("fcntl() error");
1136 +//    close(skfd);
1137 +//    return -1;
1138 +//  }
1139 +//
1140 +//  AddDescriptorToInputSet(skfd);
1141 +//
1142 +//  return skfd;
1143 +//} /* CreateListeningSocket */
1144 +
1145 +/* -------------------------------------------------------------------------
1146 + * Function   : CreateEncapsulateSocket
1147 + * Description: Create a socket for sending and receiving encapsulated
1148 + *              multicast packets
1149 + * Input      : ifname - network interface (e.g. "eth0")
1150 + * Output     : none
1151 + * Return     : the socket descriptor ( >= 0), or -1 if an error occurred
1152 + * Data Used  : none
1153 + * Notes      : The socket is an UDP (datagram) over IP socket, bound to the
1154 + *              specified network interface
1155 + * ------------------------------------------------------------------------- */
1156 +//static int CreateEncapsulateSocket(const char* ifName)
1157 +//{
1158 +//  int on = 1;
1159 +//  struct sockaddr_in bindTo;
1160 +//
1161 +//  /* Open UDP-IP socket */
1162 +//  int skfd = socket(PF_INET, SOCK_DGRAM, 0);
1163 +//  if (skfd < 0)
1164 +//  {
1165 +//    BmfPError("socket(PF_INET) error");
1166 +//    return -1;
1167 +//  }
1168 +//
1169 +//  /* Enable sending to broadcast addresses */
1170 +//  if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
1171 +//  {
1172 +//    BmfPError("setsockopt(SO_BROADCAST) error");
1173 +//    close(skfd);
1174 +//    return -1;
1175 +//  }
1176 +//
1177 +//  /* Bind to the specific network interfaces indicated by ifName. */
1178 +//  /* When using Kernel 2.6 this must happer prior to the port binding! */
1179 +//  if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0)
1180 +//  {
1181 +//    BmfPError("setsockopt(SO_BINDTODEVICE) error");
1182 +//    close(skfd);
1183 +//    return -1;
1184 +//  }
1185 +//
1186 +//  /* Bind to BMF port */
1187 +//  memset(&bindTo, 0, sizeof(bindTo));
1188 +//  bindTo.sin_family = AF_INET;
1189 +//  bindTo.sin_port = htons(BMF_ENCAP_PORT);
1190 +//  bindTo.sin_addr.s_addr = htonl(INADDR_ANY);
1191 +//
1192 +//  if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1193 +//  {
1194 +//    BmfPError("bind() error");
1195 +//    close(skfd);
1196 +//    return -1;
1197 +//  }
1198 +//
1199 +//  /* Set socket to blocking operation */
1200 +//  if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1201 +//  {
1202 +//    BmfPError("fcntl() error");
1203 +//    close(skfd);
1204 +//    return -1;
1205 +//  }
1206 +//
1207 +//  AddDescriptorToInputSet(skfd);
1208 +//
1209 +//  return skfd;
1210 +//} /* CreateEncapsulateSocket */
1211 +
1212 +/* -------------------------------------------------------------------------
1213 + * Function   : CreateLocalEtherTunTap
1214 + * Description: Creates and brings up an EtherTunTap interface
1215 + * Input      : none
1216 + * Output     : none
1217 + * Return     : the socket file descriptor (>= 0), or -1 in case of failure
1218 + * Data Used  : EtherTunTapIfName - name used for the tuntap interface (e.g.
1219 + *                "bmf0")
1220 + *              EtherTunTapIp
1221 + *              EtherTunTapIpMask
1222 + *              EtherTunTapIpBroadcast
1223 + *              BmfInterfaces
1224 + * Note       : Order dependency: call this function only if BmfInterfaces
1225 + *              is filled with a list of network interfaces.
1226 + * ------------------------------------------------------------------------- */
1227 +//static int CreateLocalEtherTunTap(void)
1228 +//{
1229 +//  static const char deviceName[] = "/dev/net/tun";
1230 +//  struct ifreq ifreq;
1231 +//  int etfd;
1232 +//  int ioctlSkfd;
1233 +//  int ioctlres;
1234 +//
1235 +//  etfd = open(deviceName, O_RDWR | O_NONBLOCK);
1236 +//  if (etfd < 0)
1237 +//  {
1238 +//    BmfPError("error opening %s", deviceName);
1239 +//    return -1;
1240 +//  }
1241 +//
1242 +//  memset(&ifreq, 0, sizeof(ifreq));
1243 +//  strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1244 +//  ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1245 +//
1246 +//  /* Specify the IFF_TUN flag for IP packets.
1247 +//   * Specify IFF_NO_PI for not receiving extra meta packet information. */
1248 +//  ifreq.ifr_flags = IFF_TUN;
1249 +//  ifreq.ifr_flags |= IFF_NO_PI;
1250 +//
1251 +//  if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
1252 +//  {
1253 +//    BmfPError("ioctl(TUNSETIFF) error on %s", deviceName);
1254 +//    close(etfd);
1255 +//    return -1;
1256 +//  }
1257 +//
1258 +//  memset(&ifreq, 0, sizeof(ifreq));
1259 +//  strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1260 +//  ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1261 +//  ifreq.ifr_addr.sa_family = AF_INET;
1262 +//
1263 +//  ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1264 +//  if (ioctlSkfd < 0)
1265 +//  {
1266 +//    BmfPError("socket(PF_INET) error on %s", deviceName);
1267 +//    close(etfd);
1268 +//    return -1;
1269 +//  }
1270 +//
1271 +//  /* Give the EtherTunTap interface an IP address.
1272 +//   * The default IP address is the address of the first OLSR interface;
1273 +//   * the default netmask is 255.255.255.255 . Having an all-ones netmask prevents
1274 +//   * automatic entry of the BMF network interface in the routing table. */
1275 +//  if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
1276 +//  {
1277 +//    struct TBmfInterface* nextBmfIf = BmfInterfaces;
1278 +//    while (nextBmfIf != NULL)
1279 +//    {
1280 +//      struct TBmfInterface* bmfIf = nextBmfIf;
1281 +//      nextBmfIf = bmfIf->next;
1282 +//
1283 +//      if (bmfIf->olsrIntf != NULL)
1284 +//      {
1285 +//        EtherTunTapIp = ntohl(bmfIf->intAddr.v4.s_addr);
1286 +//        EtherTunTapIpBroadcast = EtherTunTapIp;
1287 +//      }
1288 +//    }
1289 +//  }
1290 +//
1291 +//  if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
1292 +//  {
1293 +//    /* No IP address configured for BMF network interface, and no OLSR interface found to
1294 +//     * copy IP address from. Fall back to default: 10.255.255.253 . */
1295 +//    EtherTunTapIp = ETHERTUNTAPDEFAULTIP;
1296 +//  }
1297 +//
1298 +//  ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp);
1299 +//  ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq);
1300 +//  if (ioctlres >= 0)
1301 +//  {
1302 +//    /* Set net mask */
1303 +//    ((struct sockaddr_in*)&ifreq.ifr_netmask)->sin_addr.s_addr = htonl(EtherTunTapIpMask);
1304 +//    ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq);
1305 +//    if (ioctlres >= 0)
1306 +//    {
1307 +//      /* Set broadcast IP */
1308 +//      ((struct sockaddr_in*)&ifreq.ifr_broadaddr)->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast);
1309 +//      ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq);
1310 +//      if (ioctlres >= 0)
1311 +//      {
1312 +//        /* Bring EtherTunTap interface up (if not already) */
1313 +//        ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1314 +//        if (ioctlres >= 0)
1315 +//        {
1316 +//          ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_BROADCAST);
1317 +//          ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1318 +//        }
1319 +//      }
1320 +//    }
1321 +//  }
1322 +//
1323 +//  if (ioctlres < 0)
1324 +//  {
1325 +//    /* Any of the above ioctl() calls failed */
1326 +//    BmfPError("error bringing up EtherTunTap interface \"%s\"", EtherTunTapIfName);
1327 +//
1328 +//    close(etfd);
1329 +//    close(ioctlSkfd);
1330 +//    return -1;
1331 +//  } /* if (ioctlres < 0) */
1332 +//
1333 +//  /* Set the multicast flag on the interface */
1334 +//  memset(&ifreq, 0, sizeof(ifreq));
1335 +//  strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1336 +//  ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1337 +//
1338 +//  ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1339 +//  if (ioctlres >= 0)
1340 +//  {
1341 +//    ifreq.ifr_flags |= IFF_MULTICAST;
1342 +//    ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1343 +//  }
1344 +//  if (ioctlres < 0)
1345 +//  {
1346 +//    /* Any of the two above ioctl() calls failed */
1347 +//    BmfPError("error setting multicast flag on EtherTunTap interface \"%s\"", EtherTunTapIfName);
1348 +//
1349 +//    /* Continue anyway */
1350 +//  }
1351 +//
1352 +//  /* Use ioctl to make the tuntap persistent. Otherwise it will disappear
1353 +//   * when this program exits. That is not desirable, since a multicast
1354 +//   * daemon (e.g. mrouted) may be using the tuntap interface. */
1355 +//  if (ioctl(etfd, TUNSETPERSIST, (void *)&ifreq) < 0)
1356 +//  {
1357 +//    BmfPError("error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName);
1358 +//
1359 +//    /* Continue anyway */
1360 +//  }
1361 +//
1362 +//  OLSR_PRINTF(8, "%s: opened 1 socket on \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1363 +//
1364 +//  AddDescriptorToInputSet(etfd);
1365 +//
1366 +//  /* If the user configured a specific IP address for the BMF network interface,
1367 +//   * help the user and advertise the IP address of the BMF network interface
1368 +//   * on the OLSR network via HNA */
1369 +//  if (TunTapIpOverruled != 0)
1370 +//  {
1371 +//    union olsr_ip_addr temp_net;
1372 +//
1373 +//    temp_net.v4.s_addr = htonl(EtherTunTapIp);
1374 +//    ip_prefix_list_add(&olsr_cnf->hna_entries, &temp_net, 32);
1375 +//  }
1376 +//
1377 +//  close(ioctlSkfd);
1378 +//
1379 +//  return etfd;
1380 +//} /* CreateLocalEtherTunTap */
1381 +
1382 +/* -------------------------------------------------------------------------
1383 + * Function   : CreateInterface
1384 + * Description: Create a new TBmfInterface object and adds it to the global
1385 + *              BmfInterfaces list
1386 + * Input      : ifName - name of the network interface (e.g. "eth0")
1387 + *            : olsrIntf - OLSR interface object of the network interface, or
1388 + *                NULL if the network interface is not OLSR-enabled
1389 + * Output     : none
1390 + * Return     : the number of opened sockets
1391 + * Data Used  : BmfInterfaces, LastBmfInterface
1392 + * ------------------------------------------------------------------------- */
1393 +
1394 +//FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
1395 +
1396 +static int CreateInterface(
1397 +  const char* ifName,
1398 +  struct interface* olsrIntf)
1399 +{
1400 +  int capturingSkfd = -1;
1401 +  int encapsulatingSkfd = -1;
1402 +  int listeningSkfd = -1;
1403 +  int ioctlSkfd;
1404 +  struct ifreq ifr;
1405 +  int nOpened = 0;
1406 +  struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
1407 +
1408 +  assert(ifName != NULL);
1409 +
1410 +  if (newIf == NULL)
1411 +  {
1412 +    return 0;
1413 +  }
1414 +
1415 +//TODO: assert interface is not talking OLSR
1416 +
1417 +//  if (olsrIntf != NULL)
1418 +//  {
1419 +//    /* On OLSR-enabled interfaces, create socket for encapsulating and forwarding
1420 +//     * multicast packets */
1421 +//    encapsulatingSkfd = CreateEncapsulateSocket(ifName);
1422 +//    if (encapsulatingSkfd < 0)
1423 +//    {
1424 +//      free(newIf);
1425 +//      return 0;
1426 +//    }
1427 +//    nOpened++;
1428 +//  }
1429 +
1430 +  /* Create socket for capturing and sending of multicast packets on
1431 +   * non-OLSR interfaces, and on OLSR-interfaces if configured. */
1432 +  if ((olsrIntf == NULL) || (CapturePacketsOnOlsrInterfaces != 0))
1433 +  {
1434 +    capturingSkfd = CreateCaptureSocket(ifName);
1435 +    if (capturingSkfd < 0)
1436 +    {
1437 +      close(encapsulatingSkfd);
1438 +      free(newIf);
1439 +      return 0;
1440 +    }
1441 +
1442 +    nOpened++;
1443 +  }
1444 +
1445 +//  /* Create promiscuous mode listening interface if BMF uses IP unicast
1446 +//   * as underlying forwarding mechanism */
1447 +//  if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
1448 +//  {
1449 +//    listeningSkfd = CreateListeningSocket(ifName);
1450 +//    if (listeningSkfd < 0)
1451 +//    {
1452 +//      close(listeningSkfd);
1453 +//      close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */
1454 +//      free(newIf);
1455 +//      return 0;
1456 +//    }
1457 +//
1458 +//    nOpened++;
1459 +//  }
1460 +
1461 +  /* For ioctl operations on the network interface, use either capturingSkfd
1462 +   * or encapsulatingSkfd, whichever is available */
1463 +  ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
1464 +
1465 +  /* Retrieve the MAC address of the interface. */
1466 +  memset(&ifr, 0, sizeof(struct ifreq));
1467 +  strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1468 +  ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1469 +  if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0)
1470 +  {
1471 +    BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
1472 +    close(capturingSkfd);
1473 +    close(encapsulatingSkfd);
1474 +    free(newIf);
1475 +    return 0;
1476 +  }
1477 +
1478 +  /* Copy data into TBmfInterface object */
1479 +  newIf->capturingSkfd = capturingSkfd;
1480 +  newIf->encapsulatingSkfd = encapsulatingSkfd;
1481 +  newIf->listeningSkfd = listeningSkfd;
1482 +  memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
1483 +  memcpy(newIf->ifName, ifName, IFNAMSIZ);
1484 +  newIf->olsrIntf = olsrIntf;
1485 +  if (olsrIntf != NULL)
1486 +  {
1487 +    /* For an OLSR-interface, copy the interface address and broadcast
1488 +     * address from the OLSR interface object. Downcast to correct sockaddr
1489 +     * subtype. */
1490 +    newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
1491 +    newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
1492 +  }
1493 +  else
1494 +  {
1495 +    /* For a non-OLSR interface, retrieve the IP address ourselves */
1496 +    memset(&ifr, 0, sizeof(struct ifreq));
1497 +    strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1498 +    ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1499 +    if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0)
1500 +    {
1501 +      BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
1502 +
1503 +      newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
1504 +    }
1505 +    else
1506 +    {
1507 +      /* Downcast to correct sockaddr subtype */
1508 +      newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
1509 +    }
1510 +
1511 +    /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
1512 +    memset(&ifr, 0, sizeof(struct ifreq));
1513 +    strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1514 +    ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1515 +    if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0)
1516 +    {
1517 +      BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
1518 +
1519 +      newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
1520 +    }
1521 +    else
1522 +    {
1523 +      /* Downcast to correct sockaddr subtype */
1524 +      newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
1525 +    }
1526 +  }
1527 +
1528 +  /* Initialize fragment history table */
1529 +  //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
1530 +  //newIf->nextFragmentHistoryEntry = 0;
1531 +
1532 +  /* Reset counters */
1533 +  //newIf->nBmfPacketsRx = 0;
1534 +  //newIf->nBmfPacketsRxDup = 0;
1535 +  //newIf->nBmfPacketsTx = 0;
1536 +
1537 +  /* Add new TBmfInterface object to global list. OLSR interfaces are
1538 +   * added at the front of the list, non-OLSR interfaces at the back. */
1539 +  if (BmfInterfaces == NULL)
1540 +  {
1541 +    /* First TBmfInterface object in list */
1542 +    BmfInterfaces = newIf;
1543 +    LastBmfInterface = newIf;
1544 +  }
1545 +  else if (olsrIntf != NULL)
1546 +  {
1547 +    /* Add new TBmfInterface object at front of list */
1548 +    newIf->next = BmfInterfaces;
1549 +    BmfInterfaces = newIf;
1550 +  }
1551 +  else
1552 +  {
1553 +    /* Add new TBmfInterface object at back of list */
1554 +    newIf->next = NULL;
1555 +    LastBmfInterface->next= newIf;
1556 +    LastBmfInterface = newIf;
1557 +  }
1558 +
1559 +  OLSR_PRINTF(
1560 +    8,
1561 +    "%s: opened %d socket%s on %s interface \"%s\"\n",
1562 +    PLUGIN_NAME_SHORT,
1563 +    nOpened,
1564 +    nOpened == 1 ? "" : "s",
1565 +    olsrIntf != NULL ? "OLSR" : "non-OLSR",
1566 +    ifName);
1567 +
1568 +  return nOpened;
1569 +} /* CreateInterface */
1570 +
1571 +/* -------------------------------------------------------------------------
1572 + * Function   : CreateBmfNetworkInterfaces
1573 + * Description: Create a list of TBmfInterface objects, one for each network
1574 + *              interface on which BMF runs
1575 + * Input      : skipThisIntf - network interface to skip, if seen
1576 + * Output     : none
1577 + * Return     : fail (-1) or success (0)
1578 + * Data Used  : none
1579 + * ------------------------------------------------------------------------- */
1580 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
1581 +{
1582 +  int skfd;
1583 +  struct ifconf ifc;
1584 +  int numreqs = 30;
1585 +  struct ifreq* ifr;
1586 +  int n;
1587 +  int nOpenedSockets = 0;
1588 +
1589 +  /* Clear input descriptor set */
1590 +  FD_ZERO(&InputSet);
1591 +
1592 +  skfd = socket(PF_INET, SOCK_DGRAM, 0);
1593 +  if (skfd < 0)
1594 +  {
1595 +    BmfPError("no inet socket available to retrieve interface list");
1596 +    return -1;
1597 +  }
1598 +
1599 +  /* Retrieve the network interface configuration list */
1600 +  ifc.ifc_buf = NULL;
1601 +  for (;;)
1602 +  {
1603 +    ifc.ifc_len = sizeof(struct ifreq) * numreqs;
1604 +    ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
1605 +
1606 +    if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
1607 +    {
1608 +      BmfPError("ioctl(SIOCGIFCONF) error");
1609 +
1610 +      close(skfd);
1611 +      free(ifc.ifc_buf);
1612 +      return -1;
1613 +    }
1614 +    if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
1615 +    {
1616 +      /* Assume it overflowed; double the space and try again */
1617 +      numreqs *= 2;
1618 +      assert(numreqs < 1024);
1619 +      continue; /* for (;;) */
1620 +    }
1621 +    break; /* for (;;) */
1622 +  } /* for (;;) */
1623 +
1624 +  close(skfd);
1625 +
1626 +  /* For each item in the interface configuration list... */
1627 +  ifr = ifc.ifc_req;
1628 +  for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++)
1629 +  {
1630 +    struct interface* olsrIntf;
1631 +    union olsr_ip_addr ipAddr;
1632 +
1633 +    /* Skip the BMF network interface itself */
1634 +    //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
1635 +    //{
1636 +    //  continue; /* for (n = ...) */
1637 +    //}
1638 +
1639 +    /* ...find the OLSR interface structure, if any */
1640 +    ipAddr.v4 =  ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr;
1641 +    olsrIntf = if_ifwithaddr(&ipAddr);
1642 +
1643 +    if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
1644 +    {
1645 +      continue; /* for (n = ...) */
1646 +    }
1647 +
1648 +    if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
1649 +    {
1650 +      /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
1651 +       * interface in the BMF plugin parameter list */
1652 +      continue; /* for (n = ...) */
1653 +    }
1654 +       
1655 +    if (! IsNonOlsrBmfIf(ifr->ifr_name))
1656 +    {
1657 +       //If the interface is not specified in the configuration file then go ahead
1658 +       continue; /* for (n = ...) */
1659 +    }
1660 +   //TODO: asser if->ifr_name is not talking OLSR
1661 +    //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
1662 +    nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
1663 +
1664 +  } /* for (n = ...) */
1665 +
1666 +  free(ifc.ifc_buf);
1667 +
1668 +  /* Create the BMF network interface */
1669 +  //EtherTunTapFd = CreateLocalEtherTunTap();
1670 +  //if (EtherTunTapFd >= 0)
1671 +  //{
1672 +  //  nOpenedSockets++;
1673 +  //}
1674 +
1675 +  if (BmfInterfaces == NULL)
1676 +  {
1677 +    OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
1678 +  }
1679 +  else
1680 +  {
1681 +    OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
1682 +  }
1683 +  return 0;
1684 +} /* CreateBmfNetworkInterfaces */
1685 +
1686 +/* -------------------------------------------------------------------------
1687 + * Function   : AddInterface
1688 + * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
1689 + *              network interfaces
1690 + * Input      : newIntf - network interface to add
1691 + * Output     : none
1692 + * Return     : none
1693 + * Data Used  : none
1694 + * ------------------------------------------------------------------------- */
1695 +void AddInterface(struct interface* newIntf)
1696 +{
1697 +  int nOpened;
1698 +
1699 +  assert(newIntf != NULL);
1700 +
1701 +  nOpened = CreateInterface(newIntf->int_name, newIntf);
1702 +
1703 +  OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
1704 +} /* AddInterface */
1705 +
1706 +/* -------------------------------------------------------------------------
1707 + * Function   : CloseBmfNetworkInterfaces
1708 + * Description: Closes every socket on each network interface used by BMF
1709 + * Input      : none
1710 + * Output     : none
1711 + * Return     : none
1712 + * Data Used  : none
1713 + * Notes      : Closes
1714 + *              - the local EtherTunTap interface (e.g. "tun0" or "tap0")
1715 + *              - for each BMF-enabled interface, the socket used for
1716 + *                capturing multicast packets
1717 + *              - for each OLSR-enabled interface, the socket used for
1718 + *                encapsulating packets
1719 + *              Also restores the network state to the situation before BMF
1720 + *              was started.
1721 + * ------------------------------------------------------------------------- */
1722 +void CloseBmfNetworkInterfaces(void)
1723 +{
1724 +  int nClosed = 0;
1725 +  u_int32_t totalOlsrBmfPacketsRx = 0;
1726 +  u_int32_t totalOlsrBmfPacketsRxDup = 0;
1727 +  u_int32_t totalOlsrBmfPacketsTx = 0;
1728 +  u_int32_t totalNonOlsrBmfPacketsRx = 0;
1729 +  u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
1730 +  u_int32_t totalNonOlsrBmfPacketsTx = 0;
1731 +
1732 +  /* Close all opened sockets */
1733 +  struct TBmfInterface* nextBmfIf = BmfInterfaces;
1734 +  while (nextBmfIf != NULL)
1735 +  {
1736 +    struct TBmfInterface* bmfIf = nextBmfIf;
1737 +    nextBmfIf = bmfIf->next;
1738 +
1739 +    if (bmfIf->capturingSkfd >= 0)
1740 +    {
1741 +      close(bmfIf->capturingSkfd);
1742 +      nClosed++;
1743 +    }
1744 +    if (bmfIf->encapsulatingSkfd >= 0)
1745 +    {
1746 +      close(bmfIf->encapsulatingSkfd);
1747 +      nClosed++;
1748 +    }
1749 +
1750 +    OLSR_PRINTF(
1751 +      7,
1752 +      "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
1753 +      PLUGIN_NAME_SHORT,
1754 +      bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
1755 +      bmfIf->ifName,
1756 +      bmfIf->nBmfPacketsRx,
1757 +      bmfIf->nBmfPacketsRxDup,
1758 +      bmfIf->nBmfPacketsTx);
1759 +
1760 +    OLSR_PRINTF(
1761 +      1,
1762 +      "%s: closed %s interface \"%s\"\n",
1763 +      PLUGIN_NAME_SHORT,
1764 +      bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
1765 +      bmfIf->ifName);
1766 +
1767 +    /* Add totals */
1768 +    if (bmfIf->olsrIntf != NULL)
1769 +    {
1770 +      totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1771 +      totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1772 +      totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1773 +    }
1774 +    else
1775 +    {
1776 +      totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1777 +      totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1778 +      totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1779 +    }
1780 +
1781 +    free(bmfIf);
1782 +  } /* while */
1783 +
1784 +  if (EtherTunTapFd >= 0)
1785 +  {
1786 +    close(EtherTunTapFd);
1787 +    nClosed++;
1788 +
1789 +    OLSR_PRINTF(7, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1790 +  }
1791 +
1792 +  BmfInterfaces = NULL;
1793 +
1794 +  OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
1795 +
1796 +  OLSR_PRINTF(
1797 +    7,
1798 +    "%s: Total all OLSR interfaces    : RX pkts %u (%u dups); TX pkts %u\n",
1799 +    PLUGIN_NAME_SHORT,
1800 +    totalOlsrBmfPacketsRx,
1801 +    totalOlsrBmfPacketsRxDup,
1802 +    totalOlsrBmfPacketsTx);
1803 +  OLSR_PRINTF(
1804 +    7,
1805 +    "%s: Total all non-OLSR interfaces: RX pkts %u (%u dups); TX pkts %u\n",
1806 +    PLUGIN_NAME_SHORT,
1807 +    totalNonOlsrBmfPacketsRx,
1808 +    totalNonOlsrBmfPacketsRxDup,
1809 +    totalNonOlsrBmfPacketsTx);
1810 +} /* CloseBmfNetworkInterfaces */
1811 +
1812 +#define MAX_NON_OLSR_IFS 32
1813 +static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
1814 +static int nNonOlsrIfs = 0;
1815 +
1816 +/* -------------------------------------------------------------------------
1817 + * Function   : AddNonOlsrBmfIf
1818 + * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
1819 + *              network interfaces
1820 + * Input      : ifName - network interface (e.g. "eth0")
1821 + *              data - not used
1822 + *              addon - not used
1823 + * Output     : none
1824 + * Return     : success (0) or fail (1)
1825 + * Data Used  : NonOlsrIfNames
1826 + * ------------------------------------------------------------------------- */
1827 +int AddNonOlsrBmfIf(
1828 +  const char* ifName,
1829 +  void* data __attribute__((unused)),
1830 +  set_plugin_parameter_addon addon __attribute__((unused)))
1831 +{
1832 +  assert(ifName != NULL);
1833 +
1834 +  if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
1835 +  {
1836 +    OLSR_PRINTF(
1837 +      1,
1838 +      "%s: too many non-OLSR interfaces specified, maximum is %d\n",
1839 +      PLUGIN_NAME,
1840 +      MAX_NON_OLSR_IFS);
1841 +    return 1;
1842 +  }
1843 +
1844 +  strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
1845 +  NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1846 +  nNonOlsrIfs++;
1847 +  return 0;
1848 +} /* AddNonOlsrBmfIf */
1849 +
1850 +/* -------------------------------------------------------------------------
1851 + * Function   : IsNonOlsrBmfIf
1852 + * Description: Checks if a network interface is OLSR-enabled
1853 + * Input      : ifName - network interface (e.g. "eth0")
1854 + * Output     : none
1855 + * Return     : true (1) or false (0)
1856 + * Data Used  : NonOlsrIfNames
1857 + * ------------------------------------------------------------------------- */
1858 +int IsNonOlsrBmfIf(const char* ifName)
1859 +{
1860 +  int i;
1861 +
1862 +  assert(ifName != NULL);
1863 +
1864 +  for (i = 0; i < nNonOlsrIfs; i++)
1865 +  {
1866 +    if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
1867 +  }
1868 +  return 0;
1869 +} /* IsNonOlsrBmfIf */
1870 +
1871 +/* -------------------------------------------------------------------------
1872 + * Function   : CheckAndUpdateLocalBroadcast
1873 + * Description: For an IP packet, check if the destination address is not a
1874 + *              multicast address. If it is not, the packet is assumed to be
1875 + *              a local broadcast packet. In that case, set the destination
1876 + *              address of the IP packet to the passed broadcast address.
1877 + * Input      : ipPacket - the IP packet
1878 + *              broadAddr - the broadcast address to fill in
1879 + * Output     : none
1880 + * Return     : none
1881 + * Data Used  : none
1882 + * Notes      : See also RFC1141
1883 + * ------------------------------------------------------------------------- */
1884 +void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr)
1885 +{
1886 +  struct iphdr* iph;
1887 +  union olsr_ip_addr destIp;
1888 +
1889 +  assert(ipPacket != NULL && broadAddr != NULL);
1890 +
1891 +  iph = (struct iphdr*) ipPacket;
1892 +  destIp.v4.s_addr = iph->daddr;
1893 +  if (! IsMulticast(&destIp))
1894 +  {
1895 +    u_int32_t origDaddr, newDaddr;
1896 +    u_int32_t check;
1897 +
1898 +    origDaddr = ntohl(iph->daddr);
1899 +
1900 +    iph->daddr = broadAddr->v4.s_addr;
1901 +    newDaddr = ntohl(iph->daddr);
1902 +
1903 +    /* Re-calculate IP header checksum for new destination */
1904 +    check = ntohs(iph->check);
1905 +
1906 +    check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1907 +    check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1908 +
1909 +    /* Add carry */
1910 +    check = check + (check >> 16);
1911 +
1912 +    iph->check = htons(check);
1913 +
1914 +    if (iph->protocol == SOL_UDP)
1915 +    {
1916 +      /* Re-calculate UDP/IP checksum for new destination */
1917 +
1918 +      int ipHeaderLen = GetIpHeaderLength(ipPacket);
1919 +      struct udphdr* udph = (struct udphdr*) (ipPacket + ipHeaderLen);
1920 +
1921 +      /* RFC 1624, Eq. 3: HC' = ~(~HC - m + m') */
1922 +
1923 +      check = ntohs(udph->check);
1924 +
1925 +      check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1926 +      check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1927 +
1928 +      /* Add carry */
1929 +      check = check + (check >> 16);
1930 +
1931 +      udph->check = htons(check);
1932 +     } /* if */
1933 +  } /* if */
1934 +} /* CheckAndUpdateLocalBroadcast */
1935 +
1936 +/* -------------------------------------------------------------------------
1937 + * Function   : AddMulticastRoute
1938 + * Description: Insert a route to all multicast addresses in the kernel
1939 + *              routing table. The route will be via the BMF network interface.
1940 + * Input      : none
1941 + * Output     : none
1942 + * Return     : none
1943 + * Data Used  : none
1944 + * ------------------------------------------------------------------------- */
1945 +void AddMulticastRoute(void)
1946 +{
1947 +  struct rtentry kernel_route;
1948 +  int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1949 +  if (ioctlSkfd < 0)
1950 +  {
1951 +    BmfPError("socket(PF_INET) error");
1952 +    return;
1953 +  }
1954 +
1955 +  memset(&kernel_route, 0, sizeof(struct rtentry));
1956 +
1957 +  ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
1958 +  ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
1959 +  ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
1960 +
1961 +  /* 224.0.0.0/4 */
1962 +  ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
1963 +  ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
1964 +
1965 +  kernel_route.rt_metric = 0;
1966 +  kernel_route.rt_flags = RTF_UP;
1967 +
1968 +  kernel_route.rt_dev = EtherTunTapIfName;
1969 +
1970 +  if (ioctl(ioctlSkfd, SIOCADDRT, &kernel_route) < 0)
1971 +  {
1972 +    BmfPError("error setting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
1973 +
1974 +    /* Continue anyway */
1975 +  }
1976 +  close(ioctlSkfd);
1977 +} /* AddMulticastRoute */
1978 +
1979 +/* -------------------------------------------------------------------------
1980 + * Function   : DeleteMulticastRoute
1981 + * Description: Delete the route to all multicast addresses from the kernel
1982 + *              routing table
1983 + * Input      : none
1984 + * Output     : none
1985 + * Return     : none
1986 + * Data Used  : none
1987 + * ------------------------------------------------------------------------- */
1988 +void DeleteMulticastRoute(void)
1989 +{
1990 +  if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP)
1991 +  {
1992 +    struct rtentry kernel_route;
1993 +    int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1994 +    if (ioctlSkfd < 0)
1995 +    {
1996 +      BmfPError("socket(PF_INET) error");
1997 +      return;
1998 +    }
1999 +
2000 +    memset(&kernel_route, 0, sizeof(struct rtentry));
2001 +
2002 +    ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
2003 +    ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
2004 +    ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
2005 +
2006 +    /* 224.0.0.0/4 */
2007 +    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
2008 +    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
2009 +
2010 +    kernel_route.rt_metric = 0;
2011 +    kernel_route.rt_flags = RTF_UP;
2012 +
2013 +    kernel_route.rt_dev = EtherTunTapIfName;
2014 +
2015 +    if (ioctl(ioctlSkfd, SIOCDELRT, &kernel_route) < 0)
2016 +    {
2017 +      BmfPError("error deleting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
2018 +
2019 +      /* Continue anyway */
2020 +    }
2021 +    close(ioctlSkfd);
2022 +  } /* if */
2023 +} /* DeleteMulticastRoute */
2024 +
2025 +/*
2026 + * Local Variables:
2027 + * c-basic-offset: 2
2028 + * indent-tabs-mode: nil
2029 + * End:
2030 + */
2031 --- /dev/null
2032 +++ b/lib/mdns/src/NetworkInterfaces.h
2033 @@ -0,0 +1,162 @@
2034 +#ifndef _BMF_NETWORKINTERFACES_H
2035 +#define _BMF_NETWORKINTERFACES_H
2036 +
2037 +/*
2038 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2039 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2040 + * Written by Erik Tromp.
2041 + * All rights reserved.
2042 + *
2043 + * Redistribution and use in source and binary forms, with or without
2044 + * modification, are permitted provided that the following conditions
2045 + * are met:
2046 + *
2047 + * * Redistributions of source code must retain the above copyright
2048 + *   notice, this list of conditions and the following disclaimer.
2049 + * * Redistributions in binary form must reproduce the above copyright
2050 + *   notice, this list of conditions and the following disclaimer in
2051 + *   the documentation and/or other materials provided with the
2052 + *   distribution.
2053 + * * Neither the name of Thales, BMF nor the names of its
2054 + *   contributors may be used to endorse or promote products derived
2055 + *   from this software without specific prior written permission.
2056 + *
2057 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2058 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2059 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2060 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2061 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2062 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2063 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2064 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2065 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2066 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2067 + */
2068 +
2069 +/* -------------------------------------------------------------------------
2070 + * File       : NetworkInterfaces.h
2071 + * Description: Functions to open and close sockets
2072 + * Created    : 29 Jun 2006
2073 + *
2074 + * ------------------------------------------------------------------------- */
2075 +
2076 +/* System includes */
2077 +#include <netinet/in.h> /* struct in_addr */
2078 +
2079 +/* OLSR includes */
2080 +#include "olsr_types.h" /* olsr_ip_addr */
2081 +#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
2082 +#include "socket_parser.h"
2083 +/* Plugin includes */
2084 +#include "Packet.h" /* IFHWADDRLEN */
2085 +#include "mdns.h"
2086 +/* Size of buffer in which packets are received */
2087 +#define BMF_BUFFER_SIZE 2048
2088 +
2089 +struct TBmfInterface
2090 +{
2091 +  /* File descriptor of raw packet socket, used for capturing multicast packets */
2092 +  int capturingSkfd;
2093 +
2094 +  /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.
2095 +   * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */
2096 +  int encapsulatingSkfd;
2097 +
2098 +  /* File descriptor of UDP packet socket, used for listening to encapsulation packets.
2099 +   * Used only when PlParam "BmfMechanism" is set to "UnicastPromiscuous". */
2100 +  int listeningSkfd;
2101 +
2102 +  unsigned char macAddr[IFHWADDRLEN];
2103 +
2104 +  char ifName[IFNAMSIZ];
2105 +
2106 +  /* OLSRs idea of this network interface. NULL if this interface is not
2107 +   * OLSR-enabled. */
2108 +  struct interface* olsrIntf;
2109 +
2110 +  /* IP address of this network interface */
2111 +  union olsr_ip_addr intAddr;
2112 +
2113 +  /* Broadcast address of this network interface */
2114 +  union olsr_ip_addr broadAddr;
2115 +
2116 +  #define FRAGMENT_HISTORY_SIZE 10
2117 +  struct TFragmentHistory
2118 +  {
2119 +    u_int16_t ipId;
2120 +    u_int8_t ipProto;
2121 +    struct in_addr ipSrc;
2122 +    struct in_addr ipDst;
2123 +  } fragmentHistory [FRAGMENT_HISTORY_SIZE];
2124 +
2125 +  int nextFragmentHistoryEntry;
2126 +
2127 +  /* Number of received and transmitted BMF packets on this interface */
2128 +  u_int32_t nBmfPacketsRx;
2129 +  u_int32_t nBmfPacketsRxDup;
2130 +  u_int32_t nBmfPacketsTx;
2131 +
2132 +  /* Next element in list */
2133 +  struct TBmfInterface* next;
2134 +};
2135 +
2136 +extern struct TBmfInterface* BmfInterfaces;
2137 +
2138 +extern int HighestSkfd;
2139 +extern fd_set InputSet;
2140 +
2141 +extern int EtherTunTapFd;
2142 +
2143 +extern char EtherTunTapIfName[];
2144 +
2145 +/* 10.255.255.253 in host byte order */
2146 +#define ETHERTUNTAPDEFAULTIP 0x0AFFFFFD
2147 +
2148 +extern u_int32_t EtherTunTapIp;
2149 +extern u_int32_t EtherTunTapIpMask;
2150 +extern u_int32_t EtherTunTapIpBroadcast;
2151 +
2152 +extern int CapturePacketsOnOlsrInterfaces;
2153 +
2154 +enum TBmfMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };
2155 +extern enum TBmfMechanism BmfMechanism;
2156 +
2157 +int SetBmfInterfaceName(const char* ifname, void* data, set_plugin_parameter_addon addon);
2158 +int SetBmfInterfaceIp(const char* ip, void* data, set_plugin_parameter_addon addon);
2159 +int SetCapturePacketsOnOlsrInterfaces(const char* enable, void* data, set_plugin_parameter_addon addon);
2160 +int SetBmfMechanism(const char* mechanism, void* data, set_plugin_parameter_addon addon);
2161 +int DeactivateSpoofFilter(void);
2162 +void RestoreSpoofFilter(void);
2163 +
2164 +#define MAX_UNICAST_NEIGHBORS 10
2165 +struct TBestNeighbors
2166 +{
2167 +  struct link_entry* links[MAX_UNICAST_NEIGHBORS];
2168 +};
2169 +
2170 +void FindNeighbors(
2171 +  struct TBestNeighbors* neighbors,
2172 +  struct link_entry** bestNeighbor,
2173 +  struct TBmfInterface* intf,
2174 +  union olsr_ip_addr* source,
2175 +  union olsr_ip_addr* forwardedBy,
2176 +  union olsr_ip_addr* forwardedTo,
2177 +  int* nPossibleNeighbors);
2178 +
2179 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
2180 +void AddInterface(struct interface* newIntf);
2181 +void CloseBmfNetworkInterfaces(void);
2182 +int AddNonOlsrBmfIf(const char* ifName, void* data, set_plugin_parameter_addon addon);
2183 +int IsNonOlsrBmfIf(const char* ifName);
2184 +void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr);
2185 +void AddMulticastRoute(void);
2186 +void DeleteMulticastRoute(void);
2187 +
2188 +#endif /* _BMF_NETWORKINTERFACES_H */
2189 +
2190 +/*
2191 + * Local Variables:
2192 + * c-basic-offset: 2
2193 + * indent-tabs-mode: nil
2194 + * End:
2195 + */
2196 --- /dev/null
2197 +++ b/lib/mdns/src/Packet.c
2198 @@ -0,0 +1,238 @@
2199 +/*
2200 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2201 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2202 + * Written by Erik Tromp.
2203 + * All rights reserved.
2204 + *
2205 + * Redistribution and use in source and binary forms, with or without
2206 + * modification, are permitted provided that the following conditions
2207 + * are met:
2208 + *
2209 + * * Redistributions of source code must retain the above copyright
2210 + *   notice, this list of conditions and the following disclaimer.
2211 + * * Redistributions in binary form must reproduce the above copyright
2212 + *   notice, this list of conditions and the following disclaimer in
2213 + *   the documentation and/or other materials provided with the
2214 + *   distribution.
2215 + * * Neither the name of Thales, BMF nor the names of its
2216 + *   contributors may be used to endorse or promote products derived
2217 + *   from this software without specific prior written permission.
2218 + *
2219 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2220 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2221 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2222 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2223 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2224 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2225 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2226 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2227 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2228 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2229 + */
2230 +
2231 +/* -------------------------------------------------------------------------
2232 + * File       : Packet.c
2233 + * Description: IP packet and Ethernet frame processing functions
2234 + * Created    : 29 Jun 2006
2235 + *
2236 + * ------------------------------------------------------------------------- */
2237 +
2238 +#include "Packet.h"
2239 +
2240 +/* System includes */
2241 +#include <stddef.h> /* NULL */
2242 +#include <assert.h> /* assert() */
2243 +#include <string.h> /* memcpy() */
2244 +#include <sys/types.h> /* u_int8_t, u_int16_t, u_int32_t */
2245 +#include <netinet/in.h> /* ntohs(), htons() */
2246 +#include <netinet/ip.h> /* struct iphdr */
2247 +
2248 +/* -------------------------------------------------------------------------
2249 + * Function   : IsIpFragment
2250 + * Description: Check if an IP packet is an IP fragment
2251 + * Input      : ipPacket - the IP packet
2252 + * Output     : none
2253 + * Return     : true (1) or false (0)
2254 + * Data Used  : none
2255 + * ------------------------------------------------------------------------- */
2256 +int IsIpFragment(unsigned char* ipPacket)
2257 +{
2258 +  struct ip* iph;
2259 +
2260 +  assert(ipPacket != NULL);
2261 +
2262 +  iph = (struct ip*) ipPacket;
2263 +  if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
2264 +  {
2265 +    return 1;
2266 +  }
2267 +  return 0;
2268 +} /* IsIpFragment */
2269 +
2270 +/* -------------------------------------------------------------------------
2271 + * Function   : GetIpTotalLength
2272 + * Description: Retrieve the total length of the IP packet (in bytes) of
2273 + *              an IP packet
2274 + * Input      : ipPacket - the IP packet
2275 + * Output     : none
2276 + * Return     : IP packet length
2277 + * Data Used  : none
2278 + * ------------------------------------------------------------------------- */
2279 +u_int16_t GetIpTotalLength(unsigned char* ipPacket)
2280 +{
2281 +  struct iphdr* iph;
2282 +
2283 +  assert(ipPacket != NULL);
2284 +
2285 +  iph = (struct iphdr*) ipPacket;
2286 +  return ntohs(iph->tot_len);
2287 +} /* GetIpTotalLength */
2288 +
2289 +/* -------------------------------------------------------------------------
2290 + * Function   : GetIpHeaderLength
2291 + * Description: Retrieve the IP header length (in bytes) of an IP packet
2292 + * Input      : ipPacket - the IP packet
2293 + * Output     : none
2294 + * Return     : IP header length
2295 + * Data Used  : none
2296 + * ------------------------------------------------------------------------- */
2297 +unsigned int GetIpHeaderLength(unsigned char* ipPacket)
2298 +{
2299 +  struct iphdr* iph;
2300 +
2301 +  assert(ipPacket != NULL);
2302 +
2303 +  iph = (struct iphdr*) ipPacket;
2304 +  return iph->ihl << 2;
2305 +} /* GetIpHeaderLength */
2306 +
2307 +/* -------------------------------------------------------------------------
2308 + * Function   : GetTtl
2309 + * Description: Retrieve the TTL (Time To Live) value from the IP header of
2310 + *              an IP packet
2311 + * Input      : ipPacket - the IP packet
2312 + * Output     : none
2313 + * Return     : TTL value
2314 + * Data Used  : none
2315 + * ------------------------------------------------------------------------- */
2316 +u_int8_t GetTtl(unsigned char* ipPacket)
2317 +{
2318 +  struct iphdr* iph;
2319 +
2320 +  assert(ipPacket != NULL);
2321 +
2322 +  iph = (struct iphdr*) ipPacket;
2323 +  return iph->ttl;
2324 +} /* GetTtl */
2325 +
2326 +/* -------------------------------------------------------------------------
2327 + * Function   : SaveTtlAndChecksum
2328 + * Description: Save the TTL (Time To Live) value and IP checksum as found in
2329 + *              the IP header of an IP packet
2330 + * Input      : ipPacket - the IP packet
2331 + * Output     : sttl - the TTL and checksum values
2332 + * Return     : none
2333 + * Data Used  : none
2334 + * ------------------------------------------------------------------------- */
2335 +void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
2336 +{
2337 +  struct iphdr* iph;
2338 +
2339 +  assert(ipPacket != NULL && sttl != NULL);
2340 +
2341 +  iph = (struct iphdr*) ipPacket;
2342 +  sttl->ttl = iph->ttl;
2343 +  sttl->check = ntohs(iph->check);
2344 +} /* SaveTtlAndChecksum */
2345 +
2346 +/* -------------------------------------------------------------------------
2347 + * Function   : RestoreTtlAndChecksum
2348 + * Description: Restore the TTL (Time To Live) value and IP checksum in
2349 + *              the IP header of an IP packet
2350 + * Input      : ipPacket - the IP packet
2351 + *              sttl - the TTL and checksum values
2352 + * Output     : none
2353 + * Return     : none
2354 + * Data Used  : none
2355 + * ------------------------------------------------------------------------- */
2356 +void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
2357 +{
2358 +  struct iphdr* iph;
2359 +
2360 +  assert(ipPacket != NULL && sttl != NULL);
2361 +
2362 +  iph = (struct iphdr*) ipPacket;
2363 +  iph->ttl = sttl->ttl;
2364 +  iph->check = htons(sttl->check);
2365 +} /* RestoreTtlAndChecksum */
2366 +
2367 +/* -------------------------------------------------------------------------
2368 + * Function   : DecreaseTtlAndUpdateHeaderChecksum
2369 + * Description: For an IP packet, decrement the TTL value and update the IP header
2370 + *              checksum accordingly.
2371 + * Input      : ipPacket - the IP packet
2372 + * Output     : none
2373 + * Return     : none
2374 + * Data Used  : none
2375 + * Notes      : See also RFC1141
2376 + * ------------------------------------------------------------------------- */
2377 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
2378 +{
2379 +  struct iphdr* iph;
2380 +  u_int32_t sum;
2381 +
2382 +  assert(ipPacket != NULL);
2383 +
2384 +  iph = (struct iphdr*) ipPacket;
2385 +
2386 +  iph->ttl--; /* decrement ttl */
2387 +  sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
2388 +  iph->check = htons(sum + (sum>>16)); /* add carry */
2389 +} /* DecreaseTtlAndUpdateHeaderChecksum */
2390 +
2391 +/* -------------------------------------------------------------------------
2392 + * Function   : GetIpHeader
2393 + * Description: Retrieve the IP header from BMF encapsulation UDP data
2394 + * Input      : encapsulationUdpData - the encapsulation UDP data
2395 + * Output     : none
2396 + * Return     : IP header
2397 + * Data Used  : none
2398 + * ------------------------------------------------------------------------- */
2399 +struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
2400 +{
2401 +  return (struct ip*)(encapsulationUdpData + ENCAP_HDR_LEN);
2402 +} /* GetIpHeader */
2403 +
2404 +/* -------------------------------------------------------------------------
2405 + * Function   : GetIpPacket
2406 + * Description: Retrieve the IP packet from BMF encapsulation UDP data
2407 + * Input      : encapsulationUdpData - the encapsulation UDP data
2408 + * Output     : none
2409 + * Return     : The IP packet
2410 + * Data Used  : none
2411 + * ------------------------------------------------------------------------- */
2412 +unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
2413 +{
2414 +  return encapsulationUdpData + ENCAP_HDR_LEN;
2415 +} /* GetIpPacket */
2416 +
2417 +/* -------------------------------------------------------------------------
2418 + * Function   : GetEncapsulationUdpDataLength
2419 + * Description: Return the length of BMF encapsulation UDP data
2420 + * Input      : encapsulationUdpData - the encapsulation UDP data
2421 + * Output     : none
2422 + * Return     : The encapsulation data length
2423 + * Data Used  : none
2424 + * ------------------------------------------------------------------------- */
2425 +u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData)
2426 +{
2427 +  return GetIpTotalLength(GetIpPacket(encapsulationUdpData)) + ENCAP_HDR_LEN;
2428 +} /* GetEncapsulationUdpDataLength */
2429 +
2430 +
2431 +/*
2432 + * Local Variables:
2433 + * c-basic-offset: 2
2434 + * indent-tabs-mode: nil
2435 + * End:
2436 + */
2437 --- /dev/null
2438 +++ b/lib/mdns/src/Packet.h
2439 @@ -0,0 +1,88 @@
2440 +#ifndef _BMF_PACKET_H
2441 +#define _BMF_PACKET_H
2442 +
2443 +/*
2444 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2445 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2446 + * Written by Erik Tromp.
2447 + * All rights reserved.
2448 + *
2449 + * Redistribution and use in source and binary forms, with or without
2450 + * modification, are permitted provided that the following conditions
2451 + * are met:
2452 + *
2453 + * * Redistributions of source code must retain the above copyright
2454 + *   notice, this list of conditions and the following disclaimer.
2455 + * * Redistributions in binary form must reproduce the above copyright
2456 + *   notice, this list of conditions and the following disclaimer in
2457 + *   the documentation and/or other materials provided with the
2458 + *   distribution.
2459 + * * Neither the name of Thales, BMF nor the names of its
2460 + *   contributors may be used to endorse or promote products derived
2461 + *   from this software without specific prior written permission.
2462 + *
2463 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2464 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2465 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2466 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2467 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2468 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2469 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2470 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2471 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2472 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2473 + */
2474 +
2475 +/* -------------------------------------------------------------------------
2476 + * File       : Packet.h
2477 + * Description: BMF and IP packet processing functions
2478 + * Created    : 29 Jun 2006
2479 + *
2480 + * ------------------------------------------------------------------------- */
2481 +
2482 +/* System includes */
2483 +#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
2484 +#include <sys/types.h> /* u_int8_t, u_int16_t */
2485 +
2486 +/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
2487 + * with a 8-bytes BMF header (struct TEncapHeader), followed by the
2488 + * encapsulated Ethernet-IP packet itself */
2489 +
2490 +struct TEncapHeader
2491 +{
2492 +  /* Use a standard Type-Length-Value (TLV) element */
2493 +  u_int8_t type;
2494 +  u_int8_t len;
2495 +  u_int16_t reserved; /* Always 0 */
2496 +  u_int32_t crc32;
2497 +} __attribute__((__packed__));
2498 +
2499 +#define ENCAP_HDR_LEN ((int)sizeof(struct TEncapHeader))
2500 +#define BMF_ENCAP_TYPE 1
2501 +#define BMF_ENCAP_LEN 6
2502 +
2503 +struct TSaveTtl
2504 +{
2505 +  u_int8_t ttl;
2506 +  u_int16_t check;
2507 +} __attribute__((__packed__));
2508 +
2509 +int IsIpFragment(unsigned char* ipPacket);
2510 +u_int16_t GetIpTotalLength(unsigned char* ipPacket);
2511 +unsigned int GetIpHeaderLength(unsigned char* ipPacket);
2512 +u_int8_t GetTtl(unsigned char* ipPacket);
2513 +void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
2514 +void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
2515 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket);
2516 +struct ip* GetIpHeader(unsigned char* encapsulationUdpData);
2517 +unsigned char* GetIpPacket(unsigned char* encapsulationUdpData);
2518 +u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData);
2519 +
2520 +#endif /* _BMF_PACKET_H */
2521 +
2522 +/*
2523 + * Local Variables:
2524 + * c-basic-offset: 2
2525 + * indent-tabs-mode: nil
2526 + * End:
2527 + */
2528 --- /dev/null
2529 +++ b/lib/mdns/src/PacketHistory.c
2530 @@ -0,0 +1,324 @@
2531 +/*
2532 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2533 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2534 + * Written by Erik Tromp.
2535 + * All rights reserved.
2536 + *
2537 + * Redistribution and use in source and binary forms, with or without
2538 + * modification, are permitted provided that the following conditions
2539 + * are met:
2540 + *
2541 + * * Redistributions of source code must retain the above copyright
2542 + *   notice, this list of conditions and the following disclaimer.
2543 + * * Redistributions in binary form must reproduce the above copyright
2544 + *   notice, this list of conditions and the following disclaimer in
2545 + *   the documentation and/or other materials provided with the
2546 + *   distribution.
2547 + * * Neither the name of Thales, BMF nor the names of its
2548 + *   contributors may be used to endorse or promote products derived
2549 + *   from this software without specific prior written permission.
2550 + *
2551 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2552 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2553 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2554 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2555 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2556 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2557 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2558 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2559 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2560 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2561 + */
2562 +
2563 +/* -------------------------------------------------------------------------
2564 + * File       : PacketHistory.c
2565 + * Description: Functions for keeping and accessing the history of processed
2566 + *              multicast IP packets.
2567 + * Created    : 29 Jun 2006
2568 + *
2569 + * ------------------------------------------------------------------------- */
2570 +
2571 +#include "PacketHistory.h"
2572 +
2573 +/* System includes */
2574 +#include <stddef.h> /* NULL */
2575 +#include <assert.h> /* assert() */
2576 +#include <string.h> /* memset */
2577 +#include <sys/types.h> /* u_int16_t, u_int32_t */
2578 +#include <netinet/ip.h> /* struct iphdr */
2579 +#include <stdlib.h> /* atoi, malloc */
2580 +
2581 +/* OLSRD includes */
2582 +#include "defs.h" /* GET_TIMESTAMP, TIMED_OUT */
2583 +#include "olsr.h" /* OLSR_PRINTF */
2584 +#include "scheduler.h" /* now_times */
2585 +
2586 +/* Plugin includes */
2587 +#include "Packet.h"
2588 +
2589 +static struct TDupEntry* PacketHistory[HISTORY_HASH_SIZE];
2590 +
2591 +#define CRC_UPTO_NBYTES 256
2592 +
2593 +#if 0
2594 +/* -------------------------------------------------------------------------
2595 + * Function   : CalcCrcCcitt
2596 + * Description: Calculate 16-bits CRC according to CRC-CCITT specification
2597 + * Input      : buffer - the bytes to calculate the CRC value over
2598 + *              len - the number of bytes to calculate the CRC value over
2599 + * Output     : none
2600 + * Return     : CRC-16 value
2601 + * Data Used  : none
2602 + * ------------------------------------------------------------------------- */
2603 +static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)
2604 +{
2605 +  /* Initial value of 0xFFFF should be 0x1D0F according to
2606 +   * www.joegeluso.com/software/articles/ccitt.htm */
2607 +  u_int16_t crc = 0xFFFF;
2608 +  int i;
2609 +
2610 +  assert(buffer != NULL);
2611 +
2612 +  for (i = 0; i < len; i++)
2613 +  {
2614 +    crc  = (unsigned char)(crc >> 8) | (crc << 8);
2615 +    crc ^= buffer[i];
2616 +    crc ^= (unsigned char)(crc & 0xff) >> 4;
2617 +    crc ^= (crc << 8) << 4;
2618 +    crc ^= ((crc & 0xff) << 4) << 1;
2619 +  }
2620 +  return crc;
2621 +} /* CalcCrcCcitt */
2622 +#endif
2623 +
2624 +/* -------------------------------------------------------------------------
2625 + * Function   : GenerateCrc32Table
2626 + * Description: Generate the table of CRC remainders for all possible bytes,
2627 + *              according to CRC-32-IEEE 802.3
2628 + * Input      : none
2629 + * Output     : none
2630 + * Return     : none
2631 + * Data Used  : none
2632 + * ------------------------------------------------------------------------- */
2633 +#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */
2634 +
2635 +static unsigned long CrcTable[256];
2636 +
2637 +static void GenerateCrc32Table(void)
2638 +{
2639 +  int i, j;
2640 +  u_int32_t crc;
2641 +  for (i = 0; i < 256; i++)
2642 +  {
2643 +    crc = (u_int32_t) i;
2644 +    for (j = 0; j < 8; j++)
2645 +    {
2646 +      if (crc & 1)
2647 +      {
2648 +        crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
2649 +      }
2650 +      else
2651 +      {
2652 +        crc = (crc >> 1);
2653 +      }
2654 +    }
2655 +    CrcTable[i] = crc;
2656 +  } /* for */
2657 +} /* GenerateCrc32Table */
2658 +
2659 +/* -------------------------------------------------------------------------
2660 + * Function   : CalcCrc32
2661 + * Description: Calculate CRC-32 according to CRC-32-IEEE 802.3
2662 + * Input      : buffer - the bytes to calculate the CRC value over
2663 + *              len - the number of bytes to calculate the CRC value over
2664 + * Output     : none
2665 + * Return     : CRC-32 value
2666 + * Data Used  : none
2667 + * ------------------------------------------------------------------------- */
2668 +static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)
2669 +{
2670 +  int i, j;
2671 +  u_int32_t crc = 0xffffffffUL;
2672 +  for (i = 0; i < len; i++)
2673 +  {
2674 +    j = ((int) (crc & 0xFF) ^ *buffer++);
2675 +    crc = (crc >> 8) ^ CrcTable[j];
2676 +  }
2677 +  return crc ^ 0xffffffffUL;
2678 +} /* CalcCrc32 */
2679 +
2680 +/* -------------------------------------------------------------------------
2681 + * Function   : PacketCrc32
2682 + * Description: Calculates the CRC-32 value for an IP packet
2683 + * Input      : ipPacket - the IP packet
2684 + *              len - the number of octets in the IP packet
2685 + * Output     : none
2686 + * Return     : 32-bits CRC value
2687 + * Data Used  : none
2688 + * ------------------------------------------------------------------------- */
2689 +u_int32_t PacketCrc32(unsigned char* ipPacket, ssize_t len)
2690 +{
2691 +  struct TSaveTtl sttl;
2692 +  struct ip* ipHeader;
2693 +  u_int32_t result;
2694 +
2695 +  assert(ipPacket != NULL);
2696 +
2697 +  /* Skip TTL: in a multi-homed OLSR-network, the same multicast packet
2698 +   * may enter the network multiple times, each copy differing only in its
2699 +   * TTL value. BMF must not calculate a different CRC for packets that
2700 +   * differ only in TTL. Skip also the IP-header checksum, because it changes
2701 +   * along with TTL. Besides, it is not a good idea to calculate a CRC over
2702 +   * data that already contains a checksum.
2703 +   *
2704 +   * Clip number of bytes over which CRC is calculated to prevent
2705 +   * long packets from possibly claiming too much CPU resources. */
2706 +  assert(len > 0);
2707 +  if (len > CRC_UPTO_NBYTES)
2708 +  {
2709 +    len = CRC_UPTO_NBYTES;
2710 +  }
2711 +
2712 +  SaveTtlAndChecksum(ipPacket, &sttl);
2713 +
2714 +  ipHeader = (struct ip*)ipPacket;
2715 +  ipHeader->ip_ttl = 0xFF; /* fixed value of TTL for CRC-32 calculation */
2716 +  ipHeader->ip_sum = 0x5A5A; /* fixed value of IP header checksum for CRC-32 calculation */
2717 +
2718 +  result = CalcCrc32(ipPacket, len);
2719 +
2720 +  RestoreTtlAndChecksum(ipPacket, &sttl);
2721 +  return result;
2722 +} /* PacketCrc32 */
2723 +
2724 +/* -------------------------------------------------------------------------
2725 + * Function   : Hash
2726 + * Description: Calculates a hash value from a 32-bit value
2727 + * Input      : from32 - 32-bit value
2728 + * Output     : none
2729 + * Return     : hash value
2730 + * Data Used  : none
2731 + * ------------------------------------------------------------------------- */
2732 +u_int32_t Hash(u_int32_t from32)
2733 +{
2734 +  return ((from32 >> N_HASH_BITS) + from32) & ((1 << N_HASH_BITS) - 1);
2735 +} /* Hash */
2736 +
2737 +/* -------------------------------------------------------------------------
2738 + * Function   : InitPacketHistory
2739 + * Description: Initialize the packet history table and CRC-32 table
2740 + * Input      : none
2741 + * Output     : none
2742 + * Return     : none
2743 + * Data Used  : PacketHistory
2744 + * ------------------------------------------------------------------------- */
2745 +void InitPacketHistory(void)
2746 +{
2747 +  int i;
2748 +
2749 +  GenerateCrc32Table();
2750 +
2751 +  for(i = 0; i < HISTORY_HASH_SIZE; i++)
2752 +  {
2753 +    PacketHistory[i] = NULL;
2754 +  }
2755 +} /* InitPacketHistory */
2756 +
2757 +/* -------------------------------------------------------------------------
2758 + * Function   : CheckAndMarkRecentPacket
2759 + * Description: Check if this packet was seen recently, then record the fact
2760 + *              that this packet was seen recently.
2761 + * Input      : crc32 - 32-bits crc value of the packet
2762 + * Output     : none
2763 + * Return     : not recently seen (0), recently seen (1)
2764 + * Data Used  : PacketHistory
2765 + * ------------------------------------------------------------------------- */
2766 +int CheckAndMarkRecentPacket(u_int32_t crc32)
2767 +{
2768 +  u_int32_t idx;
2769 +  struct TDupEntry* walker;
2770 +  struct TDupEntry* newEntry;
2771 +
2772 +  idx = Hash(crc32);
2773 +  assert(idx < HISTORY_HASH_SIZE);
2774 +
2775 +  for (walker = PacketHistory[idx]; walker != NULL; walker = walker->next)
2776 +  {
2777 +    if (walker->crc32 == crc32)
2778 +    {
2779 +      /* Found duplicate entry */
2780 +
2781 +      /* Always mark as "seen recently": refresh time-out */
2782 +      walker->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
2783 +
2784 +      return 1;
2785 +    } /* if */
2786 +  } /* for */
2787 +
2788 +  /* No duplicate entry found: create one */
2789 +  newEntry = malloc(sizeof(struct TDupEntry));
2790 +  if (newEntry != NULL)
2791 +  {
2792 +    newEntry->crc32 = crc32;
2793 +    newEntry->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
2794 +
2795 +    /* Add new entry at the front of the list */
2796 +    newEntry->next = PacketHistory[idx];
2797 +    PacketHistory[idx] = newEntry;
2798 +  }
2799 +
2800 +  return 0;
2801 +} /* CheckAndMarkRecentPacket */
2802 +
2803 +/* -------------------------------------------------------------------------
2804 + * Function   : PrunePacketHistory
2805 + * Description: Prune the packet history table.
2806 + * Input      : useless - not used
2807 + * Output     : none
2808 + * Return     : none
2809 + * Data Used  : PacketHistory
2810 + * ------------------------------------------------------------------------- */
2811 +void PrunePacketHistory(void* useless __attribute__((unused)))
2812 +{
2813 +  uint i;
2814 +  for (i = 0; i < HISTORY_HASH_SIZE; i++)
2815 +  {
2816 +    if (PacketHistory[i] != NULL)
2817 +    {
2818 +      struct TDupEntry* nextEntry = PacketHistory[i];
2819 +      struct TDupEntry* prevEntry = NULL;
2820 +      while (nextEntry != NULL)
2821 +      {
2822 +        struct TDupEntry* entry = nextEntry;
2823 +        nextEntry = entry->next;
2824 +
2825 +        if (TIMED_OUT(entry->timeOut))
2826 +        {
2827 +          /* De-queue */
2828 +          if (prevEntry != NULL)
2829 +          {
2830 +            prevEntry->next = entry->next;
2831 +          }
2832 +          else
2833 +          {
2834 +            PacketHistory[i] = entry->next;
2835 +          } /* if */
2836 +
2837 +          /* De-allocate memory */
2838 +          free(entry);
2839 +             }
2840 +             else
2841 +             {
2842 +               prevEntry = entry;
2843 +             } /* if */
2844 +      } /* while */
2845 +    } /* if (PacketHistory[i] != NULL) */
2846 +  } /* for (i = ...) */
2847 +} /* PrunePacketHistory */
2848 +
2849 +/*
2850 + * Local Variables:
2851 + * c-basic-offset: 2
2852 + * indent-tabs-mode: nil
2853 + * End:
2854 + */
2855 --- /dev/null
2856 +++ b/lib/mdns/src/PacketHistory.h
2857 @@ -0,0 +1,75 @@
2858 +#ifndef _BMF_PACKETHISTORY_H
2859 +#define _BMF_PACKETHISTORY_H
2860 +
2861 +/*
2862 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2863 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2864 + * Written by Erik Tromp.
2865 + * All rights reserved.
2866 + *
2867 + * Redistribution and use in source and binary forms, with or without
2868 + * modification, are permitted provided that the following conditions
2869 + * are met:
2870 + *
2871 + * * Redistributions of source code must retain the above copyright
2872 + *   notice, this list of conditions and the following disclaimer.
2873 + * * Redistributions in binary form must reproduce the above copyright
2874 + *   notice, this list of conditions and the following disclaimer in
2875 + *   the documentation and/or other materials provided with the
2876 + *   distribution.
2877 + * * Neither the name of Thales, BMF nor the names of its
2878 + *   contributors may be used to endorse or promote products derived
2879 + *   from this software without specific prior written permission.
2880 + *
2881 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2882 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2883 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2884 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2885 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2886 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2887 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2888 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2889 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2890 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2891 + */
2892 +
2893 +/* -------------------------------------------------------------------------
2894 + * File       : PacketHistory.h
2895 + * Description: Functions for keeping and accessing the history of processed
2896 + *              multicast IP packets.
2897 + * Created    : 29 Jun 2006
2898 + *
2899 + * ------------------------------------------------------------------------- */
2900 +
2901 +/* System includes */
2902 +#include <sys/types.h> /* ssize_t */
2903 +#include <sys/times.h> /* clock_t */
2904 +
2905 +#define N_HASH_BITS 12
2906 +#define HISTORY_HASH_SIZE (1 << N_HASH_BITS)
2907 +
2908 +/* Time-out of duplicate entries, in milliseconds */
2909 +#define HISTORY_HOLD_TIME 3000
2910 +
2911 +struct TDupEntry
2912 +{
2913 +  u_int32_t crc32;
2914 +  clock_t timeOut;
2915 +  struct TDupEntry* next;
2916 +};
2917 +
2918 +void InitPacketHistory(void);
2919 +u_int32_t PacketCrc32(unsigned char* ipPkt, ssize_t len);
2920 +u_int32_t Hash(u_int32_t from32);
2921 +void MarkRecentPacket(u_int32_t crc32);
2922 +int CheckAndMarkRecentPacket(u_int32_t crc32);
2923 +void PrunePacketHistory(void*);
2924 +
2925 +#endif /* _BMF_PACKETHISTORY_H */
2926 +
2927 +/*
2928 + * Local Variables:
2929 + * c-basic-offset: 2
2930 + * indent-tabs-mode: nil
2931 + * End:
2932 + */
2933 --- /dev/null
2934 +++ b/lib/mdns/src/mdns.c
2935 @@ -0,0 +1,1174 @@
2936 +/*
2937 + * OLSR MDNS plugin.
2938 + * Written by Saverio Proto.
2939 + *
2940 + * Redistribution and use in source and binary forms, with or without
2941 + * modification, are permitted provided that the following conditions
2942 + * are met:
2943 + *
2944 + * * Redistributions of source code must retain the above copyright
2945 + *   notice, this list of conditions and the following disclaimer.
2946 + * * Redistributions in binary form must reproduce the above copyright
2947 + *   notice, this list of conditions and the following disclaimer in
2948 + *   the documentation and/or other materials provided with the
2949 + *   distribution.
2950 + * * Neither the name of Thales, BMF nor the names of its
2951 + *   contributors may be used to endorse or promote products derived
2952 + *   from this software without specific prior written permission.
2953 + *
2954 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2955 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2956 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2957 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2958 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2959 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2960 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2961 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2962 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2963 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2964 + */
2965 +
2966 +
2967 +//#define _MULTI_THREADED
2968 +
2969 +#include "mdns.h"
2970 +
2971 +/* System includes */
2972 +#include <stddef.h> /* NULL */
2973 +#include <sys/types.h> /* ssize_t */
2974 +#include <string.h> /* strerror() */
2975 +#include <stdarg.h> /* va_list, va_start, va_end */
2976 +#include <errno.h> /* errno */
2977 +#include <assert.h> /* assert() */
2978 +#include <linux/if_ether.h> /* ETH_P_IP */
2979 +#include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
2980 +//#include <pthread.h> /* pthread_t, pthread_create() */
2981 +#include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
2982 +#include <netinet/ip.h> /* struct ip */
2983 +#include <netinet/udp.h> /* struct udphdr */
2984 +#include <unistd.h> /* close() */
2985 +
2986 +#include <netinet/in.h>
2987 +#include <netinet/ip6.h>
2988 +
2989 +/* OLSRD includes */
2990 +#include "plugin_util.h" /* set_plugin_int */
2991 +#include "defs.h" /* olsr_cnf, OLSR_PRINTF */
2992 +#include "ipcalc.h"
2993 +#include "olsr.h" /* OLSR_PRINTF */
2994 +#include "mid_set.h" /* mid_lookup_main_addr() */
2995 +#include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
2996 +#include "link_set.h" /* get_best_link_to_neighbor() */
2997 +#include "net_olsr.h" /* ipequal */
2998 +
2999 +/* plugin includes */
3000 +#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
3001 +#include "Address.h" /* IsMulticast() */
3002 +#include "Packet.h" /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
3003 +#include "PacketHistory.h" /* InitPacketHistory() */
3004 +
3005 +//static pthread_t mdnsThread;
3006 +//static int mdnsThreadRunning = 0;
3007 +
3008 +/* -------------------------------------------------------------------------
3009 + * Function   : PacketReceivedFromOLSR
3010 + * Description: Handle a received packet from a OLSR message
3011 + * Input      : ipPacket into an unsigned char and the lenght of the packet
3012 + * Output     : none
3013 + * Return     : none
3014 + * Data Used  : BmfInterfaces
3015 + * ------------------------------------------------------------------------- */
3016 +static void PacketReceivedFromOLSR(
3017 +  unsigned char* encapsulationUdpData, int len)
3018 +{
3019 +  struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
3020 +  union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
3021 +  union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
3022 +  struct TBmfInterface* walker;
3023 +  ipHeader = (struct ip*) encapsulationUdpData;
3024 +  mcSrc.v4 = ipHeader->ip_src;
3025 +  mcDst.v4 = ipHeader->ip_dst;
3026 +
3027 +  OLSR_PRINTF(3, "MDNS PLUGIN got packet from OLSR message\n");
3028 +
3029 +
3030 +  /* Check with each network interface what needs to be done on it */
3031 +  for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3032 +  {
3033 +    /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
3034 +    if (walker->olsrIntf == NULL)
3035 +    {
3036 +      int nBytesWritten;
3037 +      struct sockaddr_ll dest;
3038 +
3039 +      memset(&dest, 0, sizeof(dest));
3040 +      dest.sll_family = AF_PACKET;
3041 +      if ((encapsulationUdpData[0] & 0xf0) == 0x40) dest.sll_protocol = htons(ETH_P_IP);
3042 +      if ((encapsulationUdpData[0] & 0xf0) == 0x60) dest.sll_protocol = htons(ETH_P_IPV6);
3043 +      //TODO: if packet is not IP die here
3044 +      dest.sll_ifindex = if_nametoindex(walker->ifName);
3045 +      dest.sll_halen = IFHWADDRLEN;
3046 +
3047 +      /* Use all-ones as destination MAC address. When the IP destination is
3048 +       * a multicast address, the destination MAC address should normally also
3049 +       * be a multicast address. E.g., when the destination IP is 224.0.0.1,
3050 +       * the destination MAC should be 01:00:5e:00:00:01. However, it does not
3051 +       * seem to matter when the destination MAC address is set to all-ones
3052 +       * in that case. */
3053 +      memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
3054 +
3055 +      nBytesWritten = sendto(
3056 +        walker->capturingSkfd,
3057 +        encapsulationUdpData,
3058 +        len,
3059 +        0,
3060 +        (struct sockaddr*) &dest,
3061 +        sizeof(dest));
3062 +      if (nBytesWritten != len)
3063 +      {
3064 +        BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
3065 +      }
3066 +      else
3067 +      {
3068 +
3069 +        OLSR_PRINTF(
3070 +          2,
3071 +          "%s: --> unpacked and forwarded on \"%s\"\n",
3072 +          PLUGIN_NAME_SHORT,
3073 +          walker->ifName);
3074 +     }
3075 +    } /* if (walker->olsrIntf == NULL) */
3076 +} 
3077 +} /* PacketReceivedFromOLSR */
3078 +
3079 +
3080 +
3081 +bool
3082 +olsr_parser(union olsr_message *m,
3083 +            struct interface *in_if __attribute__((unused)),
3084 +            union olsr_ip_addr *ipaddr)
3085 +{
3086 +        union olsr_ip_addr originator;
3087 +        int size;
3088 +        olsr_reltime vtime;
3089 +        OLSR_PRINTF(2, "MDNS PLUGIN: Received msg in parser\n");
3090 +        /* Fetch the originator of the messsage */
3091 +        if(olsr_cnf->ip_version == AF_INET) {
3092 +                memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
3093 +               vtime = me_to_reltime(m->v4.olsr_vtime);
3094 +                size = ntohs(m->v4.olsr_msgsize);
3095 +        } else {
3096 +                memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
3097 +               vtime = me_to_reltime(m->v6.olsr_vtime);
3098 +               size = ntohs(m->v6.olsr_msgsize);
3099 +        }    
3100 +
3101 +        /* Check if message originated from this node.
3102 + *         If so - back off */
3103 +        if(ipequal(&originator, &olsr_cnf->main_addr))
3104 +                return false;
3105 +
3106 +        /* Check that the neighbor this message was received from is symmetric.
3107 + *         If not - back off*/
3108 +        if(check_neighbor_link(ipaddr) != SYM_LINK) {
3109 +                struct ipaddr_str strbuf;
3110 +                OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(&strbuf, ipaddr));
3111 +                return false;
3112 +        }    
3113 +       
3114 +        if(olsr_cnf->ip_version == AF_INET){
3115 +       PacketReceivedFromOLSR((unsigned char*) &m->v4.message,size-12);
3116 +       }
3117 +       else {
3118 +       PacketReceivedFromOLSR((unsigned char*) &m->v6.message,size-12-96);
3119 +       }
3120 +        /* Forward the message */
3121 +        return 1;
3122 +}
3123 +
3124 +//Sends a packet in the OLSR network
3125 +void
3126 +olsr_mdns_gen(unsigned char* packet, int len)
3127 +{
3128 +        /* send buffer: huge */
3129 +        char buffer[10240];
3130 +        union olsr_message *message = (union olsr_message *)buffer;
3131 +        struct interface *ifn;
3132 +        //int namesize;
3133 +
3134 +        /* fill message */
3135 +        if(olsr_cnf->ip_version == AF_INET)
3136 +        {    
3137 +                /* IPv4 */
3138 +                message->v4.olsr_msgtype = MESSAGE_TYPE;
3139 +                message->v4.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
3140 +                memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
3141 +                message->v4.ttl = MAX_TTL;
3142 +                message->v4.hopcnt = 0; 
3143 +                message->v4.seqno = htons(get_msg_seqno());
3144 +
3145 +                message->v4.olsr_msgsize = htons(len+12);
3146 +
3147 +               memcpy(&message->v4.message,packet,len);
3148 +                len=len+12;
3149 +        }    
3150 +        else 
3151 +        {    
3152 +                /* IPv6 */
3153 +                message->v6.olsr_msgtype = MESSAGE_TYPE;
3154 +                message->v6.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
3155 +                memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
3156 +                message->v6.ttl = MAX_TTL;
3157 +                message->v6.hopcnt = 0; 
3158 +                message->v6.seqno = htons(get_msg_seqno());
3159 +
3160 +                message->v6.olsr_msgsize = htons(len+12+96);
3161 +               memcpy(&message->v6.message,packet,len);
3162 +                len=len+12+96;
3163 +        }    
3164 +
3165 +        /* looping trough interfaces */
3166 +               for (ifn = ifnet; ifn; ifn = ifn->int_next) {
3167 +                OLSR_PRINTF(1, "MDNS PLUGIN: Generating packet - [%s]\n", ifn->int_name);
3168 +
3169 +                if(net_outbuffer_push(ifn, message, len) != len) {
3170 +                        /* send data and try again */
3171 +                        net_output(ifn);
3172 +                        if(net_outbuffer_push(ifn, message, len) != len) {
3173 +                                OLSR_PRINTF(1, "MDNS PLUGIN: could not send on interface: %s\n", ifn->int_name);
3174 +                        }    
3175 +                }    
3176 +        } 
3177 +}
3178 +
3179 +/* -------------------------------------------------------------------------
3180 + * Function   : BmfPError
3181 + * Description: Prints an error message at OLSR debug level 1.
3182 + *              First the plug-in name is printed. Then (if format is not NULL
3183 + *              and *format is not empty) the arguments are printed, followed
3184 + *              by a colon and a blank. Then the message and a new-line.
3185 + * Input      : format, arguments
3186 + * Output     : none
3187 + * Return     : none
3188 + * Data Used  : none
3189 + * ------------------------------------------------------------------------- */
3190 +
3191 +void BmfPError(const char* format, ...)
3192 +{
3193 +#define MAX_STR_DESC 255
3194 +#ifndef NODEBUG
3195 +  char* strErr = strerror(errno);
3196 +#endif
3197 +  char strDesc[MAX_STR_DESC];
3198 +
3199 +  /* Rely on short-circuit boolean evaluation */
3200 +  if (format == NULL || *format == '\0')
3201 +  {
3202 +    OLSR_PRINTF(1, "%s: %s\n", PLUGIN_NAME, strErr);
3203 +  }
3204 +  else
3205 +  {
3206 +    va_list arglist;
3207 +
3208 +    OLSR_PRINTF(1, "%s: ", PLUGIN_NAME);
3209 +
3210 +    va_start(arglist, format);
3211 +    vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
3212 +    va_end(arglist);
3213 +
3214 +    strDesc[MAX_STR_DESC - 1] = '\0'; /* Ensures null termination */
3215 +
3216 +    OLSR_PRINTF(1, "%s: %s\n", strDesc, strErr);
3217 +  }
3218 +} /* BmfPError */
3219 +
3220 +/* -------------------------------------------------------------------------
3221 + * Function   : MainAddressOf
3222 + * Description: Lookup the main address of a node
3223 + * Input      : ip - IP address of the node
3224 + * Output     : none
3225 + * Return     : The main IP address of the node
3226 + * Data Used  : none
3227 + * ------------------------------------------------------------------------- */
3228 +union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip)
3229 +{
3230 +  union olsr_ip_addr* result;
3231 +
3232 +  /* TODO: mid_lookup_main_addr() is not thread-safe! */
3233 +  result = mid_lookup_main_addr(ip);
3234 +  if (result == NULL)
3235 +  {
3236 +    result = ip;
3237 +  }
3238 +  return result;
3239 +} /* MainAddressOf */
3240 +
3241 +/* -------------------------------------------------------------------------
3242 + * Function   : EncapsulateAndForwardPacket
3243 + * Description: Encapsulate a captured raw IP packet and forward it
3244 + * Input      : intf - the network interface on which to forward the packet
3245 + *              encapsulationUdpData - The encapsulation header, followed by
3246 + *                the encapsulated IP packet
3247 + * Output     : none
3248 + * Return     : none
3249 + * Data Used  : none
3250 + * ------------------------------------------------------------------------- */
3251 +//static void EncapsulateAndForwardPacket(
3252 +//  struct TBmfInterface* intf,
3253 +//  unsigned char* encapsulationUdpData)
3254 +//{
3255 +////  /* The packet */
3256 +//  u_int16_t udpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
3257 +//
3258 +//  /* The next destination(s) */
3259 +//  struct TBestNeighbors bestNeighborLinks;
3260 +//  struct link_entry* bestNeighbor;
3261 +//
3262 +//  int nPossibleNeighbors = 0;
3263 +//  struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
3264 +//  int nPacketsToSend;
3265 +//  int sendUnicast; /* 0 = send broadcast; 1 = send unicast */
3266 +//
3267 +//  int i;
3268 +//
3269 +//  /* Find at most 'FanOutLimit' best neigbors to forward the packet to */
3270 +//  FindNeighbors(&bestNeighborLinks, &bestNeighbor, intf, NULL, NULL, NULL, &nPossibleNeighbors);
3271 +//
3272 +//  if (nPossibleNeighbors <= 0)
3273 +//  {
3274 +//    OLSR_PRINTF(
3275 +//      8,
3276 +//      "%s: --> not encap-forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
3277 +//      PLUGIN_NAME_SHORT,
3278 +//      intf->ifName);
3279 +//    return;
3280 +//  }
3281 +//
3282 +//  /* Compose destination of encapsulation packet */
3283 +//
3284 +//  memset(&forwardTo, 0, sizeof(forwardTo));
3285 +//  forwardTo.sin_family = AF_INET;
3286 +//  forwardTo.sin_port = htons(BMF_ENCAP_PORT);
3287 +//
3288 +//  /* Start by filling in the local broadcast address. This may be overwritten later. */
3289 +//  forwardTo.sin_addr = intf->broadAddr.v4;
3290 +//
3291 +//  /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
3292 +//   *   unicast packet (to the best neighbor).
3293 +//   * - But if the BMF mechanism is BM_BROADCAST,
3294 +//   *   - send 'nPossibleNeighbors' unicast packets if there are up to
3295 +//   *     'FanOutLimit' possible neighbors,
3296 +//   *   - if there are more than 'FanOutLimit' possible neighbors, then
3297 +//   *     send a (WLAN-air-expensive, less reliable) broadcast packet. */
3298 +//  if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
3299 +//  {
3300 +//    /* One unicast packet to the best neighbor */
3301 +//    nPacketsToSend = 1;
3302 +//    sendUnicast = 1;
3303 +//    bestNeighborLinks.links[0] = bestNeighbor;
3304 +//  }
3305 +//  else /* BmfMechanism == BM_BROADCAST */
3306 +//  {
3307 +//    if (nPossibleNeighbors <= FanOutLimit)
3308 +//    {
3309 +//      /* 'nPossibleNeighbors' unicast packets */
3310 +//      nPacketsToSend = nPossibleNeighbors;
3311 +//      sendUnicast = 1;
3312 +//    }
3313 +//    else /* nPossibleNeighbors > FanOutLimit */
3314 +//    {
3315 +//      /* One broadcast packet, possibly retransmitted as specified in the
3316 +//       * 'BroadcastRetransmitCount' plugin parameter */
3317 +//      nPacketsToSend = BroadcastRetransmitCount;
3318 +//      sendUnicast = 0;
3319 +//    } /* if */
3320 +//  } /* if */
3321 +//
3322 +//  for (i = 0; i < nPacketsToSend; i++)
3323 +//  {
3324 +//    int nBytesWritten;
3325 +//
3326 +//    if (sendUnicast == 1)
3327 +//    {
3328 +//      /* For unicast, overwrite the local broadcast address which was filled in above */
3329 +//      forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
3330 +//    }
3331 +//
3332 +//    /* Forward the BMF packet via the encapsulation socket */
3333 +//    nBytesWritten = sendto(
3334 +//      intf->encapsulatingSkfd,
3335 +//      encapsulationUdpData,
3336 +//      udpDataLen,
3337 +//      MSG_DONTROUTE,
3338 +//      (struct sockaddr*) &forwardTo,
3339 +//      sizeof(forwardTo));
3340 +//
3341 +//    /* Evaluate and display result */
3342 +//    if (nBytesWritten != udpDataLen)
3343 +//    {
3344 +//      BmfPError("sendto() error forwarding pkt on \"%s\"", intf->ifName);
3345 +//    }
3346 +//    else
3347 +//    {
3348 +//      /* Increase counter */
3349 +//      intf->nBmfPacketsTx++;
3350 +//
3351 +//      OLSR_PRINTF(
3352 +//        8,
3353 +//        "%s: --> encapsulated and forwarded on \"%s\" to %s\n",
3354 +//        PLUGIN_NAME_SHORT,
3355 +//        intf->ifName,
3356 +//        inet_ntoa(forwardTo.sin_addr));
3357 +//    } /* if (nBytesWritten != udpDataLen) */
3358 +//  } /* for */
3359 +//} /* EncapsulateAndForwardPacket */
3360 +
3361 +/* -------------------------------------------------------------------------
3362 + * Function   : BmfPacketCaptured
3363 + * Description: Handle a captured IP packet
3364 + * Input      : intf - the network interface on which the packet was captured
3365 + *              sllPkttype - the type of packet. Either PACKET_OUTGOING,
3366 + *                PACKET_BROADCAST or PACKET_MULTICAST.
3367 + *              encapsulationUdpData - space for the encapsulation header, followed by
3368 + *                the captured IP packet
3369 + * Output     : none
3370 + * Return     : none
3371 + * Data Used  : BmfInterfaces
3372 + * Notes      : The IP packet is assumed to be captured on a socket of family
3373 + *              PF_PACKET and type SOCK_DGRAM (cooked).
3374 + * ------------------------------------------------------------------------- */
3375 +static void BmfPacketCaptured(
3376 +  //struct TBmfInterface* intf,
3377 +  //unsigned char sllPkttype,
3378 +  unsigned char* encapsulationUdpData,
3379 +  int nBytes)
3380 +{
3381 +  union olsr_ip_addr src; /* Source IP address in captured packet */
3382 +  union olsr_ip_addr dst; /* Destination IP address in captured packet */
3383 +  union olsr_ip_addr* origIp; /* Main OLSR address of source of captured packet */
3384 +  //struct TBmfInterface* walker;
3385 +  //int isFromOlsrIntf;
3386 +  //int isFromOlsrNeighbor;
3387 +  //int iAmMpr;
3388 +  //unsigned char* ipPacket; /* The captured IP packet... */
3389 +  //u_int16_t ipPacketLen; /* ...and its length */
3390 +  struct ip* ipHeader; /* The IP header inside the captured IP packet */
3391 +  struct ip6_hdr* ipHeader6; /* The IP header inside the captured IP packet */
3392 +  //u_int32_t crc32;
3393 +  //struct TEncapHeader* encapHdr;
3394 +  //struct ipaddr_str srcBuf, dstBuf;
3395 +  struct udphdr* udpHeader;
3396 +  u_int16_t destPort;
3397 +  
3398 +  if ((encapsulationUdpData[0] & 0xf0) == 0x40) { //IPV4
3399 +
3400 +            ipHeader = (struct ip*) encapsulationUdpData;
3401 +
3402 +            dst.v4 = ipHeader->ip_dst;
3403 +
3404 +            /* Only forward multicast packets. If configured, also forward local broadcast packets */
3405 +            if (IsMulticast(&dst))
3406 +            {
3407 +              /* continue */
3408 +            }
3409 +            else
3410 +            {
3411 +              return;
3412 +            }
3413 +            if (ipHeader->ip_p != SOL_UDP)
3414 +            {
3415 +              /* Not UDP */
3416 +              OLSR_PRINTF(1,"NON UDP PACKET\n");
3417 +              return; /* for */
3418 +            }
3419 +            udpHeader = (struct udphdr*)(encapsulationUdpData + GetIpHeaderLength(encapsulationUdpData));
3420 +            destPort = ntohs(udpHeader->dest);
3421 +            if (destPort != 5353)
3422 +            {
3423 +               return; 
3424 +            }
3425 +  }//END IPV4
3426 +
3427 +  else if ((encapsulationUdpData[0] & 0xf0) == 0x60) { //IPv6
3428 +  
3429 +            ipHeader6 = (struct ip6_hdr*) encapsulationUdpData;
3430 +            if (ipHeader6->ip6_dst.s6_addr[0] == 0xff) //Multicast
3431 +            {
3432 +              //Continua
3433 +            }
3434 +            else
3435 +            {
3436 +            return; //not multicast
3437 +            }
3438 +            if (ipHeader6->ip6_nxt != SOL_UDP)
3439 +            {
3440 +              /* Not UDP */
3441 +              OLSR_PRINTF(1,"NON UDP PACKET\n");
3442 +              return; /* for */
3443 +            }
3444 +            udpHeader = (struct udphdr*)(encapsulationUdpData + 40);
3445 +            destPort = ntohs(udpHeader->dest);
3446 +            if (destPort != 5353)
3447 +            {
3448 +               return; 
3449 +            }
3450 +  } //END IPV6
3451 +  else return; //Is not IP packet
3452 +
3453 +  /* Check if the frame is captured on an OLSR-enabled interface */
3454 +  //isFromOlsrIntf = (intf->olsrIntf != NULL); TODO: put again this check
3455 +
3456 +  /* Retrieve the length of the captured packet */
3457 +  //ipPacketLen = GetIpTotalLength(ipPacket);
3458 +
3459 +  //src.v4 = ipHeader->ip_src;
3460 +
3461 +  //OLSR_PRINTF(
3462 +  //  1,
3463 +  //  "%s: %s pkt of %ld bytes captured on %s interface \"%s\": %s->%s\n",
3464 +  //  PLUGIN_NAME_SHORT,
3465 +  //  sllPkttype == PACKET_OUTGOING ? "outgoing" : "incoming",
3466 +  //  (long)ipPacketLen,
3467 +  //  isFromOlsrIntf ? "OLSR" : "non-OLSR",
3468 +  //  intf->ifName,
3469 +  //  olsr_ip_to_string(&srcBuf, &src),
3470 +  //  olsr_ip_to_string(&dstBuf, &dst));
3471 +
3472 +  /* Lookup main address of source in the MID table of OLSR */
3473 +  origIp = MainAddressOf(&src);
3474 +
3475 +  // send the packet to OLSR forward mechanism
3476 +  olsr_mdns_gen(encapsulationUdpData,nBytes);
3477 +} /* BmfPacketCaptured */
3478 +
3479 +
3480 +/* -------------------------------------------------------------------------
3481 + * Function   : BmfEncapsulationPacketReceived
3482 + * Description: Handle a received BMF-encapsulation packet
3483 + * Input      : intf - the network interface on which the packet was received
3484 + *              forwardedBy - the IP node that forwarded the packet to me
3485 + *              forwardedTo - the destination IP address of the encapsulation
3486 + *                packet, in case the packet was received promiscuously.
3487 + *                Pass NULL if the packet is received normally (unicast or
3488 + *                broadcast).
3489 + *              encapsulationUdpData - the encapsulating IP UDP data, containting
3490 + *                the BMF encapsulation header, followed by the encapsulated
3491 + *                IP packet
3492 + * Output     : none
3493 + * Return     : none
3494 + * Data Used  : BmfInterfaces
3495 + * ------------------------------------------------------------------------- */
3496 +//static void BmfEncapsulationPacketReceived(
3497 +//  struct TBmfInterface* intf,
3498 +//  union olsr_ip_addr* forwardedBy,
3499 +//  union olsr_ip_addr* forwardedTo,
3500 +//  unsigned char* encapsulationUdpData)
3501 +//{
3502 +//  int iAmMpr; /* True (1) if I am selected as MPR by 'forwardedBy' */
3503 +//  struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
3504 +//  unsigned char* ipPacket; /* The encapsulated IP packet */
3505 +//  u_int16_t ipPacketLen; /* Length of the encapsulated IP packet */
3506 +//  struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
3507 +//  union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
3508 +//  union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
3509 +//  struct TEncapHeader* encapsulationHdr;
3510 +//  u_int16_t encapsulationUdpDataLen;
3511 +//  struct TBmfInterface* walker;
3512 +//  struct ipaddr_str mcSrcBuf, mcDstBuf, forwardedByBuf, forwardedToBuf;
3513 +//  /* Are we talking to ourselves? */
3514 +//  if (if_ifwithaddr(forwardedBy) != NULL)
3515 +//  {
3516 +//    return;
3517 +//  }
3518 +//
3519 +//  /* Discard encapsulated packets received on a non-OLSR interface */
3520 +//  if (intf->olsrIntf == NULL)
3521 +//  {
3522 +//    return;
3523 +//  }
3524 +//
3525 +//  /* Retrieve details about the encapsulated IP packet */
3526 +//  ipPacket = GetIpPacket(encapsulationUdpData);
3527 +//  ipPacketLen = GetIpTotalLength(ipPacket);
3528 +//  ipHeader = GetIpHeader(encapsulationUdpData);
3529 +//
3530 +//  mcSrc.v4 = ipHeader->ip_src;
3531 +//  mcDst.v4 = ipHeader->ip_dst;
3532 +//
3533 +//  /* Increase counter */
3534 +//  intf->nBmfPacketsRx++;
3535 +//
3536 +//  /* Beware: not possible to call olsr_ip_to_string more than 4 times in same printf */
3537 +//  OLSR_PRINTF(
3538 +//    8,
3539 +//    "%s: encapsulated pkt of %ld bytes incoming on \"%s\": %s->%s, forwarded by %s to %s\n",
3540 +//    PLUGIN_NAME_SHORT,
3541 +//    (long)ipPacketLen,
3542 +//    intf->ifName,
3543 +//    olsr_ip_to_string(&mcSrcBuf, &mcSrc),
3544 +//    olsr_ip_to_string(&mcDstBuf, &mcDst),
3545 +//    olsr_ip_to_string(&forwardedByBuf, forwardedBy),
3546 +//    forwardedTo != NULL ? olsr_ip_to_string(&forwardedToBuf, forwardedTo) : "me");
3547 +//
3548 +//  /* Get encapsulation header */
3549 +//  encapsulationHdr = (struct TEncapHeader*) encapsulationUdpData;
3550 +//
3551 +//  /* Verify correct format of BMF encapsulation header */
3552 +//  if (encapsulationHdr->type != BMF_ENCAP_TYPE ||
3553 +//      encapsulationHdr->len != BMF_ENCAP_LEN ||
3554 +//      ntohs(encapsulationHdr->reserved != 0))
3555 +//  {
3556 +//    OLSR_PRINTF(
3557 +//      8,
3558 +//      "%s: --> discarding: format of BMF encapsulation header not recognized\n",
3559 +//      PLUGIN_NAME_SHORT);
3560 +//    return;
3561 +//  }
3562 +//
3563 +//  /* Check if this packet was seen recently */
3564 +//  if (CheckAndMarkRecentPacket(ntohl(encapsulationHdr->crc32)))
3565 +//  {
3566 +//    /* Increase counter */
3567 +//    intf->nBmfPacketsRxDup++;
3568 +//
3569 +//    OLSR_PRINTF(
3570 +//      8,
3571 +//      "%s: --> discarding: packet is duplicate\n",
3572 +//      PLUGIN_NAME_SHORT);
3573 +//    return;
3574 +//  }
3575 +//
3576 +//  if (EtherTunTapFd >= 0)
3577 +//  {
3578 +//    /* Unpack the encapsulated IP packet and deliver it locally, by sending
3579 +//     * a copy into the local IP stack via the EtherTunTap interface */
3580 +//
3581 +//    union olsr_ip_addr broadAddr;
3582 +//    int nBytesToWrite, nBytesWritten;
3583 +//    unsigned char* bufferToWrite;
3584 +//
3585 +//    /* If the encapsulated IP packet is a local broadcast packet,
3586 +//     * update its destination address to match the subnet of the EtherTunTap
3587 +//     * interface */
3588 +//    broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
3589 +//    CheckAndUpdateLocalBroadcast(ipPacket, &broadAddr);
3590 +//
3591 +//    bufferToWrite = ipPacket;
3592 +//    nBytesToWrite = ipPacketLen;
3593 +//
3594 +//    /* Write the packet into the EtherTunTap interface for local delivery */
3595 +//    nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);
3596 +//    if (nBytesWritten != nBytesToWrite)
3597 +//    {
3598 +//      BmfPError("write() error forwarding encapsulated pkt on \"%s\"", EtherTunTapIfName);
3599 +//    }
3600 +//    else
3601 +//    {
3602 +//      OLSR_PRINTF(
3603 +//        8,
3604 +//        "%s: --> unpacked and delivered locally on \"%s\"\n",
3605 +//        PLUGIN_NAME_SHORT,
3606 +//        EtherTunTapIfName);
3607 +//    }
3608 +//  } /* if (EtherTunTapFd >= 0) */
3609 +//
3610 +//  /* Check if I am MPR for the forwarder */
3611 +//  /* TODO: olsr_lookup_mprs_set() is not thread-safe! */
3612 +//  iAmMpr = (olsr_lookup_mprs_set(MainAddressOf(forwardedBy)) != NULL);
3613 +//
3614 +//  /* Compose destination address for next hop */
3615 +//  memset(&forwardTo, 0, sizeof(forwardTo));
3616 +//  forwardTo.sin_family = AF_INET;
3617 +//  forwardTo.sin_port = htons(BMF_ENCAP_PORT);
3618 +//
3619 +//  /* Retrieve the number of bytes to be forwarded via the encapsulation socket */
3620 +//  encapsulationUdpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
3621 +//
3622 +//  /* Check with each network interface what needs to be done on it */
3623 +//  for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3624 +//  {
3625 +//    /* What to do with the packet on a non-OLSR interface? Unpack
3626 +//     * encapsulated packet, and forward it.
3627 +//     *
3628 +//     * What to do with the packet on an OLSR interface? Forward it only
3629 +//     * if the forwarding node has selected us as MPR (iAmMpr).
3630 +//     *
3631 +//     * Note that the packet is always coming in on an OLSR interface, because
3632 +//     * it is an encapsulated BMF packet. */
3633 +//
3634 +//    /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
3635 +//    if (walker->olsrIntf == NULL)
3636 +//    {
3637 +//      int nBytesWritten;
3638 +//      struct sockaddr_ll dest;
3639 +//
3640 +//      /* If the encapsulated IP packet is a local broadcast packet,
3641 +//       * update its destination address to match the subnet of the network
3642 +//       * interface on which the packet is being sent. */
3643 +//      CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
3644 +//
3645 +//      memset(&dest, 0, sizeof(dest));
3646 +//      dest.sll_family = AF_PACKET;
3647 +//      dest.sll_protocol = htons(ETH_P_IP);
3648 +//      dest.sll_ifindex = if_nametoindex(walker->ifName);
3649 +//      dest.sll_halen = IFHWADDRLEN;
3650 +//
3651 +//      /* Use all-ones as destination MAC address. When the IP destination is
3652 +//       * a multicast address, the destination MAC address should normally also
3653 +//       * be a multicast address. E.g., when the destination IP is 224.0.0.1,
3654 +//       * the destination MAC should be 01:00:5e:00:00:01. However, it does not
3655 +//       * seem to matter when the destination MAC address is set to all-ones
3656 +//       * in that case. */
3657 +//      memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
3658 +//
3659 +//      nBytesWritten = sendto(
3660 +//        walker->capturingSkfd,
3661 +//        ipPacket,
3662 +//        ipPacketLen,
3663 +//        0,
3664 +//        (struct sockaddr*) &dest,
3665 +//        sizeof(dest));
3666 +//      if (nBytesWritten != ipPacketLen)
3667 +//      {
3668 +//        BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
3669 +//      }
3670 +//      else
3671 +//      {
3672 +//        /* Increase counter */
3673 +//        walker->nBmfPacketsTx++;
3674 +//
3675 +//        OLSR_PRINTF(
3676 +//          8,
3677 +//          "%s: --> unpacked and forwarded on \"%s\"\n",
3678 +//          PLUGIN_NAME_SHORT,
3679 +//          walker->ifName);
3680 +//      }
3681 +//    } /* if (walker->olsrIntf == NULL) */
3682 +//
3683 +//    /* To an OLSR interface: forward the packet, but only if this node is
3684 +//     * selected as MPR by the forwarding node */
3685 +//    else if (iAmMpr)
3686 +//    {
3687 +//      struct TBestNeighbors bestNeighborLinks;
3688 +//      struct link_entry* bestNeighbor;
3689 +//      int nPossibleNeighbors;
3690 +//      int nPacketsToSend;
3691 +//      int sendUnicast; /* 0 = send broadcast; 1 = send unicast */
3692 +//      int i;
3693 +//
3694 +//      /* Retrieve at most two best neigbors to forward the packet to */
3695 +//      FindNeighbors(
3696 +//        &bestNeighborLinks,
3697 +//        &bestNeighbor,
3698 +//        walker,
3699 +//        &mcSrc,
3700 +//        forwardedBy,
3701 +//        forwardedTo,
3702 +//        &nPossibleNeighbors);
3703 +//
3704 +//      if (nPossibleNeighbors <= 0)
3705 +//      {
3706 +//        OLSR_PRINTF(
3707 +//          8,
3708 +//          "%s: --> not forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
3709 +//          PLUGIN_NAME_SHORT,
3710 +//          walker->ifName);
3711 +//
3712 +//        continue; /* for */
3713 +//      }
3714 +//
3715 +//      /* Compose destination of encapsulation packet.
3716 +//       * Start by filling in the local broadcast address. This may be overwritten later. */
3717 +//      forwardTo.sin_addr = walker->broadAddr.v4;
3718 +//
3719 +//      /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
3720 +//       *   unicast packet (to the best neighbor).
3721 +//       * - But if the BMF mechanism is BM_BROADCAST,
3722 +//       *   - send 'nPossibleNeighbors' unicast packets if there are up to
3723 +//       *     'FanOutLimit' possible neighbors,
3724 +//       *   - if there are more than 'FanOutLimit' possible neighbors, then
3725 +//       *     send a (WLAN-air-expensive, less reliable) broadcast packet. */
3726 +//      if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
3727 +//      {
3728 +//        /* One unicast packet to the best neighbor */
3729 +//        nPacketsToSend = 1;
3730 +//        sendUnicast = 1;
3731 +//        bestNeighborLinks.links[0] = bestNeighbor;
3732 +//      }
3733 +//      else /* BmfMechanism == BM_BROADCAST */
3734 +//      {
3735 +//        if (nPossibleNeighbors <= FanOutLimit)
3736 +//        {
3737 +//          /* 'nPossibleNeighbors' unicast packets */
3738 +//          nPacketsToSend = nPossibleNeighbors;
3739 +//          sendUnicast = 1;
3740 +//        }
3741 +//        else /* nPossibleNeighbors > FanOutLimit */
3742 +//        {
3743 +//          /* One broadcast packet, possibly retransmitted as specified in the
3744 +//           * 'BroadcastRetransmitCount' plugin parameter */
3745 +//          nPacketsToSend = BroadcastRetransmitCount;
3746 +//          sendUnicast = 0;
3747 +//        } /* if */
3748 +//      } /* if */
3749 +//
3750 +//      for (i = 0; i < nPacketsToSend; i++)
3751 +//      {
3752 +//        int nBytesWritten;
3753 +//
3754 +//        if (sendUnicast)
3755 +//        {
3756 +//          /* For unicast, overwrite the local broadcast address which was filled in above */
3757 +//          forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
3758 +//        }
3759 +//
3760 +//        /* Forward the BMF packet via the encapsulation socket */
3761 +//        nBytesWritten = sendto(
3762 +//          walker->encapsulatingSkfd,
3763 +//          encapsulationUdpData,
3764 +//          encapsulationUdpDataLen,
3765 +//          MSG_DONTROUTE,
3766 +//          (struct sockaddr*) &forwardTo,
3767 +//          sizeof(forwardTo));
3768 +//
3769 +//        /* Evaluate and display result */
3770 +//        if (nBytesWritten != encapsulationUdpDataLen)
3771 +//        {
3772 +//          BmfPError("sendto() error forwarding encapsulated pkt on \"%s\"", walker->ifName);
3773 +//        }
3774 +//        else
3775 +//        {
3776 +//          /* Increase counter */
3777 +//          walker->nBmfPacketsTx++;
3778 +//
3779 +//          OLSR_PRINTF(
3780 +//            8,
3781 +//            "%s: --> forwarded on \"%s\" to %s\n",
3782 +//            PLUGIN_NAME_SHORT,
3783 +//            walker->ifName,
3784 +//            inet_ntoa(forwardTo.sin_addr));
3785 +//        } /* if */
3786 +//      } /* for */
3787 +//    }  /* else if (iAmMpr) */
3788 +//
3789 +//    else /* walker->olsrIntf != NULL && !iAmMpr */
3790 +//    {
3791 +//      struct ipaddr_str buf;
3792 +//      /* 'walker' is an OLSR interface, but I am not selected as MPR. In that
3793 +//       * case, don't forward. */
3794 +//      OLSR_PRINTF(
3795 +//        8,
3796 +//        "%s: --> not forwarding on \"%s\": I am not selected as MPR by %s\n",
3797 +//        PLUGIN_NAME_SHORT,
3798 +//        walker->ifName,
3799 +//        olsr_ip_to_string(&buf, forwardedBy));
3800 +//    } /* else */
3801 +//  } /* for */
3802 +//} /* BmfEncapsulationPacketReceived */
3803 +//
3804 +/* -------------------------------------------------------------------------
3805 + * Function   : BmfTunPacketCaptured
3806 + * Description: Handle an IP packet, captured outgoing on the tuntap interface
3807 + * Input      : encapsulationUdpData - space for the encapsulation header, followed by
3808 + *                the captured outgoing IP packet
3809 + * Output     : none
3810 + * Return     : none
3811 + * Data Used  : none
3812 + * Notes      : The packet is assumed to be captured on a socket of family
3813 + *              PF_PACKET and type SOCK_DGRAM (cooked).
3814 + * ------------------------------------------------------------------------- */
3815 +//static void BmfTunPacketCaptured(unsigned char* encapsulationUdpData)
3816 +//{
3817 +//  union olsr_ip_addr srcIp;
3818 +//  union olsr_ip_addr dstIp;
3819 +//  union olsr_ip_addr broadAddr;
3820 +//  struct TBmfInterface* walker;
3821 +//  unsigned char* ipPacket;
3822 +//  u_int16_t ipPacketLen;
3823 +//  struct ip* ipHeader;
3824 +//  u_int32_t crc32;
3825 +//  struct TEncapHeader* encapHdr;
3826 +//  struct ipaddr_str srcIpBuf, dstIpBuf;
3827 +//  ipPacket = GetIpPacket(encapsulationUdpData);
3828 +//  ipPacketLen = GetIpTotalLength(ipPacket);
3829 +//  ipHeader = GetIpHeader(encapsulationUdpData);
3830 +//
3831 +//  dstIp.v4 = ipHeader->ip_dst;
3832 +//  broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
3833 +//
3834 +//  /* Only forward multicast packets. If configured, also forward local broadcast packets */
3835 +//  if (IsMulticast(&dstIp) ||
3836 +//      (EnableLocalBroadcast != 0 && olsr_ipequal(&dstIp, &broadAddr)))
3837 +//  {
3838 +//    /* continue */
3839 +//  }
3840 +//  else
3841 +//  {
3842 +//    return;
3843 +//  }
3844 +//
3845 +//  srcIp.v4 = ipHeader->ip_src;
3846 +//
3847 +//  OLSR_PRINTF(
3848 +//    8,
3849 +//    "%s: outgoing pkt of %ld bytes captured on tuntap interface \"%s\": %s->%s\n",
3850 +//    PLUGIN_NAME_SHORT,
3851 +//    (long)ipPacketLen,
3852 +//    EtherTunTapIfName,
3853 +//    olsr_ip_to_string(&srcIpBuf, &srcIp),
3854 +//    olsr_ip_to_string(&dstIpBuf, &dstIp));
3855 +//
3856 +//  /* Calculate packet fingerprint */
3857 +//  crc32 = PacketCrc32(ipPacket, ipPacketLen);
3858 +//
3859 +//  /* Check if this packet was seen recently */
3860 +//  if (CheckAndMarkRecentPacket(crc32))
3861 +//  {
3862 +//    OLSR_PRINTF(
3863 +//      8,
3864 +//      "%s: --> discarding: packet is duplicate\n",
3865 +//      PLUGIN_NAME_SHORT);
3866 +//    return;
3867 +//  }
3868 +//
3869 +//  /* Compose encapsulation header */
3870 +//  encapHdr = (struct TEncapHeader*) encapsulationUdpData;
3871 +//  memset (encapHdr, 0, ENCAP_HDR_LEN);
3872 +//  encapHdr->type = BMF_ENCAP_TYPE;
3873 +//  encapHdr->len = BMF_ENCAP_LEN;
3874 +//  encapHdr->reserved = 0;
3875 +//  encapHdr->crc32 = htonl(crc32);
3876 +//
3877 +//  /* Check with each network interface what needs to be done on it */
3878 +//  for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3879 +//  {
3880 +//    /* Is the forwarding interface OLSR-enabled? */
3881 +//    if (walker->olsrIntf != NULL)
3882 +//    {
3883 +//      /* On an OLSR interface: encapsulate and forward packet. */
3884 +//
3885 +//      EncapsulateAndForwardPacket(walker, encapsulationUdpData);
3886 +//    }
3887 +//    else
3888 +//    {
3889 +//      /* On a non-OLSR interface: what to do?
3890 +//       * Answer 1: nothing. Multicast routing between non-OLSR interfaces