From d674c54faca07cf84ecd45458028c1364b58e448 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 25 Mar 2009 12:53:08 +0000 Subject: [PATCH 1/1] contrib/package/olsrd-luci: add mdns plugin --- contrib/package/olsrd-luci/Makefile | 15 +- .../package/olsrd-luci/patches/160-add-mdns.patch | 4422 ++++++++++++++++++++ 2 files changed, 4436 insertions(+), 1 deletion(-) create mode 100644 contrib/package/olsrd-luci/patches/160-add-mdns.patch diff --git a/contrib/package/olsrd-luci/Makefile b/contrib/package/olsrd-luci/Makefile index 1fc21cdf3..56dc833d7 100644 --- a/contrib/package/olsrd-luci/Makefile +++ b/contrib/package/olsrd-luci/Makefile @@ -126,6 +126,13 @@ define Package/olsrd-luci-mod-watchdog DEPENDS:=olsrd-luci endef +define Package/olsrd-luci-mod-mdns + $(call Package/olsrd-luci/common_info) + MENU:=1 + TITLE:=OLSR - mDNS Plugin + DEPENDS:=olsrd-luci +endef + TARGET_CFLAGS += $(FPIC) define Build/Compile @@ -141,7 +148,7 @@ define Build/Compile MANDIR="$(PKG_INSTALL_DIR)/usr/share/man" \ STRIP="true" \ INSTALL_LIB="true" \ - SUBDIRS="arprefresh bmf dot_draw dyn_gw dyn_gw_plain httpinfo nameservice secure txtinfo quagga watchdog" + SUBDIRS="arprefresh bmf dot_draw dyn_gw dyn_gw_plain httpinfo nameservice secure txtinfo quagga watchdog mdns" endef define Package/olsrd-luci/install @@ -208,6 +215,11 @@ define Package/olsrd-luci-mod-watchdog/install $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/watchdog/olsrd_watchdog.so.* $(1)/usr/lib/ endef +define Package/olsrd-luci-mod-mdns/install + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/mdns/olsrd_mdns.so.* $(1)/usr/lib/ +endef + $(eval $(call BuildPackage,olsrd-luci)) $(eval $(call BuildPackage,olsrd-luci-mod-arprefresh)) @@ -221,3 +233,4 @@ $(eval $(call BuildPackage,olsrd-luci-mod-secure)) $(eval $(call BuildPackage,olsrd-luci-mod-txtinfo)) $(eval $(call BuildPackage,olsrd-luci-mod-quagga)) $(eval $(call BuildPackage,olsrd-luci-mod-watchdog)) +$(eval $(call BuildPackage,olsrd-luci-mod-mdns)) diff --git a/contrib/package/olsrd-luci/patches/160-add-mdns.patch b/contrib/package/olsrd-luci/patches/160-add-mdns.patch new file mode 100644 index 000000000..3be22bb04 --- /dev/null +++ b/contrib/package/olsrd-luci/patches/160-add-mdns.patch @@ -0,0 +1,4422 @@ +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 /* NULL */ ++#include /* strcmp */ ++#include /* assert() */ ++#include /* struct ip */ ++#include /* 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 /* NULL */ ++#include /* syslog() */ ++#include /* strerror(), strchr(), strcmp() */ ++#include /* errno */ ++#include /* close() */ ++#include /* ioctl() */ ++#include /* fcntl() */ ++#include /* assert() */ ++#include /* socket(), ifreq, if_indextoname(), if_nametoindex() */ ++#include /* htons() */ ++#include /* ETH_P_IP */ ++#include /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */ ++#include /* IFF_TAP */ ++#include /* struct ip */ ++#include /* SOL_UDP */ ++#include /* 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 /* 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 /* NULL */ ++#include /* assert() */ ++#include /* memcpy() */ ++#include /* u_int8_t, u_int16_t, u_int32_t */ ++#include /* ntohs(), htons() */ ++#include /* 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 /* IFNAMSIZ, IFHWADDRLEN */ ++#include /* 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 /* NULL */ ++#include /* assert() */ ++#include /* memset */ ++#include /* u_int16_t, u_int32_t */ ++#include /* struct iphdr */ ++#include /* 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 /* ssize_t */ ++#include /* 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 /* NULL */ ++#include /* ssize_t */ ++#include /* strerror() */ ++#include /* va_list, va_start, va_end */ ++#include /* errno */ ++#include /* assert() */ ++#include /* ETH_P_IP */ ++#include /* struct sockaddr_ll, PACKET_MULTICAST */ ++//#include /* pthread_t, pthread_create() */ ++#include /* sigset_t, sigfillset(), sigdelset(), SIGINT */ ++#include /* struct ip */ ++#include /* struct udphdr */ ++#include /* close() */ ++ ++#include ++#include ++ ++/* 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 ++ ++#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() */ ++#include /* 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: ++ *; ++}; -- 2.11.0