--- /dev/null
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/Makefile olsrd-0-5-6-ecb9cb41f488/Makefile
+--- olsrd-0-5-6-ecb9cb41f488.orig/Makefile 2009-03-25 13:33:46.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/Makefile 2009-03-25 13:37:04.000000000 +0000
+@@ -148,7 +148,7 @@
+ ifeq ($(OS),win32)
+ SUBDIRS := dot_draw httpinfo mini pgraph secure txtinfo
+ else
+-SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo mini nameservice pgraph secure txtinfo watchdog
++SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo mini nameservice pgraph secure txtinfo watchdog mdns
+ endif
+ endif
+
+@@ -234,6 +234,11 @@
+ $(MAKECMD) -C lib/watchdog
+ $(MAKECMD) -C lib/watchdog DESTDIR=$(DESTDIR) install
+
++mdns:
++ $(MAKECMD) -C lib/mdns clean
++ $(MAKECMD) -C lib/mdns
++ $(MAKECMD) -C lib/mdns DESTDIR=$(DESTDIR) install
++
+ build_all: all switch libs
+ install_all: install install_libs
+ clean_all: uberclean clean_libs
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/Makefile olsrd-0-5-6-ecb9cb41f488/lib/mdns/Makefile
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/Makefile 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/Makefile 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,66 @@
++#
++# OLSR Basic Multicast Forwarding (BMF) plugin.
++# Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
++# Written by Erik Tromp.
++# All rights reserved.
++#
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions
++# are met:
++#
++# * Redistributions of source code must retain the above copyright
++# notice, this list of conditions and the following disclaimer.
++# * Redistributions in binary form must reproduce the above copyright
++# notice, this list of conditions and the following disclaimer in
++# the documentation and/or other materials provided with the
++# distribution.
++# * Neither the name of Thales, BMF nor the names of its
++# contributors may be used to endorse or promote products derived
++# from this software without specific prior written permission.
++#
++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
++# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
++# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
++# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++# POSSIBILITY OF SUCH DAMAGE.
++#
++
++OLSRD_PLUGIN = true
++PLUGIN_NAME = olsrd_mdns
++PLUGIN_VER = 1.0.0
++
++TOPDIR = ../..
++include $(TOPDIR)/Makefile.inc
++
++LIBS += $(OS_LIB_PTHREAD)
++
++# Must be specified along with -lpthread on linux
++CPPFLAGS += $(OS_CFLAG_PTHREAD)
++
++ifneq ($(OS),linux)
++
++default_target install clean:
++ @echo "*** BMF Plugin only supported on Linux, sorry!"
++
++else
++
++default_target: $(PLUGIN_FULLNAME)
++
++$(PLUGIN_FULLNAME): $(OBJS) version-script.txt
++ $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
++
++install: $(PLUGIN_FULLNAME)
++ $(STRIP) $(PLUGIN_FULLNAME)
++ $(INSTALL_LIB)
++
++clean:
++ rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
++
++endif
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Address.c olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Address.c
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Address.c 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Address.c 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,164 @@
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : Address.c
++ * Description: IP packet characterization functions
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++#include "Address.h"
++
++/* System includes */
++#include <stddef.h> /* NULL */
++#include <string.h> /* strcmp */
++#include <assert.h> /* assert() */
++#include <netinet/ip.h> /* struct ip */
++#include <netinet/udp.h> /* struct udphdr */
++
++/* OLSRD includes */
++#include "defs.h" /* ipequal */
++#include "olsr_protocol.h" /* OLSRPORT */
++
++/* Plugin includes */
++#include "mdns.h" /* BMF_ENCAP_PORT */
++#include "NetworkInterfaces.h" /* TBmfInterface */
++
++/* Whether or not to flood local broadcast packets (e.g. packets with IP
++ * destination 192.168.1.255). May be overruled by setting the plugin
++ * parameter "DoLocalBroadcast" to "no" */
++int EnableLocalBroadcast = 1;
++
++/* -------------------------------------------------------------------------
++ * Function : DoLocalBroadcast
++ * Description: Overrule the default setting, enabling or disabling the
++ * flooding of local broadcast packets
++ * Input : enable - either "yes" or "no"
++ * data - not used
++ * addon - not used
++ * Output : none
++ * Return : success (0) or fail (1)
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++int DoLocalBroadcast(
++ const char* enable,
++ void* data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused)))
++{
++ if (strcmp(enable, "yes") == 0)
++ {
++ EnableLocalBroadcast = 1;
++ return 0;
++ }
++ else if (strcmp(enable, "no") == 0)
++ {
++ EnableLocalBroadcast = 0;
++ return 0;
++ }
++
++ /* Value not recognized */
++ return 1;
++}
++
++/* -------------------------------------------------------------------------
++ * Function : IsMulticast
++ * Description: Check if an IP address is a multicast address
++ * Input : ipAddress
++ * Output : none
++ * Return : true (1) or false (0)
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++int IsMulticast(union olsr_ip_addr* ipAddress)
++{
++ assert(ipAddress != NULL);
++
++ return (ntohl(ipAddress->v4.s_addr) & 0xF0000000) == 0xE0000000;
++}
++
++/* -------------------------------------------------------------------------
++ * Function : IsOlsrOrBmfPacket
++ * Description: Check if an IP packet is either an OLSR packet or a BMF packet
++ * Input : ipPacket
++ * Output : none
++ * Return : true (1) or false (0)
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++//int IsOlsrOrBmfPacket(unsigned char* ipPacket)
++//{//MODIFICATA
++// struct ip* ipHeader;
++// unsigned int ipHeaderLen;
++// struct udphdr* udpHeader;
++// u_int16_t destPort;
++//
++// assert(ipPacket != NULL);
++//
++// /* OLSR packets are UDP - port 698
++// * OLSR-BMF packets are UDP - port 50698
++// * OLSR-Autodetect probe packets are UDP - port 51698 */
++//
++// /* Check if UDP */
++// ipHeader = (struct ip*) ipPacket;
++// if (ipHeader->ip_p != SOL_UDP)
++// {
++// /* Not UDP */
++// return 0;
++// }
++//
++// /* The total length must be at least large enough to store the UDP header */
++// ipHeaderLen = GetIpHeaderLength(ipPacket);
++// if (GetIpTotalLength(ipPacket) < ipHeaderLen + sizeof(struct udphdr))
++// {
++// /* Not long enough */
++// return 0;
++// }
++//
++// /* Go into the UDP header and check port number */
++// udpHeader = (struct udphdr*) (ipPacket + ipHeaderLen);
++// destPort = ntohs(udpHeader->dest);
++//
++// //if (destPort == OLSRPORT || destPort == BMF_ENCAP_PORT || destPort == 51698)
++// if (destPort == 5353)
++// /* TODO: #define for 51698 */
++// {
++// return 1;
++// }
++//
++// return 0;
++//}
++//
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Address.h olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Address.h
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Address.h 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Address.h 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,62 @@
++#ifndef _BMF_ADDRESS_H
++#define _BMF_ADDRESS_H
++
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : Address.h
++ * Description: IP packet characterization functions
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++#include "olsr_types.h" /* olsr_ip_addr */
++#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
++#include "interfaces.h" /* struct interface */
++
++struct TBmfInterface;
++
++extern int EnableLocalBroadcast;
++
++int DoLocalBroadcast(const char* enable, void* data, set_plugin_parameter_addon addon);
++int IsMulticast(union olsr_ip_addr* ipAddress);
++int IsOlsrOrBmfPacket(unsigned char* ipPacket);
++
++#endif /* _BMF_ADDRESS_H */
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/NetworkInterfaces.c olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/NetworkInterfaces.c
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/NetworkInterfaces.c 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/NetworkInterfaces.c 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,1703 @@
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : NetworkInterfaces.c
++ * Description: Functions to open and close sockets
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++#include "NetworkInterfaces.h"
++
++/* System includes */
++#include <stddef.h> /* NULL */
++#include <syslog.h> /* syslog() */
++#include <string.h> /* strerror(), strchr(), strcmp() */
++#include <errno.h> /* errno */
++#include <unistd.h> /* close() */
++#include <sys/ioctl.h> /* ioctl() */
++#include <fcntl.h> /* fcntl() */
++#include <assert.h> /* assert() */
++#include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
++#include <netinet/in.h> /* htons() */
++#include <linux/if_ether.h> /* ETH_P_IP */
++#include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
++#include <linux/if_tun.h> /* IFF_TAP */
++#include <netinet/ip.h> /* struct ip */
++#include <netinet/udp.h> /* SOL_UDP */
++#include <stdlib.h> /* atoi, malloc */
++
++/* OLSRD includes */
++#include "olsr.h" /* OLSR_PRINTF() */
++#include "ipcalc.h"
++#include "defs.h" /* olsr_cnf */
++#include "link_set.h" /* get_link_set() */
++#include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
++#include "net_olsr.h" /* ipequal */
++#include "lq_plugin.h"
++
++
++/* Plugin includes */
++#include "Packet.h" /* IFHWADDRLEN */
++#include "mdns.h" /* PLUGIN_NAME, MainAddressOf() */
++#include "Address.h" /* IsMulticast() */
++
++/* List of network interface objects used by BMF plugin */
++struct TBmfInterface* BmfInterfaces = NULL;
++struct TBmfInterface* LastBmfInterface = NULL;
++
++/* Highest-numbered open socket file descriptor. To be used as first
++ * parameter in calls to select(...). */
++int HighestSkfd = -1;
++
++/* Set of socket file descriptors */
++fd_set InputSet;
++
++/* File descriptor of EtherTunTap interface */
++int EtherTunTapFd = -1;
++
++/* Network interface name of EtherTunTap interface. May be overruled by
++ * setting the plugin parameter "BmfInterface". */
++char EtherTunTapIfName[IFNAMSIZ] = "bmf0";
++
++/* The underlying mechanism to forward multicast packets. Either:
++ * - BM_BROADCAST: BMF uses the IP local broadcast as destination address
++ * - BM_UNICAST_PROMISCUOUS: BMF uses the IP address of the best neighbor as
++ * destination address. The other neighbors listen promiscuously. */
++enum TBmfMechanism BmfMechanism = BM_BROADCAST;
++
++#define ETHERTUNTAPIPNOTSET 0
++
++/* The IP address of the BMF network interface in host byte order.
++ * May be overruled by setting the plugin parameter "BmfInterfaceIp". */
++u_int32_t EtherTunTapIp = ETHERTUNTAPIPNOTSET;
++
++/* 255.255.255.255 in host byte order. May be overruled by
++ * setting the plugin parameter "BmfInterfaceIp". */
++u_int32_t EtherTunTapIpMask = 0xFFFFFFFF;
++
++/* The IP broadcast address of the BMF network interface in host byte order.
++ * May be overruled by setting the plugin parameter "BmfinterfaceIp". */
++u_int32_t EtherTunTapIpBroadcast = ETHERTUNTAPIPNOTSET;
++
++/* Whether or not the configuration has overruled the default IP
++ * configuration of the EtherTunTap interface */
++int TunTapIpOverruled = 0;
++
++/* Whether or not to capture packets on the OLSR-enabled
++ * interfaces (in promiscuous mode). May be overruled by setting the plugin
++ * parameter "CapturePacketsOnOlsrInterfaces" to "yes". */
++int CapturePacketsOnOlsrInterfaces = 0;
++
++/* -------------------------------------------------------------------------
++ * Function : SetBmfInterfaceName
++ * Description: Overrule the default network interface name ("bmf0") of the
++ * EtherTunTap interface
++ * Input : ifname - network interface name (e.g. "mybmf0")
++ * data - not used
++ * addon - not used
++ * Output : none
++ * Return : success (0) or fail (1)
++ * Data Used : EtherTunTapIfName
++ * ------------------------------------------------------------------------- */
++int SetBmfInterfaceName(
++ const char* ifname,
++ void* data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused)))
++{
++ strncpy(EtherTunTapIfName, ifname, IFNAMSIZ - 1);
++ EtherTunTapIfName[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++ return 0;
++} /* SetBmfInterfaceName */
++
++/* -------------------------------------------------------------------------
++ * Function : SetBmfInterfaceIp
++ * Description: Overrule the default IP address and prefix length
++ * ("10.255.255.253/30") of the EtherTunTap interface
++ * Input : ip - IP address string, followed by '/' and prefix length
++ * data - not used
++ * addon - not used
++ * Output : none
++ * Return : success (0) or fail (1)
++ * Data Used : EtherTunTapIp, EtherTunTapIpMask, EtherTunTapIpBroadcast,
++ * TunTapIpOverruled
++ * ------------------------------------------------------------------------- */
++int SetBmfInterfaceIp(
++ const char* ip,
++ void* data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused)))
++{
++#define IPV4_MAX_ADDRLEN 16
++#define IPV4_MAX_PREFIXLEN 32
++ char* slashAt;
++ char ipAddr[IPV4_MAX_ADDRLEN];
++ struct in_addr sinaddr;
++ int prefixLen;
++ int i;
++
++ /* Inspired by function str2prefix_ipv4 as found in Quagga source
++ * file lib/prefix.c */
++
++ /* Find slash inside string. */
++ slashAt = strchr(ip, '/');
++
++ /* String doesn't contain slash. */
++ if (slashAt == NULL || slashAt - ip >= IPV4_MAX_ADDRLEN)
++ {
++ /* No prefix length specified, or IP address too long */
++ return 1;
++ }
++
++ strncpy(ipAddr, ip, slashAt - ip);
++ *(ipAddr + (slashAt - ip)) = '\0';
++ if (inet_aton(ipAddr, &sinaddr) == 0)
++ {
++ /* Invalid address passed */
++ return 1;
++ }
++
++ EtherTunTapIp = ntohl(sinaddr.s_addr);
++
++ /* Get prefix length. */
++ prefixLen = atoi(++slashAt);
++ if (prefixLen <= 0 || prefixLen > IPV4_MAX_PREFIXLEN)
++ {
++ return 1;
++ }
++
++ /* Compose IP subnet mask in host byte order */
++ EtherTunTapIpMask = 0;
++ for (i = 0; i < prefixLen; i++)
++ {
++ EtherTunTapIpMask |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
++ }
++
++ /* Compose IP broadcast address in host byte order */
++ EtherTunTapIpBroadcast = EtherTunTapIp;
++ for (i = prefixLen; i < IPV4_MAX_PREFIXLEN; i++)
++ {
++ EtherTunTapIpBroadcast |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
++ }
++
++ TunTapIpOverruled = 1;
++
++ return 0;
++} /* SetBmfInterfaceIp */
++
++/* -------------------------------------------------------------------------
++ * Function : SetCapturePacketsOnOlsrInterfaces
++ * Description: Overrule the default setting, enabling or disabling the
++ * capturing of packets on OLSR-enabled interfaces.
++ * Input : enable - either "yes" or "no"
++ * data - not used
++ * addon - not used
++ * Output : none
++ * Return : success (0) or fail (1)
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++int SetCapturePacketsOnOlsrInterfaces(
++ const char* enable,
++ void* data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused)))
++{
++ if (strcmp(enable, "yes") == 0)
++ {
++ CapturePacketsOnOlsrInterfaces = 1;
++ return 0;
++ }
++ else if (strcmp(enable, "no") == 0)
++ {
++ CapturePacketsOnOlsrInterfaces = 0;
++ return 0;
++ }
++
++ /* Value not recognized */
++ return 1;
++} /* SetCapturePacketsOnOlsrInterfaces */
++
++/* -------------------------------------------------------------------------
++ * Function : SetBmfMechanism
++ * Description: Overrule the default BMF mechanism to either BM_BROADCAST or
++ * BM_UNICAST_PROMISCUOUS.
++ * Input : mechanism - either "Broadcast" or "UnicastPromiscuous"
++ * data - not used
++ * addon - not used
++ * Output : none
++ * Return : success (0) or fail (1)
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++int SetBmfMechanism(
++ const char* mechanism,
++ void* data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused)))
++{
++ if (strcmp(mechanism, "Broadcast") == 0)
++ {
++ BmfMechanism = BM_BROADCAST;
++ return 0;
++ }
++ else if (strcmp(mechanism, "UnicastPromiscuous") == 0)
++ {
++ BmfMechanism = BM_UNICAST_PROMISCUOUS;
++ return 0;
++ }
++
++ /* Value not recognized */
++ return 1;
++} /* SetBmfMechanism */
++
++/* -------------------------------------------------------------------------
++ * Function : AddDescriptorToInputSet
++ * Description: Add a socket descriptor to the global set of socket file descriptors
++ * Input : skfd - socket file descriptor
++ * Output : none
++ * Return : none
++ * Data Used : HighestSkfd, InputSet
++ * Notes : Keeps track of the highest-numbered descriptor
++ * ------------------------------------------------------------------------- */
++static void AddDescriptorToInputSet(int skfd)
++{
++ /* Keep the highest-numbered descriptor */
++ if (skfd > HighestSkfd)
++ {
++ HighestSkfd = skfd;
++ }
++
++ /* Add descriptor to input set */
++ FD_SET(skfd, &InputSet);
++} /* AddDescriptorToInputSet */
++
++/* To save the state of the IP spoof filter for the EtherTunTap interface */
++static char EthTapSpoofState = '1';
++
++/* -------------------------------------------------------------------------
++ * Function : DeactivateSpoofFilter
++ * Description: Deactivates the Linux anti-spoofing filter for the tuntap
++ * interface
++ * Input : none
++ * Output : none
++ * Return : fail (0) or success (1)
++ * Data Used : EtherTunTapIfName, EthTapSpoofState
++ * Notes : Saves the current filter state for later restoring
++ * ------------------------------------------------------------------------- */
++int DeactivateSpoofFilter(void)
++{
++ FILE* procSpoof;
++ char procFile[FILENAME_MAX];
++
++ /* Generate the procfile name */
++ sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
++
++ /* Open procfile for reading */
++ procSpoof = fopen(procFile, "r");
++ if (procSpoof == NULL)
++ {
++ fprintf(
++ stderr,
++ "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
++ "Are you using the procfile filesystem?\n"
++ "Does your system support IPv4?\n"
++ "I will continue (in 3 sec) - but you should manually ensure that IP spoof\n"
++ "filtering is disabled!\n\n",
++ procFile);
++
++ sleep(3);
++ return 0;
++ }
++
++ EthTapSpoofState = fgetc(procSpoof);
++ fclose(procSpoof);
++
++ /* Open procfile for writing */
++ procSpoof = fopen(procFile, "w");
++ if (procSpoof == NULL)
++ {
++ fprintf(stderr, "Could not open %s for writing!\n", procFile);
++ fprintf(
++ stderr,
++ "I will continue (in 3 sec) - but you should manually ensure that IP"
++ " spoof filtering is disabled!\n\n");
++ sleep(3);
++ return 0;
++ }
++
++ syslog(LOG_INFO, "Writing \"0\" to %s", procFile);
++ fputs("0", procSpoof);
++
++ fclose(procSpoof);
++
++ return 1;
++} /* DeactivateSpoofFilter */
++
++/* -------------------------------------------------------------------------
++ * Function : RestoreSpoofFilter
++ * Description: Restores the Linux anti-spoofing filter setting for the tuntap
++ * interface
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : EtherTunTapIfName, EthTapSpoofState
++ * ------------------------------------------------------------------------- */
++void RestoreSpoofFilter(void)
++{
++ FILE* procSpoof;
++ char procFile[FILENAME_MAX];
++
++ /* Generate the procfile name */
++ sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
++
++ /* Open procfile for writing */
++ procSpoof = fopen(procFile, "w");
++ if (procSpoof == NULL)
++ {
++ fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procFile);
++ }
++ else
++ {
++ syslog(LOG_INFO, "Resetting %s to %c\n", procFile, EthTapSpoofState);
++
++ fputc(EthTapSpoofState, procSpoof);
++ fclose(procSpoof);
++ }
++} /* RestoreSpoofFilter */
++
++/* -------------------------------------------------------------------------
++ * Function : FindNeighbors
++ * Description: Find the neighbors on a network interface to forward a BMF
++ * packet to
++ * Input : intf - the network interface
++ * source - the source IP address of the BMF packet
++ * forwardedBy - the IP address of the node that forwarded the BMF
++ * packet
++ * forwardedTo - the IP address of the node to which the BMF packet
++ * was directed
++ * Output : neighbors - list of (up to a number of 'FanOutLimit') neighbors.
++ * bestNeighbor - the best neighbor (in terms of lowest cost or ETX
++ * value)
++ * nPossibleNeighbors - number of found possible neighbors
++ * Data Used : FanOutLimit
++ * ------------------------------------------------------------------------- */
++//void FindNeighbors(
++// struct TBestNeighbors* neighbors,
++// struct link_entry** bestNeighbor,
++// struct TBmfInterface* intf,
++// union olsr_ip_addr* source,
++// union olsr_ip_addr* forwardedBy,
++// union olsr_ip_addr* forwardedTo,
++// int* nPossibleNeighbors)
++//{
++// struct link_entry* walker;
++// olsr_linkcost previousLinkEtx = LINK_COST_BROKEN;
++// olsr_linkcost bestEtx = LINK_COST_BROKEN;
++//
++// int i;
++//
++// /* Initialize */
++// *bestNeighbor = NULL;
++// for (i = 0; i < MAX_UNICAST_NEIGHBORS; i++)
++// {
++// neighbors->links[i] = NULL;
++// }
++// *nPossibleNeighbors = 0;
++//
++// if (forwardedBy != NULL)
++// {
++// /* Retrieve the cost of the link from 'forwardedBy' to myself */
++// struct link_entry* bestLinkFromForwarder = get_best_link_to_neighbor(forwardedBy);
++// if (bestLinkFromForwarder != NULL)
++// {
++// previousLinkEtx = bestLinkFromForwarder->linkcost;
++// }
++// }
++//
++// OLSR_FOR_ALL_LINK_ENTRIES(walker) {
++// struct ipaddr_str buf;
++// union olsr_ip_addr* neighborMainIp;
++// struct link_entry* bestLinkToNeighbor;
++// struct tc_entry* tcLastHop;
++// float currEtx;
++//
++// /* Consider only links from the specified interface */
++// if (! olsr_ipequal(&intf->intAddr, &walker->local_iface_addr))
++// {
++// continue; /* for */
++// }
++//
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
++// PLUGIN_NAME_SHORT,
++// intf->ifName,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
++//
++// neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
++//
++// /* Consider only neighbors with an IP address that differs from the
++// * passed IP addresses (if passed). Rely on short-circuit boolean evaluation. */
++// if (source != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(source)))
++// {
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Not forwarding to %s: is source of pkt\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
++//
++// continue; /* for */
++// }
++//
++// /* Rely on short-circuit boolean evaluation */
++// if (forwardedBy != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
++// {
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
++//
++// continue; /* for */
++// }
++//
++// /* Rely on short-circuit boolean evaluation */
++// if (forwardedTo != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
++// {
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
++//
++// continue; /* for */
++// }
++//
++// /* Found a candidate neighbor to direct our packet to */
++//
++// /* Calculate the link quality (ETX) of the link to the found neighbor */
++// currEtx = walker->linkcost;
++//
++// if (currEtx >= LINK_COST_BROKEN)
++// {
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Not forwarding to %s: link is timing out\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
++//
++// continue; /* for */
++// }
++//
++// /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Forwarding pkt to %s will cost ETX %5.2f\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
++// currEtx);
++//
++// /*
++// * If the candidate neighbor is best reached via another interface, then skip
++// * the candidate neighbor; the candidate neighbor has been / will be selected via that
++// * other interface.
++// */
++// bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
++//
++// if (walker != bestLinkToNeighbor)
++// {
++// if (bestLinkToNeighbor == NULL)
++// {
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Not forwarding to %s: no link found\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
++// }
++// else
++// {
++//#ifndef NODEBUG
++// struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
++// struct lqtextbuffer lqbuffer;
++//#endif
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
++// bestIntf->int_name,
++// get_linkcost_text(bestLinkToNeighbor->linkcost, 0, &lqbuffer));
++// }
++//
++// continue; /* for */
++// }
++//
++// if (forwardedBy != NULL)
++// {
++//#ifndef NODEBUG
++// struct ipaddr_str forwardedByBuf, niaBuf;
++// struct lqtextbuffer lqbuffer;
++//#endif
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> 2-hop path from %s via me to %s will cost ETX %s\n",
++// PLUGIN_NAME_SHORT,
++// olsr_ip_to_string(&forwardedByBuf, forwardedBy),
++// olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
++// get_linkcost_text(previousLinkEtx + currEtx, 1, &lqbuffer));
++// }
++//
++// /* Check the topology table whether the 'forwardedBy' node is itself a direct
++// * neighbor of the candidate neighbor, at a lower cost than the 2-hop route
++// * via myself. If so, we do not need to forward the BMF packet to the candidate
++// * neighbor, because the 'forwardedBy' node will forward the packet. */
++// if (forwardedBy != NULL)
++// {
++// tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
++// if (tcLastHop != NULL)
++// {
++// struct tc_edge_entry* tc_edge;
++//
++// tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
++//
++// /* We are not interested in dead-end edges. */
++// if (tc_edge) {
++// olsr_linkcost tcEtx = tc_edge->cost;
++//
++// if (previousLinkEtx + currEtx > tcEtx)
++// {
++//#ifndef NODEBUG
++// struct ipaddr_str neighbor_iface_buf, forw_buf;
++// struct lqtextbuffer lqbuffer;
++// olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
++//#endif
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
++// PLUGIN_NAME_SHORT,
++// neighbor_iface_buf.buf,
++// olsr_ip_to_string(&forw_buf, forwardedBy),
++// neighbor_iface_buf.buf,
++// get_linkcost_text(tcEtx, 0, &lqbuffer));
++//
++// continue; /* for */
++// } /* if */
++// } /* if */
++// } /* if */
++// } /* if */
++//
++// /* Remember the best neighbor. If all are very bad, remember none. */
++// if (currEtx < bestEtx)
++// {
++// *bestNeighbor = walker;
++// bestEtx = currEtx;
++// }
++//
++// /* Fill the list with up to 'FanOutLimit' neighbors. If there
++// * are more neighbors, broadcast is used instead of unicast. In that
++// * case we do not need the list of neighbors. */
++// if (*nPossibleNeighbors < FanOutLimit)
++// {
++// neighbors->links[*nPossibleNeighbors] = walker;
++// }
++//
++// *nPossibleNeighbors += 1;
++// } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
++//
++// /* Display the result of the neighbor search */
++// if (*nPossibleNeighbors == 0)
++// {
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> No suitable neighbor found to forward to on \"%s\"\n",
++// PLUGIN_NAME_SHORT,
++// intf->ifName);
++// }
++// else
++// {
++// struct ipaddr_str buf;
++// OLSR_PRINTF(
++// 9,
++// "%s: ----> %d neighbors found on \"%s\"; best neighbor to forward to: %s\n",
++// PLUGIN_NAME_SHORT,
++// *nPossibleNeighbors,
++// intf->ifName,
++// olsr_ip_to_string(&buf, &(*bestNeighbor)->neighbor_iface_addr));
++// } /* if */
++//
++//} /* FindNeighbors */
++
++/* -------------------------------------------------------------------------
++ * Function : CreateCaptureSocket
++ * Description: Create socket for promiscuously capturing multicast IP traffic
++ * Input : ifname - network interface (e.g. "eth0")
++ * Output : none
++ * Return : the socket descriptor ( >= 0), or -1 if an error occurred
++ * Data Used : none
++ * Notes : The socket is a cooked IP packet socket, bound to the specified
++ * network interface
++ * ------------------------------------------------------------------------- */
++static int CreateCaptureSocket(const char* ifName)
++{
++ int ifIndex = if_nametoindex(ifName);
++ struct packet_mreq mreq;
++ struct ifreq req;
++ struct sockaddr_ll bindTo;
++ int skfd = 0;
++ /* Open cooked IP packet socket */
++ if (olsr_cnf->ip_version == AF_INET){
++ skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
++ }
++ else {
++ skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
++ }
++ if (skfd < 0)
++ {
++ BmfPError("socket(PF_PACKET) error");
++ return -1;
++ }
++
++ /* Set interface to promiscuous mode */
++ memset(&mreq, 0, sizeof(struct packet_mreq));
++ mreq.mr_ifindex = ifIndex;
++ mreq.mr_type = PACKET_MR_PROMISC;
++ if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
++ {
++ BmfPError("setsockopt(PACKET_MR_PROMISC) error");
++ close(skfd);
++ return -1;
++ }
++
++ /* Get hardware (MAC) address */
++ memset(&req, 0, sizeof(struct ifreq));
++ strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
++ req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
++ if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
++ {
++ BmfPError("error retrieving MAC address");
++ close(skfd);
++ return -1;
++ }
++
++ /* Bind the socket to the specified interface */
++ memset(&bindTo, 0, sizeof(bindTo));
++ bindTo.sll_family = AF_PACKET;
++ if (olsr_cnf->ip_version == AF_INET){
++ bindTo.sll_protocol = htons(ETH_P_IP);
++ }
++ else{
++ bindTo.sll_protocol = htons(ETH_P_IPV6);
++ }
++ bindTo.sll_ifindex = ifIndex;
++ memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
++ bindTo.sll_halen = IFHWADDRLEN;
++
++ if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
++ {
++ BmfPError("bind() error");
++ close(skfd);
++ return -1;
++ }
++
++ /* Set socket to blocking operation */
++ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
++ {
++ BmfPError("fcntl() error");
++ close(skfd);
++ return -1;
++ }
++
++ AddDescriptorToInputSet(skfd);
++ add_olsr_socket(skfd,&DoMDNS);
++
++ return skfd;
++} /* CreateCaptureSocket */
++
++/* -------------------------------------------------------------------------
++ * Function : CreateListeningSocket
++ * Description: Create socket for promiscuously listening to BMF packets.
++ * Used only when 'BmfMechanism' is BM_UNICAST_PROMISCUOUS
++ * Input : ifname - network interface (e.g. "eth0")
++ * Output : none
++ * Return : the socket descriptor ( >= 0), or -1 if an error occurred
++ * Data Used : none
++ * Notes : The socket is a cooked IP packet socket, bound to the specified
++ * network interface
++ * ------------------------------------------------------------------------- */
++//static int CreateListeningSocket(const char* ifName)
++//{
++// int ifIndex = if_nametoindex(ifName);
++// struct packet_mreq mreq;
++// struct ifreq req;
++// struct sockaddr_ll bindTo;
++//
++// /* Open cooked IP packet socket */
++// int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
++// if (skfd < 0)
++// {
++// BmfPError("socket(PF_PACKET) error");
++// return -1;
++// }
++//
++// /* Set interface to promiscuous mode */
++// memset(&mreq, 0, sizeof(struct packet_mreq));
++// mreq.mr_ifindex = ifIndex;
++// mreq.mr_type = PACKET_MR_PROMISC;
++// if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
++// {
++// BmfPError("setsockopt(PACKET_MR_PROMISC) error");
++// close(skfd);
++// return -1;
++// }
++//
++// /* Get hardware (MAC) address */
++// memset(&req, 0, sizeof(struct ifreq));
++// strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
++// req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
++// if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
++// {
++// BmfPError("error retrieving MAC address");
++// close(skfd);
++// return -1;
++// }
++//
++// /* Bind the socket to the specified interface */
++// memset(&bindTo, 0, sizeof(bindTo));
++// bindTo.sll_family = AF_PACKET;
++// bindTo.sll_protocol = htons(ETH_P_IP);
++// bindTo.sll_ifindex = ifIndex;
++// memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
++// bindTo.sll_halen = IFHWADDRLEN;
++//
++// if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
++// {
++// BmfPError("bind() error");
++// close(skfd);
++// return -1;
++// }
++//
++// /* Set socket to blocking operation */
++// if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
++// {
++// BmfPError("fcntl() error");
++// close(skfd);
++// return -1;
++// }
++//
++// AddDescriptorToInputSet(skfd);
++//
++// return skfd;
++//} /* CreateListeningSocket */
++
++/* -------------------------------------------------------------------------
++ * Function : CreateEncapsulateSocket
++ * Description: Create a socket for sending and receiving encapsulated
++ * multicast packets
++ * Input : ifname - network interface (e.g. "eth0")
++ * Output : none
++ * Return : the socket descriptor ( >= 0), or -1 if an error occurred
++ * Data Used : none
++ * Notes : The socket is an UDP (datagram) over IP socket, bound to the
++ * specified network interface
++ * ------------------------------------------------------------------------- */
++//static int CreateEncapsulateSocket(const char* ifName)
++//{
++// int on = 1;
++// struct sockaddr_in bindTo;
++//
++// /* Open UDP-IP socket */
++// int skfd = socket(PF_INET, SOCK_DGRAM, 0);
++// if (skfd < 0)
++// {
++// BmfPError("socket(PF_INET) error");
++// return -1;
++// }
++//
++// /* Enable sending to broadcast addresses */
++// if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
++// {
++// BmfPError("setsockopt(SO_BROADCAST) error");
++// close(skfd);
++// return -1;
++// }
++//
++// /* Bind to the specific network interfaces indicated by ifName. */
++// /* When using Kernel 2.6 this must happer prior to the port binding! */
++// if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0)
++// {
++// BmfPError("setsockopt(SO_BINDTODEVICE) error");
++// close(skfd);
++// return -1;
++// }
++//
++// /* Bind to BMF port */
++// memset(&bindTo, 0, sizeof(bindTo));
++// bindTo.sin_family = AF_INET;
++// bindTo.sin_port = htons(BMF_ENCAP_PORT);
++// bindTo.sin_addr.s_addr = htonl(INADDR_ANY);
++//
++// if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
++// {
++// BmfPError("bind() error");
++// close(skfd);
++// return -1;
++// }
++//
++// /* Set socket to blocking operation */
++// if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
++// {
++// BmfPError("fcntl() error");
++// close(skfd);
++// return -1;
++// }
++//
++// AddDescriptorToInputSet(skfd);
++//
++// return skfd;
++//} /* CreateEncapsulateSocket */
++
++/* -------------------------------------------------------------------------
++ * Function : CreateLocalEtherTunTap
++ * Description: Creates and brings up an EtherTunTap interface
++ * Input : none
++ * Output : none
++ * Return : the socket file descriptor (>= 0), or -1 in case of failure
++ * Data Used : EtherTunTapIfName - name used for the tuntap interface (e.g.
++ * "bmf0")
++ * EtherTunTapIp
++ * EtherTunTapIpMask
++ * EtherTunTapIpBroadcast
++ * BmfInterfaces
++ * Note : Order dependency: call this function only if BmfInterfaces
++ * is filled with a list of network interfaces.
++ * ------------------------------------------------------------------------- */
++//static int CreateLocalEtherTunTap(void)
++//{
++// static const char deviceName[] = "/dev/net/tun";
++// struct ifreq ifreq;
++// int etfd;
++// int ioctlSkfd;
++// int ioctlres;
++//
++// etfd = open(deviceName, O_RDWR | O_NONBLOCK);
++// if (etfd < 0)
++// {
++// BmfPError("error opening %s", deviceName);
++// return -1;
++// }
++//
++// memset(&ifreq, 0, sizeof(ifreq));
++// strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
++// ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++//
++// /* Specify the IFF_TUN flag for IP packets.
++// * Specify IFF_NO_PI for not receiving extra meta packet information. */
++// ifreq.ifr_flags = IFF_TUN;
++// ifreq.ifr_flags |= IFF_NO_PI;
++//
++// if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
++// {
++// BmfPError("ioctl(TUNSETIFF) error on %s", deviceName);
++// close(etfd);
++// return -1;
++// }
++//
++// memset(&ifreq, 0, sizeof(ifreq));
++// strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
++// ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++// ifreq.ifr_addr.sa_family = AF_INET;
++//
++// ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
++// if (ioctlSkfd < 0)
++// {
++// BmfPError("socket(PF_INET) error on %s", deviceName);
++// close(etfd);
++// return -1;
++// }
++//
++// /* Give the EtherTunTap interface an IP address.
++// * The default IP address is the address of the first OLSR interface;
++// * the default netmask is 255.255.255.255 . Having an all-ones netmask prevents
++// * automatic entry of the BMF network interface in the routing table. */
++// if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
++// {
++// struct TBmfInterface* nextBmfIf = BmfInterfaces;
++// while (nextBmfIf != NULL)
++// {
++// struct TBmfInterface* bmfIf = nextBmfIf;
++// nextBmfIf = bmfIf->next;
++//
++// if (bmfIf->olsrIntf != NULL)
++// {
++// EtherTunTapIp = ntohl(bmfIf->intAddr.v4.s_addr);
++// EtherTunTapIpBroadcast = EtherTunTapIp;
++// }
++// }
++// }
++//
++// if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
++// {
++// /* No IP address configured for BMF network interface, and no OLSR interface found to
++// * copy IP address from. Fall back to default: 10.255.255.253 . */
++// EtherTunTapIp = ETHERTUNTAPDEFAULTIP;
++// }
++//
++// ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp);
++// ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq);
++// if (ioctlres >= 0)
++// {
++// /* Set net mask */
++// ((struct sockaddr_in*)&ifreq.ifr_netmask)->sin_addr.s_addr = htonl(EtherTunTapIpMask);
++// ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq);
++// if (ioctlres >= 0)
++// {
++// /* Set broadcast IP */
++// ((struct sockaddr_in*)&ifreq.ifr_broadaddr)->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast);
++// ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq);
++// if (ioctlres >= 0)
++// {
++// /* Bring EtherTunTap interface up (if not already) */
++// ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
++// if (ioctlres >= 0)
++// {
++// ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_BROADCAST);
++// ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
++// }
++// }
++// }
++// }
++//
++// if (ioctlres < 0)
++// {
++// /* Any of the above ioctl() calls failed */
++// BmfPError("error bringing up EtherTunTap interface \"%s\"", EtherTunTapIfName);
++//
++// close(etfd);
++// close(ioctlSkfd);
++// return -1;
++// } /* if (ioctlres < 0) */
++//
++// /* Set the multicast flag on the interface */
++// memset(&ifreq, 0, sizeof(ifreq));
++// strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
++// ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++//
++// ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
++// if (ioctlres >= 0)
++// {
++// ifreq.ifr_flags |= IFF_MULTICAST;
++// ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
++// }
++// if (ioctlres < 0)
++// {
++// /* Any of the two above ioctl() calls failed */
++// BmfPError("error setting multicast flag on EtherTunTap interface \"%s\"", EtherTunTapIfName);
++//
++// /* Continue anyway */
++// }
++//
++// /* Use ioctl to make the tuntap persistent. Otherwise it will disappear
++// * when this program exits. That is not desirable, since a multicast
++// * daemon (e.g. mrouted) may be using the tuntap interface. */
++// if (ioctl(etfd, TUNSETPERSIST, (void *)&ifreq) < 0)
++// {
++// BmfPError("error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName);
++//
++// /* Continue anyway */
++// }
++//
++// OLSR_PRINTF(8, "%s: opened 1 socket on \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
++//
++// AddDescriptorToInputSet(etfd);
++//
++// /* If the user configured a specific IP address for the BMF network interface,
++// * help the user and advertise the IP address of the BMF network interface
++// * on the OLSR network via HNA */
++// if (TunTapIpOverruled != 0)
++// {
++// union olsr_ip_addr temp_net;
++//
++// temp_net.v4.s_addr = htonl(EtherTunTapIp);
++// ip_prefix_list_add(&olsr_cnf->hna_entries, &temp_net, 32);
++// }
++//
++// close(ioctlSkfd);
++//
++// return etfd;
++//} /* CreateLocalEtherTunTap */
++
++/* -------------------------------------------------------------------------
++ * Function : CreateInterface
++ * Description: Create a new TBmfInterface object and adds it to the global
++ * BmfInterfaces list
++ * Input : ifName - name of the network interface (e.g. "eth0")
++ * : olsrIntf - OLSR interface object of the network interface, or
++ * NULL if the network interface is not OLSR-enabled
++ * Output : none
++ * Return : the number of opened sockets
++ * Data Used : BmfInterfaces, LastBmfInterface
++ * ------------------------------------------------------------------------- */
++
++//FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
++
++static int CreateInterface(
++ const char* ifName,
++ struct interface* olsrIntf)
++{
++ int capturingSkfd = -1;
++ int encapsulatingSkfd = -1;
++ int listeningSkfd = -1;
++ int ioctlSkfd;
++ struct ifreq ifr;
++ int nOpened = 0;
++ struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
++
++ assert(ifName != NULL);
++
++ if (newIf == NULL)
++ {
++ return 0;
++ }
++
++//TODO: assert interface is not talking OLSR
++
++// if (olsrIntf != NULL)
++// {
++// /* On OLSR-enabled interfaces, create socket for encapsulating and forwarding
++// * multicast packets */
++// encapsulatingSkfd = CreateEncapsulateSocket(ifName);
++// if (encapsulatingSkfd < 0)
++// {
++// free(newIf);
++// return 0;
++// }
++// nOpened++;
++// }
++
++ /* Create socket for capturing and sending of multicast packets on
++ * non-OLSR interfaces, and on OLSR-interfaces if configured. */
++ if ((olsrIntf == NULL) || (CapturePacketsOnOlsrInterfaces != 0))
++ {
++ capturingSkfd = CreateCaptureSocket(ifName);
++ if (capturingSkfd < 0)
++ {
++ close(encapsulatingSkfd);
++ free(newIf);
++ return 0;
++ }
++
++ nOpened++;
++ }
++
++// /* Create promiscuous mode listening interface if BMF uses IP unicast
++// * as underlying forwarding mechanism */
++// if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
++// {
++// listeningSkfd = CreateListeningSocket(ifName);
++// if (listeningSkfd < 0)
++// {
++// close(listeningSkfd);
++// close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */
++// free(newIf);
++// return 0;
++// }
++//
++// nOpened++;
++// }
++
++ /* For ioctl operations on the network interface, use either capturingSkfd
++ * or encapsulatingSkfd, whichever is available */
++ ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
++
++ /* Retrieve the MAC address of the interface. */
++ memset(&ifr, 0, sizeof(struct ifreq));
++ strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
++ ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++ if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0)
++ {
++ BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
++ close(capturingSkfd);
++ close(encapsulatingSkfd);
++ free(newIf);
++ return 0;
++ }
++
++ /* Copy data into TBmfInterface object */
++ newIf->capturingSkfd = capturingSkfd;
++ newIf->encapsulatingSkfd = encapsulatingSkfd;
++ newIf->listeningSkfd = listeningSkfd;
++ memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
++ memcpy(newIf->ifName, ifName, IFNAMSIZ);
++ newIf->olsrIntf = olsrIntf;
++ if (olsrIntf != NULL)
++ {
++ /* For an OLSR-interface, copy the interface address and broadcast
++ * address from the OLSR interface object. Downcast to correct sockaddr
++ * subtype. */
++ newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
++ newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
++ }
++ else
++ {
++ /* For a non-OLSR interface, retrieve the IP address ourselves */
++ memset(&ifr, 0, sizeof(struct ifreq));
++ strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
++ ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++ if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0)
++ {
++ BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
++
++ newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
++ }
++ else
++ {
++ /* Downcast to correct sockaddr subtype */
++ newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
++ }
++
++ /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
++ memset(&ifr, 0, sizeof(struct ifreq));
++ strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
++ ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++ if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0)
++ {
++ BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
++
++ newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
++ }
++ else
++ {
++ /* Downcast to correct sockaddr subtype */
++ newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
++ }
++ }
++
++ /* Initialize fragment history table */
++ //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
++ //newIf->nextFragmentHistoryEntry = 0;
++
++ /* Reset counters */
++ //newIf->nBmfPacketsRx = 0;
++ //newIf->nBmfPacketsRxDup = 0;
++ //newIf->nBmfPacketsTx = 0;
++
++ /* Add new TBmfInterface object to global list. OLSR interfaces are
++ * added at the front of the list, non-OLSR interfaces at the back. */
++ if (BmfInterfaces == NULL)
++ {
++ /* First TBmfInterface object in list */
++ BmfInterfaces = newIf;
++ LastBmfInterface = newIf;
++ }
++ else if (olsrIntf != NULL)
++ {
++ /* Add new TBmfInterface object at front of list */
++ newIf->next = BmfInterfaces;
++ BmfInterfaces = newIf;
++ }
++ else
++ {
++ /* Add new TBmfInterface object at back of list */
++ newIf->next = NULL;
++ LastBmfInterface->next= newIf;
++ LastBmfInterface = newIf;
++ }
++
++ OLSR_PRINTF(
++ 8,
++ "%s: opened %d socket%s on %s interface \"%s\"\n",
++ PLUGIN_NAME_SHORT,
++ nOpened,
++ nOpened == 1 ? "" : "s",
++ olsrIntf != NULL ? "OLSR" : "non-OLSR",
++ ifName);
++
++ return nOpened;
++} /* CreateInterface */
++
++/* -------------------------------------------------------------------------
++ * Function : CreateBmfNetworkInterfaces
++ * Description: Create a list of TBmfInterface objects, one for each network
++ * interface on which BMF runs
++ * Input : skipThisIntf - network interface to skip, if seen
++ * Output : none
++ * Return : fail (-1) or success (0)
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
++{
++ int skfd;
++ struct ifconf ifc;
++ int numreqs = 30;
++ struct ifreq* ifr;
++ int n;
++ int nOpenedSockets = 0;
++
++ /* Clear input descriptor set */
++ FD_ZERO(&InputSet);
++
++ skfd = socket(PF_INET, SOCK_DGRAM, 0);
++ if (skfd < 0)
++ {
++ BmfPError("no inet socket available to retrieve interface list");
++ return -1;
++ }
++
++ /* Retrieve the network interface configuration list */
++ ifc.ifc_buf = NULL;
++ for (;;)
++ {
++ ifc.ifc_len = sizeof(struct ifreq) * numreqs;
++ ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
++
++ if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
++ {
++ BmfPError("ioctl(SIOCGIFCONF) error");
++
++ close(skfd);
++ free(ifc.ifc_buf);
++ return -1;
++ }
++ if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
++ {
++ /* Assume it overflowed; double the space and try again */
++ numreqs *= 2;
++ assert(numreqs < 1024);
++ continue; /* for (;;) */
++ }
++ break; /* for (;;) */
++ } /* for (;;) */
++
++ close(skfd);
++
++ /* For each item in the interface configuration list... */
++ ifr = ifc.ifc_req;
++ for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++)
++ {
++ struct interface* olsrIntf;
++ union olsr_ip_addr ipAddr;
++
++ /* Skip the BMF network interface itself */
++ //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
++ //{
++ // continue; /* for (n = ...) */
++ //}
++
++ /* ...find the OLSR interface structure, if any */
++ ipAddr.v4 = ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr;
++ olsrIntf = if_ifwithaddr(&ipAddr);
++
++ if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
++ {
++ continue; /* for (n = ...) */
++ }
++
++ if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
++ {
++ /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
++ * interface in the BMF plugin parameter list */
++ continue; /* for (n = ...) */
++ }
++
++ if (! IsNonOlsrBmfIf(ifr->ifr_name))
++ {
++ //If the interface is not specified in the configuration file then go ahead
++ continue; /* for (n = ...) */
++ }
++ //TODO: asser if->ifr_name is not talking OLSR
++ //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
++ nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
++
++ } /* for (n = ...) */
++
++ free(ifc.ifc_buf);
++
++ /* Create the BMF network interface */
++ //EtherTunTapFd = CreateLocalEtherTunTap();
++ //if (EtherTunTapFd >= 0)
++ //{
++ // nOpenedSockets++;
++ //}
++
++ if (BmfInterfaces == NULL)
++ {
++ OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
++ }
++ else
++ {
++ OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
++ }
++ return 0;
++} /* CreateBmfNetworkInterfaces */
++
++/* -------------------------------------------------------------------------
++ * Function : AddInterface
++ * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
++ * network interfaces
++ * Input : newIntf - network interface to add
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++void AddInterface(struct interface* newIntf)
++{
++ int nOpened;
++
++ assert(newIntf != NULL);
++
++ nOpened = CreateInterface(newIntf->int_name, newIntf);
++
++ OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
++} /* AddInterface */
++
++/* -------------------------------------------------------------------------
++ * Function : CloseBmfNetworkInterfaces
++ * Description: Closes every socket on each network interface used by BMF
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * Notes : Closes
++ * - the local EtherTunTap interface (e.g. "tun0" or "tap0")
++ * - for each BMF-enabled interface, the socket used for
++ * capturing multicast packets
++ * - for each OLSR-enabled interface, the socket used for
++ * encapsulating packets
++ * Also restores the network state to the situation before BMF
++ * was started.
++ * ------------------------------------------------------------------------- */
++void CloseBmfNetworkInterfaces(void)
++{
++ int nClosed = 0;
++ u_int32_t totalOlsrBmfPacketsRx = 0;
++ u_int32_t totalOlsrBmfPacketsRxDup = 0;
++ u_int32_t totalOlsrBmfPacketsTx = 0;
++ u_int32_t totalNonOlsrBmfPacketsRx = 0;
++ u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
++ u_int32_t totalNonOlsrBmfPacketsTx = 0;
++
++ /* Close all opened sockets */
++ struct TBmfInterface* nextBmfIf = BmfInterfaces;
++ while (nextBmfIf != NULL)
++ {
++ struct TBmfInterface* bmfIf = nextBmfIf;
++ nextBmfIf = bmfIf->next;
++
++ if (bmfIf->capturingSkfd >= 0)
++ {
++ close(bmfIf->capturingSkfd);
++ nClosed++;
++ }
++ if (bmfIf->encapsulatingSkfd >= 0)
++ {
++ close(bmfIf->encapsulatingSkfd);
++ nClosed++;
++ }
++
++ OLSR_PRINTF(
++ 7,
++ "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
++ PLUGIN_NAME_SHORT,
++ bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
++ bmfIf->ifName,
++ bmfIf->nBmfPacketsRx,
++ bmfIf->nBmfPacketsRxDup,
++ bmfIf->nBmfPacketsTx);
++
++ OLSR_PRINTF(
++ 1,
++ "%s: closed %s interface \"%s\"\n",
++ PLUGIN_NAME_SHORT,
++ bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
++ bmfIf->ifName);
++
++ /* Add totals */
++ if (bmfIf->olsrIntf != NULL)
++ {
++ totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
++ totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
++ totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
++ }
++ else
++ {
++ totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
++ totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
++ totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
++ }
++
++ free(bmfIf);
++ } /* while */
++
++ if (EtherTunTapFd >= 0)
++ {
++ close(EtherTunTapFd);
++ nClosed++;
++
++ OLSR_PRINTF(7, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
++ }
++
++ BmfInterfaces = NULL;
++
++ OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
++
++ OLSR_PRINTF(
++ 7,
++ "%s: Total all OLSR interfaces : RX pkts %u (%u dups); TX pkts %u\n",
++ PLUGIN_NAME_SHORT,
++ totalOlsrBmfPacketsRx,
++ totalOlsrBmfPacketsRxDup,
++ totalOlsrBmfPacketsTx);
++ OLSR_PRINTF(
++ 7,
++ "%s: Total all non-OLSR interfaces: RX pkts %u (%u dups); TX pkts %u\n",
++ PLUGIN_NAME_SHORT,
++ totalNonOlsrBmfPacketsRx,
++ totalNonOlsrBmfPacketsRxDup,
++ totalNonOlsrBmfPacketsTx);
++} /* CloseBmfNetworkInterfaces */
++
++#define MAX_NON_OLSR_IFS 32
++static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
++static int nNonOlsrIfs = 0;
++
++/* -------------------------------------------------------------------------
++ * Function : AddNonOlsrBmfIf
++ * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
++ * network interfaces
++ * Input : ifName - network interface (e.g. "eth0")
++ * data - not used
++ * addon - not used
++ * Output : none
++ * Return : success (0) or fail (1)
++ * Data Used : NonOlsrIfNames
++ * ------------------------------------------------------------------------- */
++int AddNonOlsrBmfIf(
++ const char* ifName,
++ void* data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused)))
++{
++ assert(ifName != NULL);
++
++ if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
++ {
++ OLSR_PRINTF(
++ 1,
++ "%s: too many non-OLSR interfaces specified, maximum is %d\n",
++ PLUGIN_NAME,
++ MAX_NON_OLSR_IFS);
++ return 1;
++ }
++
++ strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
++ NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
++ nNonOlsrIfs++;
++ return 0;
++} /* AddNonOlsrBmfIf */
++
++/* -------------------------------------------------------------------------
++ * Function : IsNonOlsrBmfIf
++ * Description: Checks if a network interface is OLSR-enabled
++ * Input : ifName - network interface (e.g. "eth0")
++ * Output : none
++ * Return : true (1) or false (0)
++ * Data Used : NonOlsrIfNames
++ * ------------------------------------------------------------------------- */
++int IsNonOlsrBmfIf(const char* ifName)
++{
++ int i;
++
++ assert(ifName != NULL);
++
++ for (i = 0; i < nNonOlsrIfs; i++)
++ {
++ if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
++ }
++ return 0;
++} /* IsNonOlsrBmfIf */
++
++/* -------------------------------------------------------------------------
++ * Function : CheckAndUpdateLocalBroadcast
++ * Description: For an IP packet, check if the destination address is not a
++ * multicast address. If it is not, the packet is assumed to be
++ * a local broadcast packet. In that case, set the destination
++ * address of the IP packet to the passed broadcast address.
++ * Input : ipPacket - the IP packet
++ * broadAddr - the broadcast address to fill in
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * Notes : See also RFC1141
++ * ------------------------------------------------------------------------- */
++void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr)
++{
++ struct iphdr* iph;
++ union olsr_ip_addr destIp;
++
++ assert(ipPacket != NULL && broadAddr != NULL);
++
++ iph = (struct iphdr*) ipPacket;
++ destIp.v4.s_addr = iph->daddr;
++ if (! IsMulticast(&destIp))
++ {
++ u_int32_t origDaddr, newDaddr;
++ u_int32_t check;
++
++ origDaddr = ntohl(iph->daddr);
++
++ iph->daddr = broadAddr->v4.s_addr;
++ newDaddr = ntohl(iph->daddr);
++
++ /* Re-calculate IP header checksum for new destination */
++ check = ntohs(iph->check);
++
++ check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
++ check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
++
++ /* Add carry */
++ check = check + (check >> 16);
++
++ iph->check = htons(check);
++
++ if (iph->protocol == SOL_UDP)
++ {
++ /* Re-calculate UDP/IP checksum for new destination */
++
++ int ipHeaderLen = GetIpHeaderLength(ipPacket);
++ struct udphdr* udph = (struct udphdr*) (ipPacket + ipHeaderLen);
++
++ /* RFC 1624, Eq. 3: HC' = ~(~HC - m + m') */
++
++ check = ntohs(udph->check);
++
++ check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
++ check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
++
++ /* Add carry */
++ check = check + (check >> 16);
++
++ udph->check = htons(check);
++ } /* if */
++ } /* if */
++} /* CheckAndUpdateLocalBroadcast */
++
++/* -------------------------------------------------------------------------
++ * Function : AddMulticastRoute
++ * Description: Insert a route to all multicast addresses in the kernel
++ * routing table. The route will be via the BMF network interface.
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++void AddMulticastRoute(void)
++{
++ struct rtentry kernel_route;
++ int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
++ if (ioctlSkfd < 0)
++ {
++ BmfPError("socket(PF_INET) error");
++ return;
++ }
++
++ memset(&kernel_route, 0, sizeof(struct rtentry));
++
++ ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
++ ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
++ ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
++
++ /* 224.0.0.0/4 */
++ ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
++ ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
++
++ kernel_route.rt_metric = 0;
++ kernel_route.rt_flags = RTF_UP;
++
++ kernel_route.rt_dev = EtherTunTapIfName;
++
++ if (ioctl(ioctlSkfd, SIOCADDRT, &kernel_route) < 0)
++ {
++ BmfPError("error setting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
++
++ /* Continue anyway */
++ }
++ close(ioctlSkfd);
++} /* AddMulticastRoute */
++
++/* -------------------------------------------------------------------------
++ * Function : DeleteMulticastRoute
++ * Description: Delete the route to all multicast addresses from the kernel
++ * routing table
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++void DeleteMulticastRoute(void)
++{
++ if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP)
++ {
++ struct rtentry kernel_route;
++ int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
++ if (ioctlSkfd < 0)
++ {
++ BmfPError("socket(PF_INET) error");
++ return;
++ }
++
++ memset(&kernel_route, 0, sizeof(struct rtentry));
++
++ ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
++ ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
++ ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
++
++ /* 224.0.0.0/4 */
++ ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
++ ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
++
++ kernel_route.rt_metric = 0;
++ kernel_route.rt_flags = RTF_UP;
++
++ kernel_route.rt_dev = EtherTunTapIfName;
++
++ if (ioctl(ioctlSkfd, SIOCDELRT, &kernel_route) < 0)
++ {
++ BmfPError("error deleting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
++
++ /* Continue anyway */
++ }
++ close(ioctlSkfd);
++ } /* if */
++} /* DeleteMulticastRoute */
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/NetworkInterfaces.h olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/NetworkInterfaces.h
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/NetworkInterfaces.h 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/NetworkInterfaces.h 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,162 @@
++#ifndef _BMF_NETWORKINTERFACES_H
++#define _BMF_NETWORKINTERFACES_H
++
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : NetworkInterfaces.h
++ * Description: Functions to open and close sockets
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++/* System includes */
++#include <netinet/in.h> /* struct in_addr */
++
++/* OLSR includes */
++#include "olsr_types.h" /* olsr_ip_addr */
++#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
++#include "socket_parser.h"
++/* Plugin includes */
++#include "Packet.h" /* IFHWADDRLEN */
++#include "mdns.h"
++/* Size of buffer in which packets are received */
++#define BMF_BUFFER_SIZE 2048
++
++struct TBmfInterface
++{
++ /* File descriptor of raw packet socket, used for capturing multicast packets */
++ int capturingSkfd;
++
++ /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.
++ * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */
++ int encapsulatingSkfd;
++
++ /* File descriptor of UDP packet socket, used for listening to encapsulation packets.
++ * Used only when PlParam "BmfMechanism" is set to "UnicastPromiscuous". */
++ int listeningSkfd;
++
++ unsigned char macAddr[IFHWADDRLEN];
++
++ char ifName[IFNAMSIZ];
++
++ /* OLSRs idea of this network interface. NULL if this interface is not
++ * OLSR-enabled. */
++ struct interface* olsrIntf;
++
++ /* IP address of this network interface */
++ union olsr_ip_addr intAddr;
++
++ /* Broadcast address of this network interface */
++ union olsr_ip_addr broadAddr;
++
++ #define FRAGMENT_HISTORY_SIZE 10
++ struct TFragmentHistory
++ {
++ u_int16_t ipId;
++ u_int8_t ipProto;
++ struct in_addr ipSrc;
++ struct in_addr ipDst;
++ } fragmentHistory [FRAGMENT_HISTORY_SIZE];
++
++ int nextFragmentHistoryEntry;
++
++ /* Number of received and transmitted BMF packets on this interface */
++ u_int32_t nBmfPacketsRx;
++ u_int32_t nBmfPacketsRxDup;
++ u_int32_t nBmfPacketsTx;
++
++ /* Next element in list */
++ struct TBmfInterface* next;
++};
++
++extern struct TBmfInterface* BmfInterfaces;
++
++extern int HighestSkfd;
++extern fd_set InputSet;
++
++extern int EtherTunTapFd;
++
++extern char EtherTunTapIfName[];
++
++/* 10.255.255.253 in host byte order */
++#define ETHERTUNTAPDEFAULTIP 0x0AFFFFFD
++
++extern u_int32_t EtherTunTapIp;
++extern u_int32_t EtherTunTapIpMask;
++extern u_int32_t EtherTunTapIpBroadcast;
++
++extern int CapturePacketsOnOlsrInterfaces;
++
++enum TBmfMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };
++extern enum TBmfMechanism BmfMechanism;
++
++int SetBmfInterfaceName(const char* ifname, void* data, set_plugin_parameter_addon addon);
++int SetBmfInterfaceIp(const char* ip, void* data, set_plugin_parameter_addon addon);
++int SetCapturePacketsOnOlsrInterfaces(const char* enable, void* data, set_plugin_parameter_addon addon);
++int SetBmfMechanism(const char* mechanism, void* data, set_plugin_parameter_addon addon);
++int DeactivateSpoofFilter(void);
++void RestoreSpoofFilter(void);
++
++#define MAX_UNICAST_NEIGHBORS 10
++struct TBestNeighbors
++{
++ struct link_entry* links[MAX_UNICAST_NEIGHBORS];
++};
++
++void FindNeighbors(
++ struct TBestNeighbors* neighbors,
++ struct link_entry** bestNeighbor,
++ struct TBmfInterface* intf,
++ union olsr_ip_addr* source,
++ union olsr_ip_addr* forwardedBy,
++ union olsr_ip_addr* forwardedTo,
++ int* nPossibleNeighbors);
++
++int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
++void AddInterface(struct interface* newIntf);
++void CloseBmfNetworkInterfaces(void);
++int AddNonOlsrBmfIf(const char* ifName, void* data, set_plugin_parameter_addon addon);
++int IsNonOlsrBmfIf(const char* ifName);
++void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr);
++void AddMulticastRoute(void);
++void DeleteMulticastRoute(void);
++
++#endif /* _BMF_NETWORKINTERFACES_H */
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Packet.c olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Packet.c
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Packet.c 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Packet.c 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,238 @@
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : Packet.c
++ * Description: IP packet and Ethernet frame processing functions
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++#include "Packet.h"
++
++/* System includes */
++#include <stddef.h> /* NULL */
++#include <assert.h> /* assert() */
++#include <string.h> /* memcpy() */
++#include <sys/types.h> /* u_int8_t, u_int16_t, u_int32_t */
++#include <netinet/in.h> /* ntohs(), htons() */
++#include <netinet/ip.h> /* struct iphdr */
++
++/* -------------------------------------------------------------------------
++ * Function : IsIpFragment
++ * Description: Check if an IP packet is an IP fragment
++ * Input : ipPacket - the IP packet
++ * Output : none
++ * Return : true (1) or false (0)
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++int IsIpFragment(unsigned char* ipPacket)
++{
++ struct ip* iph;
++
++ assert(ipPacket != NULL);
++
++ iph = (struct ip*) ipPacket;
++ if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
++ {
++ return 1;
++ }
++ return 0;
++} /* IsIpFragment */
++
++/* -------------------------------------------------------------------------
++ * Function : GetIpTotalLength
++ * Description: Retrieve the total length of the IP packet (in bytes) of
++ * an IP packet
++ * Input : ipPacket - the IP packet
++ * Output : none
++ * Return : IP packet length
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++u_int16_t GetIpTotalLength(unsigned char* ipPacket)
++{
++ struct iphdr* iph;
++
++ assert(ipPacket != NULL);
++
++ iph = (struct iphdr*) ipPacket;
++ return ntohs(iph->tot_len);
++} /* GetIpTotalLength */
++
++/* -------------------------------------------------------------------------
++ * Function : GetIpHeaderLength
++ * Description: Retrieve the IP header length (in bytes) of an IP packet
++ * Input : ipPacket - the IP packet
++ * Output : none
++ * Return : IP header length
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++unsigned int GetIpHeaderLength(unsigned char* ipPacket)
++{
++ struct iphdr* iph;
++
++ assert(ipPacket != NULL);
++
++ iph = (struct iphdr*) ipPacket;
++ return iph->ihl << 2;
++} /* GetIpHeaderLength */
++
++/* -------------------------------------------------------------------------
++ * Function : GetTtl
++ * Description: Retrieve the TTL (Time To Live) value from the IP header of
++ * an IP packet
++ * Input : ipPacket - the IP packet
++ * Output : none
++ * Return : TTL value
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++u_int8_t GetTtl(unsigned char* ipPacket)
++{
++ struct iphdr* iph;
++
++ assert(ipPacket != NULL);
++
++ iph = (struct iphdr*) ipPacket;
++ return iph->ttl;
++} /* GetTtl */
++
++/* -------------------------------------------------------------------------
++ * Function : SaveTtlAndChecksum
++ * Description: Save the TTL (Time To Live) value and IP checksum as found in
++ * the IP header of an IP packet
++ * Input : ipPacket - the IP packet
++ * Output : sttl - the TTL and checksum values
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
++{
++ struct iphdr* iph;
++
++ assert(ipPacket != NULL && sttl != NULL);
++
++ iph = (struct iphdr*) ipPacket;
++ sttl->ttl = iph->ttl;
++ sttl->check = ntohs(iph->check);
++} /* SaveTtlAndChecksum */
++
++/* -------------------------------------------------------------------------
++ * Function : RestoreTtlAndChecksum
++ * Description: Restore the TTL (Time To Live) value and IP checksum in
++ * the IP header of an IP packet
++ * Input : ipPacket - the IP packet
++ * sttl - the TTL and checksum values
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
++{
++ struct iphdr* iph;
++
++ assert(ipPacket != NULL && sttl != NULL);
++
++ iph = (struct iphdr*) ipPacket;
++ iph->ttl = sttl->ttl;
++ iph->check = htons(sttl->check);
++} /* RestoreTtlAndChecksum */
++
++/* -------------------------------------------------------------------------
++ * Function : DecreaseTtlAndUpdateHeaderChecksum
++ * Description: For an IP packet, decrement the TTL value and update the IP header
++ * checksum accordingly.
++ * Input : ipPacket - the IP packet
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * Notes : See also RFC1141
++ * ------------------------------------------------------------------------- */
++void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
++{
++ struct iphdr* iph;
++ u_int32_t sum;
++
++ assert(ipPacket != NULL);
++
++ iph = (struct iphdr*) ipPacket;
++
++ iph->ttl--; /* decrement ttl */
++ sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
++ iph->check = htons(sum + (sum>>16)); /* add carry */
++} /* DecreaseTtlAndUpdateHeaderChecksum */
++
++/* -------------------------------------------------------------------------
++ * Function : GetIpHeader
++ * Description: Retrieve the IP header from BMF encapsulation UDP data
++ * Input : encapsulationUdpData - the encapsulation UDP data
++ * Output : none
++ * Return : IP header
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
++{
++ return (struct ip*)(encapsulationUdpData + ENCAP_HDR_LEN);
++} /* GetIpHeader */
++
++/* -------------------------------------------------------------------------
++ * Function : GetIpPacket
++ * Description: Retrieve the IP packet from BMF encapsulation UDP data
++ * Input : encapsulationUdpData - the encapsulation UDP data
++ * Output : none
++ * Return : The IP packet
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
++{
++ return encapsulationUdpData + ENCAP_HDR_LEN;
++} /* GetIpPacket */
++
++/* -------------------------------------------------------------------------
++ * Function : GetEncapsulationUdpDataLength
++ * Description: Return the length of BMF encapsulation UDP data
++ * Input : encapsulationUdpData - the encapsulation UDP data
++ * Output : none
++ * Return : The encapsulation data length
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData)
++{
++ return GetIpTotalLength(GetIpPacket(encapsulationUdpData)) + ENCAP_HDR_LEN;
++} /* GetEncapsulationUdpDataLength */
++
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Packet.h olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Packet.h
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/Packet.h 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/Packet.h 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,88 @@
++#ifndef _BMF_PACKET_H
++#define _BMF_PACKET_H
++
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : Packet.h
++ * Description: BMF and IP packet processing functions
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++/* System includes */
++#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
++#include <sys/types.h> /* u_int8_t, u_int16_t */
++
++/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
++ * with a 8-bytes BMF header (struct TEncapHeader), followed by the
++ * encapsulated Ethernet-IP packet itself */
++
++struct TEncapHeader
++{
++ /* Use a standard Type-Length-Value (TLV) element */
++ u_int8_t type;
++ u_int8_t len;
++ u_int16_t reserved; /* Always 0 */
++ u_int32_t crc32;
++} __attribute__((__packed__));
++
++#define ENCAP_HDR_LEN ((int)sizeof(struct TEncapHeader))
++#define BMF_ENCAP_TYPE 1
++#define BMF_ENCAP_LEN 6
++
++struct TSaveTtl
++{
++ u_int8_t ttl;
++ u_int16_t check;
++} __attribute__((__packed__));
++
++int IsIpFragment(unsigned char* ipPacket);
++u_int16_t GetIpTotalLength(unsigned char* ipPacket);
++unsigned int GetIpHeaderLength(unsigned char* ipPacket);
++u_int8_t GetTtl(unsigned char* ipPacket);
++void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
++void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
++void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket);
++struct ip* GetIpHeader(unsigned char* encapsulationUdpData);
++unsigned char* GetIpPacket(unsigned char* encapsulationUdpData);
++u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData);
++
++#endif /* _BMF_PACKET_H */
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/PacketHistory.c olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/PacketHistory.c
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/PacketHistory.c 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/PacketHistory.c 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,324 @@
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : PacketHistory.c
++ * Description: Functions for keeping and accessing the history of processed
++ * multicast IP packets.
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++#include "PacketHistory.h"
++
++/* System includes */
++#include <stddef.h> /* NULL */
++#include <assert.h> /* assert() */
++#include <string.h> /* memset */
++#include <sys/types.h> /* u_int16_t, u_int32_t */
++#include <netinet/ip.h> /* struct iphdr */
++#include <stdlib.h> /* atoi, malloc */
++
++/* OLSRD includes */
++#include "defs.h" /* GET_TIMESTAMP, TIMED_OUT */
++#include "olsr.h" /* OLSR_PRINTF */
++#include "scheduler.h" /* now_times */
++
++/* Plugin includes */
++#include "Packet.h"
++
++static struct TDupEntry* PacketHistory[HISTORY_HASH_SIZE];
++
++#define CRC_UPTO_NBYTES 256
++
++#if 0
++/* -------------------------------------------------------------------------
++ * Function : CalcCrcCcitt
++ * Description: Calculate 16-bits CRC according to CRC-CCITT specification
++ * Input : buffer - the bytes to calculate the CRC value over
++ * len - the number of bytes to calculate the CRC value over
++ * Output : none
++ * Return : CRC-16 value
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)
++{
++ /* Initial value of 0xFFFF should be 0x1D0F according to
++ * www.joegeluso.com/software/articles/ccitt.htm */
++ u_int16_t crc = 0xFFFF;
++ int i;
++
++ assert(buffer != NULL);
++
++ for (i = 0; i < len; i++)
++ {
++ crc = (unsigned char)(crc >> 8) | (crc << 8);
++ crc ^= buffer[i];
++ crc ^= (unsigned char)(crc & 0xff) >> 4;
++ crc ^= (crc << 8) << 4;
++ crc ^= ((crc & 0xff) << 4) << 1;
++ }
++ return crc;
++} /* CalcCrcCcitt */
++#endif
++
++/* -------------------------------------------------------------------------
++ * Function : GenerateCrc32Table
++ * Description: Generate the table of CRC remainders for all possible bytes,
++ * according to CRC-32-IEEE 802.3
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */
++
++static unsigned long CrcTable[256];
++
++static void GenerateCrc32Table(void)
++{
++ int i, j;
++ u_int32_t crc;
++ for (i = 0; i < 256; i++)
++ {
++ crc = (u_int32_t) i;
++ for (j = 0; j < 8; j++)
++ {
++ if (crc & 1)
++ {
++ crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
++ }
++ else
++ {
++ crc = (crc >> 1);
++ }
++ }
++ CrcTable[i] = crc;
++ } /* for */
++} /* GenerateCrc32Table */
++
++/* -------------------------------------------------------------------------
++ * Function : CalcCrc32
++ * Description: Calculate CRC-32 according to CRC-32-IEEE 802.3
++ * Input : buffer - the bytes to calculate the CRC value over
++ * len - the number of bytes to calculate the CRC value over
++ * Output : none
++ * Return : CRC-32 value
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)
++{
++ int i, j;
++ u_int32_t crc = 0xffffffffUL;
++ for (i = 0; i < len; i++)
++ {
++ j = ((int) (crc & 0xFF) ^ *buffer++);
++ crc = (crc >> 8) ^ CrcTable[j];
++ }
++ return crc ^ 0xffffffffUL;
++} /* CalcCrc32 */
++
++/* -------------------------------------------------------------------------
++ * Function : PacketCrc32
++ * Description: Calculates the CRC-32 value for an IP packet
++ * Input : ipPacket - the IP packet
++ * len - the number of octets in the IP packet
++ * Output : none
++ * Return : 32-bits CRC value
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++u_int32_t PacketCrc32(unsigned char* ipPacket, ssize_t len)
++{
++ struct TSaveTtl sttl;
++ struct ip* ipHeader;
++ u_int32_t result;
++
++ assert(ipPacket != NULL);
++
++ /* Skip TTL: in a multi-homed OLSR-network, the same multicast packet
++ * may enter the network multiple times, each copy differing only in its
++ * TTL value. BMF must not calculate a different CRC for packets that
++ * differ only in TTL. Skip also the IP-header checksum, because it changes
++ * along with TTL. Besides, it is not a good idea to calculate a CRC over
++ * data that already contains a checksum.
++ *
++ * Clip number of bytes over which CRC is calculated to prevent
++ * long packets from possibly claiming too much CPU resources. */
++ assert(len > 0);
++ if (len > CRC_UPTO_NBYTES)
++ {
++ len = CRC_UPTO_NBYTES;
++ }
++
++ SaveTtlAndChecksum(ipPacket, &sttl);
++
++ ipHeader = (struct ip*)ipPacket;
++ ipHeader->ip_ttl = 0xFF; /* fixed value of TTL for CRC-32 calculation */
++ ipHeader->ip_sum = 0x5A5A; /* fixed value of IP header checksum for CRC-32 calculation */
++
++ result = CalcCrc32(ipPacket, len);
++
++ RestoreTtlAndChecksum(ipPacket, &sttl);
++ return result;
++} /* PacketCrc32 */
++
++/* -------------------------------------------------------------------------
++ * Function : Hash
++ * Description: Calculates a hash value from a 32-bit value
++ * Input : from32 - 32-bit value
++ * Output : none
++ * Return : hash value
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++u_int32_t Hash(u_int32_t from32)
++{
++ return ((from32 >> N_HASH_BITS) + from32) & ((1 << N_HASH_BITS) - 1);
++} /* Hash */
++
++/* -------------------------------------------------------------------------
++ * Function : InitPacketHistory
++ * Description: Initialize the packet history table and CRC-32 table
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : PacketHistory
++ * ------------------------------------------------------------------------- */
++void InitPacketHistory(void)
++{
++ int i;
++
++ GenerateCrc32Table();
++
++ for(i = 0; i < HISTORY_HASH_SIZE; i++)
++ {
++ PacketHistory[i] = NULL;
++ }
++} /* InitPacketHistory */
++
++/* -------------------------------------------------------------------------
++ * Function : CheckAndMarkRecentPacket
++ * Description: Check if this packet was seen recently, then record the fact
++ * that this packet was seen recently.
++ * Input : crc32 - 32-bits crc value of the packet
++ * Output : none
++ * Return : not recently seen (0), recently seen (1)
++ * Data Used : PacketHistory
++ * ------------------------------------------------------------------------- */
++int CheckAndMarkRecentPacket(u_int32_t crc32)
++{
++ u_int32_t idx;
++ struct TDupEntry* walker;
++ struct TDupEntry* newEntry;
++
++ idx = Hash(crc32);
++ assert(idx < HISTORY_HASH_SIZE);
++
++ for (walker = PacketHistory[idx]; walker != NULL; walker = walker->next)
++ {
++ if (walker->crc32 == crc32)
++ {
++ /* Found duplicate entry */
++
++ /* Always mark as "seen recently": refresh time-out */
++ walker->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
++
++ return 1;
++ } /* if */
++ } /* for */
++
++ /* No duplicate entry found: create one */
++ newEntry = malloc(sizeof(struct TDupEntry));
++ if (newEntry != NULL)
++ {
++ newEntry->crc32 = crc32;
++ newEntry->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
++
++ /* Add new entry at the front of the list */
++ newEntry->next = PacketHistory[idx];
++ PacketHistory[idx] = newEntry;
++ }
++
++ return 0;
++} /* CheckAndMarkRecentPacket */
++
++/* -------------------------------------------------------------------------
++ * Function : PrunePacketHistory
++ * Description: Prune the packet history table.
++ * Input : useless - not used
++ * Output : none
++ * Return : none
++ * Data Used : PacketHistory
++ * ------------------------------------------------------------------------- */
++void PrunePacketHistory(void* useless __attribute__((unused)))
++{
++ uint i;
++ for (i = 0; i < HISTORY_HASH_SIZE; i++)
++ {
++ if (PacketHistory[i] != NULL)
++ {
++ struct TDupEntry* nextEntry = PacketHistory[i];
++ struct TDupEntry* prevEntry = NULL;
++ while (nextEntry != NULL)
++ {
++ struct TDupEntry* entry = nextEntry;
++ nextEntry = entry->next;
++
++ if (TIMED_OUT(entry->timeOut))
++ {
++ /* De-queue */
++ if (prevEntry != NULL)
++ {
++ prevEntry->next = entry->next;
++ }
++ else
++ {
++ PacketHistory[i] = entry->next;
++ } /* if */
++
++ /* De-allocate memory */
++ free(entry);
++ }
++ else
++ {
++ prevEntry = entry;
++ } /* if */
++ } /* while */
++ } /* if (PacketHistory[i] != NULL) */
++ } /* for (i = ...) */
++} /* PrunePacketHistory */
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/PacketHistory.h olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/PacketHistory.h
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/PacketHistory.h 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/PacketHistory.h 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,75 @@
++#ifndef _BMF_PACKETHISTORY_H
++#define _BMF_PACKETHISTORY_H
++
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : PacketHistory.h
++ * Description: Functions for keeping and accessing the history of processed
++ * multicast IP packets.
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++/* System includes */
++#include <sys/types.h> /* ssize_t */
++#include <sys/times.h> /* clock_t */
++
++#define N_HASH_BITS 12
++#define HISTORY_HASH_SIZE (1 << N_HASH_BITS)
++
++/* Time-out of duplicate entries, in milliseconds */
++#define HISTORY_HOLD_TIME 3000
++
++struct TDupEntry
++{
++ u_int32_t crc32;
++ clock_t timeOut;
++ struct TDupEntry* next;
++};
++
++void InitPacketHistory(void);
++u_int32_t PacketCrc32(unsigned char* ipPkt, ssize_t len);
++u_int32_t Hash(u_int32_t from32);
++void MarkRecentPacket(u_int32_t crc32);
++int CheckAndMarkRecentPacket(u_int32_t crc32);
++void PrunePacketHistory(void*);
++
++#endif /* _BMF_PACKETHISTORY_H */
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/mdns.c olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/mdns.c
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/mdns.c 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/mdns.c 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,1174 @@
++/*
++ * OLSR MDNS plugin.
++ * Written by Saverio Proto.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++
++//#define _MULTI_THREADED
++
++#include "mdns.h"
++
++/* System includes */
++#include <stddef.h> /* NULL */
++#include <sys/types.h> /* ssize_t */
++#include <string.h> /* strerror() */
++#include <stdarg.h> /* va_list, va_start, va_end */
++#include <errno.h> /* errno */
++#include <assert.h> /* assert() */
++#include <linux/if_ether.h> /* ETH_P_IP */
++#include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
++//#include <pthread.h> /* pthread_t, pthread_create() */
++#include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
++#include <netinet/ip.h> /* struct ip */
++#include <netinet/udp.h> /* struct udphdr */
++#include <unistd.h> /* close() */
++
++#include <netinet/in.h>
++#include <netinet/ip6.h>
++
++/* OLSRD includes */
++#include "plugin_util.h" /* set_plugin_int */
++#include "defs.h" /* olsr_cnf, OLSR_PRINTF */
++#include "ipcalc.h"
++#include "olsr.h" /* OLSR_PRINTF */
++#include "mid_set.h" /* mid_lookup_main_addr() */
++#include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
++#include "link_set.h" /* get_best_link_to_neighbor() */
++#include "net_olsr.h" /* ipequal */
++
++/* plugin includes */
++#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
++#include "Address.h" /* IsMulticast() */
++#include "Packet.h" /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
++#include "PacketHistory.h" /* InitPacketHistory() */
++
++//static pthread_t mdnsThread;
++//static int mdnsThreadRunning = 0;
++
++/* -------------------------------------------------------------------------
++ * Function : PacketReceivedFromOLSR
++ * Description: Handle a received packet from a OLSR message
++ * Input : ipPacket into an unsigned char and the lenght of the packet
++ * Output : none
++ * Return : none
++ * Data Used : BmfInterfaces
++ * ------------------------------------------------------------------------- */
++static void PacketReceivedFromOLSR(
++ unsigned char* encapsulationUdpData, int len)
++{
++ struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
++ union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
++ union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
++ struct TBmfInterface* walker;
++ ipHeader = (struct ip*) encapsulationUdpData;
++ mcSrc.v4 = ipHeader->ip_src;
++ mcDst.v4 = ipHeader->ip_dst;
++
++ OLSR_PRINTF(3, "MDNS PLUGIN got packet from OLSR message\n");
++
++
++ /* Check with each network interface what needs to be done on it */
++ for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
++ {
++ /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
++ if (walker->olsrIntf == NULL)
++ {
++ int nBytesWritten;
++ struct sockaddr_ll dest;
++
++ memset(&dest, 0, sizeof(dest));
++ dest.sll_family = AF_PACKET;
++ if ((encapsulationUdpData[0] & 0xf0) == 0x40) dest.sll_protocol = htons(ETH_P_IP);
++ if ((encapsulationUdpData[0] & 0xf0) == 0x60) dest.sll_protocol = htons(ETH_P_IPV6);
++ //TODO: if packet is not IP die here
++ dest.sll_ifindex = if_nametoindex(walker->ifName);
++ dest.sll_halen = IFHWADDRLEN;
++
++ /* Use all-ones as destination MAC address. When the IP destination is
++ * a multicast address, the destination MAC address should normally also
++ * be a multicast address. E.g., when the destination IP is 224.0.0.1,
++ * the destination MAC should be 01:00:5e:00:00:01. However, it does not
++ * seem to matter when the destination MAC address is set to all-ones
++ * in that case. */
++ memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
++
++ nBytesWritten = sendto(
++ walker->capturingSkfd,
++ encapsulationUdpData,
++ len,
++ 0,
++ (struct sockaddr*) &dest,
++ sizeof(dest));
++ if (nBytesWritten != len)
++ {
++ BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
++ }
++ else
++ {
++
++ OLSR_PRINTF(
++ 2,
++ "%s: --> unpacked and forwarded on \"%s\"\n",
++ PLUGIN_NAME_SHORT,
++ walker->ifName);
++ }
++ } /* if (walker->olsrIntf == NULL) */
++}
++} /* PacketReceivedFromOLSR */
++
++
++
++bool
++olsr_parser(union olsr_message *m,
++ struct interface *in_if __attribute__((unused)),
++ union olsr_ip_addr *ipaddr)
++{
++ union olsr_ip_addr originator;
++ int size;
++ olsr_reltime vtime;
++ OLSR_PRINTF(2, "MDNS PLUGIN: Received msg in parser\n");
++ /* Fetch the originator of the messsage */
++ if(olsr_cnf->ip_version == AF_INET) {
++ memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
++ vtime = me_to_reltime(m->v4.olsr_vtime);
++ size = ntohs(m->v4.olsr_msgsize);
++ } else {
++ memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
++ vtime = me_to_reltime(m->v6.olsr_vtime);
++ size = ntohs(m->v6.olsr_msgsize);
++ }
++
++ /* Check if message originated from this node.
++ * If so - back off */
++ if(ipequal(&originator, &olsr_cnf->main_addr))
++ return false;
++
++ /* Check that the neighbor this message was received from is symmetric.
++ * If not - back off*/
++ if(check_neighbor_link(ipaddr) != SYM_LINK) {
++ struct ipaddr_str strbuf;
++ OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(&strbuf, ipaddr));
++ return false;
++ }
++
++ if(olsr_cnf->ip_version == AF_INET){
++ PacketReceivedFromOLSR((unsigned char*) &m->v4.message,size-12);
++ }
++ else {
++ PacketReceivedFromOLSR((unsigned char*) &m->v6.message,size-12-96);
++ }
++ /* Forward the message */
++ return 1;
++}
++
++//Sends a packet in the OLSR network
++void
++olsr_mdns_gen(unsigned char* packet, int len)
++{
++ /* send buffer: huge */
++ char buffer[10240];
++ union olsr_message *message = (union olsr_message *)buffer;
++ struct interface *ifn;
++ //int namesize;
++
++ /* fill message */
++ if(olsr_cnf->ip_version == AF_INET)
++ {
++ /* IPv4 */
++ message->v4.olsr_msgtype = MESSAGE_TYPE;
++ message->v4.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
++ memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
++ message->v4.ttl = MAX_TTL;
++ message->v4.hopcnt = 0;
++ message->v4.seqno = htons(get_msg_seqno());
++
++ message->v4.olsr_msgsize = htons(len+12);
++
++ memcpy(&message->v4.message,packet,len);
++ len=len+12;
++ }
++ else
++ {
++ /* IPv6 */
++ message->v6.olsr_msgtype = MESSAGE_TYPE;
++ message->v6.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
++ memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
++ message->v6.ttl = MAX_TTL;
++ message->v6.hopcnt = 0;
++ message->v6.seqno = htons(get_msg_seqno());
++
++ message->v6.olsr_msgsize = htons(len+12+96);
++ memcpy(&message->v6.message,packet,len);
++ len=len+12+96;
++ }
++
++ /* looping trough interfaces */
++ for (ifn = ifnet; ifn; ifn = ifn->int_next) {
++ OLSR_PRINTF(1, "MDNS PLUGIN: Generating packet - [%s]\n", ifn->int_name);
++
++ if(net_outbuffer_push(ifn, message, len) != len) {
++ /* send data and try again */
++ net_output(ifn);
++ if(net_outbuffer_push(ifn, message, len) != len) {
++ OLSR_PRINTF(1, "MDNS PLUGIN: could not send on interface: %s\n", ifn->int_name);
++ }
++ }
++ }
++}
++
++/* -------------------------------------------------------------------------
++ * Function : BmfPError
++ * Description: Prints an error message at OLSR debug level 1.
++ * First the plug-in name is printed. Then (if format is not NULL
++ * and *format is not empty) the arguments are printed, followed
++ * by a colon and a blank. Then the message and a new-line.
++ * Input : format, arguments
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++
++void BmfPError(const char* format, ...)
++{
++#define MAX_STR_DESC 255
++#ifndef NODEBUG
++ char* strErr = strerror(errno);
++#endif
++ char strDesc[MAX_STR_DESC];
++
++ /* Rely on short-circuit boolean evaluation */
++ if (format == NULL || *format == '\0')
++ {
++ OLSR_PRINTF(1, "%s: %s\n", PLUGIN_NAME, strErr);
++ }
++ else
++ {
++ va_list arglist;
++
++ OLSR_PRINTF(1, "%s: ", PLUGIN_NAME);
++
++ va_start(arglist, format);
++ vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
++ va_end(arglist);
++
++ strDesc[MAX_STR_DESC - 1] = '\0'; /* Ensures null termination */
++
++ OLSR_PRINTF(1, "%s: %s\n", strDesc, strErr);
++ }
++} /* BmfPError */
++
++/* -------------------------------------------------------------------------
++ * Function : MainAddressOf
++ * Description: Lookup the main address of a node
++ * Input : ip - IP address of the node
++ * Output : none
++ * Return : The main IP address of the node
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip)
++{
++ union olsr_ip_addr* result;
++
++ /* TODO: mid_lookup_main_addr() is not thread-safe! */
++ result = mid_lookup_main_addr(ip);
++ if (result == NULL)
++ {
++ result = ip;
++ }
++ return result;
++} /* MainAddressOf */
++
++/* -------------------------------------------------------------------------
++ * Function : EncapsulateAndForwardPacket
++ * Description: Encapsulate a captured raw IP packet and forward it
++ * Input : intf - the network interface on which to forward the packet
++ * encapsulationUdpData - The encapsulation header, followed by
++ * the encapsulated IP packet
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * ------------------------------------------------------------------------- */
++//static void EncapsulateAndForwardPacket(
++// struct TBmfInterface* intf,
++// unsigned char* encapsulationUdpData)
++//{
++//// /* The packet */
++// u_int16_t udpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
++//
++// /* The next destination(s) */
++// struct TBestNeighbors bestNeighborLinks;
++// struct link_entry* bestNeighbor;
++//
++// int nPossibleNeighbors = 0;
++// struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
++// int nPacketsToSend;
++// int sendUnicast; /* 0 = send broadcast; 1 = send unicast */
++//
++// int i;
++//
++// /* Find at most 'FanOutLimit' best neigbors to forward the packet to */
++// FindNeighbors(&bestNeighborLinks, &bestNeighbor, intf, NULL, NULL, NULL, &nPossibleNeighbors);
++//
++// if (nPossibleNeighbors <= 0)
++// {
++// OLSR_PRINTF(
++// 8,
++// "%s: --> not encap-forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
++// PLUGIN_NAME_SHORT,
++// intf->ifName);
++// return;
++// }
++//
++// /* Compose destination of encapsulation packet */
++//
++// memset(&forwardTo, 0, sizeof(forwardTo));
++// forwardTo.sin_family = AF_INET;
++// forwardTo.sin_port = htons(BMF_ENCAP_PORT);
++//
++// /* Start by filling in the local broadcast address. This may be overwritten later. */
++// forwardTo.sin_addr = intf->broadAddr.v4;
++//
++// /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
++// * unicast packet (to the best neighbor).
++// * - But if the BMF mechanism is BM_BROADCAST,
++// * - send 'nPossibleNeighbors' unicast packets if there are up to
++// * 'FanOutLimit' possible neighbors,
++// * - if there are more than 'FanOutLimit' possible neighbors, then
++// * send a (WLAN-air-expensive, less reliable) broadcast packet. */
++// if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
++// {
++// /* One unicast packet to the best neighbor */
++// nPacketsToSend = 1;
++// sendUnicast = 1;
++// bestNeighborLinks.links[0] = bestNeighbor;
++// }
++// else /* BmfMechanism == BM_BROADCAST */
++// {
++// if (nPossibleNeighbors <= FanOutLimit)
++// {
++// /* 'nPossibleNeighbors' unicast packets */
++// nPacketsToSend = nPossibleNeighbors;
++// sendUnicast = 1;
++// }
++// else /* nPossibleNeighbors > FanOutLimit */
++// {
++// /* One broadcast packet, possibly retransmitted as specified in the
++// * 'BroadcastRetransmitCount' plugin parameter */
++// nPacketsToSend = BroadcastRetransmitCount;
++// sendUnicast = 0;
++// } /* if */
++// } /* if */
++//
++// for (i = 0; i < nPacketsToSend; i++)
++// {
++// int nBytesWritten;
++//
++// if (sendUnicast == 1)
++// {
++// /* For unicast, overwrite the local broadcast address which was filled in above */
++// forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
++// }
++//
++// /* Forward the BMF packet via the encapsulation socket */
++// nBytesWritten = sendto(
++// intf->encapsulatingSkfd,
++// encapsulationUdpData,
++// udpDataLen,
++// MSG_DONTROUTE,
++// (struct sockaddr*) &forwardTo,
++// sizeof(forwardTo));
++//
++// /* Evaluate and display result */
++// if (nBytesWritten != udpDataLen)
++// {
++// BmfPError("sendto() error forwarding pkt on \"%s\"", intf->ifName);
++// }
++// else
++// {
++// /* Increase counter */
++// intf->nBmfPacketsTx++;
++//
++// OLSR_PRINTF(
++// 8,
++// "%s: --> encapsulated and forwarded on \"%s\" to %s\n",
++// PLUGIN_NAME_SHORT,
++// intf->ifName,
++// inet_ntoa(forwardTo.sin_addr));
++// } /* if (nBytesWritten != udpDataLen) */
++// } /* for */
++//} /* EncapsulateAndForwardPacket */
++
++/* -------------------------------------------------------------------------
++ * Function : BmfPacketCaptured
++ * Description: Handle a captured IP packet
++ * Input : intf - the network interface on which the packet was captured
++ * sllPkttype - the type of packet. Either PACKET_OUTGOING,
++ * PACKET_BROADCAST or PACKET_MULTICAST.
++ * encapsulationUdpData - space for the encapsulation header, followed by
++ * the captured IP packet
++ * Output : none
++ * Return : none
++ * Data Used : BmfInterfaces
++ * Notes : The IP packet is assumed to be captured on a socket of family
++ * PF_PACKET and type SOCK_DGRAM (cooked).
++ * ------------------------------------------------------------------------- */
++static void BmfPacketCaptured(
++ //struct TBmfInterface* intf,
++ //unsigned char sllPkttype,
++ unsigned char* encapsulationUdpData,
++ int nBytes)
++{
++ union olsr_ip_addr src; /* Source IP address in captured packet */
++ union olsr_ip_addr dst; /* Destination IP address in captured packet */
++ union olsr_ip_addr* origIp; /* Main OLSR address of source of captured packet */
++ //struct TBmfInterface* walker;
++ //int isFromOlsrIntf;
++ //int isFromOlsrNeighbor;
++ //int iAmMpr;
++ //unsigned char* ipPacket; /* The captured IP packet... */
++ //u_int16_t ipPacketLen; /* ...and its length */
++ struct ip* ipHeader; /* The IP header inside the captured IP packet */
++ struct ip6_hdr* ipHeader6; /* The IP header inside the captured IP packet */
++ //u_int32_t crc32;
++ //struct TEncapHeader* encapHdr;
++ //struct ipaddr_str srcBuf, dstBuf;
++ struct udphdr* udpHeader;
++ u_int16_t destPort;
++
++ if ((encapsulationUdpData[0] & 0xf0) == 0x40) { //IPV4
++
++ ipHeader = (struct ip*) encapsulationUdpData;
++
++ dst.v4 = ipHeader->ip_dst;
++
++ /* Only forward multicast packets. If configured, also forward local broadcast packets */
++ if (IsMulticast(&dst))
++ {
++ /* continue */
++ }
++ else
++ {
++ return;
++ }
++ if (ipHeader->ip_p != SOL_UDP)
++ {
++ /* Not UDP */
++ OLSR_PRINTF(1,"NON UDP PACKET\n");
++ return; /* for */
++ }
++ udpHeader = (struct udphdr*)(encapsulationUdpData + GetIpHeaderLength(encapsulationUdpData));
++ destPort = ntohs(udpHeader->dest);
++ if (destPort != 5353)
++ {
++ return;
++ }
++ }//END IPV4
++
++ else if ((encapsulationUdpData[0] & 0xf0) == 0x60) { //IPv6
++
++ ipHeader6 = (struct ip6_hdr*) encapsulationUdpData;
++ if (ipHeader6->ip6_dst.s6_addr[0] == 0xff) //Multicast
++ {
++ //Continua
++ }
++ else
++ {
++ return; //not multicast
++ }
++ if (ipHeader6->ip6_nxt != SOL_UDP)
++ {
++ /* Not UDP */
++ OLSR_PRINTF(1,"NON UDP PACKET\n");
++ return; /* for */
++ }
++ udpHeader = (struct udphdr*)(encapsulationUdpData + 40);
++ destPort = ntohs(udpHeader->dest);
++ if (destPort != 5353)
++ {
++ return;
++ }
++ } //END IPV6
++ else return; //Is not IP packet
++
++ /* Check if the frame is captured on an OLSR-enabled interface */
++ //isFromOlsrIntf = (intf->olsrIntf != NULL); TODO: put again this check
++
++ /* Retrieve the length of the captured packet */
++ //ipPacketLen = GetIpTotalLength(ipPacket);
++
++ //src.v4 = ipHeader->ip_src;
++
++ //OLSR_PRINTF(
++ // 1,
++ // "%s: %s pkt of %ld bytes captured on %s interface \"%s\": %s->%s\n",
++ // PLUGIN_NAME_SHORT,
++ // sllPkttype == PACKET_OUTGOING ? "outgoing" : "incoming",
++ // (long)ipPacketLen,
++ // isFromOlsrIntf ? "OLSR" : "non-OLSR",
++ // intf->ifName,
++ // olsr_ip_to_string(&srcBuf, &src),
++ // olsr_ip_to_string(&dstBuf, &dst));
++
++ /* Lookup main address of source in the MID table of OLSR */
++ origIp = MainAddressOf(&src);
++
++ // send the packet to OLSR forward mechanism
++ olsr_mdns_gen(encapsulationUdpData,nBytes);
++} /* BmfPacketCaptured */
++
++
++/* -------------------------------------------------------------------------
++ * Function : BmfEncapsulationPacketReceived
++ * Description: Handle a received BMF-encapsulation packet
++ * Input : intf - the network interface on which the packet was received
++ * forwardedBy - the IP node that forwarded the packet to me
++ * forwardedTo - the destination IP address of the encapsulation
++ * packet, in case the packet was received promiscuously.
++ * Pass NULL if the packet is received normally (unicast or
++ * broadcast).
++ * encapsulationUdpData - the encapsulating IP UDP data, containting
++ * the BMF encapsulation header, followed by the encapsulated
++ * IP packet
++ * Output : none
++ * Return : none
++ * Data Used : BmfInterfaces
++ * ------------------------------------------------------------------------- */
++//static void BmfEncapsulationPacketReceived(
++// struct TBmfInterface* intf,
++// union olsr_ip_addr* forwardedBy,
++// union olsr_ip_addr* forwardedTo,
++// unsigned char* encapsulationUdpData)
++//{
++// int iAmMpr; /* True (1) if I am selected as MPR by 'forwardedBy' */
++// struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
++// unsigned char* ipPacket; /* The encapsulated IP packet */
++// u_int16_t ipPacketLen; /* Length of the encapsulated IP packet */
++// struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
++// union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
++// union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
++// struct TEncapHeader* encapsulationHdr;
++// u_int16_t encapsulationUdpDataLen;
++// struct TBmfInterface* walker;
++// struct ipaddr_str mcSrcBuf, mcDstBuf, forwardedByBuf, forwardedToBuf;
++// /* Are we talking to ourselves? */
++// if (if_ifwithaddr(forwardedBy) != NULL)
++// {
++// return;
++// }
++//
++// /* Discard encapsulated packets received on a non-OLSR interface */
++// if (intf->olsrIntf == NULL)
++// {
++// return;
++// }
++//
++// /* Retrieve details about the encapsulated IP packet */
++// ipPacket = GetIpPacket(encapsulationUdpData);
++// ipPacketLen = GetIpTotalLength(ipPacket);
++// ipHeader = GetIpHeader(encapsulationUdpData);
++//
++// mcSrc.v4 = ipHeader->ip_src;
++// mcDst.v4 = ipHeader->ip_dst;
++//
++// /* Increase counter */
++// intf->nBmfPacketsRx++;
++//
++// /* Beware: not possible to call olsr_ip_to_string more than 4 times in same printf */
++// OLSR_PRINTF(
++// 8,
++// "%s: encapsulated pkt of %ld bytes incoming on \"%s\": %s->%s, forwarded by %s to %s\n",
++// PLUGIN_NAME_SHORT,
++// (long)ipPacketLen,
++// intf->ifName,
++// olsr_ip_to_string(&mcSrcBuf, &mcSrc),
++// olsr_ip_to_string(&mcDstBuf, &mcDst),
++// olsr_ip_to_string(&forwardedByBuf, forwardedBy),
++// forwardedTo != NULL ? olsr_ip_to_string(&forwardedToBuf, forwardedTo) : "me");
++//
++// /* Get encapsulation header */
++// encapsulationHdr = (struct TEncapHeader*) encapsulationUdpData;
++//
++// /* Verify correct format of BMF encapsulation header */
++// if (encapsulationHdr->type != BMF_ENCAP_TYPE ||
++// encapsulationHdr->len != BMF_ENCAP_LEN ||
++// ntohs(encapsulationHdr->reserved != 0))
++// {
++// OLSR_PRINTF(
++// 8,
++// "%s: --> discarding: format of BMF encapsulation header not recognized\n",
++// PLUGIN_NAME_SHORT);
++// return;
++// }
++//
++// /* Check if this packet was seen recently */
++// if (CheckAndMarkRecentPacket(ntohl(encapsulationHdr->crc32)))
++// {
++// /* Increase counter */
++// intf->nBmfPacketsRxDup++;
++//
++// OLSR_PRINTF(
++// 8,
++// "%s: --> discarding: packet is duplicate\n",
++// PLUGIN_NAME_SHORT);
++// return;
++// }
++//
++// if (EtherTunTapFd >= 0)
++// {
++// /* Unpack the encapsulated IP packet and deliver it locally, by sending
++// * a copy into the local IP stack via the EtherTunTap interface */
++//
++// union olsr_ip_addr broadAddr;
++// int nBytesToWrite, nBytesWritten;
++// unsigned char* bufferToWrite;
++//
++// /* If the encapsulated IP packet is a local broadcast packet,
++// * update its destination address to match the subnet of the EtherTunTap
++// * interface */
++// broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
++// CheckAndUpdateLocalBroadcast(ipPacket, &broadAddr);
++//
++// bufferToWrite = ipPacket;
++// nBytesToWrite = ipPacketLen;
++//
++// /* Write the packet into the EtherTunTap interface for local delivery */
++// nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);
++// if (nBytesWritten != nBytesToWrite)
++// {
++// BmfPError("write() error forwarding encapsulated pkt on \"%s\"", EtherTunTapIfName);
++// }
++// else
++// {
++// OLSR_PRINTF(
++// 8,
++// "%s: --> unpacked and delivered locally on \"%s\"\n",
++// PLUGIN_NAME_SHORT,
++// EtherTunTapIfName);
++// }
++// } /* if (EtherTunTapFd >= 0) */
++//
++// /* Check if I am MPR for the forwarder */
++// /* TODO: olsr_lookup_mprs_set() is not thread-safe! */
++// iAmMpr = (olsr_lookup_mprs_set(MainAddressOf(forwardedBy)) != NULL);
++//
++// /* Compose destination address for next hop */
++// memset(&forwardTo, 0, sizeof(forwardTo));
++// forwardTo.sin_family = AF_INET;
++// forwardTo.sin_port = htons(BMF_ENCAP_PORT);
++//
++// /* Retrieve the number of bytes to be forwarded via the encapsulation socket */
++// encapsulationUdpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
++//
++// /* Check with each network interface what needs to be done on it */
++// for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
++// {
++// /* What to do with the packet on a non-OLSR interface? Unpack
++// * encapsulated packet, and forward it.
++// *
++// * What to do with the packet on an OLSR interface? Forward it only
++// * if the forwarding node has selected us as MPR (iAmMpr).
++// *
++// * Note that the packet is always coming in on an OLSR interface, because
++// * it is an encapsulated BMF packet. */
++//
++// /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
++// if (walker->olsrIntf == NULL)
++// {
++// int nBytesWritten;
++// struct sockaddr_ll dest;
++//
++// /* If the encapsulated IP packet is a local broadcast packet,
++// * update its destination address to match the subnet of the network
++// * interface on which the packet is being sent. */
++// CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
++//
++// memset(&dest, 0, sizeof(dest));
++// dest.sll_family = AF_PACKET;
++// dest.sll_protocol = htons(ETH_P_IP);
++// dest.sll_ifindex = if_nametoindex(walker->ifName);
++// dest.sll_halen = IFHWADDRLEN;
++//
++// /* Use all-ones as destination MAC address. When the IP destination is
++// * a multicast address, the destination MAC address should normally also
++// * be a multicast address. E.g., when the destination IP is 224.0.0.1,
++// * the destination MAC should be 01:00:5e:00:00:01. However, it does not
++// * seem to matter when the destination MAC address is set to all-ones
++// * in that case. */
++// memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
++//
++// nBytesWritten = sendto(
++// walker->capturingSkfd,
++// ipPacket,
++// ipPacketLen,
++// 0,
++// (struct sockaddr*) &dest,
++// sizeof(dest));
++// if (nBytesWritten != ipPacketLen)
++// {
++// BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
++// }
++// else
++// {
++// /* Increase counter */
++// walker->nBmfPacketsTx++;
++//
++// OLSR_PRINTF(
++// 8,
++// "%s: --> unpacked and forwarded on \"%s\"\n",
++// PLUGIN_NAME_SHORT,
++// walker->ifName);
++// }
++// } /* if (walker->olsrIntf == NULL) */
++//
++// /* To an OLSR interface: forward the packet, but only if this node is
++// * selected as MPR by the forwarding node */
++// else if (iAmMpr)
++// {
++// struct TBestNeighbors bestNeighborLinks;
++// struct link_entry* bestNeighbor;
++// int nPossibleNeighbors;
++// int nPacketsToSend;
++// int sendUnicast; /* 0 = send broadcast; 1 = send unicast */
++// int i;
++//
++// /* Retrieve at most two best neigbors to forward the packet to */
++// FindNeighbors(
++// &bestNeighborLinks,
++// &bestNeighbor,
++// walker,
++// &mcSrc,
++// forwardedBy,
++// forwardedTo,
++// &nPossibleNeighbors);
++//
++// if (nPossibleNeighbors <= 0)
++// {
++// OLSR_PRINTF(
++// 8,
++// "%s: --> not forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
++// PLUGIN_NAME_SHORT,
++// walker->ifName);
++//
++// continue; /* for */
++// }
++//
++// /* Compose destination of encapsulation packet.
++// * Start by filling in the local broadcast address. This may be overwritten later. */
++// forwardTo.sin_addr = walker->broadAddr.v4;
++//
++// /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
++// * unicast packet (to the best neighbor).
++// * - But if the BMF mechanism is BM_BROADCAST,
++// * - send 'nPossibleNeighbors' unicast packets if there are up to
++// * 'FanOutLimit' possible neighbors,
++// * - if there are more than 'FanOutLimit' possible neighbors, then
++// * send a (WLAN-air-expensive, less reliable) broadcast packet. */
++// if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
++// {
++// /* One unicast packet to the best neighbor */
++// nPacketsToSend = 1;
++// sendUnicast = 1;
++// bestNeighborLinks.links[0] = bestNeighbor;
++// }
++// else /* BmfMechanism == BM_BROADCAST */
++// {
++// if (nPossibleNeighbors <= FanOutLimit)
++// {
++// /* 'nPossibleNeighbors' unicast packets */
++// nPacketsToSend = nPossibleNeighbors;
++// sendUnicast = 1;
++// }
++// else /* nPossibleNeighbors > FanOutLimit */
++// {
++// /* One broadcast packet, possibly retransmitted as specified in the
++// * 'BroadcastRetransmitCount' plugin parameter */
++// nPacketsToSend = BroadcastRetransmitCount;
++// sendUnicast = 0;
++// } /* if */
++// } /* if */
++//
++// for (i = 0; i < nPacketsToSend; i++)
++// {
++// int nBytesWritten;
++//
++// if (sendUnicast)
++// {
++// /* For unicast, overwrite the local broadcast address which was filled in above */
++// forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
++// }
++//
++// /* Forward the BMF packet via the encapsulation socket */
++// nBytesWritten = sendto(
++// walker->encapsulatingSkfd,
++// encapsulationUdpData,
++// encapsulationUdpDataLen,
++// MSG_DONTROUTE,
++// (struct sockaddr*) &forwardTo,
++// sizeof(forwardTo));
++//
++// /* Evaluate and display result */
++// if (nBytesWritten != encapsulationUdpDataLen)
++// {
++// BmfPError("sendto() error forwarding encapsulated pkt on \"%s\"", walker->ifName);
++// }
++// else
++// {
++// /* Increase counter */
++// walker->nBmfPacketsTx++;
++//
++// OLSR_PRINTF(
++// 8,
++// "%s: --> forwarded on \"%s\" to %s\n",
++// PLUGIN_NAME_SHORT,
++// walker->ifName,
++// inet_ntoa(forwardTo.sin_addr));
++// } /* if */
++// } /* for */
++// } /* else if (iAmMpr) */
++//
++// else /* walker->olsrIntf != NULL && !iAmMpr */
++// {
++// struct ipaddr_str buf;
++// /* 'walker' is an OLSR interface, but I am not selected as MPR. In that
++// * case, don't forward. */
++// OLSR_PRINTF(
++// 8,
++// "%s: --> not forwarding on \"%s\": I am not selected as MPR by %s\n",
++// PLUGIN_NAME_SHORT,
++// walker->ifName,
++// olsr_ip_to_string(&buf, forwardedBy));
++// } /* else */
++// } /* for */
++//} /* BmfEncapsulationPacketReceived */
++//
++/* -------------------------------------------------------------------------
++ * Function : BmfTunPacketCaptured
++ * Description: Handle an IP packet, captured outgoing on the tuntap interface
++ * Input : encapsulationUdpData - space for the encapsulation header, followed by
++ * the captured outgoing IP packet
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * Notes : The packet is assumed to be captured on a socket of family
++ * PF_PACKET and type SOCK_DGRAM (cooked).
++ * ------------------------------------------------------------------------- */
++//static void BmfTunPacketCaptured(unsigned char* encapsulationUdpData)
++//{
++// union olsr_ip_addr srcIp;
++// union olsr_ip_addr dstIp;
++// union olsr_ip_addr broadAddr;
++// struct TBmfInterface* walker;
++// unsigned char* ipPacket;
++// u_int16_t ipPacketLen;
++// struct ip* ipHeader;
++// u_int32_t crc32;
++// struct TEncapHeader* encapHdr;
++// struct ipaddr_str srcIpBuf, dstIpBuf;
++// ipPacket = GetIpPacket(encapsulationUdpData);
++// ipPacketLen = GetIpTotalLength(ipPacket);
++// ipHeader = GetIpHeader(encapsulationUdpData);
++//
++// dstIp.v4 = ipHeader->ip_dst;
++// broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
++//
++// /* Only forward multicast packets. If configured, also forward local broadcast packets */
++// if (IsMulticast(&dstIp) ||
++// (EnableLocalBroadcast != 0 && olsr_ipequal(&dstIp, &broadAddr)))
++// {
++// /* continue */
++// }
++// else
++// {
++// return;
++// }
++//
++// srcIp.v4 = ipHeader->ip_src;
++//
++// OLSR_PRINTF(
++// 8,
++// "%s: outgoing pkt of %ld bytes captured on tuntap interface \"%s\": %s->%s\n",
++// PLUGIN_NAME_SHORT,
++// (long)ipPacketLen,
++// EtherTunTapIfName,
++// olsr_ip_to_string(&srcIpBuf, &srcIp),
++// olsr_ip_to_string(&dstIpBuf, &dstIp));
++//
++// /* Calculate packet fingerprint */
++// crc32 = PacketCrc32(ipPacket, ipPacketLen);
++//
++// /* Check if this packet was seen recently */
++// if (CheckAndMarkRecentPacket(crc32))
++// {
++// OLSR_PRINTF(
++// 8,
++// "%s: --> discarding: packet is duplicate\n",
++// PLUGIN_NAME_SHORT);
++// return;
++// }
++//
++// /* Compose encapsulation header */
++// encapHdr = (struct TEncapHeader*) encapsulationUdpData;
++// memset (encapHdr, 0, ENCAP_HDR_LEN);
++// encapHdr->type = BMF_ENCAP_TYPE;
++// encapHdr->len = BMF_ENCAP_LEN;
++// encapHdr->reserved = 0;
++// encapHdr->crc32 = htonl(crc32);
++//
++// /* Check with each network interface what needs to be done on it */
++// for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
++// {
++// /* Is the forwarding interface OLSR-enabled? */
++// if (walker->olsrIntf != NULL)
++// {
++// /* On an OLSR interface: encapsulate and forward packet. */
++//
++// EncapsulateAndForwardPacket(walker, encapsulationUdpData);
++// }
++// else
++// {
++// /* On a non-OLSR interface: what to do?
++// * Answer 1: nothing. Multicast routing between non-OLSR interfaces
++// * is to be done by other protocols (e.g. PIM, DVMRP).
++// * Answer 2 (better): Forward it. */
++//
++// int nBytesWritten;
++// struct sockaddr_ll dest;
++//
++// /* If the encapsulated IP packet is a local broadcast packet,
++// * update its destination address to match the subnet of the network
++// * interface on which the packet is being sent. */
++// CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
++//
++// memset(&dest, 0, sizeof(dest));
++// dest.sll_family = AF_PACKET;
++// dest.sll_protocol = htons(ETH_P_IP);
++// dest.sll_ifindex = if_nametoindex(walker->ifName);
++// dest.sll_halen = IFHWADDRLEN;
++//
++// /* Use all-ones as destination MAC address. When the IP destination is
++// * a multicast address, the destination MAC address should normally also
++// * be a multicast address. E.g., when the destination IP is 224.0.0.1,
++// * the destination MAC should be 01:00:5e:00:00:01. However, it does not
++// * seem to matter when the destination MAC address is set to all-ones
++// * in that case. */
++// memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
++//
++// nBytesWritten = sendto(
++// walker->capturingSkfd,
++// ipPacket,
++// ipPacketLen,
++// 0,
++// (struct sockaddr*) &dest,
++// sizeof(dest));
++// if (nBytesWritten != ipPacketLen)
++// {
++// BmfPError("sendto() error forwarding pkt on \"%s\"", walker->ifName);
++// }
++// else
++// {
++// /* Increase counter */
++// walker->nBmfPacketsTx++;
++//
++// OLSR_PRINTF(
++// 8,
++// "%s: --> forwarded from non-OLSR to non-OLSR \"%s\"\n",
++// PLUGIN_NAME_SHORT,
++// walker->ifName);
++// } /* if */
++// } /* if */
++// } /* for */
++//} /* BmfTunPacketCaptured */
++//
++/* -------------------------------------------------------------------------
++ * Function : DoBmf
++ * Description: Wait (blocking) for IP packets, then call the handler for each
++ * received packet
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : BmfInterfaces
++ * ------------------------------------------------------------------------- */
++void DoMDNS(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
++
++{
++// int nFdBitsSet;
++ unsigned char rxBuffer[BMF_BUFFER_SIZE];
++// fd_set rxFdSet;
++// OLSR_PRINTF(1,"ENTERING DoMDNS\n");
++// assert(HighestSkfd >= 0);
++//
++// /* Make a local copy of the set of file descriptors that select() can
++// * modify to indicate which descriptors actually changed status */
++// rxFdSet = InputSet;
++//
++// /* Wait (blocking) for packets received on any of the sockets.
++// * NOTE: don't use a timeout (last parameter). It causes a high system CPU load! */
++// nFdBitsSet = select(HighestSkfd + 1, &rxFdSet, NULL, NULL, NULL);
++// if (nFdBitsSet < 0)
++// {
++// if (errno != EINTR)
++// {
++// BmfPError("select() error");
++// }
++// return;
++// }
++//
++ //while (nFdBitsSet > 0)
++ //{
++ //struct TBmfInterface* walker;
++
++ /* Check if a packet was received on the capturing socket (if any)
++ * of each network interface */
++ //for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
++ //{
++ //int skfd = walker->capturingSkfd;
++ //if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))
++ if (skfd >= 0)
++ {
++ struct sockaddr_ll pktAddr;
++ socklen_t addrLen = sizeof(pktAddr);
++ int nBytes;
++ unsigned char* ipPacket;
++
++ /* Receive the captured Ethernet frame, leaving space for the BMF
++ * encapsulation header */
++ ipPacket = GetIpPacket(rxBuffer);
++ nBytes = recvfrom(
++ skfd,
++ ipPacket,
++ //BMF_BUFFER_SIZE - ENCAP_HDR_LEN, //TODO: understand how to change this
++ BMF_BUFFER_SIZE, //TODO: understand how to change this
++ 0,
++ (struct sockaddr*)&pktAddr,
++ &addrLen);
++ if (nBytes < 0)
++ {
++ //BmfPError("recvfrom() error on \"%s\"", walker->ifName);
++
++ return; /* for */
++ } /* if (nBytes < 0) */
++
++ /* Check if the number of received bytes is large enough for an IP
++ * packet which contains at least a minimum-size IP header.
++ * Note: There is an apparent bug in the packet socket implementation in
++ * combination with VLAN interfaces. On a VLAN interface, the value returned
++ * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
++ * returned on a non-VLAN interface, for the same ethernet frame. */
++ if (nBytes < (int)sizeof(struct ip))
++ {
++ //OLSR_PRINTF(
++ // 1,
++ // "%s: captured frame too short (%d bytes) on \"%s\"\n",
++ // PLUGIN_NAME,
++ // nBytes,
++ // walker->ifName);
++
++ return; /* for */
++ }
++
++ if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
++ pktAddr.sll_pkttype == PACKET_MULTICAST ||
++ pktAddr.sll_pkttype == PACKET_BROADCAST)
++ {
++ /* A multicast or broadcast packet was captured */
++
++ //OLSR_PRINTF(
++ // 1,
++ // "%s: captured frame (%d bytes) on \"%s\"\n",
++ // PLUGIN_NAME,
++ // nBytes,
++ // walker->ifName);
++ //BmfPacketCaptured(walker, pktAddr.sll_pkttype, rxBuffer);
++ BmfPacketCaptured(ipPacket,nBytes);
++
++ } /* if (pktAddr.sll_pkttype == ...) */
++ } /* if (skfd >= 0 && (FD_ISSET...)) */
++// } /* for */
++
++// } /* while (nFdBitsSet > 0) */
++} /* DoMDNS */
++
++int InitMDNS(struct interface* skipThisIntf)
++{
++
++
++ //Tells OLSR to launch olsr_parser when the packets for this plugin arrive
++ olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
++ CreateBmfNetworkInterfaces(skipThisIntf);
++
++ return 0;
++} /* InitBmf */
++
++/* -------------------------------------------------------------------------
++ * Function : CloseBmf
++ * Description: Close the BMF plugin and clean up
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : BmfThread
++ * ------------------------------------------------------------------------- */
++void CloseMDNS(void)
++{
++// if (EtherTunTapFd >= 0)
++// {
++// /* If there is a multicast route, try to delete it first */
++// DeleteMulticastRoute();
++//
++// /* Restore IP spoof filter for EtherTunTap interface */
++// RestoreSpoofFilter();
++// }
++//
++// if (mdnsThreadRunning)
++// {
++// /* Signal BmfThread to exit */
++// /* Strangely enough, all running threads receive the SIGALRM signal. But only the
++// * BMF thread is affected by this signal, having specified a handler for this
++// * signal in its thread entry function BmfRun(...). */
++// if (pthread_kill(mdnsThread, SIGALRM) != 0)
++// {
++// BmfPError("pthread_kill() error");
++// }
++//
++// /* Wait for BmfThread to acknowledge */
++// if (pthread_join(mdnsThread, NULL) != 0)
++// {
++// BmfPError("pthread_join() error");
++// }
++// }
++//
++// /* Clean up after the BmfThread has been killed */
++ CloseBmfNetworkInterfaces();
++} /* CloseBmf */
++
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/mdns.h olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/mdns.h
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/mdns.h 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/mdns.h 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,95 @@
++#ifndef _BMF_BMF_H
++#define _BMF_BMF_H
++
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : Bmf.h
++ * Description: Multicast forwarding functions
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
++
++#include "parser.h"
++#include <socket_parser.h>
++
++#define MESSAGE_TYPE 132
++#define PARSER_TYPE MESSAGE_TYPE
++#define EMISSION_INTERVAL 10 /* seconds */
++#define EMISSION_JITTER 25 /* percent */
++#define MDNS_VALID_TIME 1800 /* seconds */
++
++/* BMF plugin data */
++#define PLUGIN_NAME "OLSRD MDNS plugin"
++#define PLUGIN_NAME_SHORT "OLSRD MDNS"
++#define PLUGIN_VERSION "1.0.0 (" __DATE__ " " __TIME__ ")"
++#define PLUGIN_COPYRIGHT " (C) Ninux.org"
++#define PLUGIN_AUTHOR " Saverio Proto (zioproto@gmail.com)"
++#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION "\n" PLUGIN_COPYRIGHT "\n" PLUGIN_AUTHOR
++#define PLUGIN_INTERFACE_VERSION 5
++
++/* UDP-Port on which multicast packets are encapsulated */
++//#define BMF_ENCAP_PORT 50698
++
++/* Forward declaration of OLSR interface type */
++struct interface;
++
++//extern int FanOutLimit;
++//extern int BroadcastRetransmitCount;
++
++void DoMDNS(int sd, void * x, unsigned int y);
++void BmfPError(const char* format, ...) __attribute__((format(printf, 1, 2)));
++union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip);
++//int InterfaceChange(struct interface* interf, int action);
++//int SetFanOutLimit(const char* value, void* data, set_plugin_parameter_addon addon);
++//int InitBmf(struct interface* skipThisIntf);
++//void CloseBmf(void);
++int InitMDNS(struct interface* skipThisIntf);
++void CloseMDNS(void);
++
++void olsr_mdns_gen(unsigned char* packet, int len);
++
++/* Parser function to register with the scheduler */
++bool
++olsr_parser(union olsr_message *, struct interface *, union olsr_ip_addr *);
++
++#endif /* _BMF_BMF_H */
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/olsrd_plugin.c olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/olsrd_plugin.c
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/src/olsrd_plugin.c 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/src/olsrd_plugin.c 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,185 @@
++/*
++ * OLSR Basic Multicast Forwarding (BMF) plugin.
++ * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
++ * Written by Erik Tromp.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in
++ * the documentation and/or other materials provided with the
++ * distribution.
++ * * Neither the name of Thales, BMF nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
++ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* -------------------------------------------------------------------------
++ * File : olsrd_plugin.c
++ * Description: Interface to the OLSRD plugin system
++ * Created : 29 Jun 2006
++ *
++ * ------------------------------------------------------------------------- */
++
++/* System includes */
++#include <assert.h> /* assert() */
++#include <stddef.h> /* NULL */
++
++/* OLSRD includes */
++#include "olsrd_plugin.h"
++#include "plugin_util.h"
++#include "defs.h" /* uint8_t, olsr_cnf */
++#include "scheduler.h" /* olsr_start_timer() */
++#include "olsr_cfg.h" /* olsr_cnf() */
++#include "olsr_cookie.h" /* olsr_alloc_cookie() */
++
++/* BMF includes */
++#include "mdns.h" /* InitBmf(), CloseBmf() */
++#include "PacketHistory.h" /* InitPacketHistory() */
++#include "NetworkInterfaces.h" /* AddNonOlsrBmfIf(), SetBmfInterfaceIp(), ... */
++#include "Address.h" /* DoLocalBroadcast() */
++
++static void __attribute__ ((constructor)) my_init(void);
++static void __attribute__ ((destructor)) my_fini(void);
++
++//static struct olsr_cookie_info *prune_packet_history_timer_cookie;
++
++void olsr_plugin_exit(void);
++
++/* -------------------------------------------------------------------------
++ * Function : olsrd_plugin_interface_version
++ * Description: Plugin interface version
++ * Input : none
++ * Output : none
++ * Return : BMF plugin interface version number
++ * Data Used : none
++ * Notes : Called by main OLSRD (olsr_load_dl) to check plugin interface
++ * version
++ * ------------------------------------------------------------------------- */
++int olsrd_plugin_interface_version(void)
++{
++ return PLUGIN_INTERFACE_VERSION;
++}
++
++/* -------------------------------------------------------------------------
++ * Function : olsrd_plugin_init
++ * Description: Plugin initialisation
++ * Input : none
++ * Output : none
++ * Return : fail (0) or success (1)
++ * Data Used : olsr_cnf
++ * Notes : Called by main OLSRD (init_olsr_plugin) to initialize plugin
++ * ------------------------------------------------------------------------- */
++int olsrd_plugin_init(void)
++{
++ /* Clear the packet history */
++ //InitPacketHistory();
++
++ /* Register ifchange function */
++ //add_ifchgf(&InterfaceChange);
++
++ /* create the cookie */
++ //prune_packet_history_timer_cookie = olsr_alloc_cookie("BMF: Prune Packet History", OLSR_COOKIE_TYPE_TIMER);
++
++ /* Register the duplicate registration pruning process */
++ //olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
++ // &PrunePacketHistory, NULL, prune_packet_history_timer_cookie->ci_id);
++
++
++ return InitMDNS(NULL);
++}
++
++/* -------------------------------------------------------------------------
++ * Function : olsr_plugin_exit
++ * Description: Plugin cleanup
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * Notes : Called by my_fini() at unload of shared object
++ * ------------------------------------------------------------------------- */
++void olsr_plugin_exit(void)
++{
++ CloseMDNS();
++}
++
++static const struct olsrd_plugin_parameters plugin_parameters[] = {
++ { .name = "NonOlsrIf", .set_plugin_parameter = &AddNonOlsrBmfIf, .data = NULL },
++ //{ .name = "DoLocalBroadcast", .set_plugin_parameter = &DoLocalBroadcast, .data = NULL },
++ //{ .name = "BmfInterface", .set_plugin_parameter = &SetBmfInterfaceName, .data = NULL },
++ //{ .name = "BmfInterfaceIp", .set_plugin_parameter = &SetBmfInterfaceIp, .data = NULL },
++ //{ .name = "CapturePacketsOnOlsrInterfaces", .set_plugin_parameter = &SetCapturePacketsOnOlsrInterfaces, .data = NULL },
++ //{ .name = "BmfMechanism", .set_plugin_parameter = &SetBmfMechanism, .data = NULL },
++ //{ .name = "FanOutLimit", .set_plugin_parameter = &SetFanOutLimit, .data = NULL },
++ //{ .name = "BroadcastRetransmitCount", .set_plugin_parameter = &set_plugin_int, .data = &BroadcastRetransmitCount},
++};
++
++/* -------------------------------------------------------------------------
++ * Function : olsrd_get_plugin_parameters
++ * Description: Return the parameter table and its size
++ * Input : none
++ * Output : params - the parameter table
++ * size - its size in no. of entries
++ * Return : none
++ * Data Used : plugin_parameters
++ * Notes : Called by main OLSR (init_olsr_plugin) for all plugins
++ * ------------------------------------------------------------------------- */
++void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
++{
++ *params = plugin_parameters;
++ *size = ARRAYSIZE(plugin_parameters);
++}
++
++/* -------------------------------------------------------------------------
++ * Function : my_init
++ * Description: Plugin constructor
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * Notes : Called at load of shared object
++ * ------------------------------------------------------------------------- */
++static void my_init(void)
++{
++ /* Print plugin info to stdout */
++ printf("%s\n", MOD_DESC);
++
++ return;
++}
++
++/* -------------------------------------------------------------------------
++ * Function : my_fini
++ * Description: Plugin destructor
++ * Input : none
++ * Output : none
++ * Return : none
++ * Data Used : none
++ * Notes : Called at unload of shared object
++ * ------------------------------------------------------------------------- */
++static void my_fini(void)
++{
++ olsr_plugin_exit();
++}
++
++/*
++ * Local Variables:
++ * c-basic-offset: 2
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff -Nurb olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/version-script.txt olsrd-0-5-6-ecb9cb41f488/lib/mdns/version-script.txt
+--- olsrd-0-5-6-ecb9cb41f488.orig/lib/mdns/version-script.txt 1970-01-01 00:00:00.000000000 +0000
++++ olsrd-0-5-6-ecb9cb41f488/lib/mdns/version-script.txt 2009-03-16 18:04:32.000000000 +0000
+@@ -0,0 +1,10 @@
++VERS_1.0
++{
++ global:
++ olsrd_plugin_interface_version;
++ olsrd_plugin_init;
++ olsrd_get_plugin_parameters;
++
++ local:
++ *;
++};