1
0
mirror of https://git.openwrt.org/feed/routing.git synced 2024-06-13 10:49:15 +02:00
openwrt-routing/patches/170-olsrd-bmf.patch
Tim Yardley 776adbfedd merge olsrd changes with freifunks code changes. compiles completely, but have not tested with an actually mesh.
git-svn-id: svn://svn.openwrt.org/openwrt/packages/net/olsrd@6273 3c298f89-4303-0410-b956-a3cf2f4a3e73
2007-02-06 16:45:04 +00:00

3574 lines
122 KiB
Diff

diff -Nur olsrd-0.4.10.orig/lib/bmf/Makefile olsrd-0.4.10/lib/bmf/Makefile
--- olsrd-0.4.10.orig/lib/bmf/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/Makefile 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,64 @@
+#
+# 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.
+#
+# $Id: Makefile,v 1.10 2005/05/25 13:50:22 br1 Exp $
+
+OLSRD_PLUGIN = true
+PLUGIN_NAME = olsrd_bmf
+PLUGIN_VER = 1.1
+
+TOPDIR = ../..
+include $(TOPDIR)/Makefile.inc
+
+LIBS += -lpthread
+
+ifneq ($(OS),linux)
+
+default_target install clean:
+ @echo "*** BMF Plugin only supported on Linux, sorry!"
+
+else
+
+default_target: $(PLUGIN_FULLNAME)
+
+$(PLUGIN_FULLNAME): $(OBJS)
+ $(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
\ Kein Zeilenumbruch am Dateiende.
diff -Nur olsrd-0.4.10.orig/lib/bmf/PluginBmf.prj olsrd-0.4.10/lib/bmf/PluginBmf.prj
--- olsrd-0.4.10.orig/lib/bmf/PluginBmf.prj 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/PluginBmf.prj 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,83 @@
+#DO NOT EDIT THIS FILE!!!
+[APPTYPE@DEBUG]
+APPTYPE = 0
+[APPTYPE@RELEASE]
+APPTYPE = 0
+[COMPILE@DEBUG]
+COMPILEOPTION = -c -g
+[COMPILE@RELEASE]
+COMPILEOPTION = -c
+[CVS]
+INITDIR = $CVSROOT
+REMOTELOGIN = 0
+[DEBUG@DEBUG]
+EXEPOS = PluginSmf2
+WORKDIR =
+[DEBUG@RELEASE]
+EXEPOS = PluginSmf2
+WORKDIR =
+[DEPENDENCY]
+FILENAME = README_BMF.txt
+FILENAME = ../../olsrd.conf
+FILENAME = README_BMF
+FILENAME = version-script.txt
+FILENAME = README_SMF
+FILENAME = Makefile
+[GDBSERVER]
+ISGDBSERVER = 0
+[HEADER]
+FILENAME = src/Bmf.h
+FILENAME = src/PacketHistory.h
+FILENAME = src/Packet.h
+FILENAME = src/Address.h
+FILENAME = src/NetworkInterfaces.h
+FILENAME = src/DropList.h
+[LANTYPE@DEBUG]
+LANTYPE = 0
+[LANTYPE@RELEASE]
+LANTYPE = 0
+[LINK@DEBUG]
+LINKOPTION = -g -o PluginSmf2
+OUTPUT = PluginSmf2
+[LINK@RELEASE]
+LINKOPTION = -o PluginSmf2
+OUTPUT = PluginSmf2
+[MAIN]
+CONFIG = RELEASE,DEBUG
+DEFAULTCONFIG = DEBUG
+DEVTYPE = 0
+ONLINE = 1
+VERSION = 3.0
+WATCH =
+[MAKE@DEBUG]
+CUSTOMMAKE = Makefile
+CUSTOMMAKEBUILDPARAM =
+CUSTOMMAKECLEANPARAM = clean
+CUSTOMMAKEDIR =
+CUSTOMSHELL =
+MAKEFILE = Makefile_DEBUG.mk
+MANUALDEFAULT = 1
+REGENMAKEFILE = 1
+[MAKE@RELEASE]
+CUSTOMMAKE = Makefile
+CUSTOMMAKEBUILDPARAM =
+CUSTOMMAKECLEANPARAM = clean
+CUSTOMMAKEDIR =
+CUSTOMSHELL =
+MAKEFILE = Makefile_DEBUG.mk
+MANUALDEFAULT = 1
+REGENMAKEFILE = 1
+[PRECOMPILE@DEBUG]
+ESQL_OPTION = -g
+PROC_OPTION = DEFINE=_PROC_ MODE=ORACLE LINES=true
+[PRECOMPILE@RELEASE]
+ESQL_OPTION =
+PROC_OPTION = DEFINE=_PROC_ MODE=ORACLE
+[SOURCE]
+FILENAME = src/Bmf.c
+FILENAME = src/Packet.c
+FILENAME = src/PacketHistory.c
+FILENAME = src/DropList.c
+FILENAME = src/olsrd_plugin.c
+FILENAME = src/Address.c
+FILENAME = src/NetworkInterfaces.c
diff -Nur olsrd-0.4.10.orig/lib/bmf/README_BMF.txt olsrd-0.4.10/lib/bmf/README_BMF.txt
--- olsrd-0.4.10.orig/lib/bmf/README_BMF.txt 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/README_BMF.txt 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,233 @@
+BASIC MULTICAST FORWARDING PLUGIN FOR OLSRD
+by Erik Tromp (erik.tromp@nl.thalesgroup.com)
+
+12 Jul 2006: Version 1.1
+* Major updates in code forwarding from and to non-OLSR enabled
+ network interfaces.
+* Debug level 9 gives a better indication of what happens to each
+ handled multicast/broadcast packet.
+* Can now deal with network interface removal ("ifdown eth1") and
+ addition ("ifup eth1").
+* CRC-calculation for duplicate detection is done over first 256
+ bytes in packet instead of over full packet length.
+* CRC calculated only on captured packets, and is subsequently
+ passed on in a special OLSR-BMF encapsulation header.
+* Deals correctly with fragmented packets
+
+27 Apr 2006: Version 1.0.1
+* First release.
+
+1. Introduction
+---------------
+
+The Basic Multicast Forwarding Plugin floods IP-multicast and
+IP-local-broadcast traffic over an OLSRD network. It uses the
+Multi-Point Relays (MPRs) as identified by the OLSR protocol
+to optimize the flooding of multicast and local broadcast packets
+to all the nodes in the network. To prevent broadcast storms, a
+history of packets is kept; only packets that have not been seen
+in the past 3-6 seconds are forwarded.
+
+In the IP header there is room for only two IP-addresses:
+* the destination IP address (in our case either a multicast
+ IP-address 224.0.0.0...239.255.255.255, or a local broadcast
+ address e.g. 192.168.1.255), and
+* the source IP address (the originator).
+
+For optimized flooding, however, we need more information. Let's
+assume we are the BMF process on one node. We will need to know which
+node forwarded the IP packet to us. Since OLSR keeps track of which
+nodes select our node as MPR (see the olsr_lookup_mprs_set function),
+we can determine if the node that forwarded the packet, has selected us as
+MPR. If so, we must also forward the packet, changing the 'forwarded-by'
+IP-address to that of us.
+
+Because we need more information than fits in a normal IP-header, the
+original packets are encapsulated into a new IP packet. Encapsulated
+packets are transported in UDP, port 50505. The source address of the
+encapsulation packet is set to the address of the forwarder instead of
+the originator. Of course, the payload of the encapsulation packet is
+the original IP packet.
+
+For local reception, each received encapsulated packets is unpacked
+and passed into a tuntap interface which is specially created for
+this purpose.
+
+Here is in short how the flooding works (see also the
+BmfEncapsulatedPacketReceived(...) function; details with respect to
+the forwarding towards non-OLSR enabled nodes are omitted):
+
+ On all OLSR-enabled interfaces, setup reception of packets
+ on UDP port 50505.
+ Upon reception of such a packet:
+ If the received packet was sent by myself, drop it.
+ If the packet was recently seen, drop it.
+ Unpack the encapsulated packet and send a copy to myself via the
+ TunTap device.
+ If I am an MPR for the node that forwarded the packet to me,
+ forward the packet to all OLSR-enabled interfaces *including*
+ the interface on which it was received.
+
+As with all good things in life, it's so simple you could have
+thought of it yourself.
+
+
+2. How to build and install
+---------------------------
+
+Follow the instructions in the base directory README file under
+section II. - BUILDING AND RUNNING OLSRD. To be sure to install
+the BMF plugin, cd to the base directory and issue the follwing
+command at the shell prompt:
+
+ make install_all
+
+Next, turn on the possibility to create a tuntap device (see also
+/usr/src/linux/Documentation/networking/tuntap.txt)
+
+ mkdir /dev/net # if it doesn't exist already
+ mknod /dev/net/tun c 10 200
+
+Set permissions, e.g.:
+ chmod 0700 /dev/net/tun
+
+Edit the file /etc/olsrd.conf to load the BMF plugin. For example:
+
+ LoadPlugin "olsrd_bmf.so.1.1"
+ {
+ # No PlParam entries required for basic operation
+ }
+
+
+3. How to run
+-------------
+
+After building and installing OLSRD with the BMF plugin, run the
+olsrd deamon by entering at the shell prompt:
+ olsrd
+
+Look at the output; it should list the BMF plugin, e.g.:
+
+ ---------- Plugin loader ----------
+ Library: olsrd_bmf.so.1.1
+ OLSRD Basic Multicast Forwarding plugin 1.1 (Jul 12 2006 04:12:42)
+ (C) Thales Communications Huizen, Netherlands
+ Erik Tromp (erik.tromp@nl.thalesgroup.com)
+ Checking plugin interface version... 4 - OK
+ Trying to fetch plugin init function... OK
+ Trying to fetch param function... OK
+ Sending parameters...
+ "NonOlsrIf"/"eth0"... OK
+ Running plugin_init function...
+ OLSRD Basic Multicast Forwarding plugin: opened 6 sockets
+ ---------- LIBRARY LOADED ----------
+
+
+4. How to check if it works
+---------------------------
+
+To check that BMF is working, enter the following command on the
+command prompt:
+
+ ping -I eth1 224.0.0.1
+
+Replace eth1 with the name of any OLSR-enabled network interface.
+
+All OLSR-BMF nodes in the MANET should respond. For example:
+
+root@IsdbServer:~# ping -I eth1 224.0.0.1
+PING 224.0.0.1 (224.0.0.1) from 192.168.151.50 eth1: 56(84) bytes of data.
+64 bytes from 192.168.151.50: icmp_seq=1 ttl=64 time=0.511 ms
+64 bytes from 192.168.151.53: icmp_seq=1 ttl=64 time=4.67 ms (DUP!)
+64 bytes from 192.168.151.55: icmp_seq=1 ttl=63 time=10.7 ms (DUP!)
+64 bytes from 192.168.151.50: icmp_seq=2 ttl=64 time=0.076 ms
+64 bytes from 192.168.151.53: icmp_seq=2 ttl=64 time=1.23 ms (DUP!)
+64 bytes from 192.168.151.55: icmp_seq=2 ttl=63 time=1.23 ms (DUP!)
+64 bytes from 192.168.151.50: icmp_seq=3 ttl=64 time=0.059 ms
+64 bytes from 192.168.151.53: icmp_seq=3 ttl=64 time=2.94 ms (DUP!)
+64 bytes from 192.168.151.55: icmp_seq=3 ttl=63 time=5.62 ms (DUP!)
+64 bytes from 192.168.151.50: icmp_seq=4 ttl=64 time=0.158 ms
+64 bytes from 192.168.151.53: icmp_seq=4 ttl=64 time=1.14 ms (DUP!)
+64 bytes from 192.168.151.55: icmp_seq=4 ttl=63 time=1.16 ms (DUP!)
+
+
+5. Adding non-OLSR interfaces to the multicast flooding
+-------------------------------------------------------
+
+As a special feature, it is possible to have multicast and local-broadcast
+IP packets forwarded also on non-OLSR interfaces.
+
+If you have network interfaces on which OLSR is *not* running, but you *do*
+want to forward multicast and local-broadcast IP packets, specify these
+interfaces one by one as "NonOlsrIf" parameters in the BMF plugin section
+of /etc/olsrd.conf. For example:
+
+ LoadPlugin "olsrd_bmf.so.1.1"
+ {
+ # Non-OLSR interfaces to participate in the multicast flooding
+ PlParam "NonOlsrIf" "eth2"
+ PlParam "NonOlsrIf" "eth3"
+ }
+
+If an interface is listed both as NonOlsrIf for BMF, and in the
+Interfaces { ... } section of olsrd.conf, it will be seen by BMF
+as an OLSR-enabled interface.
+
+Note that when BMF receives or sends a packet via a non-OLSR interface,
+the TTL is decremented. TTL is NOT decremented on packets traveling
+within the OLSR-BMF MANET, since that is considered to be one (repaired)
+broadcast domain.
+
+Packets are not forwarded from one non-OLSR interface to another non-OLSR
+interface, only from non-OLSR interfaces to OLSR interfaces and vice versa.
+Packet forwarding between non-OLSR interfaces should be the result of
+other multicast routing protocols.
+
+
+6. Testing in a lab environment
+-------------------------------
+
+Setup IP-tables to drop packets from nodes which are not
+direct (1-hop) neigbors. For example, to drop all packets from
+a host with MAC address 00:0C:29:28:0E:CC, enter at the shell prompt:
+
+ iptables -A INPUT -m mac --mac-source 00:0C:29:28:0E:CC -j DROP
+
+Edit the file /etc/olsrd.conf, and specify the MAC addresses of the nodes
+we do not want to see; even though packets from these nodes are dropped
+by iptables, they are still received on network interfaces which are in
+promiscuous mode. For example:
+
+ LoadPlugin "olsrd_bmf.so.1.1"
+ {
+ # Drop all packets received from the following MAC sources
+ PlParam "DropMac" "00:0C:29:C6:E2:61" # RemoteClient1
+ PlParam "DropMac" "00:0C:29:61:34:B7" # SimpleClient1
+ PlParam "DropMac" "00:0C:29:28:0E:CC" # SimpleClient2
+ }
+
+
+
+7. Common problems, FAQ
+-----------------------
+
+Question:
+On which platforms does BMF currently compile?
+
+Answer:
+Only on Linux. No compilation on Windows (yet). The oldest Linux
+kernel on which the BMF plugin was tested was version 2.4.18.
+
+
+Question:
+When starting OLSRD with the BMF plugin, I can see the following
+error message:
+
+OLSRD Basic Multicast Forwarding plugin: error opening /dev/net/tun: No such file or directory
+
+Wat to do?
+
+Answer:
+Turn on the possibility to create a tuntap device; see section 2 of this
+file.
+
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Address.c olsrd-0.4.10/lib/bmf/src/Address.c
--- olsrd-0.4.10.orig/lib/bmf/src/Address.c 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/Address.c 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : Address.c
+ * Description: IP packet characterization functions
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+#include "Address.h"
+
+/* System includes */
+#include <assert.h> /* assert() */
+#include <netinet/ip.h> /* struct ip */
+#include <netinet/udp.h> /* struct udphdr */
+
+/* OLSRD includes */
+#include "defs.h" /* COMP_IP */
+
+/* Plugin includes */
+#include "Bmf.h" /* BMF_ENCAP_PORT */
+#include "NetworkInterfaces.h" /* TBmfInterface */
+
+/* -------------------------------------------------------------------------
+ * 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) & 0xF0000000) == 0xE0000000;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : IsLocalBroadcast
+ * Description: Check if an IP address is a local broadcast address for a
+ * given network interface
+ * Input : destIp, ifFrom
+ * Output : none
+ * Return : true (1) or false (0)
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+int IsLocalBroadcast(union olsr_ip_addr* destIp, struct TBmfInterface* ifFrom)
+{
+ struct sockaddr_in* sin;
+
+ assert(destIp != NULL && ifFrom != NULL);
+
+ /* Cast down to correct sockaddr subtype */
+ sin = (struct sockaddr_in*)&(ifFrom->broadAddr);
+
+ return COMP_IP(&(sin->sin_addr.s_addr), destIp);
+}
+
+/* -------------------------------------------------------------------------
+ * Function : IsOlsrOrBmfPacket
+ * Description: Check if an ethernet packet is an OLSR packet or a BMF packet
+ * Input : intf, ethPkt, len
+ * Output : none
+ * Return : true (1) or false (0)
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+int IsOlsrOrBmfPacket(struct TBmfInterface* intf, unsigned char* ethPkt, size_t len)
+{
+ struct ip* ipData;
+ unsigned int ipHeaderLen;
+
+ assert(ethPkt != NULL);
+
+ /* Consider OLSR and BMF packets not to be local broadcast
+ * OLSR packets are UDP - port 698
+ * OLSR-BMF packets are UDP - port 50698
+ * OLSR-Autodetect probe packets are UDP - port 51698
+ * Fragments of the above packets are also not local broadcast */
+
+ ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
+ ipHeaderLen = ipData->ip_hl << 2;
+ if (len < IP_HDR_OFFSET + ipHeaderLen)
+ {
+ return 0;
+ }
+
+ if (ipData->ip_p != SOL_UDP)
+ {
+ return 0;
+ }
+
+ /* Check if the packet is a fragment */
+ if ((ntohs(ipData->ip_off) & IP_OFFMASK) != 0)
+ {
+ int i;
+ for (i = 0; i < FRAGMENT_HISTORY_SIZE; i++)
+ {
+ /* Quick-access pointer */
+ struct TFragmentHistory* entry = &intf->fragmentHistory[i];
+
+ /* Match */
+ if (entry->ipId == ntohs(ipData->ip_id) &&
+ entry->ipProto == ipData->ip_p &&
+ entry->ipSrc.s_addr == ntohl(ipData->ip_src.s_addr) &&
+ entry->ipDst.s_addr == ntohl(ipData->ip_dst.s_addr))
+ {
+ /* Found matching history entry, so packet is assumed to be a fragment
+ * of an earlier OLSR/OLSR-BMF/OLSR-Autodetect packet */
+
+ /* More fragments? If not, invalidate entry */
+ if (((ntohs(ipData->ip_off) & IP_MF) == 0))
+ {
+ memset(entry, 0, sizeof(struct TFragmentHistory));
+ }
+
+ return 1;
+ }
+ }
+
+ /* Matching history entry not found, so packet is not assumed to be a fragment
+ * of an earlier OLSR/OLSR-BMF/OLSR-Autodetect packet */
+ return 0;
+ }
+
+ /* The packet is the first (or only) fragment */
+
+ /* Check length first */
+ if (len < IP_HDR_OFFSET + ipHeaderLen + sizeof(struct udphdr ))
+ {
+ return 0;
+ }
+
+ /* Go into the UDP header and check port number */
+ struct udphdr* udpData = (struct udphdr*) (ethPkt + IP_HDR_OFFSET + ipHeaderLen);
+ u_int16_t port = ntohs(udpData->source);
+
+ if (port == OLSRPORT || port == BMF_ENCAP_PORT || port == 51698)
+ /* TODO define for 51698 */
+ {
+ /* If more fragments are expected, keep a record in the fragment history */
+ if ((ntohs(ipData->ip_off) & IP_MF) != 0)
+ {
+ /* Quick-access pointer */
+ struct TFragmentHistory* entry = &intf->fragmentHistory[intf->nextFragmentHistoryEntry];
+
+ /* Store in fragment history */
+ entry->ipId = ntohs(ipData->ip_id);
+ entry->ipProto = ipData->ip_p;
+ entry->ipSrc.s_addr = ntohl(ipData->ip_src.s_addr);
+ entry->ipDst.s_addr = ntohl(ipData->ip_dst.s_addr);
+
+ /* Advance to next entry */
+ intf->nextFragmentHistoryEntry++;
+ intf->nextFragmentHistoryEntry %= FRAGMENT_HISTORY_SIZE;
+ }
+ return 1;
+ }
+
+ return 0;
+}
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Address.h olsrd-0.4.10/lib/bmf/src/Address.h
--- olsrd-0.4.10.orig/lib/bmf/src/Address.h 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/Address.h 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,55 @@
+#ifndef _BMF_ADDRESS_H
+#define _BMF_ADDRESS_H
+
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : Address.h
+ * Description: IP packet characterization functions
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+#include "olsr_types.h" /* olsr_ip_addr */
+#include "interfaces.h" /* struct interface */
+
+struct TBmfInterface;
+
+int IsMulticast(union olsr_ip_addr* ipAddress);
+int IsLocalBroadcast(union olsr_ip_addr* destIp, struct TBmfInterface* ifFrom);
+int IsOlsrOrBmfPacket(struct TBmfInterface* intf, unsigned char* ethPkt, size_t len);
+
+#endif /* _BMF_ADDRESS_H */
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Bmf.c olsrd-0.4.10/lib/bmf/src/Bmf.c
--- olsrd-0.4.10.orig/lib/bmf/src/Bmf.c 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/Bmf.c 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,935 @@
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : Bmf.c
+ * Description: Multicast forwarding functions
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+#define _MULTI_THREADED
+
+#include "Bmf.h"
+
+/* System includes */
+#include <stdio.h> /* NULL */
+#include <sys/types.h> /* ssize_t */
+#include <string.h> /* strerror() */
+#include <errno.h> /* errno */
+#include <assert.h> /* assert() */
+#include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
+#include <pthread.h> /* pthread_t, pthread_create() */
+#include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
+#include <netinet/ip.h> /* struct ip */
+
+/* OLSRD includes */
+#include "defs.h" /* olsr_cnf */
+#include "olsr.h" /* olsr_printf */
+#include "scheduler.h" /* olsr_register_scheduler_event */
+#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() */
+
+/* Plugin includes */
+#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
+#include "Address.h" /* IsMulticast(), IsLocalBroadcast() */
+#include "Packet.h" /* ETH_TYPE_OFFSET, IFHWADDRLEN etc. */
+#include "PacketHistory.h" /* InitPacketHistory() */
+#include "DropList.h" /* DropMac() */
+
+static pthread_t BmfThread;
+static int BmfThreadRunning = 0;
+
+
+/* -------------------------------------------------------------------------
+ * Function : BmfPacketCaptured
+ * Description: Handle a captured raw IP packet
+ * Input : intf - the network interface on which the packet was captured
+ * buffer - space for the encapsulation header, followed by
+ * the captured packet
+ * len - the number of octets in the encapsulation header plus
+ * captured packet
+ * Output : none
+ * Return : none
+ * Data Used : BmfInterfaces
+ * Notes : The packet is assumed to be captured on a socket of family
+ * PF_PACKET and type SOCK_RAW.
+ * ------------------------------------------------------------------------- */
+static void BmfPacketCaptured(struct TBmfInterface* intf, unsigned char* buffer, ssize_t len)
+{
+ unsigned char* srcMac;
+ union olsr_ip_addr srcIp;
+ union olsr_ip_addr destIp;
+ union olsr_ip_addr* origIp;
+ struct sockaddr_in encapDest;
+ struct TBmfInterface* nextFwIntf;
+ int isFromOlsrIntf; /* Boolean indicating if packet captured on OLSR-enabled interface */
+ int iAmNotMpr;
+ unsigned char* ethPkt = buffer + ENCAP_HDR_LEN;
+ ssize_t ethPktLen = len - ENCAP_HDR_LEN;
+ struct ip* ipData;
+
+ /* Only forward IPv4 packets */
+ u_int16_t type;
+ memcpy(&type, ethPkt + ETH_TYPE_OFFSET, 2);
+ if (ntohs(type) != IPV4_TYPE)
+ {
+ return;
+ }
+
+ ipData = (struct ip*)(ethPkt + IP_HDR_OFFSET);
+
+ /* Only forward multicast or local broadcast packets */
+ COPY_IP(&destIp, &ipData->ip_dst);
+ if (! IsMulticast(&destIp) && ! IsLocalBroadcast(&destIp, intf))
+ {
+ return;
+ }
+
+ /* Discard OLSR packets (UDP port 698) and BMF encapsulated packets */
+ if (IsOlsrOrBmfPacket(intf, ethPkt, ethPktLen))
+ {
+ return;
+ }
+
+ COPY_IP(&srcIp, &ipData->ip_src);
+ olsr_printf(
+ 9,
+ "%s: pkt of %d bytes incoming on \"%s\": %s->%s\n",
+ PLUGIN_NAME_SHORT,
+ ethPktLen,
+ intf->ifName,
+ olsr_ip_to_string(&srcIp),
+ olsr_ip_to_string(&destIp));
+
+ /* Apply drop list for testing purposes. */
+ srcMac = ethPkt + IFHWADDRLEN;
+ if (IsInDropList(srcMac))
+ {
+ olsr_printf(
+ 9,
+ "%s: --> discarding: source MAC (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) found in drop list\n",
+ PLUGIN_NAME_SHORT,
+ srcMac, srcMac + 1, srcMac + 2, srcMac + 3, srcMac + 4, srcMac + 5);
+ return;
+ }
+
+ /* Lookup main address of source in the MID table of OLSR */
+ origIp = mid_lookup_main_addr(&srcIp);
+ if (origIp == NULL)
+ {
+ origIp = &srcIp;
+ }
+
+ /* Check if this packet is received on an OLSR-enabled interface */
+ isFromOlsrIntf = (intf->olsrIntf != NULL);
+
+ /* If this packet is captured on a non-OLSR interface, it will be forwarded
+ * only to OLSR interfaces, thereby crossing the boundary between the external
+ * network and the OLSR network. So decrease the TTL and re-calculate the IP header
+ * checksum. */
+ if (! isFromOlsrIntf)
+ {
+ DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
+ }
+
+ /* If the resulting TTL is <= 0, this packet life has ended, so do not forward it */
+ if (GetIpTtl(ethPkt) <= 0)
+ {
+ olsr_printf(
+ 9,
+ "%s: --> discarding: TTL=0\n",
+ PLUGIN_NAME_SHORT);
+ return;
+ }
+
+ /* Check if this packet was seen recently */
+ u_int32_t crc32 = PacketCrc32(ethPkt, ethPktLen);
+ if (CheckAndMarkRecentPacket(Hash16(crc32)))
+ {
+ olsr_printf(
+ 9,
+ "%s: --> discarding: packet is duplicate\n",
+ PLUGIN_NAME_SHORT);
+ return;
+ }
+
+ /* Compose encapsulation header */
+ struct TEncapHeader* encapHdr = (struct TEncapHeader*) buffer;
+ memset (encapHdr, 0, ENCAP_HDR_LEN);
+ encapHdr->crc32 = htonl(crc32);
+
+ /* If this packet is captured on an OLSR interface from an OLSR neighbor,
+ * check with OLSR if I am MPR for that neighbor */
+ iAmNotMpr =
+ (isFromOlsrIntf /* captured on an OLSR interface */
+ && get_best_link_to_neighbor(origIp) != NULL /* from an OLSR neighbor */
+ && olsr_lookup_mprs_set(origIp) == NULL); /* but not selected as MPR */
+
+ memset(&encapDest, 0, sizeof(encapDest));
+ encapDest.sin_family = AF_INET;
+ encapDest.sin_port = htons(BMF_ENCAP_PORT);
+
+ /* Check with each interface what needs to be done on it */
+ nextFwIntf = BmfInterfaces;
+ while (nextFwIntf != NULL)
+ {
+ int isToOlsrIntf; /* Boolean indicating if forwarding interface is OLSR-enabled */
+
+ struct TBmfInterface* fwIntf = nextFwIntf;
+ nextFwIntf = fwIntf->next;
+
+ isToOlsrIntf = (fwIntf->olsrIntf != NULL);
+
+ /* The following if-else statement seems very complicated. Let's
+ * draw a Karnaugh-diagram of it for some clarification.
+ *
+ * ------- isFromOlsrIntf
+ * -------- isToOlsrIntf
+ * +---+---+---+---+
+ * | 3 | 2 | 2 | 1 |
+ * +---+---+---+---+
+ * | | X | X | 4 | 1 |
+ * +---+---+---+---+
+ * iAmNotMpr
+ *
+ * X = does not occur (iAmNotMpr = isFromOlsrIntf && ...)
+ * 1 = handled in first if-clause: if (isFromOlsrIntf && !isToOlsrIntf)...
+ * 2 = handled in second if-clause: if (isToOlsrIntf && !iAmNotMpr)...
+ * 3 = handled in third if-clause: if (!isFromOlsrIntf && !isToOlsrIntf)...
+ * 4 = handled in else-clause.
+ */
+
+ /* Forward from OLSR-interface to non-OLSR interface */
+ if (isFromOlsrIntf && !isToOlsrIntf)
+ {
+ struct TSaveTtl sttl;
+
+ /* Save IP header checksum and the TTL-value of the packet */
+ SaveTtlAndChecksum(ethPkt, &sttl);
+
+ /* Save IP header checksum and the TTL-value of the packet, then
+ * decrease the TTL by 1 before writing */
+ DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
+
+ /* If the TTL is <= 0, do not forward this packet */
+ if (GetIpTtl(ethPkt) <= 0)
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> not forwarding on \"%s\": TTL=0\n",
+ PLUGIN_NAME_SHORT,
+ fwIntf->ifName);
+ }
+ else
+ {
+ /* Change source MAC address to that of sending interface */
+ memcpy(ethPkt + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
+
+ int nBytesWritten = write(fwIntf->capturingSkfd, ethPkt, ethPktLen);
+ if (nBytesWritten != ethPktLen)
+ {
+ olsr_printf(
+ 1,
+ "%s: write() error forwarding pkt for %s to \"%s\": %s\n",
+ PLUGIN_NAME,
+ olsr_ip_to_string(&destIp),
+ fwIntf->ifName,
+ strerror(errno));
+ }
+ else
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> forwarded to \"%s\"\n",
+ PLUGIN_NAME_SHORT,
+ fwIntf->ifName);
+ }
+ }
+
+ /* Restore the IP header checksum and the TTL-value of the packet */
+ RestoreTtlAndChecksum(ethPkt, &sttl);
+
+ } /* if (isFromOlsrIntf && !isToOlsrIntf) */
+
+ /* Forward from any interface to OLSR interface. Packets from non-OLSR interfaces
+ * already had their TTL decreased. */
+ else /* !isFromOlsrIntf || isToOlsrIntf */
+ if (isToOlsrIntf && !iAmNotMpr)
+ {
+ int nBytesWritten;
+
+ /* Change encapsulated source MAC address to that of sending interface */
+ memcpy(ethPkt + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
+
+ /* Destination address is local broadcast */
+ encapDest.sin_addr.s_addr = ((struct sockaddr_in*)&fwIntf->olsrIntf->int_broadaddr)->sin_addr.s_addr;
+
+ nBytesWritten = sendto(
+ fwIntf->encapsulatingSkfd,
+ buffer,
+ len,
+ MSG_DONTROUTE,
+ (struct sockaddr*) &encapDest,
+ sizeof(encapDest));
+
+ if (nBytesWritten != len)
+ {
+ olsr_printf(
+ 1,
+ "%s: sendto() error forwarding pkt for %s to \"%s\": %s\n",
+ PLUGIN_NAME,
+ olsr_ip_to_string(&destIp),
+ fwIntf->ifName,
+ strerror(errno));
+ }
+ else
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> encapsulated and forwarded to \"%s\"\n",
+ PLUGIN_NAME_SHORT,
+ fwIntf->ifName);
+ } /* if (nBytesWritten != len) */
+ } /* else if (isToOlsrIntf && !iAmNotMpr) */
+
+ else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) */
+ if (!isFromOlsrIntf && !isToOlsrIntf)
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> not forwarding from \"%s\" to \"%s\": both non-OLSR interfaces\n",
+ PLUGIN_NAME_SHORT,
+ intf->ifName,
+ fwIntf->ifName);
+ }
+
+ else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) && (isFromOlsrIntf || isToOlsrIntf) */
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> not forwarding from \"%s\" to \"%s\": I am not selected as MPR by %s\n",
+ PLUGIN_NAME_SHORT,
+ intf->ifName,
+ fwIntf->ifName,
+ olsr_ip_to_string(&srcIp));
+ }
+ } /* while (nextFwIntf != NULL) */
+}
+
+/* -------------------------------------------------------------------------
+ * Function : BmfEncapsulatedPacketReceived
+ * Description: Handle a received BMF-encapsulated IP packet
+ * Input : intf - the network interface on which the packet was received
+ * fromIp - the IP node that forwarded the packet to us
+ * buffer - the received encapsulated packet
+ * len - the number of octets in the received encapsulated packet
+ * Output : none
+ * Return : none
+ * Data Used : BmfInterfaces
+ * Notes : The packet is assumed to be received on a socket of family
+ * PF_INET and type SOCK_DGRAM (UDP).
+ * ------------------------------------------------------------------------- */
+static void BmfEncapsulatedPacketReceived(
+ struct TBmfInterface* intf,
+ union olsr_ip_addr* fromIp,
+ unsigned char* buffer,
+ ssize_t len)
+{
+ union olsr_ip_addr* forwarder;
+ int nBytesToWrite;
+ unsigned char* bufferToWrite;
+ int nBytesWritten;
+ int iAmMpr;
+ struct sockaddr_in encapDest;
+ struct TBmfInterface* nextFwIntf;
+ struct ip* ipData;
+ unsigned char* ethPkt;
+ ssize_t ethPktLen;
+
+ /* Are we talking to ourselves? */
+ if (if_ifwithaddr(fromIp) != NULL)
+ {
+ return;
+ }
+
+ /* Encapsulated packet received on non-OLSR interface? Then discard */
+ if (intf->olsrIntf == NULL)
+ {
+ return;
+ }
+
+ /* Apply drop list? No, not needed: encapsulated packets are routed,
+ * so filtering should be done by adding a rule to the iptables FORWARD
+ * chain, e.g.:
+ * iptables -A FORWARD -m mac --mac-source 00:0C:29:28:0E:CC -j DROP */
+
+ ethPkt = buffer + ENCAP_HDR_LEN;
+ ethPktLen = len - ENCAP_HDR_LEN;
+
+ ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
+
+ OLSR_PRINTF(
+ 9,
+ "%s: encapsulated pkt of %d bytes incoming on \"%s\": %s->",
+ PLUGIN_NAME_SHORT,
+ ethPktLen,
+ intf->ifName,
+ inet_ntoa(ipData->ip_src));
+ OLSR_PRINTF(
+ 9,
+ "%s, forwarded by %s\n",
+ inet_ntoa(ipData->ip_dst), /* not possible to call inet_ntoa twice in same printf */
+ olsr_ip_to_string(fromIp));
+
+ /* Get encapsulation header */
+ struct TEncapHeader* encapHdr = (struct TEncapHeader*) buffer;
+
+ /* Check if this packet was seen recently */
+ if (CheckAndMarkRecentPacket(Hash16(ntohl(encapHdr->crc32))))
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> discarding: packet is duplicate\n",
+ PLUGIN_NAME_SHORT);
+ return;
+ }
+
+ /* Unpack encapsulated packet and send a copy to myself via the EtherTunTap device */
+ bufferToWrite = ethPkt;
+ nBytesToWrite = ethPktLen;
+ if (TunOrTap == TT_TUN)
+ {
+ bufferToWrite += IP_HDR_OFFSET;
+ nBytesToWrite -= IP_HDR_OFFSET;
+ }
+ nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);
+ if (nBytesWritten != nBytesToWrite)
+ {
+ olsr_printf(
+ 1,
+ "%s: write() error forwarding encapsulated pkt to \"%s\": %s\n",
+ PLUGIN_NAME,
+ EtherTunTapIfName,
+ strerror(errno));
+ }
+ else
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> unpacked and forwarded to \"%s\"\n",
+ PLUGIN_NAME_SHORT,
+ EtherTunTapIfName);
+ }
+
+ /* Lookup main address of forwarding node */
+ forwarder = mid_lookup_main_addr(fromIp);
+ if (forwarder == NULL)
+ {
+ forwarder = fromIp;
+ }
+
+ /* Check if I am MPR for the forwarder */
+ iAmMpr = (olsr_lookup_mprs_set(forwarder) != NULL);
+
+ memset(&encapDest, 0, sizeof(encapDest));
+ encapDest.sin_family = AF_INET;
+ encapDest.sin_port = htons(BMF_ENCAP_PORT);
+
+ nextFwIntf = BmfInterfaces;
+ while (nextFwIntf != NULL)
+ {
+ struct TBmfInterface* fwIntf = nextFwIntf;
+ nextFwIntf = fwIntf->next;
+
+ /* Forward from OLSR interface to non-OLSR interface: unpack encapsulated
+ * packet, decrease TTL and forward */
+ if (fwIntf->olsrIntf == NULL)
+ {
+ struct TSaveTtl sttl;
+
+ /* Save IP header checksum and the TTL-value of the packet, then
+ * decrease the TTL by 1 before writing */
+ SaveTtlAndChecksum(ethPkt, &sttl);
+ DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
+
+ /* If the TTL is <= 0, do not forward this packet */
+ if (GetIpTtl(ethPkt) <= 0)
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> not forwarding on \"%s\": TTL=0\n",
+ PLUGIN_NAME_SHORT,
+ fwIntf->ifName);
+ }
+ else
+ {
+ nBytesWritten = write(fwIntf->capturingSkfd, ethPkt, ethPktLen);
+ if (nBytesWritten != ethPktLen)
+ {
+ olsr_printf(
+ 1,
+ "%s: write() error forwarding unpacked encapsulated MC pkt to \"%s\": %s\n",
+ PLUGIN_NAME,
+ fwIntf->ifName,
+ strerror(errno));
+ }
+ else
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> unpacked and forwarded to \"%s\"\n",
+ PLUGIN_NAME_SHORT,
+ fwIntf->ifName);
+ }
+ }
+
+ /* Restore the IP header checksum and the TTL-value of the packet */
+ RestoreTtlAndChecksum(ethPkt, &sttl);
+
+ } /* if (fwIntf->olsrIntf == NULL) */
+
+ /* Forward from OLSR interface to OLSR interface: forward the packet if this
+ * node is selected as MPR by the forwarding node */
+ else if (iAmMpr)
+ {
+ /* Change source MAC address to that of sending interface */
+ memcpy(buffer + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
+
+ /* Destination address is local broadcast */
+ encapDest.sin_addr.s_addr = ((struct sockaddr_in*)&fwIntf->olsrIntf->int_broadaddr)->sin_addr.s_addr;
+
+ nBytesWritten = sendto(
+ fwIntf->encapsulatingSkfd,
+ buffer,
+ len,
+ MSG_DONTROUTE,
+ (struct sockaddr*) &encapDest,
+ sizeof(encapDest));
+
+ if (nBytesWritten != len)
+ {
+ olsr_printf(
+ 1,
+ "%s: sendto() error forwarding encapsulated pkt via \"%s\": %s\n",
+ PLUGIN_NAME,
+ fwIntf->ifName,
+ strerror(errno));
+ }
+ else
+ {
+ OLSR_PRINTF(
+ 9,
+ "%s: --> forwarded to \"%s\"\n",
+ PLUGIN_NAME_SHORT,
+ fwIntf->ifName);
+ }
+ } /* else if (iAmMpr) */
+ else /* fwIntf->olsrIntf != NULL && !iAmMpr */
+ {
+ /* fwIntf is an OLSR interface and I am not selected as MPR */
+ OLSR_PRINTF(
+ 9,
+ "%s: --> not forwarding to \"%s\": I am not selected as MPR by %s\n",
+ PLUGIN_NAME_SHORT,
+ fwIntf->ifName,
+ olsr_ip_to_string(fromIp));
+ }
+ } /* while (nextFwIntf != NULL) */
+}
+
+/* -------------------------------------------------------------------------
+ * 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
+ * ------------------------------------------------------------------------- */
+static void DoBmf(void)
+{
+#define BUFFER_MAX 2048
+ struct TBmfInterface* currIf;
+ int nFdBitsSet;
+
+ /* Compose set of socket file descriptors.
+ * Keep the highest descriptor seen. */
+ int highestSkfd = -1;
+ fd_set input_set;
+ FD_ZERO(&input_set);
+
+ currIf = BmfInterfaces;
+ while (currIf != NULL)
+ {
+ FD_SET(currIf->capturingSkfd, &input_set);
+ if (currIf->capturingSkfd > highestSkfd)
+ {
+ highestSkfd = currIf->capturingSkfd;
+ }
+
+ if (currIf->encapsulatingSkfd >= 0)
+ {
+ FD_SET(currIf->encapsulatingSkfd, &input_set);
+ if (currIf->encapsulatingSkfd > highestSkfd)
+ {
+ highestSkfd = currIf->encapsulatingSkfd;
+ }
+ }
+
+ currIf = currIf->next;
+ }
+
+ assert(highestSkfd >= 0);
+
+ /* 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, &input_set, NULL, NULL, NULL);
+ if (nFdBitsSet < 0)
+ {
+ if (errno != EINTR)
+ {
+ olsr_printf(1, "%s: select() error: %s\n", PLUGIN_NAME, strerror(errno));
+ }
+ return;
+ }
+
+ if (nFdBitsSet == 0)
+ {
+ /* No packets waiting. This is unexpected; normally we would excpect select(...)
+ * to return only if at least one packet was received (so nFdBitsSet > 0), or
+ * if this thread received a signal (so nFdBitsSet < 0). */
+ return;
+ }
+
+ while (nFdBitsSet > 0)
+ {
+ struct TBmfInterface* nextIf = BmfInterfaces;
+ while (nextIf != NULL)
+ {
+ int skfd;
+ currIf = nextIf;
+ nextIf = currIf->next;
+
+ skfd = currIf->capturingSkfd;
+ if (FD_ISSET(skfd, &input_set))
+ {
+ unsigned char buffer[BUFFER_MAX];
+ struct sockaddr_ll pktAddr;
+ socklen_t addrLen;
+ int nBytes;
+ unsigned char* ethPkt = buffer + ENCAP_HDR_LEN;
+ struct ip* ipData;
+
+ /* A packet was captured. */
+
+ nFdBitsSet--;
+
+ memset(&pktAddr, 0, sizeof(struct sockaddr_ll));
+ addrLen = sizeof(pktAddr);
+
+ /* Receive the packet, leaving space for the BMF encap header */
+ nBytes = recvfrom(
+ skfd,
+ ethPkt,
+ BUFFER_MAX - ENCAP_HDR_LEN,
+ 0,
+ (struct sockaddr*)&pktAddr,
+ &addrLen);
+ if (nBytes < 0)
+ {
+ olsr_printf(
+ 1,
+ "%s: recvfrom() error on \"%s\": %s\n",
+ PLUGIN_NAME,
+ currIf->ifName,
+ strerror(errno));
+ }
+ else
+ {
+ /* Don't let BMF crash by sending too short packets */
+ int ipHeaderLen;
+ ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
+ ipHeaderLen = ipData->ip_hl << 2;
+ if (nBytes >= IP_HDR_OFFSET + ipHeaderLen)
+ {
+ if (pktAddr.sll_pkttype == PACKET_OUTGOING)
+ {
+ union olsr_ip_addr destIp;
+ COPY_IP(&destIp, &ipData->ip_dst);
+ if (IsMulticast(&destIp) || IsLocalBroadcast(&destIp, currIf))
+ {
+ if (! IsOlsrOrBmfPacket(currIf, ethPkt, nBytes))
+ {
+ /* For outbound packets, just record the fact that the packet was
+ * seen recently */
+ u_int32_t crc32 = PacketCrc32(ethPkt, nBytes);
+ MarkRecentPacket(Hash16(crc32));
+ }
+ }
+ }
+ else if (pktAddr.sll_pkttype == PACKET_MULTICAST ||
+ pktAddr.sll_pkttype == PACKET_BROADCAST)
+ {
+ /* An inbound multicast or broadcast packet was captured */
+ BmfPacketCaptured(currIf, buffer, nBytes + ENCAP_HDR_LEN);
+ }
+ } /* if (nBytes >= IP_HDR_OFFSET + ipHeaderLen) */
+ } /* if (nBytes < 0) */
+ } /* if (FD_ISSET...) */
+
+ skfd = currIf->encapsulatingSkfd;
+ if (skfd >= 0 && (FD_ISSET(skfd, &input_set)))
+ {
+ unsigned char buffer[BUFFER_MAX];
+ struct sockaddr_in from;
+ socklen_t fromLen = sizeof(from);
+ int nBytes;
+ struct ip* ipData;
+
+ /* An encapsulated packet was received */
+
+ nFdBitsSet--;
+
+ nBytes = recvfrom(skfd, buffer, BUFFER_MAX, 0, (struct sockaddr*)&from, &fromLen);
+ if (nBytes < 0)
+ {
+ olsr_printf(
+ 1,
+ "%s: recvfrom() error on \"%s\": %s\n",
+ PLUGIN_NAME,
+ currIf->ifName,
+ strerror(errno));
+ }
+ else
+ {
+ /* Don't let BMF crash by sending too short packets. */
+ int ipHeaderLen;
+ ipData = (struct ip *) (buffer + IP_HDR_OFFSET);
+ ipHeaderLen = ipData->ip_hl << 2;
+ if (nBytes >= IP_HDR_OFFSET + ipHeaderLen)
+ {
+ union olsr_ip_addr srcIp;
+ COPY_IP(&srcIp, &from.sin_addr.s_addr);
+ BmfEncapsulatedPacketReceived(currIf, &srcIp, buffer, nBytes);
+ }
+ else
+ {
+ olsr_printf(
+ 1,
+ "%s: encapsulated packet too short (%d bytes) from %s on \"%s\"\n",
+ PLUGIN_NAME,
+ nBytes,
+ inet_ntoa(from.sin_addr),
+ currIf->ifName);
+ }
+ } /* if (nBytes < 0) */
+ } /* if (skfd >= 0 && (FD_ISSET...) */
+ } /* while (intf != NULL) */
+ } /* while (nFdBitsSet > 0) */
+}
+
+/* -------------------------------------------------------------------------
+ * Function : BmfSignalHandler
+ * Description: Dummy signal handler function
+ * Input : signo - signal being handled
+ * Output : none
+ * Return : none
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+static void BmfSignalHandler(int signo)
+{
+ /* Dummy handler function */
+ return;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : BmfRun
+ * Description: Receiver thread function
+ * Input : useless - not used
+ * Output : none
+ * Return : not used
+ * Data Used : BmfThreadRunning
+ * Notes : Another thread can gracefully stop this thread by writing a
+ * '0' into global variable 'BmfThreadRunning' followed by sending
+ * a SIGALRM signal.
+ * ------------------------------------------------------------------------- */
+static void* BmfRun(void* useless)
+{
+ /* Mask all signals except SIGALRM */
+ sigset_t blockedSigs;
+ sigfillset(&blockedSigs);
+ sigdelset(&blockedSigs, SIGALRM);
+ if (pthread_sigmask(SIG_BLOCK, &blockedSigs, NULL) < 0)
+ {
+ olsr_printf(1, "%s: pthread_sigmask() error: %s\n", PLUGIN_NAME, strerror(errno));
+ }
+
+ /* Set up the signal handler for the process: use SIGALRM to terminate
+ * the BMF thread. Only if a signal handler is specified, does a blocking
+ * system call return with errno set to EINTR; if a signal hander is not
+ * specified, any system call in which the thread may be waiting will not
+ * return. Note that the BMF thread is usually blocked in the select()
+ * function (see DoBmf()). */
+ if (signal(SIGALRM, BmfSignalHandler) == SIG_ERR)
+ {
+ olsr_printf(1, "%s: signal() error: %s\n", PLUGIN_NAME, strerror(errno));
+ }
+
+ /* Call the thread function until flagged to exit */
+ while (BmfThreadRunning != 0)
+ {
+ DoBmf();
+ }
+
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : InterfaceChange
+ * Description: Callback function passed to OLSRD for it to call whenever a
+ * network interface has been added, removed or updated
+ * Input : interf - the network interface to deal with
+ * action - indicates if the specified network interface was
+ * added, removed or updated.
+ * Output : none
+ * Return : always 0
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+int InterfaceChange(struct interface* interf, int action)
+{
+ switch (action)
+ {
+ case (IFCHG_IF_ADD):
+ AddInterface(interf);
+ olsr_printf(1, "%s: interface %s added\n", PLUGIN_NAME, interf->int_name);
+ break;
+
+ case (IFCHG_IF_REMOVE):
+ CloseBmf();
+ InitBmf(interf);
+ olsr_printf(1, "%s: interface %s removed\n", PLUGIN_NAME, interf->int_name);
+ break;
+
+ case (IFCHG_IF_UPDATE):
+ olsr_printf(1, "%s: interface %s updated\n", PLUGIN_NAME, interf->int_name);
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : InitBmf
+ * Description: Initialize the BMF plugin
+ * Input : skipThisIntf - specifies which network interface should not
+ * be enabled for BMF. Pass NULL to indicate all.
+ * Output : none
+ * Return : fail (0) or success (1)
+ * Data Used : BmfThreadRunning, BmfThread
+ * ------------------------------------------------------------------------- */
+int InitBmf(struct interface* skipThisIntf)
+{
+ if (CreateBmfNetworkInterfaces(skipThisIntf) < 0)
+ {
+ olsr_printf(1, "%s: Could not initialize any network interface!\n", PLUGIN_NAME);
+ /* Continue anyway; maybe an interface will be added later */
+ }
+
+ /* Start running the multicast packet processing thread */
+ BmfThreadRunning = 1;
+ if (pthread_create(&BmfThread, NULL, BmfRun, NULL) == 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : CloseBmf
+ * Description: Close the BMF plugin and clean up
+ * Input : none
+ * Output : none
+ * Return : none
+ * Data Used : BmfThreadRunning, BmfThread
+ * ------------------------------------------------------------------------- */
+void CloseBmf()
+{
+ /* Signal BmfThread to exit */
+ BmfThreadRunning = 0;
+ if (pthread_kill(BmfThread, SIGALRM) < 0)
+ /* 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(...). */
+ {
+ olsr_printf(1, "%s: pthread_kill() error: %s\n", PLUGIN_NAME, strerror(errno));
+ }
+
+ /* Wait for BmfThread to acknowledge */
+ if (pthread_join(BmfThread, NULL) < 0)
+ {
+ olsr_printf(1, "%s: pthread_join() error: %s\n", PLUGIN_NAME, strerror(errno));
+ }
+
+ /* Time to clean up */
+ CloseBmfNetworkInterfaces();
+}
+
+/* -------------------------------------------------------------------------
+ * Function : RegisterBmfParameter
+ * Description: Register a configuration parameter with the BMF process
+ * Input : key - the parameter name: "DropMac" or "NonOlsrIf"
+ * value - the parameter value
+ * Output : none
+ * Return : fatal error (<0), minor error (0) or success (>0)
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+int RegisterBmfParameter(char* key, char* value)
+{
+ if (strcmp(key, "DropMac") == 0)
+ {
+ return DropMac(value);
+ }
+ else if (strcmp(key, "NonOlsrIf") == 0)
+ {
+ return AddNonOlsrBmfIf(value);
+ }
+
+ /* Key not recognized */
+ return 0;
+}
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Bmf.h olsrd-0.4.10/lib/bmf/src/Bmf.h
--- olsrd-0.4.10.orig/lib/bmf/src/Bmf.h 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/Bmf.h 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,64 @@
+#ifndef _BMF_BMF_H
+#define _BMF_BMF_H
+
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : Bmf.h
+ * Description: Multicast forwarding functions
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+/* BMF plugin data */
+#define PLUGIN_NAME "OLSRD Basic Multicast Forwarding plugin"
+#define PLUGIN_NAME_SHORT "OLSRD BMF"
+#define PLUGIN_VERSION "1.1 (" __DATE__ " " __TIME__ ")"
+#define PLUGIN_COPYRIGHT " (C) Thales Communications Huizen, Netherlands"
+#define PLUGIN_AUTHOR " Erik Tromp (erik.tromp@nl.thalesgroup.com)"
+#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION "\n" PLUGIN_COPYRIGHT "\n" PLUGIN_AUTHOR
+
+/* UDP-Port on which multicast packets are encapsulated */
+#define BMF_ENCAP_PORT 50698
+
+struct interface;
+
+int InterfaceChange(struct interface* interf, int action);
+int InitBmf(struct interface* skipThisIntf);
+void CloseBmf(void);
+int RegisterBmfParameter(char* key, char* value);
+
+#endif /* _BMF_BMF_H */
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/DropList.c olsrd-0.4.10/lib/bmf/src/DropList.c
--- olsrd-0.4.10.orig/lib/bmf/src/DropList.c 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/DropList.c 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : DropList.c
+ * Description: List of MAC addresses of hosts from which all packets are dropped.
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+
+#include "DropList.h"
+
+/* System includes */
+#include <assert.h> /* assert() */
+#include <stdio.h> /* NULL */
+#include <stdlib.h> /* malloc */
+#include <string.h> /* memcmp */
+
+/* OLSRD includes */
+#include "olsr.h" /* olsr_printf */
+
+/* Plugin includes */
+#include "Bmf.h" /* PLUGIN_NAME */
+#include "Packet.h" /* IFHWADDRLEN */
+
+static struct TMacAddress* DroppedMacAddresses = NULL;
+
+/* Register a MAC address in the drop list.
+ */
+/* -------------------------------------------------------------------------
+ * Function : DropMac
+ * Description: Register a MAC address in the drop list
+ * Input : macStr - MAC address as string
+ * Output : none
+ * Return : success (1) or fail (0)
+ * Data Used : DroppedMacAddresses
+ * Notes : The registered MAC address will be matched to the source MAC
+ * address of incoming multicast packets. If matched, the multicast
+ * packet will be silently dropped.
+ * The drop list is needed only in lab environments, where hidden
+ * nodes are simulated by using iptables with the
+ * -m mac helper and --mac-source option (as in:
+ * "iptables -A INPUT -m mac --mac-source 00:0C:29:EE:C9:D0 -j DROP")
+ * The drop list is needed because network interfaces in promiscuous
+ * mode will still capture packets even if they are specified to
+ * be dropped by iptables.
+ * ------------------------------------------------------------------------- */
+int DropMac(const char* macStr)
+{
+ unsigned int mac[6];
+ int n;
+ struct TMacAddress* newMacAddress;
+ int i;
+
+ assert(macStr != NULL);
+
+ n = sscanf(macStr, "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
+ if (n != 6)
+ {
+ olsr_printf(1, "%s: Invalid Ethernet address '%s'\n", PLUGIN_NAME, macStr);
+ return 0;
+ }
+
+ newMacAddress = malloc(sizeof(struct TMacAddress));
+ for (i = 0; i < 6; i++)
+ {
+ newMacAddress->addr[i] = (unsigned char) mac[i];
+ }
+ newMacAddress->next = DroppedMacAddresses;
+ DroppedMacAddresses = newMacAddress;
+
+ return 1;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : IsInDropList
+ * Description: Check if a MAC address is in the drop list
+ * Input : macAddress
+ * Output : none
+ * Return : true (1) or false (0)
+ * Data Used : DroppedMacAddresses
+ * ------------------------------------------------------------------------- */
+int IsInDropList(const unsigned char* macAddress)
+{
+ struct TMacAddress* ma = DroppedMacAddresses;
+
+ assert(macAddress != NULL);
+
+ while (ma != NULL)
+ {
+ if (memcmp(ma->addr, macAddress, IFHWADDRLEN) == 0) return 1;
+ ma = ma->next;
+ }
+ return 0;
+}
+
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/DropList.h olsrd-0.4.10/lib/bmf/src/DropList.h
--- olsrd-0.4.10.orig/lib/bmf/src/DropList.h 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/DropList.h 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,55 @@
+#ifndef _BMF_DROPLIST_H
+#define _BMF_DROPLIST_H
+
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : DropList.h
+ * Description: List of MAC addresses of hosts from which all packets are dropped.
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+struct TMacAddress
+{
+ unsigned char addr[6];
+ struct TMacAddress* next;
+};
+
+int DropMac(const char* macStr);
+int IsInDropList(const unsigned char* macAddress);
+
+#endif /* _BMF_DROPLIST_H */
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c
--- olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,818 @@
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : NetworkInterfaces.c
+ * Description: Functions to open and close sockets
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+#include "NetworkInterfaces.h"
+
+/* System includes */
+#include <syslog.h> /* syslog() */
+#include <string.h> /* strerror() */
+#include <errno.h> /* errno */
+#include <unistd.h> /* close() */
+#include <sys/ioctl.h> /* ioctl() */
+#include <fcntl.h> /* fcntl() */
+#include <assert.h> /* assert() */
+#include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
+#include <netinet/in.h> /* htons() */
+#include <linux/if_ether.h> /* ETH_P_ALL */
+#include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
+#include <linux/if_tun.h> /* IFF_TAP */
+
+/* OLSRD includes */
+#include "olsr.h" /* olsr_printf() */
+#include "defs.h" /* olsr_cnf */
+
+/* Plugin includes */
+#include "Packet.h" /* IFHWADDRLEN */
+#include "Bmf.h" /* PLUGIN_NAME */
+
+/* List of network interfaces used by BMF plugin */
+struct TBmfInterface* BmfInterfaces = NULL;
+
+/* File descriptor of EtherTunTap device */
+int EtherTunTapFd = -1;
+
+/* Network interface name of EtherTunTap device. If the name starts with "tun", an
+ * IP tunnel interface will be used. Otherwise, an EtherTap device will be used. */
+const char* EtherTunTapIfName = "tun0"; /* "tap0"; */
+
+/* If the network interface name starts with "tun", an IP tunnel interface will be
+ * used, and this variable will be set to TUN. Otherwise, an EtherTap device will
+ * be used, and this variable will be set to TAP. */
+enum TTunOrTap TunOrTap;
+
+/* -------------------------------------------------------------------------
+ * 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 raw 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;
+
+ /* Open raw packet socket */
+ int skfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if (skfd < 0)
+ {
+ olsr_printf(1, "%s: socket(PF_PACKET) error: %s\n", PLUGIN_NAME, strerror(errno));
+ 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)
+ {
+ olsr_printf(1, "%s: setsockopt(PACKET_MR_PROMISC) error: %s\n", PLUGIN_NAME, strerror(errno));
+ close(skfd);
+ return -1;
+ }
+
+ /* Get hardware (MAC) address */
+ memset(&req, 0, sizeof(struct ifreq));
+ strncpy(req.ifr_name, ifName, IFNAMSIZ);
+ if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
+ {
+ olsr_printf(1, "%s: error retrieving MAC address: %s\n", PLUGIN_NAME, strerror(errno));
+ close(skfd);
+ return -1;
+ }
+
+ /* Bind the socket to the specified interface */
+ memset(&bindTo, 0, sizeof(bindTo));
+ bindTo.sll_protocol = htons(ETH_P_ALL);
+ bindTo.sll_ifindex = ifIndex;
+ bindTo.sll_family = AF_PACKET;
+ memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
+ bindTo.sll_halen = IFHWADDRLEN;
+
+ if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
+ {
+ olsr_printf(1, "%s: bind() error: %s\n", PLUGIN_NAME, strerror(errno));
+ close(skfd);
+ return -1;
+ }
+
+ /* Set socket to blocking operation */
+ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
+ {
+ olsr_printf(1, "%s: fcntl() error: %s\n", PLUGIN_NAME, strerror(errno));
+ close(skfd);
+ return -1;
+ }
+
+ return skfd;
+}
+
+/* -------------------------------------------------------------------------
+ * 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)
+ {
+ olsr_printf(1, "%s: socket(PF_INET) error: %s\n", PLUGIN_NAME, strerror(errno));
+ return -1;
+ }
+
+ /* Enable sending to broadcast addresses */
+ if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
+ {
+ olsr_printf(1, "%s: setsockopt() error: %s\n", PLUGIN_NAME, strerror(errno));
+ 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)
+ {
+ olsr_printf(1, "%s: setsockopt() error: %s\n", PLUGIN_NAME, strerror(errno));
+ close(skfd);
+ return -1;
+ }
+
+ /* Bind to 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)
+ {
+ olsr_printf(1, "%s: bind() error: %s\n", PLUGIN_NAME, strerror(errno));
+ close(skfd);
+ return -1;
+ }
+
+ /* Set socket to blocking operation */
+ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
+ {
+ olsr_printf(1, "%s: fcntl() error: %s\n", PLUGIN_NAME, strerror(errno));
+ close(skfd);
+ return -1;
+ }
+
+ return skfd;
+}
+
+/* To save the state of the IP spoof filter for the EtherTunTap device */
+static char EthTapSpoofState = '1';
+
+/* -------------------------------------------------------------------------
+ * Function : DeactivateSpoofFilter
+ * Description: Deactivates the Linux anti-spoofing filter for the tuntap
+ * interface
+ * Input : tunTapName - name used for the tuntap interface (e.g. "tun0" or "tap1")
+ * Output : none
+ * Return : success (1) or fail (0)
+ * Data Used : EthTapSpoofState
+ * Notes : Saves the current filter state for later restoring
+ * ------------------------------------------------------------------------- */
+static int DeactivateSpoofFilter(const char* tunTapName)
+{
+ FILE* procSpoof;
+ char procFile[FILENAME_MAX];
+
+ assert(tunTapName != NULL);
+
+ /* Generate the procfile name */
+ sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", tunTapName);
+
+ 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);
+
+ 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;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : RestoreSpoofFilter
+ * Description: Restores the Linux anti-spoofing filter setting for the tuntap
+ * interface
+ * Input : tunTapName - name used for the tuntap interface (e.g. "tun0" or "tap1")
+ * Output : none
+ * Return : none
+ * Data Used : EthTapSpoofState
+ * ------------------------------------------------------------------------- */
+static void RestoreSpoofFilter(const char* tunTapName)
+{
+ FILE* procSpoof;
+ char procFile[FILENAME_MAX];
+
+ assert(tunTapName != NULL);
+
+ /* Generate the procfile name */
+ sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", tunTapName);
+
+ 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);
+ }
+}
+
+/* -------------------------------------------------------------------------
+ * Function : CreateLocalEtherTunTap
+ * Description: Creates and brings up an EtherTunTap device
+ * Input : none
+ * Output : none
+ * Return : success (0) or fail (<0)
+ * Data Used : EtherTunTapIfName - name used for the tuntap interface (e.g.
+ * "tun0" or "tap1")
+ * ------------------------------------------------------------------------- */
+static int CreateLocalEtherTunTap(void)
+{
+ static char* deviceName = "/dev/net/tun";
+ struct ifreq ifreq;
+ int etfd = open(deviceName, O_RDWR);
+ int skfd;
+ int ioctlres = 0;
+
+ if (etfd < 0)
+ {
+ olsr_printf(1, "%s: error opening %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
+ return -1;
+ }
+
+ memset(&ifreq, 0, sizeof(ifreq));
+
+ /* Specify either the IFF_TAP flag for Ethernet frames, or the IFF_TUN flag for IP.
+ * Specify IFF_NO_PI for not receiving extra meta packet information. */
+ if (strncmp(EtherTunTapIfName, "tun", 3) == 0)
+ {
+ ifreq.ifr_flags = IFF_TUN;
+ TunOrTap = TT_TUN;
+ }
+ else
+ {
+ ifreq.ifr_flags = IFF_TAP;
+ TunOrTap = TT_TAP;
+ }
+ ifreq.ifr_flags |= IFF_NO_PI;
+
+ strcpy(ifreq.ifr_name, EtherTunTapIfName);
+ if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
+ {
+ olsr_printf(1, "%s: ioctl(TUNSETIFF) error on %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
+ close(etfd);
+ return -1;
+ }
+
+ memset(&ifreq, 0, sizeof(ifreq));
+ strcpy(ifreq.ifr_name, EtherTunTapIfName);
+ ifreq.ifr_addr.sa_family = AF_INET;
+ skfd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (skfd < 0)
+ {
+ olsr_printf(1, "%s: socket(PF_INET) error on %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
+ close(etfd);
+ return -1;
+ }
+
+ if (ioctl(skfd, SIOCGIFADDR, &ifreq) < 0)
+ {
+ /* EtherTunTap interface does not yet have an IP address.
+ * Give it a dummy IP address "1.2.3.4". */
+ struct sockaddr_in *inaddr = (struct sockaddr_in *)&ifreq.ifr_addr;
+ inet_aton("1.2.3.4", &inaddr->sin_addr);
+ ioctlres = ioctl(skfd, SIOCSIFADDR, &ifreq);
+ if (ioctlres >= 0)
+ {
+ /* Bring EtherTunTap interface up (if not already) */
+ ioctlres = ioctl(skfd, SIOCGIFFLAGS, &ifreq);
+ if (ioctlres >= 0)
+ {
+ ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING);
+ ioctlres = ioctl(skfd, SIOCSIFFLAGS, &ifreq);
+ }
+ }
+
+ if (ioctlres < 0)
+ {
+ /* Any of the three above ioctl() calls failed */
+ olsr_printf(
+ 1,
+ "%s: error bringing up EtherTunTap interface \"%s\": %s\n",
+ PLUGIN_NAME,
+ EtherTunTapIfName,
+ strerror(errno));
+
+ close(etfd);
+ close(skfd);
+ return -1;
+ } /* if (ioctlres < 0) */
+ } /* if (ioctl...) */
+
+ /* Set the multicast flag on the interface. TODO: Maybe also set
+ * IFF_ALLMULTI. */
+ memset(&ifreq, 0, sizeof(ifreq));
+ strcpy(ifreq.ifr_name, EtherTunTapIfName);
+ ioctlres = ioctl(skfd, SIOCGIFFLAGS, &ifreq);
+ if (ioctlres >= 0)
+ {
+ ifreq.ifr_flags |= IFF_MULTICAST;
+ ioctlres = ioctl(skfd, SIOCSIFFLAGS, &ifreq);
+ }
+ if (ioctlres < 0)
+ {
+ /* Any of the two above ioctl() calls failed */
+ olsr_printf(
+ 1,
+ "%s: error setting multicast flag on EtherTunTap interface \"%s\": %s\n",
+ PLUGIN_NAME,
+ EtherTunTapIfName,
+ strerror(errno));
+ /* Continue anyway */
+ }
+ close(skfd);
+
+ /* Deactivate IP spoof filter for EtherTunTap device */
+ DeactivateSpoofFilter(ifreq.ifr_name);
+
+ olsr_printf(9, "%s: opened \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
+
+ return etfd;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : IsNullMacAddress
+ * Description: Checks if a MAC address is all-zeroes
+ * Input : mac - address to check
+ * Output : none
+ * Return : true (1) or false (0)
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+static int IsNullMacAddress(char* mac)
+{
+ int i;
+
+ assert(mac != NULL);
+
+ for (i = 0; i < IFHWADDRLEN; i++)
+ {
+ if (mac[i] != 0) return 0;
+ }
+ return 1;
+}
+
+/* -------------------------------------------------------------------------
+ * 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")
+ * Output : none
+ * Return : the number of opened sockets
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+static int CreateInterface(
+ const char* ifName,
+ struct interface* olsrIntf)
+{
+ int capturingSkfd;
+ int encapsulatingSkfd = -1;
+ struct ifreq ifr;
+ int nOpened = 0;
+ struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
+
+ assert(ifName != NULL);
+
+ if (newIf == NULL)
+ {
+ return 0;
+ }
+
+ if (olsrIntf != NULL)
+ {
+ /* On OLSR interfaces, create socket for encapsulating and forwarding
+ * multicast packets */
+ encapsulatingSkfd = CreateEncapsulateSocket(ifName);
+ if (encapsulatingSkfd < 0)
+ {
+ free(newIf);
+ return 0;
+ }
+ nOpened++;
+ }
+
+ /* On all interfaces, create socket for capturing and sending multicast packets */
+ capturingSkfd = CreateCaptureSocket(ifName);
+ if (capturingSkfd < 0)
+ {
+ close(encapsulatingSkfd);
+ free(newIf);
+ return 0;
+ }
+ nOpened++;
+
+ /* Retrieve the MAC address */
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, ifName, IFNAMSIZ);
+ if (ioctl(capturingSkfd, SIOCGIFHWADDR, &ifr) < 0)
+ {
+ olsr_printf(
+ 1,
+ "%s: ioctl(SIOCGIFHWADDR) error for device \"%s\": %s\n",
+ PLUGIN_NAME,
+ ifName,
+ strerror(errno));
+ close(capturingSkfd);
+ close(encapsulatingSkfd);
+ free(newIf);
+ return 0;
+ }
+
+ /* If null-interface, cancel the whole creation and return NULL */
+ if (IsNullMacAddress(ifr.ifr_hwaddr.sa_data))
+ {
+ close(capturingSkfd);
+ close(encapsulatingSkfd);
+ free(newIf);
+ return 0;
+ }
+
+ newIf->capturingSkfd = capturingSkfd;
+ newIf->encapsulatingSkfd = encapsulatingSkfd;
+ memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
+ memcpy(newIf->ifName, ifName, IFNAMSIZ);
+ newIf->olsrIntf = olsrIntf;
+ if (olsrIntf != NULL)
+ {
+ /* Copy broadcast address from OLSR interface */
+ newIf->broadAddr = olsrIntf->int_broadaddr;
+ }
+ else
+ {
+ /* Non-OLSR interface: retrieve the IP broadcast address */
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, ifName, IFNAMSIZ);
+ if (ioctl(capturingSkfd, SIOCGIFBRDADDR, &ifr) < 0)
+ {
+ olsr_printf(
+ 1,
+ "%s: ioctl(SIOCGIFBRDADDR) error for device \"%s\": %s\n",
+ PLUGIN_NAME,
+ ifName,
+ strerror(errno));
+
+ ((struct sockaddr_in*)&newIf->broadAddr)->sin_addr.s_addr = inet_addr("0.0.0.0");
+ }
+ else
+ {
+ newIf->broadAddr = ifr.ifr_broadaddr;
+ }
+ }
+
+ memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
+ newIf->nextFragmentHistoryEntry = 0;
+
+ newIf->next = BmfInterfaces;
+ BmfInterfaces = newIf;
+
+ OLSR_PRINTF(
+ 9,
+ "%s: opened %s interface \"%s\"\n",
+ PLUGIN_NAME_SHORT,
+ olsrIntf != NULL ? "OLSR" : "non-OLSR",
+ ifName);
+
+ return nOpened;
+}
+
+/* -------------------------------------------------------------------------
+ * 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 : success (0) or fail (<0)
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
+{
+ int skfd;
+ struct ifconf ifc;
+ int numreqs = 30;
+ struct ifreq* ifr;
+ int n;
+ int nOpened = 0;
+
+ EtherTunTapFd = CreateLocalEtherTunTap();
+ if (EtherTunTapFd >=0)
+ {
+ nOpened++;
+ }
+
+ skfd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (skfd < 0)
+ {
+ olsr_printf(
+ 1,
+ "%s: no inet socket available to retrieve interface list: %s\n",
+ PLUGIN_NAME,
+ strerror(errno));
+ 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)
+ {
+ olsr_printf(1, "%s: ioctl(SIOCGIFCONF) error: %s\n", PLUGIN_NAME, strerror(errno));
+
+ 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;
+
+ /* ...find the OLSR interface structure, if any */
+ union olsr_ip_addr ipAddr;
+ COPY_IP(&ipAddr, &((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr.s_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 = ...) */
+ }
+
+ nOpened += CreateInterface(ifr->ifr_name, olsrIntf);
+
+ } /* for (n = ...) */
+
+ free(ifc.ifc_buf);
+
+ if (BmfInterfaces == NULL)
+ {
+ olsr_printf(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
+ return -1;
+ }
+
+ olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
+
+ return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * 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);
+}
+
+/* -------------------------------------------------------------------------
+ * Function : CloseBmfNetworkInterfaces
+ * Description: Closes every socket on each network interface used by BMF
+ * Input : newIntf - network interface to add
+ * 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()
+{
+ int nClosed = 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(
+ 9,
+ "%s: closed %s interface \"%s\"\n",
+ PLUGIN_NAME_SHORT,
+ bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
+ bmfIf->ifName);
+
+ free(bmfIf);
+ }
+
+ if (EtherTunTapFd >= 0)
+ {
+ /* Restore IP spoof filter for EtherTunTap device */
+ RestoreSpoofFilter(EtherTunTapIfName);
+
+ close(EtherTunTapFd);
+ nClosed++;
+
+ OLSR_PRINTF(9, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
+ }
+
+ BmfInterfaces = NULL;
+
+ olsr_printf(1, "%s: closed %d sockets\n", PLUGIN_NAME, nClosed);
+}
+
+#define MAX_NON_OLSR_IFS 10
+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")
+ * Output : none
+ * Return : success (1) or fail (0)
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+int AddNonOlsrBmfIf(const char* ifName)
+{
+ 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 0;
+ }
+
+ strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ);
+ nNonOlsrIfs++;
+ return 1;
+}
+
+/* -------------------------------------------------------------------------
+ * 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 : none
+ * ------------------------------------------------------------------------- */
+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;
+}
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.h olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.h
--- olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.h 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.h 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,106 @@
+#ifndef _BMF_NETWORKINTERFACES_H
+#define _BMF_NETWORKINTERFACES_H
+
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : NetworkInterfaces.h
+ * Description: Functions to open and close sockets
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+/* System includes */
+#include <netinet/in.h> /* struct in_addr */
+
+/* Plugin includes */
+#include "Packet.h" /* IFHWADDRLEN */
+
+
+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;
+
+ unsigned char macAddr[IFHWADDRLEN];
+
+ char ifName[IFNAMSIZ];
+
+ /* OLSRs idea of this network interface. NULL if this interface is not
+ * OLSR-enabled. */
+ struct interface* olsrIntf;
+
+ /* Kernels index of this network interface */
+ int ifIndex;
+
+ /* Broadcast address of this network interface */
+ struct sockaddr 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;
+
+ /* Next element in list */
+ struct TBmfInterface* next;
+};
+
+extern struct TBmfInterface* BmfInterfaces;
+
+extern int EtherTunTapFd;
+
+extern const char* EtherTunTapIfName;
+
+enum TTunOrTap { TT_TUN = 0, TT_TAP };
+extern enum TTunOrTap TunOrTap;
+
+int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
+void AddInterface(struct interface* newIntf);
+void CloseBmfNetworkInterfaces(void);
+int AddNonOlsrBmfIf(const char* ifName);
+int IsNonOlsrBmfIf(const char* ifName);
+
+#endif /* _BMF_NETWORKINTERFACES_H */
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/olsrd_plugin.c olsrd-0.4.10/lib/bmf/src/olsrd_plugin.c
--- olsrd-0.4.10.orig/lib/bmf/src/olsrd_plugin.c 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/olsrd_plugin.c 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : olsrd_plugin.c
+ * Description: Interface to the OLSRD plugin system
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+/* System includes */
+#include <assert.h> /* assert() */
+#include <stdio.h>
+
+/* OLSRD includes */
+#include "olsrd_plugin.h"
+#include "defs.h" /* olsr_u8_t, olsr_cnf */
+#include "scheduler.h" /* olsr_register_scheduler_event */
+
+/* BMF includes */
+#include "Bmf.h" /* InitBmf(), CloseBmf(), RegisterBmfParameter() */
+#include "PacketHistory.h" /* InitPacketHistory() */
+
+static void __attribute__ ((constructor)) my_init(void);
+static void __attribute__ ((destructor)) my_fini(void);
+
+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()
+{
+ return OLSRD_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()
+{
+ /* Check validity */
+ if (olsr_cnf->ip_version != AF_INET)
+ {
+ fprintf(stderr, PLUGIN_NAME ": This plugin only supports IPv4!\n");
+ return 0;
+ }
+
+ /* Clear the packet history */
+ InitPacketHistory();
+
+ /* Register ifchange function */
+ add_ifchgf(&InterfaceChange);
+
+ /* Register the duplicate registration pruning process */
+ olsr_register_scheduler_event(&PrunePacketHistory, NULL, 3.0, 2.0, NULL);
+
+ return InitBmf(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()
+{
+ CloseBmf();
+}
+
+/* -------------------------------------------------------------------------
+ * Function : olsrd_plugin_register_param
+ * Description: Register parameters from config file
+ * Input : key - the parameter name
+ * value - the parameter value
+ * Output : none
+ * Return : fatal error (<0), minor error (0) or success (>0)
+ * Data Used : none
+ * Notes : Called by main OLSR (init_olsr_plugin) for all plugin parameters
+ * ------------------------------------------------------------------------- */
+int olsrd_plugin_register_param(char* key, char* value)
+{
+ assert(key != NULL && value != NULL);
+
+ return RegisterBmfParameter(key, value);
+}
+
+/* -------------------------------------------------------------------------
+ * 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()
+{
+ /* 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()
+{
+ olsr_plugin_exit();
+}
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.c olsrd-0.4.10/lib/bmf/src/Packet.c
--- olsrd-0.4.10.orig/lib/bmf/src/Packet.c 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/Packet.c 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : Packet.c
+ * Description: BMF and IP packet processing functions
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+#include "Packet.h"
+
+/* System includes */
+#include <assert.h> /* assert() */
+#include <sys/types.h> /* u_int32_t */
+#include <netinet/in.h> /* ntohs(), htons() */
+#include <linux/ip.h>
+
+/* -------------------------------------------------------------------------
+ * Function : GetIpTtl
+ * Description: Retrieve the TTL (Time To Live) value from the IP header of
+ * the passed ethernet-IP packet
+ * Input : buffer - the ethernet-IP packet
+ * Output : none
+ * Return : TTL value
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+int GetIpTtl(unsigned char* buffer)
+{
+ struct iphdr* iph;
+
+ assert(buffer != NULL);
+
+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
+ return iph->ttl;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : SaveTtlAndChecksum
+ * Description: Save the TTL (Time To Live) value and IP checksum as found in
+ * the IP header of the passed ethernet-IP packet
+ * Input : buffer - the ethernet-IP packet
+ * Output : sttl - the TTL and checksum values
+ * Return : none
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+void SaveTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl)
+{
+ struct iphdr* iph;
+
+ assert(buffer != NULL && sttl != NULL);
+
+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
+ sttl->ttl = iph->ttl;
+ sttl->check = ntohs(iph->check);
+}
+
+/* -------------------------------------------------------------------------
+ * Function : RestoreTtlAndChecksum
+ * Description: Restore the TTL (Time To Live) value and IP checksum in
+ * the IP header of the passed ethernet-IP packet
+ * Input : buffer - the ethernet-IP packet
+ * sttl - the TTL and checksum values
+ * Output : none
+ * Return : none
+ * Data Used : none
+ * ------------------------------------------------------------------------- */
+void RestoreTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl)
+{
+ struct iphdr* iph;
+
+ assert(buffer != NULL && sttl != NULL);
+
+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
+ iph->ttl = sttl->ttl;
+ iph->check = htons(sttl->check);
+}
+
+/* -------------------------------------------------------------------------
+ * Function : DecreaseTtlAndUpdateHeaderChecksum
+ * Description: For an IP packet, decrement the TTL value and update the IP header
+ * checksum accordingly.
+ * Input : buffer - the ethernet-IP packet
+ * Output : none
+ * Return : none
+ * Data Used : none
+ * Notes : See also RFC1141
+ * ------------------------------------------------------------------------- */
+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* buffer)
+{
+ struct iphdr* iph;
+ u_int32_t sum;
+
+ assert(buffer != NULL);
+
+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
+
+ iph->ttl--; /* decrement ttl */
+ sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
+ iph->check = htons(sum + (sum>>16)); /* add carry */
+}
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.h olsrd-0.4.10/lib/bmf/src/Packet.h
--- olsrd-0.4.10.orig/lib/bmf/src/Packet.h 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/Packet.h 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,85 @@
+#ifndef _BMF_PACKET_H
+#define _BMF_PACKET_H
+
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : Packet.h
+ * Description: BMF and IP packet processing functions
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+/* System includes */
+#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
+#include <sys/types.h> /* u_int8_t, u_int16_t */
+
+/* Offsets and sizes into IP-ethernet packets */
+#define IPV4_ADDR_SIZE 4
+#define ETH_TYPE_OFFSET (2*IFHWADDRLEN)
+#define ETH_TYPE_LEN 2
+#define IP_HDR_OFFSET (ETH_TYPE_OFFSET + ETH_TYPE_LEN)
+#define IPV4_OFFSET_SRCIP 12
+#define IPV4_OFFSET_DSTIP (IPV4_OFFSET_SRCIP + IPV4_ADDR_SIZE)
+
+#define IPV4_TYPE 0x0800
+
+/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
+ * with a 16-bytes BMF header (struct TEncapHeader), followed by the
+ * encapsulated Ethernet-IP packet itself */
+
+struct TEncapHeader
+{
+ u_int32_t crc32;
+ u_int32_t futureExpansion1;
+ u_int32_t futureExpansion2;
+ u_int32_t futureExpansion3;
+} __attribute__((__packed__));
+
+#define ENCAP_HDR_LEN sizeof(struct TEncapHeader)
+
+struct TSaveTtl
+{
+ u_int8_t ttl;
+ u_int16_t check;
+} __attribute__((__packed__));
+
+int GetIpTtl(unsigned char* buffer);
+void SaveTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl);
+void RestoreTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl);
+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* buffer);
+
+#endif /* _BMF_PACKET_H */
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.c olsrd-0.4.10/lib/bmf/src/PacketHistory.c
--- olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.c 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/PacketHistory.c 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,293 @@
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : PacketHistory.c
+ * Description: Functions for keeping and accessing the history of processed
+ * multicast IP packets.
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+#include "PacketHistory.h"
+
+/* System includes */
+#include <assert.h> /* assert() */
+#include <sys/types.h> /* u_int16_t, u_int32_t */
+#include <string.h> /* memset */
+
+/* OLSRD includes */
+#include "olsr.h" /* olsr_printf */
+
+/* Plugin includes */
+#include "Packet.h"
+
+static u_int32_t PacketHistory[HISTORY_TABLE_SIZE];
+
+#define CRC_UPTO_NBYTES 256
+
+/* -------------------------------------------------------------------------
+ * 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;
+}
+
+
+/* -------------------------------------------------------------------------
+ * 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;
+ }
+}
+
+/* -------------------------------------------------------------------------
+ * 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++)
+ {
+ /* Skip IP header checksum; we want to avoid as much as possible
+ * calculating a checksum over data containing a checksum */
+ // if (i >= 12 && i < 14) continue;
+
+ j = ((int) (crc & 0xFF) ^ *buffer++);
+ crc = (crc >> 8) ^ CrcTable[j];
+ }
+ return crc ^ 0xffffffffUL;
+}
+
+/* */
+/* -------------------------------------------------------------------------
+ * Function : PacketCrc32
+ * Description: Calculates the CRC-32 value for an Ethernet packet
+ * Input : ethPkt - the Ethernet packet
+ * len - the number of octets in the Ethernet packet
+ * Output : none
+ * Return : 32-bits hash value
+ * Data Used : none
+ * Notes : The source and destination MAC address are not taken into account
+ * in the CRC calculation.
+ * ------------------------------------------------------------------------- */
+u_int32_t PacketCrc32(unsigned char* ethPkt, ssize_t len)
+{
+ assert(ethPkt != NULL);
+ assert(len > ETH_TYPE_OFFSET);
+
+ /* Start CRC calculation at ethertype; skip source and destination MAC
+ * addresses. Clip number of bytes over which CRC is calculated to prevent
+ * long packets from possibly claiming too much CPU resources. */
+ ssize_t nCrcBytes = len - ETH_TYPE_OFFSET;
+ if (nCrcBytes > CRC_UPTO_NBYTES)
+ {
+ nCrcBytes = CRC_UPTO_NBYTES;
+ }
+ return CalcCrc32(ethPkt + ETH_TYPE_OFFSET, nCrcBytes);
+}
+
+/* Calculates a 16-bit hash value from a 32-bit hash value */
+u_int16_t Hash16(u_int32_t hash32)
+{
+ return ((hash32 >> 16) + hash32) & 0xFFFFU;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : InitPacketHistory
+ * Description: Initialize the packet history table and CRC-32 table
+ * Input : none
+ * Output : none
+ * Return : none
+ * Data Used : PacketHistory
+ * ------------------------------------------------------------------------- */
+void InitPacketHistory()
+{
+ memset(PacketHistory, 0, sizeof(PacketHistory));
+ GenerateCrc32Table();
+}
+
+/* -------------------------------------------------------------------------
+ * Function : MarkRecentPacket
+ * Description: Record the fact that this packet was seen recently
+ * Input : hash16
+ * Output : none
+ * Return : none
+ * Data Used : PacketHistory
+ * ------------------------------------------------------------------------- */
+void MarkRecentPacket(u_int16_t hash16)
+{
+ u_int32_t index;
+ uint offset;
+
+ index = hash16 / NPACKETS_PER_ENTRY;
+ assert(index < HISTORY_TABLE_SIZE);
+
+ offset = (hash16 % NPACKETS_PER_ENTRY) * NBITS_PER_PACKET;
+ assert(offset <= NBITS_IN_UINT32 - NBITS_PER_PACKET);
+
+ /* Mark as "seen recently" */
+ PacketHistory[index] = PacketHistory[index] | (0x3u << offset);
+}
+
+/* -------------------------------------------------------------------------
+ * Function : CheckAndMarkRecentPacket
+ * Description: Check if this packet was seen recently, then record the fact
+ * that this packet was seen recently.
+ * Input : hash16
+ * Output : none
+ * Return : not recently seen (0), recently seen (1)
+ * Data Used : PacketHistory
+ * ------------------------------------------------------------------------- */
+int CheckAndMarkRecentPacket(u_int16_t hash16)
+{
+ u_int32_t index;
+ uint offset;
+ u_int32_t bitMask;
+ int result;
+
+ index = hash16 / NPACKETS_PER_ENTRY;
+ assert(index < HISTORY_TABLE_SIZE);
+
+ offset = (hash16 % NPACKETS_PER_ENTRY) * NBITS_PER_PACKET;
+ assert(offset <= NBITS_IN_UINT32 - NBITS_PER_PACKET);
+
+ bitMask = 0x1u << offset;
+ result = ((PacketHistory[index] & bitMask) == bitMask);
+
+ /* Always mark as "seen recently" */
+ PacketHistory[index] = PacketHistory[index] | (0x3u << offset);
+
+ return result;
+}
+
+/* -------------------------------------------------------------------------
+ * Function : PrunePacketHistory
+ * Description: Prune the packet history table.
+ * Input : useless - not used
+ * Output : none
+ * Return : none
+ * Data Used : PacketHistory
+ * ------------------------------------------------------------------------- */
+void PrunePacketHistory(void* useless)
+{
+ uint i;
+ for (i = 0; i < HISTORY_TABLE_SIZE; i++)
+ {
+ if (PacketHistory[i] > 0)
+ {
+ uint j;
+ for (j = 0; j < NPACKETS_PER_ENTRY; j++)
+ {
+ uint offset = j * NBITS_PER_PACKET;
+
+ u_int32_t bitMask = 0x3u << offset;
+ u_int32_t bitsSeenRecenty = 0x3u << offset;
+ u_int32_t bitsTimingOut = 0x1u << offset;
+
+ /* 10 should never occur */
+ assert ((PacketHistory[i] & bitMask) != (0x2u << offset));
+
+ if ((PacketHistory[i] & bitMask) == bitsSeenRecenty)
+ {
+ /* 11 -> 01 */
+ PacketHistory[i] &= ~bitMask | bitsTimingOut;
+ }
+ else if ((PacketHistory[i] & bitMask) == bitsTimingOut)
+ {
+ /* 01 -> 00 */
+ PacketHistory[i] &= ~bitMask;
+ }
+ } /* for (j = ...) */
+ } /* if (PacketHistory[i] > 0) */
+ } /* for (i = ...) */
+}
diff -Nur olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.h olsrd-0.4.10/lib/bmf/src/PacketHistory.h
--- olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.h 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/src/PacketHistory.h 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,67 @@
+#ifndef _BMF_PACKETHISTORY_H
+#define _BMF_PACKETHISTORY_H
+
+/*
+ * 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.
+ */
+
+/* -------------------------------------------------------------------------
+ * File : PacketHistory.h
+ * Description: Functions for keeping and accessing the history of processed
+ * multicast IP packets.
+ * Created : 29 Jun 2006
+ *
+ * $Id$
+ *
+ * $Log$
+ * ------------------------------------------------------------------------- */
+
+#include <sys/types.h> /* ssize_t */
+
+/* 2 bits per seen packet:
+ * 11 = "seen recently",
+ * 01 = "timing out"
+ * 00 = "not seen recently"
+ * Note that 10 is unused */
+#define NBITS_PER_PACKET 2
+#define NBITS_IN_UINT16 (sizeof(u_int16_t) * 8)
+#define NBITS_IN_UINT32 (sizeof(u_int32_t) * 8)
+#define NPACKETS_PER_ENTRY (NBITS_IN_UINT32 / NBITS_PER_PACKET)
+#define HISTORY_TABLE_SIZE ((1 << NBITS_IN_UINT16) / NPACKETS_PER_ENTRY)
+
+void InitPacketHistory(void);
+u_int32_t PacketCrc32(unsigned char* ethPkt, ssize_t len);
+u_int16_t Hash16(u_int32_t hash32);
+void MarkRecentPacket(u_int16_t hash16);
+int CheckAndMarkRecentPacket(u_int16_t hash16);
+void PrunePacketHistory(void*);
+
+#endif /* _BMF_PACKETHISTORY_H */
diff -Nur olsrd-0.4.10.orig/lib/bmf/version-script.txt olsrd-0.4.10/lib/bmf/version-script.txt
--- olsrd-0.4.10.orig/lib/bmf/version-script.txt 1970-01-01 01:00:00.000000000 +0100
+++ olsrd-0.4.10/lib/bmf/version-script.txt 2006-12-01 08:26:58.000000000 +0100
@@ -0,0 +1,10 @@
+VERS_1.0
+{
+ global:
+ olsrd_plugin_interface_version;
+ olsrd_plugin_register_param;
+ olsrd_plugin_init;
+
+ local:
+ *;
+};
diff -Nur olsrd-0.4.10.orig/Makefile olsrd-0.4.10/Makefile
--- olsrd-0.4.10.orig/Makefile 2006-12-01 08:26:58.000000000 +0100
+++ olsrd-0.4.10/Makefile 2006-12-01 08:26:58.000000000 +0100
@@ -164,5 +164,10 @@
$(MAKE) -C lib/pgraph
$(MAKE) -C lib/pgraph install
+bmf:
+ $(MAKE) -C lib/bmf clean
+ $(MAKE) -C lib/bmf
+ $(MAKE) -C lib/bmf install
+
build_all: cfgparser olsrd libs
install_all: install install_libs