luci/contrib/package/olsrd-luci/patches/160-add-mdns.patch
2009-03-25 12:53:08 +00:00

4422 lines
154 KiB
Diff

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:
+ *;
+};