07e70aee64
git-svn-id: svn://svn.openwrt.org/openwrt/packages@6273 3c298f89-4303-0410-b956-a3cf2f4a3e73
3574 lines
122 KiB
Diff
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
|