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