remove the need for C99 math (closes: #1579)
[openwrt/svn-archive/archive.git] / net / olsrd / patches / 170-olsrd-bmf.patch
1 diff -Nur olsrd-0.4.10.orig/lib/bmf/Makefile olsrd-0.4.10/lib/bmf/Makefile
2 --- olsrd-0.4.10.orig/lib/bmf/Makefile 1970-01-01 01:00:00.000000000 +0100
3 +++ olsrd-0.4.10/lib/bmf/Makefile 2006-12-01 08:26:58.000000000 +0100
4 @@ -0,0 +1,64 @@
5 +#
6 +# OLSR Basic Multicast Forwarding (BMF) plugin.
7 +# Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
8 +# Written by Erik Tromp.
9 +# All rights reserved.
10 +#
11 +# Redistribution and use in source and binary forms, with or without
12 +# modification, are permitted provided that the following conditions
13 +# are met:
14 +#
15 +# * Redistributions of source code must retain the above copyright
16 +# notice, this list of conditions and the following disclaimer.
17 +# * Redistributions in binary form must reproduce the above copyright
18 +# notice, this list of conditions and the following disclaimer in
19 +# the documentation and/or other materials provided with the
20 +# distribution.
21 +# * Neither the name of Thales, BMF nor the names of its
22 +# contributors may be used to endorse or promote products derived
23 +# from this software without specific prior written permission.
24 +#
25 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 +# POSSIBILITY OF SUCH DAMAGE.
37 +#
38 +# $Id: Makefile,v 1.10 2005/05/25 13:50:22 br1 Exp $
39 +
40 +OLSRD_PLUGIN = true
41 +PLUGIN_NAME = olsrd_bmf
42 +PLUGIN_VER = 1.1
43 +
44 +TOPDIR = ../..
45 +include $(TOPDIR)/Makefile.inc
46 +
47 +LIBS += -lpthread
48 +
49 +ifneq ($(OS),linux)
50 +
51 +default_target install clean:
52 + @echo "*** BMF Plugin only supported on Linux, sorry!"
53 +
54 +else
55 +
56 +default_target: $(PLUGIN_FULLNAME)
57 +
58 +$(PLUGIN_FULLNAME): $(OBJS)
59 + $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
60 +
61 +install: $(PLUGIN_FULLNAME)
62 + $(STRIP) $(PLUGIN_FULLNAME)
63 + $(INSTALL_LIB)
64 +
65 +clean:
66 + rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
67 +
68 +endif
69 \ Kein Zeilenumbruch am Dateiende.
70 diff -Nur olsrd-0.4.10.orig/lib/bmf/PluginBmf.prj olsrd-0.4.10/lib/bmf/PluginBmf.prj
71 --- olsrd-0.4.10.orig/lib/bmf/PluginBmf.prj 1970-01-01 01:00:00.000000000 +0100
72 +++ olsrd-0.4.10/lib/bmf/PluginBmf.prj 2006-12-01 08:26:58.000000000 +0100
73 @@ -0,0 +1,83 @@
74 +#DO NOT EDIT THIS FILE!!!
75 +[APPTYPE@DEBUG]
76 +APPTYPE = 0
77 +[APPTYPE@RELEASE]
78 +APPTYPE = 0
79 +[COMPILE@DEBUG]
80 +COMPILEOPTION = -c -g
81 +[COMPILE@RELEASE]
82 +COMPILEOPTION = -c
83 +[CVS]
84 +INITDIR = $CVSROOT
85 +REMOTELOGIN = 0
86 +[DEBUG@DEBUG]
87 +EXEPOS = PluginSmf2
88 +WORKDIR =
89 +[DEBUG@RELEASE]
90 +EXEPOS = PluginSmf2
91 +WORKDIR =
92 +[DEPENDENCY]
93 +FILENAME = README_BMF.txt
94 +FILENAME = ../../olsrd.conf
95 +FILENAME = README_BMF
96 +FILENAME = version-script.txt
97 +FILENAME = README_SMF
98 +FILENAME = Makefile
99 +[GDBSERVER]
100 +ISGDBSERVER = 0
101 +[HEADER]
102 +FILENAME = src/Bmf.h
103 +FILENAME = src/PacketHistory.h
104 +FILENAME = src/Packet.h
105 +FILENAME = src/Address.h
106 +FILENAME = src/NetworkInterfaces.h
107 +FILENAME = src/DropList.h
108 +[LANTYPE@DEBUG]
109 +LANTYPE = 0
110 +[LANTYPE@RELEASE]
111 +LANTYPE = 0
112 +[LINK@DEBUG]
113 +LINKOPTION = -g -o PluginSmf2
114 +OUTPUT = PluginSmf2
115 +[LINK@RELEASE]
116 +LINKOPTION = -o PluginSmf2
117 +OUTPUT = PluginSmf2
118 +[MAIN]
119 +CONFIG = RELEASE,DEBUG
120 +DEFAULTCONFIG = DEBUG
121 +DEVTYPE = 0
122 +ONLINE = 1
123 +VERSION = 3.0
124 +WATCH =
125 +[MAKE@DEBUG]
126 +CUSTOMMAKE = Makefile
127 +CUSTOMMAKEBUILDPARAM =
128 +CUSTOMMAKECLEANPARAM = clean
129 +CUSTOMMAKEDIR =
130 +CUSTOMSHELL =
131 +MAKEFILE = Makefile_DEBUG.mk
132 +MANUALDEFAULT = 1
133 +REGENMAKEFILE = 1
134 +[MAKE@RELEASE]
135 +CUSTOMMAKE = Makefile
136 +CUSTOMMAKEBUILDPARAM =
137 +CUSTOMMAKECLEANPARAM = clean
138 +CUSTOMMAKEDIR =
139 +CUSTOMSHELL =
140 +MAKEFILE = Makefile_DEBUG.mk
141 +MANUALDEFAULT = 1
142 +REGENMAKEFILE = 1
143 +[PRECOMPILE@DEBUG]
144 +ESQL_OPTION = -g
145 +PROC_OPTION = DEFINE=_PROC_ MODE=ORACLE LINES=true
146 +[PRECOMPILE@RELEASE]
147 +ESQL_OPTION =
148 +PROC_OPTION = DEFINE=_PROC_ MODE=ORACLE
149 +[SOURCE]
150 +FILENAME = src/Bmf.c
151 +FILENAME = src/Packet.c
152 +FILENAME = src/PacketHistory.c
153 +FILENAME = src/DropList.c
154 +FILENAME = src/olsrd_plugin.c
155 +FILENAME = src/Address.c
156 +FILENAME = src/NetworkInterfaces.c
157 diff -Nur olsrd-0.4.10.orig/lib/bmf/README_BMF.txt olsrd-0.4.10/lib/bmf/README_BMF.txt
158 --- olsrd-0.4.10.orig/lib/bmf/README_BMF.txt 1970-01-01 01:00:00.000000000 +0100
159 +++ olsrd-0.4.10/lib/bmf/README_BMF.txt 2006-12-01 08:26:58.000000000 +0100
160 @@ -0,0 +1,233 @@
161 +BASIC MULTICAST FORWARDING PLUGIN FOR OLSRD
162 +by Erik Tromp (erik.tromp@nl.thalesgroup.com)
163 +
164 +12 Jul 2006: Version 1.1
165 +* Major updates in code forwarding from and to non-OLSR enabled
166 + network interfaces.
167 +* Debug level 9 gives a better indication of what happens to each
168 + handled multicast/broadcast packet.
169 +* Can now deal with network interface removal ("ifdown eth1") and
170 + addition ("ifup eth1").
171 +* CRC-calculation for duplicate detection is done over first 256
172 + bytes in packet instead of over full packet length.
173 +* CRC calculated only on captured packets, and is subsequently
174 + passed on in a special OLSR-BMF encapsulation header.
175 +* Deals correctly with fragmented packets
176 +
177 +27 Apr 2006: Version 1.0.1
178 +* First release.
179 +
180 +1. Introduction
181 +---------------
182 +
183 +The Basic Multicast Forwarding Plugin floods IP-multicast and
184 +IP-local-broadcast traffic over an OLSRD network. It uses the
185 +Multi-Point Relays (MPRs) as identified by the OLSR protocol
186 +to optimize the flooding of multicast and local broadcast packets
187 +to all the nodes in the network. To prevent broadcast storms, a
188 +history of packets is kept; only packets that have not been seen
189 +in the past 3-6 seconds are forwarded.
190 +
191 +In the IP header there is room for only two IP-addresses:
192 +* the destination IP address (in our case either a multicast
193 + IP-address 224.0.0.0...239.255.255.255, or a local broadcast
194 + address e.g. 192.168.1.255), and
195 +* the source IP address (the originator).
196 +
197 +For optimized flooding, however, we need more information. Let's
198 +assume we are the BMF process on one node. We will need to know which
199 +node forwarded the IP packet to us. Since OLSR keeps track of which
200 +nodes select our node as MPR (see the olsr_lookup_mprs_set function),
201 +we can determine if the node that forwarded the packet, has selected us as
202 +MPR. If so, we must also forward the packet, changing the 'forwarded-by'
203 +IP-address to that of us.
204 +
205 +Because we need more information than fits in a normal IP-header, the
206 +original packets are encapsulated into a new IP packet. Encapsulated
207 +packets are transported in UDP, port 50505. The source address of the
208 +encapsulation packet is set to the address of the forwarder instead of
209 +the originator. Of course, the payload of the encapsulation packet is
210 +the original IP packet.
211 +
212 +For local reception, each received encapsulated packets is unpacked
213 +and passed into a tuntap interface which is specially created for
214 +this purpose.
215 +
216 +Here is in short how the flooding works (see also the
217 +BmfEncapsulatedPacketReceived(...) function; details with respect to
218 +the forwarding towards non-OLSR enabled nodes are omitted):
219 +
220 + On all OLSR-enabled interfaces, setup reception of packets
221 + on UDP port 50505.
222 + Upon reception of such a packet:
223 + If the received packet was sent by myself, drop it.
224 + If the packet was recently seen, drop it.
225 + Unpack the encapsulated packet and send a copy to myself via the
226 + TunTap device.
227 + If I am an MPR for the node that forwarded the packet to me,
228 + forward the packet to all OLSR-enabled interfaces *including*
229 + the interface on which it was received.
230 +
231 +As with all good things in life, it's so simple you could have
232 +thought of it yourself.
233 +
234 +
235 +2. How to build and install
236 +---------------------------
237 +
238 +Follow the instructions in the base directory README file under
239 +section II. - BUILDING AND RUNNING OLSRD. To be sure to install
240 +the BMF plugin, cd to the base directory and issue the follwing
241 +command at the shell prompt:
242 +
243 + make install_all
244 +
245 +Next, turn on the possibility to create a tuntap device (see also
246 +/usr/src/linux/Documentation/networking/tuntap.txt)
247 +
248 + mkdir /dev/net # if it doesn't exist already
249 + mknod /dev/net/tun c 10 200
250 +
251 +Set permissions, e.g.:
252 + chmod 0700 /dev/net/tun
253 +
254 +Edit the file /etc/olsrd.conf to load the BMF plugin. For example:
255 +
256 + LoadPlugin "olsrd_bmf.so.1.1"
257 + {
258 + # No PlParam entries required for basic operation
259 + }
260 +
261 +
262 +3. How to run
263 +-------------
264 +
265 +After building and installing OLSRD with the BMF plugin, run the
266 +olsrd deamon by entering at the shell prompt:
267 + olsrd
268 +
269 +Look at the output; it should list the BMF plugin, e.g.:
270 +
271 + ---------- Plugin loader ----------
272 + Library: olsrd_bmf.so.1.1
273 + OLSRD Basic Multicast Forwarding plugin 1.1 (Jul 12 2006 04:12:42)
274 + (C) Thales Communications Huizen, Netherlands
275 + Erik Tromp (erik.tromp@nl.thalesgroup.com)
276 + Checking plugin interface version... 4 - OK
277 + Trying to fetch plugin init function... OK
278 + Trying to fetch param function... OK
279 + Sending parameters...
280 + "NonOlsrIf"/"eth0"... OK
281 + Running plugin_init function...
282 + OLSRD Basic Multicast Forwarding plugin: opened 6 sockets
283 + ---------- LIBRARY LOADED ----------
284 +
285 +
286 +4. How to check if it works
287 +---------------------------
288 +
289 +To check that BMF is working, enter the following command on the
290 +command prompt:
291 +
292 + ping -I eth1 224.0.0.1
293 +
294 +Replace eth1 with the name of any OLSR-enabled network interface.
295 +
296 +All OLSR-BMF nodes in the MANET should respond. For example:
297 +
298 +root@IsdbServer:~# ping -I eth1 224.0.0.1
299 +PING 224.0.0.1 (224.0.0.1) from 192.168.151.50 eth1: 56(84) bytes of data.
300 +64 bytes from 192.168.151.50: icmp_seq=1 ttl=64 time=0.511 ms
301 +64 bytes from 192.168.151.53: icmp_seq=1 ttl=64 time=4.67 ms (DUP!)
302 +64 bytes from 192.168.151.55: icmp_seq=1 ttl=63 time=10.7 ms (DUP!)
303 +64 bytes from 192.168.151.50: icmp_seq=2 ttl=64 time=0.076 ms
304 +64 bytes from 192.168.151.53: icmp_seq=2 ttl=64 time=1.23 ms (DUP!)
305 +64 bytes from 192.168.151.55: icmp_seq=2 ttl=63 time=1.23 ms (DUP!)
306 +64 bytes from 192.168.151.50: icmp_seq=3 ttl=64 time=0.059 ms
307 +64 bytes from 192.168.151.53: icmp_seq=3 ttl=64 time=2.94 ms (DUP!)
308 +64 bytes from 192.168.151.55: icmp_seq=3 ttl=63 time=5.62 ms (DUP!)
309 +64 bytes from 192.168.151.50: icmp_seq=4 ttl=64 time=0.158 ms
310 +64 bytes from 192.168.151.53: icmp_seq=4 ttl=64 time=1.14 ms (DUP!)
311 +64 bytes from 192.168.151.55: icmp_seq=4 ttl=63 time=1.16 ms (DUP!)
312 +
313 +
314 +5. Adding non-OLSR interfaces to the multicast flooding
315 +-------------------------------------------------------
316 +
317 +As a special feature, it is possible to have multicast and local-broadcast
318 +IP packets forwarded also on non-OLSR interfaces.
319 +
320 +If you have network interfaces on which OLSR is *not* running, but you *do*
321 +want to forward multicast and local-broadcast IP packets, specify these
322 +interfaces one by one as "NonOlsrIf" parameters in the BMF plugin section
323 +of /etc/olsrd.conf. For example:
324 +
325 + LoadPlugin "olsrd_bmf.so.1.1"
326 + {
327 + # Non-OLSR interfaces to participate in the multicast flooding
328 + PlParam "NonOlsrIf" "eth2"
329 + PlParam "NonOlsrIf" "eth3"
330 + }
331 +
332 +If an interface is listed both as NonOlsrIf for BMF, and in the
333 +Interfaces { ... } section of olsrd.conf, it will be seen by BMF
334 +as an OLSR-enabled interface.
335 +
336 +Note that when BMF receives or sends a packet via a non-OLSR interface,
337 +the TTL is decremented. TTL is NOT decremented on packets traveling
338 +within the OLSR-BMF MANET, since that is considered to be one (repaired)
339 +broadcast domain.
340 +
341 +Packets are not forwarded from one non-OLSR interface to another non-OLSR
342 +interface, only from non-OLSR interfaces to OLSR interfaces and vice versa.
343 +Packet forwarding between non-OLSR interfaces should be the result of
344 +other multicast routing protocols.
345 +
346 +
347 +6. Testing in a lab environment
348 +-------------------------------
349 +
350 +Setup IP-tables to drop packets from nodes which are not
351 +direct (1-hop) neigbors. For example, to drop all packets from
352 +a host with MAC address 00:0C:29:28:0E:CC, enter at the shell prompt:
353 +
354 + iptables -A INPUT -m mac --mac-source 00:0C:29:28:0E:CC -j DROP
355 +
356 +Edit the file /etc/olsrd.conf, and specify the MAC addresses of the nodes
357 +we do not want to see; even though packets from these nodes are dropped
358 +by iptables, they are still received on network interfaces which are in
359 +promiscuous mode. For example:
360 +
361 + LoadPlugin "olsrd_bmf.so.1.1"
362 + {
363 + # Drop all packets received from the following MAC sources
364 + PlParam "DropMac" "00:0C:29:C6:E2:61" # RemoteClient1
365 + PlParam "DropMac" "00:0C:29:61:34:B7" # SimpleClient1
366 + PlParam "DropMac" "00:0C:29:28:0E:CC" # SimpleClient2
367 + }
368 +
369 +
370 +
371 +7. Common problems, FAQ
372 +-----------------------
373 +
374 +Question:
375 +On which platforms does BMF currently compile?
376 +
377 +Answer:
378 +Only on Linux. No compilation on Windows (yet). The oldest Linux
379 +kernel on which the BMF plugin was tested was version 2.4.18.
380 +
381 +
382 +Question:
383 +When starting OLSRD with the BMF plugin, I can see the following
384 +error message:
385 +
386 +OLSRD Basic Multicast Forwarding plugin: error opening /dev/net/tun: No such file or directory
387 +
388 +Wat to do?
389 +
390 +Answer:
391 +Turn on the possibility to create a tuntap device; see section 2 of this
392 +file.
393 +
394 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Address.c olsrd-0.4.10/lib/bmf/src/Address.c
395 --- olsrd-0.4.10.orig/lib/bmf/src/Address.c 1970-01-01 01:00:00.000000000 +0100
396 +++ olsrd-0.4.10/lib/bmf/src/Address.c 2006-12-01 08:26:58.000000000 +0100
397 @@ -0,0 +1,194 @@
398 +/*
399 + * OLSR Basic Multicast Forwarding (BMF) plugin.
400 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
401 + * Written by Erik Tromp.
402 + * All rights reserved.
403 + *
404 + * Redistribution and use in source and binary forms, with or without
405 + * modification, are permitted provided that the following conditions
406 + * are met:
407 + *
408 + * * Redistributions of source code must retain the above copyright
409 + * notice, this list of conditions and the following disclaimer.
410 + * * Redistributions in binary form must reproduce the above copyright
411 + * notice, this list of conditions and the following disclaimer in
412 + * the documentation and/or other materials provided with the
413 + * distribution.
414 + * * Neither the name of Thales, BMF nor the names of its
415 + * contributors may be used to endorse or promote products derived
416 + * from this software without specific prior written permission.
417 + *
418 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
419 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
420 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
421 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
422 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
423 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
424 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
425 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
426 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
427 + * OF THE POSSIBILITY OF SUCH DAMAGE.
428 + */
429 +
430 +/* -------------------------------------------------------------------------
431 + * File : Address.c
432 + * Description: IP packet characterization functions
433 + * Created : 29 Jun 2006
434 + *
435 + * $Id$
436 + *
437 + * $Log$
438 + * ------------------------------------------------------------------------- */
439 +
440 +#include "Address.h"
441 +
442 +/* System includes */
443 +#include <assert.h> /* assert() */
444 +#include <netinet/ip.h> /* struct ip */
445 +#include <netinet/udp.h> /* struct udphdr */
446 +
447 +/* OLSRD includes */
448 +#include "defs.h" /* COMP_IP */
449 +
450 +/* Plugin includes */
451 +#include "Bmf.h" /* BMF_ENCAP_PORT */
452 +#include "NetworkInterfaces.h" /* TBmfInterface */
453 +
454 +/* -------------------------------------------------------------------------
455 + * Function : IsMulticast
456 + * Description: Check if an IP address is a multicast address
457 + * Input : ipAddress
458 + * Output : none
459 + * Return : true (1) or false (0)
460 + * Data Used : none
461 + * ------------------------------------------------------------------------- */
462 +int IsMulticast(union olsr_ip_addr* ipAddress)
463 +{
464 + assert(ipAddress != NULL);
465 +
466 + return (ntohl(ipAddress->v4) & 0xF0000000) == 0xE0000000;
467 +}
468 +
469 +/* -------------------------------------------------------------------------
470 + * Function : IsLocalBroadcast
471 + * Description: Check if an IP address is a local broadcast address for a
472 + * given network interface
473 + * Input : destIp, ifFrom
474 + * Output : none
475 + * Return : true (1) or false (0)
476 + * Data Used : none
477 + * ------------------------------------------------------------------------- */
478 +int IsLocalBroadcast(union olsr_ip_addr* destIp, struct TBmfInterface* ifFrom)
479 +{
480 + struct sockaddr_in* sin;
481 +
482 + assert(destIp != NULL && ifFrom != NULL);
483 +
484 + /* Cast down to correct sockaddr subtype */
485 + sin = (struct sockaddr_in*)&(ifFrom->broadAddr);
486 +
487 + return COMP_IP(&(sin->sin_addr.s_addr), destIp);
488 +}
489 +
490 +/* -------------------------------------------------------------------------
491 + * Function : IsOlsrOrBmfPacket
492 + * Description: Check if an ethernet packet is an OLSR packet or a BMF packet
493 + * Input : intf, ethPkt, len
494 + * Output : none
495 + * Return : true (1) or false (0)
496 + * Data Used : none
497 + * ------------------------------------------------------------------------- */
498 +int IsOlsrOrBmfPacket(struct TBmfInterface* intf, unsigned char* ethPkt, size_t len)
499 +{
500 + struct ip* ipData;
501 + unsigned int ipHeaderLen;
502 +
503 + assert(ethPkt != NULL);
504 +
505 + /* Consider OLSR and BMF packets not to be local broadcast
506 + * OLSR packets are UDP - port 698
507 + * OLSR-BMF packets are UDP - port 50698
508 + * OLSR-Autodetect probe packets are UDP - port 51698
509 + * Fragments of the above packets are also not local broadcast */
510 +
511 + ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
512 + ipHeaderLen = ipData->ip_hl << 2;
513 + if (len < IP_HDR_OFFSET + ipHeaderLen)
514 + {
515 + return 0;
516 + }
517 +
518 + if (ipData->ip_p != SOL_UDP)
519 + {
520 + return 0;
521 + }
522 +
523 + /* Check if the packet is a fragment */
524 + if ((ntohs(ipData->ip_off) & IP_OFFMASK) != 0)
525 + {
526 + int i;
527 + for (i = 0; i < FRAGMENT_HISTORY_SIZE; i++)
528 + {
529 + /* Quick-access pointer */
530 + struct TFragmentHistory* entry = &intf->fragmentHistory[i];
531 +
532 + /* Match */
533 + if (entry->ipId == ntohs(ipData->ip_id) &&
534 + entry->ipProto == ipData->ip_p &&
535 + entry->ipSrc.s_addr == ntohl(ipData->ip_src.s_addr) &&
536 + entry->ipDst.s_addr == ntohl(ipData->ip_dst.s_addr))
537 + {
538 + /* Found matching history entry, so packet is assumed to be a fragment
539 + * of an earlier OLSR/OLSR-BMF/OLSR-Autodetect packet */
540 +
541 + /* More fragments? If not, invalidate entry */
542 + if (((ntohs(ipData->ip_off) & IP_MF) == 0))
543 + {
544 + memset(entry, 0, sizeof(struct TFragmentHistory));
545 + }
546 +
547 + return 1;
548 + }
549 + }
550 +
551 + /* Matching history entry not found, so packet is not assumed to be a fragment
552 + * of an earlier OLSR/OLSR-BMF/OLSR-Autodetect packet */
553 + return 0;
554 + }
555 +
556 + /* The packet is the first (or only) fragment */
557 +
558 + /* Check length first */
559 + if (len < IP_HDR_OFFSET + ipHeaderLen + sizeof(struct udphdr ))
560 + {
561 + return 0;
562 + }
563 +
564 + /* Go into the UDP header and check port number */
565 + struct udphdr* udpData = (struct udphdr*) (ethPkt + IP_HDR_OFFSET + ipHeaderLen);
566 + u_int16_t port = ntohs(udpData->source);
567 +
568 + if (port == OLSRPORT || port == BMF_ENCAP_PORT || port == 51698)
569 + /* TODO define for 51698 */
570 + {
571 + /* If more fragments are expected, keep a record in the fragment history */
572 + if ((ntohs(ipData->ip_off) & IP_MF) != 0)
573 + {
574 + /* Quick-access pointer */
575 + struct TFragmentHistory* entry = &intf->fragmentHistory[intf->nextFragmentHistoryEntry];
576 +
577 + /* Store in fragment history */
578 + entry->ipId = ntohs(ipData->ip_id);
579 + entry->ipProto = ipData->ip_p;
580 + entry->ipSrc.s_addr = ntohl(ipData->ip_src.s_addr);
581 + entry->ipDst.s_addr = ntohl(ipData->ip_dst.s_addr);
582 +
583 + /* Advance to next entry */
584 + intf->nextFragmentHistoryEntry++;
585 + intf->nextFragmentHistoryEntry %= FRAGMENT_HISTORY_SIZE;
586 + }
587 + return 1;
588 + }
589 +
590 + return 0;
591 +}
592 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Address.h olsrd-0.4.10/lib/bmf/src/Address.h
593 --- olsrd-0.4.10.orig/lib/bmf/src/Address.h 1970-01-01 01:00:00.000000000 +0100
594 +++ olsrd-0.4.10/lib/bmf/src/Address.h 2006-12-01 08:26:58.000000000 +0100
595 @@ -0,0 +1,55 @@
596 +#ifndef _BMF_ADDRESS_H
597 +#define _BMF_ADDRESS_H
598 +
599 +/*
600 + * OLSR Basic Multicast Forwarding (BMF) plugin.
601 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
602 + * Written by Erik Tromp.
603 + * All rights reserved.
604 + *
605 + * Redistribution and use in source and binary forms, with or without
606 + * modification, are permitted provided that the following conditions
607 + * are met:
608 + *
609 + * * Redistributions of source code must retain the above copyright
610 + * notice, this list of conditions and the following disclaimer.
611 + * * Redistributions in binary form must reproduce the above copyright
612 + * notice, this list of conditions and the following disclaimer in
613 + * the documentation and/or other materials provided with the
614 + * distribution.
615 + * * Neither the name of Thales, BMF nor the names of its
616 + * contributors may be used to endorse or promote products derived
617 + * from this software without specific prior written permission.
618 + *
619 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
620 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
621 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
622 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
623 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
624 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
625 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
626 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
627 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
628 + * OF THE POSSIBILITY OF SUCH DAMAGE.
629 + */
630 +
631 +/* -------------------------------------------------------------------------
632 + * File : Address.h
633 + * Description: IP packet characterization functions
634 + * Created : 29 Jun 2006
635 + *
636 + * $Id$
637 + *
638 + * $Log$
639 + * ------------------------------------------------------------------------- */
640 +
641 +#include "olsr_types.h" /* olsr_ip_addr */
642 +#include "interfaces.h" /* struct interface */
643 +
644 +struct TBmfInterface;
645 +
646 +int IsMulticast(union olsr_ip_addr* ipAddress);
647 +int IsLocalBroadcast(union olsr_ip_addr* destIp, struct TBmfInterface* ifFrom);
648 +int IsOlsrOrBmfPacket(struct TBmfInterface* intf, unsigned char* ethPkt, size_t len);
649 +
650 +#endif /* _BMF_ADDRESS_H */
651 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Bmf.c olsrd-0.4.10/lib/bmf/src/Bmf.c
652 --- olsrd-0.4.10.orig/lib/bmf/src/Bmf.c 1970-01-01 01:00:00.000000000 +0100
653 +++ olsrd-0.4.10/lib/bmf/src/Bmf.c 2006-12-01 08:26:58.000000000 +0100
654 @@ -0,0 +1,935 @@
655 +/*
656 + * OLSR Basic Multicast Forwarding (BMF) plugin.
657 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
658 + * Written by Erik Tromp.
659 + * All rights reserved.
660 + *
661 + * Redistribution and use in source and binary forms, with or without
662 + * modification, are permitted provided that the following conditions
663 + * are met:
664 + *
665 + * * Redistributions of source code must retain the above copyright
666 + * notice, this list of conditions and the following disclaimer.
667 + * * Redistributions in binary form must reproduce the above copyright
668 + * notice, this list of conditions and the following disclaimer in
669 + * the documentation and/or other materials provided with the
670 + * distribution.
671 + * * Neither the name of Thales, BMF nor the names of its
672 + * contributors may be used to endorse or promote products derived
673 + * from this software without specific prior written permission.
674 + *
675 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
676 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
677 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
678 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
679 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
680 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
681 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
682 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
683 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
684 + * OF THE POSSIBILITY OF SUCH DAMAGE.
685 + */
686 +
687 +/* -------------------------------------------------------------------------
688 + * File : Bmf.c
689 + * Description: Multicast forwarding functions
690 + * Created : 29 Jun 2006
691 + *
692 + * $Id$
693 + *
694 + * $Log$
695 + * ------------------------------------------------------------------------- */
696 +
697 +#define _MULTI_THREADED
698 +
699 +#include "Bmf.h"
700 +
701 +/* System includes */
702 +#include <stdio.h> /* NULL */
703 +#include <sys/types.h> /* ssize_t */
704 +#include <string.h> /* strerror() */
705 +#include <errno.h> /* errno */
706 +#include <assert.h> /* assert() */
707 +#include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
708 +#include <pthread.h> /* pthread_t, pthread_create() */
709 +#include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
710 +#include <netinet/ip.h> /* struct ip */
711 +
712 +/* OLSRD includes */
713 +#include "defs.h" /* olsr_cnf */
714 +#include "olsr.h" /* olsr_printf */
715 +#include "scheduler.h" /* olsr_register_scheduler_event */
716 +#include "mid_set.h" /* mid_lookup_main_addr() */
717 +#include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
718 +#include "link_set.h" /* get_best_link_to_neighbor() */
719 +
720 +/* Plugin includes */
721 +#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
722 +#include "Address.h" /* IsMulticast(), IsLocalBroadcast() */
723 +#include "Packet.h" /* ETH_TYPE_OFFSET, IFHWADDRLEN etc. */
724 +#include "PacketHistory.h" /* InitPacketHistory() */
725 +#include "DropList.h" /* DropMac() */
726 +
727 +static pthread_t BmfThread;
728 +static int BmfThreadRunning = 0;
729 +
730 +
731 +/* -------------------------------------------------------------------------
732 + * Function : BmfPacketCaptured
733 + * Description: Handle a captured raw IP packet
734 + * Input : intf - the network interface on which the packet was captured
735 + * buffer - space for the encapsulation header, followed by
736 + * the captured packet
737 + * len - the number of octets in the encapsulation header plus
738 + * captured packet
739 + * Output : none
740 + * Return : none
741 + * Data Used : BmfInterfaces
742 + * Notes : The packet is assumed to be captured on a socket of family
743 + * PF_PACKET and type SOCK_RAW.
744 + * ------------------------------------------------------------------------- */
745 +static void BmfPacketCaptured(struct TBmfInterface* intf, unsigned char* buffer, ssize_t len)
746 +{
747 + unsigned char* srcMac;
748 + union olsr_ip_addr srcIp;
749 + union olsr_ip_addr destIp;
750 + union olsr_ip_addr* origIp;
751 + struct sockaddr_in encapDest;
752 + struct TBmfInterface* nextFwIntf;
753 + int isFromOlsrIntf; /* Boolean indicating if packet captured on OLSR-enabled interface */
754 + int iAmNotMpr;
755 + unsigned char* ethPkt = buffer + ENCAP_HDR_LEN;
756 + ssize_t ethPktLen = len - ENCAP_HDR_LEN;
757 + struct ip* ipData;
758 +
759 + /* Only forward IPv4 packets */
760 + u_int16_t type;
761 + memcpy(&type, ethPkt + ETH_TYPE_OFFSET, 2);
762 + if (ntohs(type) != IPV4_TYPE)
763 + {
764 + return;
765 + }
766 +
767 + ipData = (struct ip*)(ethPkt + IP_HDR_OFFSET);
768 +
769 + /* Only forward multicast or local broadcast packets */
770 + COPY_IP(&destIp, &ipData->ip_dst);
771 + if (! IsMulticast(&destIp) && ! IsLocalBroadcast(&destIp, intf))
772 + {
773 + return;
774 + }
775 +
776 + /* Discard OLSR packets (UDP port 698) and BMF encapsulated packets */
777 + if (IsOlsrOrBmfPacket(intf, ethPkt, ethPktLen))
778 + {
779 + return;
780 + }
781 +
782 + COPY_IP(&srcIp, &ipData->ip_src);
783 + olsr_printf(
784 + 9,
785 + "%s: pkt of %d bytes incoming on \"%s\": %s->%s\n",
786 + PLUGIN_NAME_SHORT,
787 + ethPktLen,
788 + intf->ifName,
789 + olsr_ip_to_string(&srcIp),
790 + olsr_ip_to_string(&destIp));
791 +
792 + /* Apply drop list for testing purposes. */
793 + srcMac = ethPkt + IFHWADDRLEN;
794 + if (IsInDropList(srcMac))
795 + {
796 + olsr_printf(
797 + 9,
798 + "%s: --> discarding: source MAC (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) found in drop list\n",
799 + PLUGIN_NAME_SHORT,
800 + srcMac, srcMac + 1, srcMac + 2, srcMac + 3, srcMac + 4, srcMac + 5);
801 + return;
802 + }
803 +
804 + /* Lookup main address of source in the MID table of OLSR */
805 + origIp = mid_lookup_main_addr(&srcIp);
806 + if (origIp == NULL)
807 + {
808 + origIp = &srcIp;
809 + }
810 +
811 + /* Check if this packet is received on an OLSR-enabled interface */
812 + isFromOlsrIntf = (intf->olsrIntf != NULL);
813 +
814 + /* If this packet is captured on a non-OLSR interface, it will be forwarded
815 + * only to OLSR interfaces, thereby crossing the boundary between the external
816 + * network and the OLSR network. So decrease the TTL and re-calculate the IP header
817 + * checksum. */
818 + if (! isFromOlsrIntf)
819 + {
820 + DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
821 + }
822 +
823 + /* If the resulting TTL is <= 0, this packet life has ended, so do not forward it */
824 + if (GetIpTtl(ethPkt) <= 0)
825 + {
826 + olsr_printf(
827 + 9,
828 + "%s: --> discarding: TTL=0\n",
829 + PLUGIN_NAME_SHORT);
830 + return;
831 + }
832 +
833 + /* Check if this packet was seen recently */
834 + u_int32_t crc32 = PacketCrc32(ethPkt, ethPktLen);
835 + if (CheckAndMarkRecentPacket(Hash16(crc32)))
836 + {
837 + olsr_printf(
838 + 9,
839 + "%s: --> discarding: packet is duplicate\n",
840 + PLUGIN_NAME_SHORT);
841 + return;
842 + }
843 +
844 + /* Compose encapsulation header */
845 + struct TEncapHeader* encapHdr = (struct TEncapHeader*) buffer;
846 + memset (encapHdr, 0, ENCAP_HDR_LEN);
847 + encapHdr->crc32 = htonl(crc32);
848 +
849 + /* If this packet is captured on an OLSR interface from an OLSR neighbor,
850 + * check with OLSR if I am MPR for that neighbor */
851 + iAmNotMpr =
852 + (isFromOlsrIntf /* captured on an OLSR interface */
853 + && get_best_link_to_neighbor(origIp) != NULL /* from an OLSR neighbor */
854 + && olsr_lookup_mprs_set(origIp) == NULL); /* but not selected as MPR */
855 +
856 + memset(&encapDest, 0, sizeof(encapDest));
857 + encapDest.sin_family = AF_INET;
858 + encapDest.sin_port = htons(BMF_ENCAP_PORT);
859 +
860 + /* Check with each interface what needs to be done on it */
861 + nextFwIntf = BmfInterfaces;
862 + while (nextFwIntf != NULL)
863 + {
864 + int isToOlsrIntf; /* Boolean indicating if forwarding interface is OLSR-enabled */
865 +
866 + struct TBmfInterface* fwIntf = nextFwIntf;
867 + nextFwIntf = fwIntf->next;
868 +
869 + isToOlsrIntf = (fwIntf->olsrIntf != NULL);
870 +
871 + /* The following if-else statement seems very complicated. Let's
872 + * draw a Karnaugh-diagram of it for some clarification.
873 + *
874 + * ------- isFromOlsrIntf
875 + * -------- isToOlsrIntf
876 + * +---+---+---+---+
877 + * | 3 | 2 | 2 | 1 |
878 + * +---+---+---+---+
879 + * | | X | X | 4 | 1 |
880 + * +---+---+---+---+
881 + * iAmNotMpr
882 + *
883 + * X = does not occur (iAmNotMpr = isFromOlsrIntf && ...)
884 + * 1 = handled in first if-clause: if (isFromOlsrIntf && !isToOlsrIntf)...
885 + * 2 = handled in second if-clause: if (isToOlsrIntf && !iAmNotMpr)...
886 + * 3 = handled in third if-clause: if (!isFromOlsrIntf && !isToOlsrIntf)...
887 + * 4 = handled in else-clause.
888 + */
889 +
890 + /* Forward from OLSR-interface to non-OLSR interface */
891 + if (isFromOlsrIntf && !isToOlsrIntf)
892 + {
893 + struct TSaveTtl sttl;
894 +
895 + /* Save IP header checksum and the TTL-value of the packet */
896 + SaveTtlAndChecksum(ethPkt, &sttl);
897 +
898 + /* Save IP header checksum and the TTL-value of the packet, then
899 + * decrease the TTL by 1 before writing */
900 + DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
901 +
902 + /* If the TTL is <= 0, do not forward this packet */
903 + if (GetIpTtl(ethPkt) <= 0)
904 + {
905 + OLSR_PRINTF(
906 + 9,
907 + "%s: --> not forwarding on \"%s\": TTL=0\n",
908 + PLUGIN_NAME_SHORT,
909 + fwIntf->ifName);
910 + }
911 + else
912 + {
913 + /* Change source MAC address to that of sending interface */
914 + memcpy(ethPkt + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
915 +
916 + int nBytesWritten = write(fwIntf->capturingSkfd, ethPkt, ethPktLen);
917 + if (nBytesWritten != ethPktLen)
918 + {
919 + olsr_printf(
920 + 1,
921 + "%s: write() error forwarding pkt for %s to \"%s\": %s\n",
922 + PLUGIN_NAME,
923 + olsr_ip_to_string(&destIp),
924 + fwIntf->ifName,
925 + strerror(errno));
926 + }
927 + else
928 + {
929 + OLSR_PRINTF(
930 + 9,
931 + "%s: --> forwarded to \"%s\"\n",
932 + PLUGIN_NAME_SHORT,
933 + fwIntf->ifName);
934 + }
935 + }
936 +
937 + /* Restore the IP header checksum and the TTL-value of the packet */
938 + RestoreTtlAndChecksum(ethPkt, &sttl);
939 +
940 + } /* if (isFromOlsrIntf && !isToOlsrIntf) */
941 +
942 + /* Forward from any interface to OLSR interface. Packets from non-OLSR interfaces
943 + * already had their TTL decreased. */
944 + else /* !isFromOlsrIntf || isToOlsrIntf */
945 + if (isToOlsrIntf && !iAmNotMpr)
946 + {
947 + int nBytesWritten;
948 +
949 + /* Change encapsulated source MAC address to that of sending interface */
950 + memcpy(ethPkt + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
951 +
952 + /* Destination address is local broadcast */
953 + encapDest.sin_addr.s_addr = ((struct sockaddr_in*)&fwIntf->olsrIntf->int_broadaddr)->sin_addr.s_addr;
954 +
955 + nBytesWritten = sendto(
956 + fwIntf->encapsulatingSkfd,
957 + buffer,
958 + len,
959 + MSG_DONTROUTE,
960 + (struct sockaddr*) &encapDest,
961 + sizeof(encapDest));
962 +
963 + if (nBytesWritten != len)
964 + {
965 + olsr_printf(
966 + 1,
967 + "%s: sendto() error forwarding pkt for %s to \"%s\": %s\n",
968 + PLUGIN_NAME,
969 + olsr_ip_to_string(&destIp),
970 + fwIntf->ifName,
971 + strerror(errno));
972 + }
973 + else
974 + {
975 + OLSR_PRINTF(
976 + 9,
977 + "%s: --> encapsulated and forwarded to \"%s\"\n",
978 + PLUGIN_NAME_SHORT,
979 + fwIntf->ifName);
980 + } /* if (nBytesWritten != len) */
981 + } /* else if (isToOlsrIntf && !iAmNotMpr) */
982 +
983 + else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) */
984 + if (!isFromOlsrIntf && !isToOlsrIntf)
985 + {
986 + OLSR_PRINTF(
987 + 9,
988 + "%s: --> not forwarding from \"%s\" to \"%s\": both non-OLSR interfaces\n",
989 + PLUGIN_NAME_SHORT,
990 + intf->ifName,
991 + fwIntf->ifName);
992 + }
993 +
994 + else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) && (isFromOlsrIntf || isToOlsrIntf) */
995 + {
996 + OLSR_PRINTF(
997 + 9,
998 + "%s: --> not forwarding from \"%s\" to \"%s\": I am not selected as MPR by %s\n",
999 + PLUGIN_NAME_SHORT,
1000 + intf->ifName,
1001 + fwIntf->ifName,
1002 + olsr_ip_to_string(&srcIp));
1003 + }
1004 + } /* while (nextFwIntf != NULL) */
1005 +}
1006 +
1007 +/* -------------------------------------------------------------------------
1008 + * Function : BmfEncapsulatedPacketReceived
1009 + * Description: Handle a received BMF-encapsulated IP packet
1010 + * Input : intf - the network interface on which the packet was received
1011 + * fromIp - the IP node that forwarded the packet to us
1012 + * buffer - the received encapsulated packet
1013 + * len - the number of octets in the received encapsulated packet
1014 + * Output : none
1015 + * Return : none
1016 + * Data Used : BmfInterfaces
1017 + * Notes : The packet is assumed to be received on a socket of family
1018 + * PF_INET and type SOCK_DGRAM (UDP).
1019 + * ------------------------------------------------------------------------- */
1020 +static void BmfEncapsulatedPacketReceived(
1021 + struct TBmfInterface* intf,
1022 + union olsr_ip_addr* fromIp,
1023 + unsigned char* buffer,
1024 + ssize_t len)
1025 +{
1026 + union olsr_ip_addr* forwarder;
1027 + int nBytesToWrite;
1028 + unsigned char* bufferToWrite;
1029 + int nBytesWritten;
1030 + int iAmMpr;
1031 + struct sockaddr_in encapDest;
1032 + struct TBmfInterface* nextFwIntf;
1033 + struct ip* ipData;
1034 + unsigned char* ethPkt;
1035 + ssize_t ethPktLen;
1036 +
1037 + /* Are we talking to ourselves? */
1038 + if (if_ifwithaddr(fromIp) != NULL)
1039 + {
1040 + return;
1041 + }
1042 +
1043 + /* Encapsulated packet received on non-OLSR interface? Then discard */
1044 + if (intf->olsrIntf == NULL)
1045 + {
1046 + return;
1047 + }
1048 +
1049 + /* Apply drop list? No, not needed: encapsulated packets are routed,
1050 + * so filtering should be done by adding a rule to the iptables FORWARD
1051 + * chain, e.g.:
1052 + * iptables -A FORWARD -m mac --mac-source 00:0C:29:28:0E:CC -j DROP */
1053 +
1054 + ethPkt = buffer + ENCAP_HDR_LEN;
1055 + ethPktLen = len - ENCAP_HDR_LEN;
1056 +
1057 + ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
1058 +
1059 + OLSR_PRINTF(
1060 + 9,
1061 + "%s: encapsulated pkt of %d bytes incoming on \"%s\": %s->",
1062 + PLUGIN_NAME_SHORT,
1063 + ethPktLen,
1064 + intf->ifName,
1065 + inet_ntoa(ipData->ip_src));
1066 + OLSR_PRINTF(
1067 + 9,
1068 + "%s, forwarded by %s\n",
1069 + inet_ntoa(ipData->ip_dst), /* not possible to call inet_ntoa twice in same printf */
1070 + olsr_ip_to_string(fromIp));
1071 +
1072 + /* Get encapsulation header */
1073 + struct TEncapHeader* encapHdr = (struct TEncapHeader*) buffer;
1074 +
1075 + /* Check if this packet was seen recently */
1076 + if (CheckAndMarkRecentPacket(Hash16(ntohl(encapHdr->crc32))))
1077 + {
1078 + OLSR_PRINTF(
1079 + 9,
1080 + "%s: --> discarding: packet is duplicate\n",
1081 + PLUGIN_NAME_SHORT);
1082 + return;
1083 + }
1084 +
1085 + /* Unpack encapsulated packet and send a copy to myself via the EtherTunTap device */
1086 + bufferToWrite = ethPkt;
1087 + nBytesToWrite = ethPktLen;
1088 + if (TunOrTap == TT_TUN)
1089 + {
1090 + bufferToWrite += IP_HDR_OFFSET;
1091 + nBytesToWrite -= IP_HDR_OFFSET;
1092 + }
1093 + nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);
1094 + if (nBytesWritten != nBytesToWrite)
1095 + {
1096 + olsr_printf(
1097 + 1,
1098 + "%s: write() error forwarding encapsulated pkt to \"%s\": %s\n",
1099 + PLUGIN_NAME,
1100 + EtherTunTapIfName,
1101 + strerror(errno));
1102 + }
1103 + else
1104 + {
1105 + OLSR_PRINTF(
1106 + 9,
1107 + "%s: --> unpacked and forwarded to \"%s\"\n",
1108 + PLUGIN_NAME_SHORT,
1109 + EtherTunTapIfName);
1110 + }
1111 +
1112 + /* Lookup main address of forwarding node */
1113 + forwarder = mid_lookup_main_addr(fromIp);
1114 + if (forwarder == NULL)
1115 + {
1116 + forwarder = fromIp;
1117 + }
1118 +
1119 + /* Check if I am MPR for the forwarder */
1120 + iAmMpr = (olsr_lookup_mprs_set(forwarder) != NULL);
1121 +
1122 + memset(&encapDest, 0, sizeof(encapDest));
1123 + encapDest.sin_family = AF_INET;
1124 + encapDest.sin_port = htons(BMF_ENCAP_PORT);
1125 +
1126 + nextFwIntf = BmfInterfaces;
1127 + while (nextFwIntf != NULL)
1128 + {
1129 + struct TBmfInterface* fwIntf = nextFwIntf;
1130 + nextFwIntf = fwIntf->next;
1131 +
1132 + /* Forward from OLSR interface to non-OLSR interface: unpack encapsulated
1133 + * packet, decrease TTL and forward */
1134 + if (fwIntf->olsrIntf == NULL)
1135 + {
1136 + struct TSaveTtl sttl;
1137 +
1138 + /* Save IP header checksum and the TTL-value of the packet, then
1139 + * decrease the TTL by 1 before writing */
1140 + SaveTtlAndChecksum(ethPkt, &sttl);
1141 + DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
1142 +
1143 + /* If the TTL is <= 0, do not forward this packet */
1144 + if (GetIpTtl(ethPkt) <= 0)
1145 + {
1146 + OLSR_PRINTF(
1147 + 9,
1148 + "%s: --> not forwarding on \"%s\": TTL=0\n",
1149 + PLUGIN_NAME_SHORT,
1150 + fwIntf->ifName);
1151 + }
1152 + else
1153 + {
1154 + nBytesWritten = write(fwIntf->capturingSkfd, ethPkt, ethPktLen);
1155 + if (nBytesWritten != ethPktLen)
1156 + {
1157 + olsr_printf(
1158 + 1,
1159 + "%s: write() error forwarding unpacked encapsulated MC pkt to \"%s\": %s\n",
1160 + PLUGIN_NAME,
1161 + fwIntf->ifName,
1162 + strerror(errno));
1163 + }
1164 + else
1165 + {
1166 + OLSR_PRINTF(
1167 + 9,
1168 + "%s: --> unpacked and forwarded to \"%s\"\n",
1169 + PLUGIN_NAME_SHORT,
1170 + fwIntf->ifName);
1171 + }
1172 + }
1173 +
1174 + /* Restore the IP header checksum and the TTL-value of the packet */
1175 + RestoreTtlAndChecksum(ethPkt, &sttl);
1176 +
1177 + } /* if (fwIntf->olsrIntf == NULL) */
1178 +
1179 + /* Forward from OLSR interface to OLSR interface: forward the packet if this
1180 + * node is selected as MPR by the forwarding node */
1181 + else if (iAmMpr)
1182 + {
1183 + /* Change source MAC address to that of sending interface */
1184 + memcpy(buffer + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
1185 +
1186 + /* Destination address is local broadcast */
1187 + encapDest.sin_addr.s_addr = ((struct sockaddr_in*)&fwIntf->olsrIntf->int_broadaddr)->sin_addr.s_addr;
1188 +
1189 + nBytesWritten = sendto(
1190 + fwIntf->encapsulatingSkfd,
1191 + buffer,
1192 + len,
1193 + MSG_DONTROUTE,
1194 + (struct sockaddr*) &encapDest,
1195 + sizeof(encapDest));
1196 +
1197 + if (nBytesWritten != len)
1198 + {
1199 + olsr_printf(
1200 + 1,
1201 + "%s: sendto() error forwarding encapsulated pkt via \"%s\": %s\n",
1202 + PLUGIN_NAME,
1203 + fwIntf->ifName,
1204 + strerror(errno));
1205 + }
1206 + else
1207 + {
1208 + OLSR_PRINTF(
1209 + 9,
1210 + "%s: --> forwarded to \"%s\"\n",
1211 + PLUGIN_NAME_SHORT,
1212 + fwIntf->ifName);
1213 + }
1214 + } /* else if (iAmMpr) */
1215 + else /* fwIntf->olsrIntf != NULL && !iAmMpr */
1216 + {
1217 + /* fwIntf is an OLSR interface and I am not selected as MPR */
1218 + OLSR_PRINTF(
1219 + 9,
1220 + "%s: --> not forwarding to \"%s\": I am not selected as MPR by %s\n",
1221 + PLUGIN_NAME_SHORT,
1222 + fwIntf->ifName,
1223 + olsr_ip_to_string(fromIp));
1224 + }
1225 + } /* while (nextFwIntf != NULL) */
1226 +}
1227 +
1228 +/* -------------------------------------------------------------------------
1229 + * Function : DoBmf
1230 + * Description: Wait (blocking) for IP packets, then call the handler for each
1231 + * received packet
1232 + * Input : none
1233 + * Output : none
1234 + * Return : none
1235 + * Data Used : BmfInterfaces
1236 + * ------------------------------------------------------------------------- */
1237 +static void DoBmf(void)
1238 +{
1239 +#define BUFFER_MAX 2048
1240 + struct TBmfInterface* currIf;
1241 + int nFdBitsSet;
1242 +
1243 + /* Compose set of socket file descriptors.
1244 + * Keep the highest descriptor seen. */
1245 + int highestSkfd = -1;
1246 + fd_set input_set;
1247 + FD_ZERO(&input_set);
1248 +
1249 + currIf = BmfInterfaces;
1250 + while (currIf != NULL)
1251 + {
1252 + FD_SET(currIf->capturingSkfd, &input_set);
1253 + if (currIf->capturingSkfd > highestSkfd)
1254 + {
1255 + highestSkfd = currIf->capturingSkfd;
1256 + }
1257 +
1258 + if (currIf->encapsulatingSkfd >= 0)
1259 + {
1260 + FD_SET(currIf->encapsulatingSkfd, &input_set);
1261 + if (currIf->encapsulatingSkfd > highestSkfd)
1262 + {
1263 + highestSkfd = currIf->encapsulatingSkfd;
1264 + }
1265 + }
1266 +
1267 + currIf = currIf->next;
1268 + }
1269 +
1270 + assert(highestSkfd >= 0);
1271 +
1272 + /* Wait (blocking) for packets received on any of the sockets.
1273 + * NOTE: don't use a timeout (last parameter). It causes a high system CPU load! */
1274 + nFdBitsSet = select(highestSkfd + 1, &input_set, NULL, NULL, NULL);
1275 + if (nFdBitsSet < 0)
1276 + {
1277 + if (errno != EINTR)
1278 + {
1279 + olsr_printf(1, "%s: select() error: %s\n", PLUGIN_NAME, strerror(errno));
1280 + }
1281 + return;
1282 + }
1283 +
1284 + if (nFdBitsSet == 0)
1285 + {
1286 + /* No packets waiting. This is unexpected; normally we would excpect select(...)
1287 + * to return only if at least one packet was received (so nFdBitsSet > 0), or
1288 + * if this thread received a signal (so nFdBitsSet < 0). */
1289 + return;
1290 + }
1291 +
1292 + while (nFdBitsSet > 0)
1293 + {
1294 + struct TBmfInterface* nextIf = BmfInterfaces;
1295 + while (nextIf != NULL)
1296 + {
1297 + int skfd;
1298 + currIf = nextIf;
1299 + nextIf = currIf->next;
1300 +
1301 + skfd = currIf->capturingSkfd;
1302 + if (FD_ISSET(skfd, &input_set))
1303 + {
1304 + unsigned char buffer[BUFFER_MAX];
1305 + struct sockaddr_ll pktAddr;
1306 + socklen_t addrLen;
1307 + int nBytes;
1308 + unsigned char* ethPkt = buffer + ENCAP_HDR_LEN;
1309 + struct ip* ipData;
1310 +
1311 + /* A packet was captured. */
1312 +
1313 + nFdBitsSet--;
1314 +
1315 + memset(&pktAddr, 0, sizeof(struct sockaddr_ll));
1316 + addrLen = sizeof(pktAddr);
1317 +
1318 + /* Receive the packet, leaving space for the BMF encap header */
1319 + nBytes = recvfrom(
1320 + skfd,
1321 + ethPkt,
1322 + BUFFER_MAX - ENCAP_HDR_LEN,
1323 + 0,
1324 + (struct sockaddr*)&pktAddr,
1325 + &addrLen);
1326 + if (nBytes < 0)
1327 + {
1328 + olsr_printf(
1329 + 1,
1330 + "%s: recvfrom() error on \"%s\": %s\n",
1331 + PLUGIN_NAME,
1332 + currIf->ifName,
1333 + strerror(errno));
1334 + }
1335 + else
1336 + {
1337 + /* Don't let BMF crash by sending too short packets */
1338 + int ipHeaderLen;
1339 + ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
1340 + ipHeaderLen = ipData->ip_hl << 2;
1341 + if (nBytes >= IP_HDR_OFFSET + ipHeaderLen)
1342 + {
1343 + if (pktAddr.sll_pkttype == PACKET_OUTGOING)
1344 + {
1345 + union olsr_ip_addr destIp;
1346 + COPY_IP(&destIp, &ipData->ip_dst);
1347 + if (IsMulticast(&destIp) || IsLocalBroadcast(&destIp, currIf))
1348 + {
1349 + if (! IsOlsrOrBmfPacket(currIf, ethPkt, nBytes))
1350 + {
1351 + /* For outbound packets, just record the fact that the packet was
1352 + * seen recently */
1353 + u_int32_t crc32 = PacketCrc32(ethPkt, nBytes);
1354 + MarkRecentPacket(Hash16(crc32));
1355 + }
1356 + }
1357 + }
1358 + else if (pktAddr.sll_pkttype == PACKET_MULTICAST ||
1359 + pktAddr.sll_pkttype == PACKET_BROADCAST)
1360 + {
1361 + /* An inbound multicast or broadcast packet was captured */
1362 + BmfPacketCaptured(currIf, buffer, nBytes + ENCAP_HDR_LEN);
1363 + }
1364 + } /* if (nBytes >= IP_HDR_OFFSET + ipHeaderLen) */
1365 + } /* if (nBytes < 0) */
1366 + } /* if (FD_ISSET...) */
1367 +
1368 + skfd = currIf->encapsulatingSkfd;
1369 + if (skfd >= 0 && (FD_ISSET(skfd, &input_set)))
1370 + {
1371 + unsigned char buffer[BUFFER_MAX];
1372 + struct sockaddr_in from;
1373 + socklen_t fromLen = sizeof(from);
1374 + int nBytes;
1375 + struct ip* ipData;
1376 +
1377 + /* An encapsulated packet was received */
1378 +
1379 + nFdBitsSet--;
1380 +
1381 + nBytes = recvfrom(skfd, buffer, BUFFER_MAX, 0, (struct sockaddr*)&from, &fromLen);
1382 + if (nBytes < 0)
1383 + {
1384 + olsr_printf(
1385 + 1,
1386 + "%s: recvfrom() error on \"%s\": %s\n",
1387 + PLUGIN_NAME,
1388 + currIf->ifName,
1389 + strerror(errno));
1390 + }
1391 + else
1392 + {
1393 + /* Don't let BMF crash by sending too short packets. */
1394 + int ipHeaderLen;
1395 + ipData = (struct ip *) (buffer + IP_HDR_OFFSET);
1396 + ipHeaderLen = ipData->ip_hl << 2;
1397 + if (nBytes >= IP_HDR_OFFSET + ipHeaderLen)
1398 + {
1399 + union olsr_ip_addr srcIp;
1400 + COPY_IP(&srcIp, &from.sin_addr.s_addr);
1401 + BmfEncapsulatedPacketReceived(currIf, &srcIp, buffer, nBytes);
1402 + }
1403 + else
1404 + {
1405 + olsr_printf(
1406 + 1,
1407 + "%s: encapsulated packet too short (%d bytes) from %s on \"%s\"\n",
1408 + PLUGIN_NAME,
1409 + nBytes,
1410 + inet_ntoa(from.sin_addr),
1411 + currIf->ifName);
1412 + }
1413 + } /* if (nBytes < 0) */
1414 + } /* if (skfd >= 0 && (FD_ISSET...) */
1415 + } /* while (intf != NULL) */
1416 + } /* while (nFdBitsSet > 0) */
1417 +}
1418 +
1419 +/* -------------------------------------------------------------------------
1420 + * Function : BmfSignalHandler
1421 + * Description: Dummy signal handler function
1422 + * Input : signo - signal being handled
1423 + * Output : none
1424 + * Return : none
1425 + * Data Used : none
1426 + * ------------------------------------------------------------------------- */
1427 +static void BmfSignalHandler(int signo)
1428 +{
1429 + /* Dummy handler function */
1430 + return;
1431 +}
1432 +
1433 +/* -------------------------------------------------------------------------
1434 + * Function : BmfRun
1435 + * Description: Receiver thread function
1436 + * Input : useless - not used
1437 + * Output : none
1438 + * Return : not used
1439 + * Data Used : BmfThreadRunning
1440 + * Notes : Another thread can gracefully stop this thread by writing a
1441 + * '0' into global variable 'BmfThreadRunning' followed by sending
1442 + * a SIGALRM signal.
1443 + * ------------------------------------------------------------------------- */
1444 +static void* BmfRun(void* useless)
1445 +{
1446 + /* Mask all signals except SIGALRM */
1447 + sigset_t blockedSigs;
1448 + sigfillset(&blockedSigs);
1449 + sigdelset(&blockedSigs, SIGALRM);
1450 + if (pthread_sigmask(SIG_BLOCK, &blockedSigs, NULL) < 0)
1451 + {
1452 + olsr_printf(1, "%s: pthread_sigmask() error: %s\n", PLUGIN_NAME, strerror(errno));
1453 + }
1454 +
1455 + /* Set up the signal handler for the process: use SIGALRM to terminate
1456 + * the BMF thread. Only if a signal handler is specified, does a blocking
1457 + * system call return with errno set to EINTR; if a signal hander is not
1458 + * specified, any system call in which the thread may be waiting will not
1459 + * return. Note that the BMF thread is usually blocked in the select()
1460 + * function (see DoBmf()). */
1461 + if (signal(SIGALRM, BmfSignalHandler) == SIG_ERR)
1462 + {
1463 + olsr_printf(1, "%s: signal() error: %s\n", PLUGIN_NAME, strerror(errno));
1464 + }
1465 +
1466 + /* Call the thread function until flagged to exit */
1467 + while (BmfThreadRunning != 0)
1468 + {
1469 + DoBmf();
1470 + }
1471 +
1472 + return NULL;
1473 +}
1474 +
1475 +/* -------------------------------------------------------------------------
1476 + * Function : InterfaceChange
1477 + * Description: Callback function passed to OLSRD for it to call whenever a
1478 + * network interface has been added, removed or updated
1479 + * Input : interf - the network interface to deal with
1480 + * action - indicates if the specified network interface was
1481 + * added, removed or updated.
1482 + * Output : none
1483 + * Return : always 0
1484 + * Data Used : none
1485 + * ------------------------------------------------------------------------- */
1486 +int InterfaceChange(struct interface* interf, int action)
1487 +{
1488 + switch (action)
1489 + {
1490 + case (IFCHG_IF_ADD):
1491 + AddInterface(interf);
1492 + olsr_printf(1, "%s: interface %s added\n", PLUGIN_NAME, interf->int_name);
1493 + break;
1494 +
1495 + case (IFCHG_IF_REMOVE):
1496 + CloseBmf();
1497 + InitBmf(interf);
1498 + olsr_printf(1, "%s: interface %s removed\n", PLUGIN_NAME, interf->int_name);
1499 + break;
1500 +
1501 + case (IFCHG_IF_UPDATE):
1502 + olsr_printf(1, "%s: interface %s updated\n", PLUGIN_NAME, interf->int_name);
1503 + break;
1504 +
1505 + default:
1506 + break;
1507 + }
1508 + return 0;
1509 +}
1510 +
1511 +/* -------------------------------------------------------------------------
1512 + * Function : InitBmf
1513 + * Description: Initialize the BMF plugin
1514 + * Input : skipThisIntf - specifies which network interface should not
1515 + * be enabled for BMF. Pass NULL to indicate all.
1516 + * Output : none
1517 + * Return : fail (0) or success (1)
1518 + * Data Used : BmfThreadRunning, BmfThread
1519 + * ------------------------------------------------------------------------- */
1520 +int InitBmf(struct interface* skipThisIntf)
1521 +{
1522 + if (CreateBmfNetworkInterfaces(skipThisIntf) < 0)
1523 + {
1524 + olsr_printf(1, "%s: Could not initialize any network interface!\n", PLUGIN_NAME);
1525 + /* Continue anyway; maybe an interface will be added later */
1526 + }
1527 +
1528 + /* Start running the multicast packet processing thread */
1529 + BmfThreadRunning = 1;
1530 + if (pthread_create(&BmfThread, NULL, BmfRun, NULL) == 0)
1531 + {
1532 + return 1;
1533 + }
1534 + return 0;
1535 +}
1536 +
1537 +/* -------------------------------------------------------------------------
1538 + * Function : CloseBmf
1539 + * Description: Close the BMF plugin and clean up
1540 + * Input : none
1541 + * Output : none
1542 + * Return : none
1543 + * Data Used : BmfThreadRunning, BmfThread
1544 + * ------------------------------------------------------------------------- */
1545 +void CloseBmf()
1546 +{
1547 + /* Signal BmfThread to exit */
1548 + BmfThreadRunning = 0;
1549 + if (pthread_kill(BmfThread, SIGALRM) < 0)
1550 + /* Strangely enough, all running threads receive the SIGALRM signal. But only the
1551 + * BMF thread is affected by this signal, having specified a handler for this
1552 + * signal in its thread entry function BmfRun(...). */
1553 + {
1554 + olsr_printf(1, "%s: pthread_kill() error: %s\n", PLUGIN_NAME, strerror(errno));
1555 + }
1556 +
1557 + /* Wait for BmfThread to acknowledge */
1558 + if (pthread_join(BmfThread, NULL) < 0)
1559 + {
1560 + olsr_printf(1, "%s: pthread_join() error: %s\n", PLUGIN_NAME, strerror(errno));
1561 + }
1562 +
1563 + /* Time to clean up */
1564 + CloseBmfNetworkInterfaces();
1565 +}
1566 +
1567 +/* -------------------------------------------------------------------------
1568 + * Function : RegisterBmfParameter
1569 + * Description: Register a configuration parameter with the BMF process
1570 + * Input : key - the parameter name: "DropMac" or "NonOlsrIf"
1571 + * value - the parameter value
1572 + * Output : none
1573 + * Return : fatal error (<0), minor error (0) or success (>0)
1574 + * Data Used : none
1575 + * ------------------------------------------------------------------------- */
1576 +int RegisterBmfParameter(char* key, char* value)
1577 +{
1578 + if (strcmp(key, "DropMac") == 0)
1579 + {
1580 + return DropMac(value);
1581 + }
1582 + else if (strcmp(key, "NonOlsrIf") == 0)
1583 + {
1584 + return AddNonOlsrBmfIf(value);
1585 + }
1586 +
1587 + /* Key not recognized */
1588 + return 0;
1589 +}
1590 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Bmf.h olsrd-0.4.10/lib/bmf/src/Bmf.h
1591 --- olsrd-0.4.10.orig/lib/bmf/src/Bmf.h 1970-01-01 01:00:00.000000000 +0100
1592 +++ olsrd-0.4.10/lib/bmf/src/Bmf.h 2006-12-01 08:26:58.000000000 +0100
1593 @@ -0,0 +1,64 @@
1594 +#ifndef _BMF_BMF_H
1595 +#define _BMF_BMF_H
1596 +
1597 +/*
1598 + * OLSR Basic Multicast Forwarding (BMF) plugin.
1599 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
1600 + * Written by Erik Tromp.
1601 + * All rights reserved.
1602 + *
1603 + * Redistribution and use in source and binary forms, with or without
1604 + * modification, are permitted provided that the following conditions
1605 + * are met:
1606 + *
1607 + * * Redistributions of source code must retain the above copyright
1608 + * notice, this list of conditions and the following disclaimer.
1609 + * * Redistributions in binary form must reproduce the above copyright
1610 + * notice, this list of conditions and the following disclaimer in
1611 + * the documentation and/or other materials provided with the
1612 + * distribution.
1613 + * * Neither the name of Thales, BMF nor the names of its
1614 + * contributors may be used to endorse or promote products derived
1615 + * from this software without specific prior written permission.
1616 + *
1617 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1618 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1619 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1620 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1621 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1622 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1623 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1624 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1625 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1626 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1627 + */
1628 +
1629 +/* -------------------------------------------------------------------------
1630 + * File : Bmf.h
1631 + * Description: Multicast forwarding functions
1632 + * Created : 29 Jun 2006
1633 + *
1634 + * $Id$
1635 + *
1636 + * $Log$
1637 + * ------------------------------------------------------------------------- */
1638 +
1639 +/* BMF plugin data */
1640 +#define PLUGIN_NAME "OLSRD Basic Multicast Forwarding plugin"
1641 +#define PLUGIN_NAME_SHORT "OLSRD BMF"
1642 +#define PLUGIN_VERSION "1.1 (" __DATE__ " " __TIME__ ")"
1643 +#define PLUGIN_COPYRIGHT " (C) Thales Communications Huizen, Netherlands"
1644 +#define PLUGIN_AUTHOR " Erik Tromp (erik.tromp@nl.thalesgroup.com)"
1645 +#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION "\n" PLUGIN_COPYRIGHT "\n" PLUGIN_AUTHOR
1646 +
1647 +/* UDP-Port on which multicast packets are encapsulated */
1648 +#define BMF_ENCAP_PORT 50698
1649 +
1650 +struct interface;
1651 +
1652 +int InterfaceChange(struct interface* interf, int action);
1653 +int InitBmf(struct interface* skipThisIntf);
1654 +void CloseBmf(void);
1655 +int RegisterBmfParameter(char* key, char* value);
1656 +
1657 +#endif /* _BMF_BMF_H */
1658 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/DropList.c olsrd-0.4.10/lib/bmf/src/DropList.c
1659 --- olsrd-0.4.10.orig/lib/bmf/src/DropList.c 1970-01-01 01:00:00.000000000 +0100
1660 +++ olsrd-0.4.10/lib/bmf/src/DropList.c 2006-12-01 08:26:58.000000000 +0100
1661 @@ -0,0 +1,129 @@
1662 +/*
1663 + * OLSR Basic Multicast Forwarding (BMF) plugin.
1664 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
1665 + * Written by Erik Tromp.
1666 + * All rights reserved.
1667 + *
1668 + * Redistribution and use in source and binary forms, with or without
1669 + * modification, are permitted provided that the following conditions
1670 + * are met:
1671 + *
1672 + * * Redistributions of source code must retain the above copyright
1673 + * notice, this list of conditions and the following disclaimer.
1674 + * * Redistributions in binary form must reproduce the above copyright
1675 + * notice, this list of conditions and the following disclaimer in
1676 + * the documentation and/or other materials provided with the
1677 + * distribution.
1678 + * * Neither the name of Thales, BMF nor the names of its
1679 + * contributors may be used to endorse or promote products derived
1680 + * from this software without specific prior written permission.
1681 + *
1682 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1683 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1684 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1685 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1686 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1687 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1688 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1689 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1690 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1691 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1692 + */
1693 +
1694 +/* -------------------------------------------------------------------------
1695 + * File : DropList.c
1696 + * Description: List of MAC addresses of hosts from which all packets are dropped.
1697 + * Created : 29 Jun 2006
1698 + *
1699 + * $Id$
1700 + *
1701 + * $Log$
1702 + * ------------------------------------------------------------------------- */
1703 +
1704 +
1705 +#include "DropList.h"
1706 +
1707 +/* System includes */
1708 +#include <assert.h> /* assert() */
1709 +#include <stdio.h> /* NULL */
1710 +#include <stdlib.h> /* malloc */
1711 +#include <string.h> /* memcmp */
1712 +
1713 +/* OLSRD includes */
1714 +#include "olsr.h" /* olsr_printf */
1715 +
1716 +/* Plugin includes */
1717 +#include "Bmf.h" /* PLUGIN_NAME */
1718 +#include "Packet.h" /* IFHWADDRLEN */
1719 +
1720 +static struct TMacAddress* DroppedMacAddresses = NULL;
1721 +
1722 +/* Register a MAC address in the drop list.
1723 + */
1724 +/* -------------------------------------------------------------------------
1725 + * Function : DropMac
1726 + * Description: Register a MAC address in the drop list
1727 + * Input : macStr - MAC address as string
1728 + * Output : none
1729 + * Return : success (1) or fail (0)
1730 + * Data Used : DroppedMacAddresses
1731 + * Notes : The registered MAC address will be matched to the source MAC
1732 + * address of incoming multicast packets. If matched, the multicast
1733 + * packet will be silently dropped.
1734 + * The drop list is needed only in lab environments, where hidden
1735 + * nodes are simulated by using iptables with the
1736 + * -m mac helper and --mac-source option (as in:
1737 + * "iptables -A INPUT -m mac --mac-source 00:0C:29:EE:C9:D0 -j DROP")
1738 + * The drop list is needed because network interfaces in promiscuous
1739 + * mode will still capture packets even if they are specified to
1740 + * be dropped by iptables.
1741 + * ------------------------------------------------------------------------- */
1742 +int DropMac(const char* macStr)
1743 +{
1744 + unsigned int mac[6];
1745 + int n;
1746 + struct TMacAddress* newMacAddress;
1747 + int i;
1748 +
1749 + assert(macStr != NULL);
1750 +
1751 + n = sscanf(macStr, "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
1752 + if (n != 6)
1753 + {
1754 + olsr_printf(1, "%s: Invalid Ethernet address '%s'\n", PLUGIN_NAME, macStr);
1755 + return 0;
1756 + }
1757 +
1758 + newMacAddress = malloc(sizeof(struct TMacAddress));
1759 + for (i = 0; i < 6; i++)
1760 + {
1761 + newMacAddress->addr[i] = (unsigned char) mac[i];
1762 + }
1763 + newMacAddress->next = DroppedMacAddresses;
1764 + DroppedMacAddresses = newMacAddress;
1765 +
1766 + return 1;
1767 +}
1768 +
1769 +/* -------------------------------------------------------------------------
1770 + * Function : IsInDropList
1771 + * Description: Check if a MAC address is in the drop list
1772 + * Input : macAddress
1773 + * Output : none
1774 + * Return : true (1) or false (0)
1775 + * Data Used : DroppedMacAddresses
1776 + * ------------------------------------------------------------------------- */
1777 +int IsInDropList(const unsigned char* macAddress)
1778 +{
1779 + struct TMacAddress* ma = DroppedMacAddresses;
1780 +
1781 + assert(macAddress != NULL);
1782 +
1783 + while (ma != NULL)
1784 + {
1785 + if (memcmp(ma->addr, macAddress, IFHWADDRLEN) == 0) return 1;
1786 + ma = ma->next;
1787 + }
1788 + return 0;
1789 +}
1790 +
1791 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/DropList.h olsrd-0.4.10/lib/bmf/src/DropList.h
1792 --- olsrd-0.4.10.orig/lib/bmf/src/DropList.h 1970-01-01 01:00:00.000000000 +0100
1793 +++ olsrd-0.4.10/lib/bmf/src/DropList.h 2006-12-01 08:26:58.000000000 +0100
1794 @@ -0,0 +1,55 @@
1795 +#ifndef _BMF_DROPLIST_H
1796 +#define _BMF_DROPLIST_H
1797 +
1798 +/*
1799 + * OLSR Basic Multicast Forwarding (BMF) plugin.
1800 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
1801 + * Written by Erik Tromp.
1802 + * All rights reserved.
1803 + *
1804 + * Redistribution and use in source and binary forms, with or without
1805 + * modification, are permitted provided that the following conditions
1806 + * are met:
1807 + *
1808 + * * Redistributions of source code must retain the above copyright
1809 + * notice, this list of conditions and the following disclaimer.
1810 + * * Redistributions in binary form must reproduce the above copyright
1811 + * notice, this list of conditions and the following disclaimer in
1812 + * the documentation and/or other materials provided with the
1813 + * distribution.
1814 + * * Neither the name of Thales, BMF nor the names of its
1815 + * contributors may be used to endorse or promote products derived
1816 + * from this software without specific prior written permission.
1817 + *
1818 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1819 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1820 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1821 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1822 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1823 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1824 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1825 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1826 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1827 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1828 + */
1829 +
1830 +/* -------------------------------------------------------------------------
1831 + * File : DropList.h
1832 + * Description: List of MAC addresses of hosts from which all packets are dropped.
1833 + * Created : 29 Jun 2006
1834 + *
1835 + * $Id$
1836 + *
1837 + * $Log$
1838 + * ------------------------------------------------------------------------- */
1839 +
1840 +struct TMacAddress
1841 +{
1842 + unsigned char addr[6];
1843 + struct TMacAddress* next;
1844 +};
1845 +
1846 +int DropMac(const char* macStr);
1847 +int IsInDropList(const unsigned char* macAddress);
1848 +
1849 +#endif /* _BMF_DROPLIST_H */
1850 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c
1851 --- olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c 1970-01-01 01:00:00.000000000 +0100
1852 +++ olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c 2006-12-01 08:26:58.000000000 +0100
1853 @@ -0,0 +1,818 @@
1854 +/*
1855 + * OLSR Basic Multicast Forwarding (BMF) plugin.
1856 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
1857 + * Written by Erik Tromp.
1858 + * All rights reserved.
1859 + *
1860 + * Redistribution and use in source and binary forms, with or without
1861 + * modification, are permitted provided that the following conditions
1862 + * are met:
1863 + *
1864 + * * Redistributions of source code must retain the above copyright
1865 + * notice, this list of conditions and the following disclaimer.
1866 + * * Redistributions in binary form must reproduce the above copyright
1867 + * notice, this list of conditions and the following disclaimer in
1868 + * the documentation and/or other materials provided with the
1869 + * distribution.
1870 + * * Neither the name of Thales, BMF nor the names of its
1871 + * contributors may be used to endorse or promote products derived
1872 + * from this software without specific prior written permission.
1873 + *
1874 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1875 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1876 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1877 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1878 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1879 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1880 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1881 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1882 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1883 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1884 + */
1885 +
1886 +/* -------------------------------------------------------------------------
1887 + * File : NetworkInterfaces.c
1888 + * Description: Functions to open and close sockets
1889 + * Created : 29 Jun 2006
1890 + *
1891 + * $Id$
1892 + *
1893 + * $Log$
1894 + * ------------------------------------------------------------------------- */
1895 +
1896 +#include "NetworkInterfaces.h"
1897 +
1898 +/* System includes */
1899 +#include <syslog.h> /* syslog() */
1900 +#include <string.h> /* strerror() */
1901 +#include <errno.h> /* errno */
1902 +#include <unistd.h> /* close() */
1903 +#include <sys/ioctl.h> /* ioctl() */
1904 +#include <fcntl.h> /* fcntl() */
1905 +#include <assert.h> /* assert() */
1906 +#include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
1907 +#include <netinet/in.h> /* htons() */
1908 +#include <linux/if_ether.h> /* ETH_P_ALL */
1909 +#include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
1910 +#include <linux/if_tun.h> /* IFF_TAP */
1911 +
1912 +/* OLSRD includes */
1913 +#include "olsr.h" /* olsr_printf() */
1914 +#include "defs.h" /* olsr_cnf */
1915 +
1916 +/* Plugin includes */
1917 +#include "Packet.h" /* IFHWADDRLEN */
1918 +#include "Bmf.h" /* PLUGIN_NAME */
1919 +
1920 +/* List of network interfaces used by BMF plugin */
1921 +struct TBmfInterface* BmfInterfaces = NULL;
1922 +
1923 +/* File descriptor of EtherTunTap device */
1924 +int EtherTunTapFd = -1;
1925 +
1926 +/* Network interface name of EtherTunTap device. If the name starts with "tun", an
1927 + * IP tunnel interface will be used. Otherwise, an EtherTap device will be used. */
1928 +const char* EtherTunTapIfName = "tun0"; /* "tap0"; */
1929 +
1930 +/* If the network interface name starts with "tun", an IP tunnel interface will be
1931 + * used, and this variable will be set to TUN. Otherwise, an EtherTap device will
1932 + * be used, and this variable will be set to TAP. */
1933 +enum TTunOrTap TunOrTap;
1934 +
1935 +/* -------------------------------------------------------------------------
1936 + * Function : CreateCaptureSocket
1937 + * Description: Create socket for promiscuously capturing multicast IP traffic
1938 + * Input : ifname - network interface (e.g. "eth0")
1939 + * Output : none
1940 + * Return : the socket descriptor ( >= 0), or -1 if an error occurred
1941 + * Data Used : none
1942 + * Notes : The socket is a raw packet socket, bound to the specified
1943 + * network interface
1944 + * ------------------------------------------------------------------------- */
1945 +static int CreateCaptureSocket(const char* ifName)
1946 +{
1947 + int ifIndex = if_nametoindex(ifName);
1948 + struct packet_mreq mreq;
1949 + struct ifreq req;
1950 + struct sockaddr_ll bindTo;
1951 +
1952 + /* Open raw packet socket */
1953 + int skfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1954 + if (skfd < 0)
1955 + {
1956 + olsr_printf(1, "%s: socket(PF_PACKET) error: %s\n", PLUGIN_NAME, strerror(errno));
1957 + return -1;
1958 + }
1959 +
1960 + /* Set interface to promiscuous mode */
1961 + memset(&mreq, 0, sizeof(struct packet_mreq));
1962 + mreq.mr_ifindex = ifIndex;
1963 + mreq.mr_type = PACKET_MR_PROMISC;
1964 + if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
1965 + {
1966 + olsr_printf(1, "%s: setsockopt(PACKET_MR_PROMISC) error: %s\n", PLUGIN_NAME, strerror(errno));
1967 + close(skfd);
1968 + return -1;
1969 + }
1970 +
1971 + /* Get hardware (MAC) address */
1972 + memset(&req, 0, sizeof(struct ifreq));
1973 + strncpy(req.ifr_name, ifName, IFNAMSIZ);
1974 + if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
1975 + {
1976 + olsr_printf(1, "%s: error retrieving MAC address: %s\n", PLUGIN_NAME, strerror(errno));
1977 + close(skfd);
1978 + return -1;
1979 + }
1980 +
1981 + /* Bind the socket to the specified interface */
1982 + memset(&bindTo, 0, sizeof(bindTo));
1983 + bindTo.sll_protocol = htons(ETH_P_ALL);
1984 + bindTo.sll_ifindex = ifIndex;
1985 + bindTo.sll_family = AF_PACKET;
1986 + memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1987 + bindTo.sll_halen = IFHWADDRLEN;
1988 +
1989 + if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1990 + {
1991 + olsr_printf(1, "%s: bind() error: %s\n", PLUGIN_NAME, strerror(errno));
1992 + close(skfd);
1993 + return -1;
1994 + }
1995 +
1996 + /* Set socket to blocking operation */
1997 + if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1998 + {
1999 + olsr_printf(1, "%s: fcntl() error: %s\n", PLUGIN_NAME, strerror(errno));
2000 + close(skfd);
2001 + return -1;
2002 + }
2003 +
2004 + return skfd;
2005 +}
2006 +
2007 +/* -------------------------------------------------------------------------
2008 + * Function : CreateEncapsulateSocket
2009 + * Description: Create a socket for sending and receiving encapsulated
2010 + * multicast packets
2011 + * Input : ifname - network interface (e.g. "eth0")
2012 + * Output : none
2013 + * Return : the socket descriptor ( >= 0), or -1 if an error occurred
2014 + * Data Used : none
2015 + * Notes : The socket is an UDP (datagram) over IP socket, bound to the
2016 + * specified network interface
2017 + * ------------------------------------------------------------------------- */
2018 +static int CreateEncapsulateSocket(const char* ifName)
2019 +{
2020 + int on = 1;
2021 + struct sockaddr_in bindTo;
2022 +
2023 + /* Open UDP-IP socket */
2024 + int skfd = socket(PF_INET, SOCK_DGRAM, 0);
2025 + if (skfd < 0)
2026 + {
2027 + olsr_printf(1, "%s: socket(PF_INET) error: %s\n", PLUGIN_NAME, strerror(errno));
2028 + return -1;
2029 + }
2030 +
2031 + /* Enable sending to broadcast addresses */
2032 + if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
2033 + {
2034 + olsr_printf(1, "%s: setsockopt() error: %s\n", PLUGIN_NAME, strerror(errno));
2035 + close(skfd);
2036 + return -1;
2037 + }
2038 +
2039 + /* Bind to the specific network interfaces indicated by ifName. */
2040 + /* When using Kernel 2.6 this must happer prior to the port binding! */
2041 + if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0)
2042 + {
2043 + olsr_printf(1, "%s: setsockopt() error: %s\n", PLUGIN_NAME, strerror(errno));
2044 + close(skfd);
2045 + return -1;
2046 + }
2047 +
2048 + /* Bind to port */
2049 + memset(&bindTo, 0, sizeof(bindTo));
2050 + bindTo.sin_family = AF_INET;
2051 + bindTo.sin_port = htons(BMF_ENCAP_PORT);
2052 + bindTo.sin_addr.s_addr = htonl(INADDR_ANY);
2053 +
2054 + if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
2055 + {
2056 + olsr_printf(1, "%s: bind() error: %s\n", PLUGIN_NAME, strerror(errno));
2057 + close(skfd);
2058 + return -1;
2059 + }
2060 +
2061 + /* Set socket to blocking operation */
2062 + if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
2063 + {
2064 + olsr_printf(1, "%s: fcntl() error: %s\n", PLUGIN_NAME, strerror(errno));
2065 + close(skfd);
2066 + return -1;
2067 + }
2068 +
2069 + return skfd;
2070 +}
2071 +
2072 +/* To save the state of the IP spoof filter for the EtherTunTap device */
2073 +static char EthTapSpoofState = '1';
2074 +
2075 +/* -------------------------------------------------------------------------
2076 + * Function : DeactivateSpoofFilter
2077 + * Description: Deactivates the Linux anti-spoofing filter for the tuntap
2078 + * interface
2079 + * Input : tunTapName - name used for the tuntap interface (e.g. "tun0" or "tap1")
2080 + * Output : none
2081 + * Return : success (1) or fail (0)
2082 + * Data Used : EthTapSpoofState
2083 + * Notes : Saves the current filter state for later restoring
2084 + * ------------------------------------------------------------------------- */
2085 +static int DeactivateSpoofFilter(const char* tunTapName)
2086 +{
2087 + FILE* procSpoof;
2088 + char procFile[FILENAME_MAX];
2089 +
2090 + assert(tunTapName != NULL);
2091 +
2092 + /* Generate the procfile name */
2093 + sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", tunTapName);
2094 +
2095 + procSpoof = fopen(procFile, "r");
2096 + if (procSpoof == NULL)
2097 + {
2098 + fprintf(
2099 + stderr,
2100 + "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
2101 + "Are you using the procfile filesystem?\n"
2102 + "Does your system support IPv4?\n"
2103 + "I will continue (in 3 sec) - but you should manually ensure that IP spoof\n"
2104 + "filtering is disabled!\n\n",
2105 + procFile);
2106 +
2107 + sleep(3);
2108 + return 0;
2109 + }
2110 +
2111 + EthTapSpoofState = fgetc(procSpoof);
2112 + fclose(procSpoof);
2113 +
2114 + procSpoof = fopen(procFile, "w");
2115 + if (procSpoof == NULL)
2116 + {
2117 + fprintf(stderr, "Could not open %s for writing!\n", procFile);
2118 + fprintf(
2119 + stderr,
2120 + "I will continue (in 3 sec) - but you should manually ensure that IP"
2121 + " spoof filtering is disabled!\n\n");
2122 + sleep(3);
2123 + return 0;
2124 + }
2125 +
2126 + syslog(LOG_INFO, "Writing \"0\" to %s", procFile);
2127 + fputs("0", procSpoof);
2128 +
2129 + fclose(procSpoof);
2130 +
2131 + return 1;
2132 +}
2133 +
2134 +/* -------------------------------------------------------------------------
2135 + * Function : RestoreSpoofFilter
2136 + * Description: Restores the Linux anti-spoofing filter setting for the tuntap
2137 + * interface
2138 + * Input : tunTapName - name used for the tuntap interface (e.g. "tun0" or "tap1")
2139 + * Output : none
2140 + * Return : none
2141 + * Data Used : EthTapSpoofState
2142 + * ------------------------------------------------------------------------- */
2143 +static void RestoreSpoofFilter(const char* tunTapName)
2144 +{
2145 + FILE* procSpoof;
2146 + char procFile[FILENAME_MAX];
2147 +
2148 + assert(tunTapName != NULL);
2149 +
2150 + /* Generate the procfile name */
2151 + sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", tunTapName);
2152 +
2153 + procSpoof = fopen(procFile, "w");
2154 + if (procSpoof == NULL)
2155 + {
2156 + fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procFile);
2157 + }
2158 + else
2159 + {
2160 + syslog(LOG_INFO, "Resetting %s to %c\n", procFile, EthTapSpoofState);
2161 +
2162 + fputc(EthTapSpoofState, procSpoof);
2163 + fclose(procSpoof);
2164 + }
2165 +}
2166 +
2167 +/* -------------------------------------------------------------------------
2168 + * Function : CreateLocalEtherTunTap
2169 + * Description: Creates and brings up an EtherTunTap device
2170 + * Input : none
2171 + * Output : none
2172 + * Return : success (0) or fail (<0)
2173 + * Data Used : EtherTunTapIfName - name used for the tuntap interface (e.g.
2174 + * "tun0" or "tap1")
2175 + * ------------------------------------------------------------------------- */
2176 +static int CreateLocalEtherTunTap(void)
2177 +{
2178 + static char* deviceName = "/dev/net/tun";
2179 + struct ifreq ifreq;
2180 + int etfd = open(deviceName, O_RDWR);
2181 + int skfd;
2182 + int ioctlres = 0;
2183 +
2184 + if (etfd < 0)
2185 + {
2186 + olsr_printf(1, "%s: error opening %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
2187 + return -1;
2188 + }
2189 +
2190 + memset(&ifreq, 0, sizeof(ifreq));
2191 +
2192 + /* Specify either the IFF_TAP flag for Ethernet frames, or the IFF_TUN flag for IP.
2193 + * Specify IFF_NO_PI for not receiving extra meta packet information. */
2194 + if (strncmp(EtherTunTapIfName, "tun", 3) == 0)
2195 + {
2196 + ifreq.ifr_flags = IFF_TUN;
2197 + TunOrTap = TT_TUN;
2198 + }
2199 + else
2200 + {
2201 + ifreq.ifr_flags = IFF_TAP;
2202 + TunOrTap = TT_TAP;
2203 + }
2204 + ifreq.ifr_flags |= IFF_NO_PI;
2205 +
2206 + strcpy(ifreq.ifr_name, EtherTunTapIfName);
2207 + if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
2208 + {
2209 + olsr_printf(1, "%s: ioctl(TUNSETIFF) error on %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
2210 + close(etfd);
2211 + return -1;
2212 + }
2213 +
2214 + memset(&ifreq, 0, sizeof(ifreq));
2215 + strcpy(ifreq.ifr_name, EtherTunTapIfName);
2216 + ifreq.ifr_addr.sa_family = AF_INET;
2217 + skfd = socket(PF_INET, SOCK_DGRAM, 0);
2218 + if (skfd < 0)
2219 + {
2220 + olsr_printf(1, "%s: socket(PF_INET) error on %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
2221 + close(etfd);
2222 + return -1;
2223 + }
2224 +
2225 + if (ioctl(skfd, SIOCGIFADDR, &ifreq) < 0)
2226 + {
2227 + /* EtherTunTap interface does not yet have an IP address.
2228 + * Give it a dummy IP address "1.2.3.4". */
2229 + struct sockaddr_in *inaddr = (struct sockaddr_in *)&ifreq.ifr_addr;
2230 + inet_aton("1.2.3.4", &inaddr->sin_addr);
2231 + ioctlres = ioctl(skfd, SIOCSIFADDR, &ifreq);
2232 + if (ioctlres >= 0)
2233 + {
2234 + /* Bring EtherTunTap interface up (if not already) */
2235 + ioctlres = ioctl(skfd, SIOCGIFFLAGS, &ifreq);
2236 + if (ioctlres >= 0)
2237 + {
2238 + ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING);
2239 + ioctlres = ioctl(skfd, SIOCSIFFLAGS, &ifreq);
2240 + }
2241 + }
2242 +
2243 + if (ioctlres < 0)
2244 + {
2245 + /* Any of the three above ioctl() calls failed */
2246 + olsr_printf(
2247 + 1,
2248 + "%s: error bringing up EtherTunTap interface \"%s\": %s\n",
2249 + PLUGIN_NAME,
2250 + EtherTunTapIfName,
2251 + strerror(errno));
2252 +
2253 + close(etfd);
2254 + close(skfd);
2255 + return -1;
2256 + } /* if (ioctlres < 0) */
2257 + } /* if (ioctl...) */
2258 +
2259 + /* Set the multicast flag on the interface. TODO: Maybe also set
2260 + * IFF_ALLMULTI. */
2261 + memset(&ifreq, 0, sizeof(ifreq));
2262 + strcpy(ifreq.ifr_name, EtherTunTapIfName);
2263 + ioctlres = ioctl(skfd, SIOCGIFFLAGS, &ifreq);
2264 + if (ioctlres >= 0)
2265 + {
2266 + ifreq.ifr_flags |= IFF_MULTICAST;
2267 + ioctlres = ioctl(skfd, SIOCSIFFLAGS, &ifreq);
2268 + }
2269 + if (ioctlres < 0)
2270 + {
2271 + /* Any of the two above ioctl() calls failed */
2272 + olsr_printf(
2273 + 1,
2274 + "%s: error setting multicast flag on EtherTunTap interface \"%s\": %s\n",
2275 + PLUGIN_NAME,
2276 + EtherTunTapIfName,
2277 + strerror(errno));
2278 + /* Continue anyway */
2279 + }
2280 + close(skfd);
2281 +
2282 + /* Deactivate IP spoof filter for EtherTunTap device */
2283 + DeactivateSpoofFilter(ifreq.ifr_name);
2284 +
2285 + olsr_printf(9, "%s: opened \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
2286 +
2287 + return etfd;
2288 +}
2289 +
2290 +/* -------------------------------------------------------------------------
2291 + * Function : IsNullMacAddress
2292 + * Description: Checks if a MAC address is all-zeroes
2293 + * Input : mac - address to check
2294 + * Output : none
2295 + * Return : true (1) or false (0)
2296 + * Data Used : none
2297 + * ------------------------------------------------------------------------- */
2298 +static int IsNullMacAddress(char* mac)
2299 +{
2300 + int i;
2301 +
2302 + assert(mac != NULL);
2303 +
2304 + for (i = 0; i < IFHWADDRLEN; i++)
2305 + {
2306 + if (mac[i] != 0) return 0;
2307 + }
2308 + return 1;
2309 +}
2310 +
2311 +/* -------------------------------------------------------------------------
2312 + * Function : CreateInterface
2313 + * Description: Create a new TBmfInterface object and adds it to the global
2314 + * BmfInterfaces list
2315 + * Input : ifName - name of the network interface (e.g. "eth0")
2316 + * Output : none
2317 + * Return : the number of opened sockets
2318 + * Data Used : none
2319 + * ------------------------------------------------------------------------- */
2320 +static int CreateInterface(
2321 + const char* ifName,
2322 + struct interface* olsrIntf)
2323 +{
2324 + int capturingSkfd;
2325 + int encapsulatingSkfd = -1;
2326 + struct ifreq ifr;
2327 + int nOpened = 0;
2328 + struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
2329 +
2330 + assert(ifName != NULL);
2331 +
2332 + if (newIf == NULL)
2333 + {
2334 + return 0;
2335 + }
2336 +
2337 + if (olsrIntf != NULL)
2338 + {
2339 + /* On OLSR interfaces, create socket for encapsulating and forwarding
2340 + * multicast packets */
2341 + encapsulatingSkfd = CreateEncapsulateSocket(ifName);
2342 + if (encapsulatingSkfd < 0)
2343 + {
2344 + free(newIf);
2345 + return 0;
2346 + }
2347 + nOpened++;
2348 + }
2349 +
2350 + /* On all interfaces, create socket for capturing and sending multicast packets */
2351 + capturingSkfd = CreateCaptureSocket(ifName);
2352 + if (capturingSkfd < 0)
2353 + {
2354 + close(encapsulatingSkfd);
2355 + free(newIf);
2356 + return 0;
2357 + }
2358 + nOpened++;
2359 +
2360 + /* Retrieve the MAC address */
2361 + memset(&ifr, 0, sizeof(struct ifreq));
2362 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ);
2363 + if (ioctl(capturingSkfd, SIOCGIFHWADDR, &ifr) < 0)
2364 + {
2365 + olsr_printf(
2366 + 1,
2367 + "%s: ioctl(SIOCGIFHWADDR) error for device \"%s\": %s\n",
2368 + PLUGIN_NAME,
2369 + ifName,
2370 + strerror(errno));
2371 + close(capturingSkfd);
2372 + close(encapsulatingSkfd);
2373 + free(newIf);
2374 + return 0;
2375 + }
2376 +
2377 + /* If null-interface, cancel the whole creation and return NULL */
2378 + if (IsNullMacAddress(ifr.ifr_hwaddr.sa_data))
2379 + {
2380 + close(capturingSkfd);
2381 + close(encapsulatingSkfd);
2382 + free(newIf);
2383 + return 0;
2384 + }
2385 +
2386 + newIf->capturingSkfd = capturingSkfd;
2387 + newIf->encapsulatingSkfd = encapsulatingSkfd;
2388 + memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
2389 + memcpy(newIf->ifName, ifName, IFNAMSIZ);
2390 + newIf->olsrIntf = olsrIntf;
2391 + if (olsrIntf != NULL)
2392 + {
2393 + /* Copy broadcast address from OLSR interface */
2394 + newIf->broadAddr = olsrIntf->int_broadaddr;
2395 + }
2396 + else
2397 + {
2398 + /* Non-OLSR interface: retrieve the IP broadcast address */
2399 + memset(&ifr, 0, sizeof(struct ifreq));
2400 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ);
2401 + if (ioctl(capturingSkfd, SIOCGIFBRDADDR, &ifr) < 0)
2402 + {
2403 + olsr_printf(
2404 + 1,
2405 + "%s: ioctl(SIOCGIFBRDADDR) error for device \"%s\": %s\n",
2406 + PLUGIN_NAME,
2407 + ifName,
2408 + strerror(errno));
2409 +
2410 + ((struct sockaddr_in*)&newIf->broadAddr)->sin_addr.s_addr = inet_addr("0.0.0.0");
2411 + }
2412 + else
2413 + {
2414 + newIf->broadAddr = ifr.ifr_broadaddr;
2415 + }
2416 + }
2417 +
2418 + memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
2419 + newIf->nextFragmentHistoryEntry = 0;
2420 +
2421 + newIf->next = BmfInterfaces;
2422 + BmfInterfaces = newIf;
2423 +
2424 + OLSR_PRINTF(
2425 + 9,
2426 + "%s: opened %s interface \"%s\"\n",
2427 + PLUGIN_NAME_SHORT,
2428 + olsrIntf != NULL ? "OLSR" : "non-OLSR",
2429 + ifName);
2430 +
2431 + return nOpened;
2432 +}
2433 +
2434 +/* -------------------------------------------------------------------------
2435 + * Function : CreateBmfNetworkInterfaces
2436 + * Description: Create a list of TBmfInterface objects, one for each network
2437 + * interface on which BMF runs
2438 + * Input : skipThisIntf - network interface to skip, if seen
2439 + * Output : none
2440 + * Return : success (0) or fail (<0)
2441 + * Data Used : none
2442 + * ------------------------------------------------------------------------- */
2443 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
2444 +{
2445 + int skfd;
2446 + struct ifconf ifc;
2447 + int numreqs = 30;
2448 + struct ifreq* ifr;
2449 + int n;
2450 + int nOpened = 0;
2451 +
2452 + EtherTunTapFd = CreateLocalEtherTunTap();
2453 + if (EtherTunTapFd >=0)
2454 + {
2455 + nOpened++;
2456 + }
2457 +
2458 + skfd = socket(PF_INET, SOCK_DGRAM, 0);
2459 + if (skfd < 0)
2460 + {
2461 + olsr_printf(
2462 + 1,
2463 + "%s: no inet socket available to retrieve interface list: %s\n",
2464 + PLUGIN_NAME,
2465 + strerror(errno));
2466 + return -1;
2467 + }
2468 +
2469 + /* Retrieve the network interface configuration list */
2470 + ifc.ifc_buf = NULL;
2471 + for (;;)
2472 + {
2473 + ifc.ifc_len = sizeof(struct ifreq) * numreqs;
2474 + ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
2475 +
2476 + if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
2477 + {
2478 + olsr_printf(1, "%s: ioctl(SIOCGIFCONF) error: %s\n", PLUGIN_NAME, strerror(errno));
2479 +
2480 + close(skfd);
2481 + free(ifc.ifc_buf);
2482 + return -1;
2483 + }
2484 + if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
2485 + {
2486 + /* Assume it overflowed; double the space and try again */
2487 + numreqs *= 2;
2488 + assert(numreqs < 1024);
2489 + continue; /* for (;;) */
2490 + }
2491 + break; /* for (;;) */
2492 + } /* for (;;) */
2493 +
2494 + close(skfd);
2495 +
2496 + /* For each item in the interface configuration list... */
2497 + ifr = ifc.ifc_req;
2498 + for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++)
2499 + {
2500 + struct interface* olsrIntf;
2501 +
2502 + /* ...find the OLSR interface structure, if any */
2503 + union olsr_ip_addr ipAddr;
2504 + COPY_IP(&ipAddr, &((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr.s_addr);
2505 + olsrIntf = if_ifwithaddr(&ipAddr);
2506 +
2507 + if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
2508 + {
2509 + continue; /* for (n = ...) */
2510 + }
2511 +
2512 + if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
2513 + {
2514 + /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
2515 + * interface in the BMF plugin parameter list */
2516 + continue; /* for (n = ...) */
2517 + }
2518 +
2519 + nOpened += CreateInterface(ifr->ifr_name, olsrIntf);
2520 +
2521 + } /* for (n = ...) */
2522 +
2523 + free(ifc.ifc_buf);
2524 +
2525 + if (BmfInterfaces == NULL)
2526 + {
2527 + olsr_printf(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
2528 + return -1;
2529 + }
2530 +
2531 + olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
2532 +
2533 + return 0;
2534 +}
2535 +
2536 +/* -------------------------------------------------------------------------
2537 + * Function : AddInterface
2538 + * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
2539 + * network interfaces
2540 + * Input : newIntf - network interface to add
2541 + * Output : none
2542 + * Return : none
2543 + * Data Used : none
2544 + * ------------------------------------------------------------------------- */
2545 +void AddInterface(struct interface* newIntf)
2546 +{
2547 + int nOpened;
2548 +
2549 + assert(newIntf != NULL);
2550 +
2551 + nOpened = CreateInterface(newIntf->int_name, newIntf);
2552 +
2553 + olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
2554 +}
2555 +
2556 +/* -------------------------------------------------------------------------
2557 + * Function : CloseBmfNetworkInterfaces
2558 + * Description: Closes every socket on each network interface used by BMF
2559 + * Input : newIntf - network interface to add
2560 + * Output : none
2561 + * Return : none
2562 + * Data Used : none
2563 + * Notes : Closes
2564 + * - the local EtherTunTap interface (e.g. "tun0" or "tap0")
2565 + * - for each BMF-enabled interface, the socket used for
2566 + * capturing multicast packets
2567 + * - for each OLSR-enabled interface, the socket used for
2568 + * encapsulating packets
2569 + * Also restores the network state to the situation before BMF
2570 + * was started.
2571 + * ------------------------------------------------------------------------- */
2572 +void CloseBmfNetworkInterfaces()
2573 +{
2574 + int nClosed = 0;
2575 +
2576 + /* Close all opened sockets */
2577 + struct TBmfInterface* nextBmfIf = BmfInterfaces;
2578 + while (nextBmfIf != NULL)
2579 + {
2580 + struct TBmfInterface* bmfIf = nextBmfIf;
2581 + nextBmfIf = bmfIf->next;
2582 +
2583 + if (bmfIf->capturingSkfd >= 0)
2584 + {
2585 + close(bmfIf->capturingSkfd);
2586 + nClosed++;
2587 + }
2588 + if (bmfIf->encapsulatingSkfd >= 0)
2589 + {
2590 + close(bmfIf->encapsulatingSkfd);
2591 + nClosed++;
2592 + }
2593 +
2594 + OLSR_PRINTF(
2595 + 9,
2596 + "%s: closed %s interface \"%s\"\n",
2597 + PLUGIN_NAME_SHORT,
2598 + bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
2599 + bmfIf->ifName);
2600 +
2601 + free(bmfIf);
2602 + }
2603 +
2604 + if (EtherTunTapFd >= 0)
2605 + {
2606 + /* Restore IP spoof filter for EtherTunTap device */
2607 + RestoreSpoofFilter(EtherTunTapIfName);
2608 +
2609 + close(EtherTunTapFd);
2610 + nClosed++;
2611 +
2612 + OLSR_PRINTF(9, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
2613 + }
2614 +
2615 + BmfInterfaces = NULL;
2616 +
2617 + olsr_printf(1, "%s: closed %d sockets\n", PLUGIN_NAME, nClosed);
2618 +}
2619 +
2620 +#define MAX_NON_OLSR_IFS 10
2621 +static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
2622 +static int nNonOlsrIfs = 0;
2623 +
2624 +/* -------------------------------------------------------------------------
2625 + * Function : AddNonOlsrBmfIf
2626 + * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
2627 + * network interfaces
2628 + * Input : ifName - network interface (e.g. "eth0")
2629 + * Output : none
2630 + * Return : success (1) or fail (0)
2631 + * Data Used : none
2632 + * ------------------------------------------------------------------------- */
2633 +int AddNonOlsrBmfIf(const char* ifName)
2634 +{
2635 + assert(ifName != NULL);
2636 +
2637 + if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
2638 + {
2639 + olsr_printf(
2640 + 1,
2641 + "%s: too many non-OLSR interfaces specified, maximum is %d\n",
2642 + PLUGIN_NAME,
2643 + MAX_NON_OLSR_IFS);
2644 + return 0;
2645 + }
2646 +
2647 + strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ);
2648 + nNonOlsrIfs++;
2649 + return 1;
2650 +}
2651 +
2652 +/* -------------------------------------------------------------------------
2653 + * Function : IsNonOlsrBmfIf
2654 + * Description: Checks if a network interface is OLSR-enabled
2655 + * Input : ifName - network interface (e.g. "eth0")
2656 + * Output : none
2657 + * Return : true (1) or false (0)
2658 + * Data Used : none
2659 + * ------------------------------------------------------------------------- */
2660 +int IsNonOlsrBmfIf(const char* ifName)
2661 +{
2662 + int i;
2663 +
2664 + assert(ifName != NULL);
2665 +
2666 + for (i = 0; i < nNonOlsrIfs; i++)
2667 + {
2668 + if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
2669 + }
2670 + return 0;
2671 +}
2672 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.h olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.h
2673 --- olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.h 1970-01-01 01:00:00.000000000 +0100
2674 +++ olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.h 2006-12-01 08:26:58.000000000 +0100
2675 @@ -0,0 +1,106 @@
2676 +#ifndef _BMF_NETWORKINTERFACES_H
2677 +#define _BMF_NETWORKINTERFACES_H
2678 +
2679 +/*
2680 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2681 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
2682 + * Written by Erik Tromp.
2683 + * All rights reserved.
2684 + *
2685 + * Redistribution and use in source and binary forms, with or without
2686 + * modification, are permitted provided that the following conditions
2687 + * are met:
2688 + *
2689 + * * Redistributions of source code must retain the above copyright
2690 + * notice, this list of conditions and the following disclaimer.
2691 + * * Redistributions in binary form must reproduce the above copyright
2692 + * notice, this list of conditions and the following disclaimer in
2693 + * the documentation and/or other materials provided with the
2694 + * distribution.
2695 + * * Neither the name of Thales, BMF nor the names of its
2696 + * contributors may be used to endorse or promote products derived
2697 + * from this software without specific prior written permission.
2698 + *
2699 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2700 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2701 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2702 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2703 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2704 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2705 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2706 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2707 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2708 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2709 + */
2710 +
2711 +/* -------------------------------------------------------------------------
2712 + * File : NetworkInterfaces.h
2713 + * Description: Functions to open and close sockets
2714 + * Created : 29 Jun 2006
2715 + *
2716 + * $Id$
2717 + *
2718 + * $Log$
2719 + * ------------------------------------------------------------------------- */
2720 +
2721 +/* System includes */
2722 +#include <netinet/in.h> /* struct in_addr */
2723 +
2724 +/* Plugin includes */
2725 +#include "Packet.h" /* IFHWADDRLEN */
2726 +
2727 +
2728 +struct TBmfInterface
2729 +{
2730 + /* File descriptor of raw packet socket, used for capturing multicast packets */
2731 + int capturingSkfd;
2732 +
2733 + /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.
2734 + * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */
2735 + int encapsulatingSkfd;
2736 +
2737 + unsigned char macAddr[IFHWADDRLEN];
2738 +
2739 + char ifName[IFNAMSIZ];
2740 +
2741 + /* OLSRs idea of this network interface. NULL if this interface is not
2742 + * OLSR-enabled. */
2743 + struct interface* olsrIntf;
2744 +
2745 + /* Kernels index of this network interface */
2746 + int ifIndex;
2747 +
2748 + /* Broadcast address of this network interface */
2749 + struct sockaddr broadAddr;
2750 +
2751 + #define FRAGMENT_HISTORY_SIZE 10
2752 + struct TFragmentHistory
2753 + {
2754 + u_int16_t ipId;
2755 + u_int8_t ipProto;
2756 + struct in_addr ipSrc;
2757 + struct in_addr ipDst;
2758 + } fragmentHistory [FRAGMENT_HISTORY_SIZE];
2759 +
2760 + int nextFragmentHistoryEntry;
2761 +
2762 + /* Next element in list */
2763 + struct TBmfInterface* next;
2764 +};
2765 +
2766 +extern struct TBmfInterface* BmfInterfaces;
2767 +
2768 +extern int EtherTunTapFd;
2769 +
2770 +extern const char* EtherTunTapIfName;
2771 +
2772 +enum TTunOrTap { TT_TUN = 0, TT_TAP };
2773 +extern enum TTunOrTap TunOrTap;
2774 +
2775 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
2776 +void AddInterface(struct interface* newIntf);
2777 +void CloseBmfNetworkInterfaces(void);
2778 +int AddNonOlsrBmfIf(const char* ifName);
2779 +int IsNonOlsrBmfIf(const char* ifName);
2780 +
2781 +#endif /* _BMF_NETWORKINTERFACES_H */
2782 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/olsrd_plugin.c olsrd-0.4.10/lib/bmf/src/olsrd_plugin.c
2783 --- olsrd-0.4.10.orig/lib/bmf/src/olsrd_plugin.c 1970-01-01 01:00:00.000000000 +0100
2784 +++ olsrd-0.4.10/lib/bmf/src/olsrd_plugin.c 2006-12-01 08:26:58.000000000 +0100
2785 @@ -0,0 +1,166 @@
2786 +/*
2787 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2788 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
2789 + * Written by Erik Tromp.
2790 + * All rights reserved.
2791 + *
2792 + * Redistribution and use in source and binary forms, with or without
2793 + * modification, are permitted provided that the following conditions
2794 + * are met:
2795 + *
2796 + * * Redistributions of source code must retain the above copyright
2797 + * notice, this list of conditions and the following disclaimer.
2798 + * * Redistributions in binary form must reproduce the above copyright
2799 + * notice, this list of conditions and the following disclaimer in
2800 + * the documentation and/or other materials provided with the
2801 + * distribution.
2802 + * * Neither the name of Thales, BMF nor the names of its
2803 + * contributors may be used to endorse or promote products derived
2804 + * from this software without specific prior written permission.
2805 + *
2806 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2807 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2808 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2809 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2810 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2811 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2812 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2813 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2814 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2815 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2816 + */
2817 +
2818 +/* -------------------------------------------------------------------------
2819 + * File : olsrd_plugin.c
2820 + * Description: Interface to the OLSRD plugin system
2821 + * Created : 29 Jun 2006
2822 + *
2823 + * $Id$
2824 + *
2825 + * $Log$
2826 + * ------------------------------------------------------------------------- */
2827 +
2828 +/* System includes */
2829 +#include <assert.h> /* assert() */
2830 +#include <stdio.h>
2831 +
2832 +/* OLSRD includes */
2833 +#include "olsrd_plugin.h"
2834 +#include "defs.h" /* olsr_u8_t, olsr_cnf */
2835 +#include "scheduler.h" /* olsr_register_scheduler_event */
2836 +
2837 +/* BMF includes */
2838 +#include "Bmf.h" /* InitBmf(), CloseBmf(), RegisterBmfParameter() */
2839 +#include "PacketHistory.h" /* InitPacketHistory() */
2840 +
2841 +static void __attribute__ ((constructor)) my_init(void);
2842 +static void __attribute__ ((destructor)) my_fini(void);
2843 +
2844 +void olsr_plugin_exit(void);
2845 +
2846 +/* -------------------------------------------------------------------------
2847 + * Function : olsrd_plugin_interface_version
2848 + * Description: Plugin interface version
2849 + * Input : none
2850 + * Output : none
2851 + * Return : BMF plugin interface version number
2852 + * Data Used : none
2853 + * Notes : Called by main OLSRD (olsr_load_dl) to check plugin interface
2854 + * version
2855 + * ------------------------------------------------------------------------- */
2856 +int olsrd_plugin_interface_version()
2857 +{
2858 + return OLSRD_PLUGIN_INTERFACE_VERSION;
2859 +}
2860 +
2861 +/* -------------------------------------------------------------------------
2862 + * Function : olsrd_plugin_init
2863 + * Description: Plugin initialisation
2864 + * Input : none
2865 + * Output : none
2866 + * Return : fail (0) or success (1)
2867 + * Data Used : olsr_cnf
2868 + * Notes : Called by main OLSRD (init_olsr_plugin) to initialize plugin
2869 + * ------------------------------------------------------------------------- */
2870 +int olsrd_plugin_init()
2871 +{
2872 + /* Check validity */
2873 + if (olsr_cnf->ip_version != AF_INET)
2874 + {
2875 + fprintf(stderr, PLUGIN_NAME ": This plugin only supports IPv4!\n");
2876 + return 0;
2877 + }
2878 +
2879 + /* Clear the packet history */
2880 + InitPacketHistory();
2881 +
2882 + /* Register ifchange function */
2883 + add_ifchgf(&InterfaceChange);
2884 +
2885 + /* Register the duplicate registration pruning process */
2886 + olsr_register_scheduler_event(&PrunePacketHistory, NULL, 3.0, 2.0, NULL);
2887 +
2888 + return InitBmf(NULL);
2889 +}
2890 +
2891 +/* -------------------------------------------------------------------------
2892 + * Function : olsr_plugin_exit
2893 + * Description: Plugin cleanup
2894 + * Input : none
2895 + * Output : none
2896 + * Return : none
2897 + * Data Used : none
2898 + * Notes : Called by my_fini() at unload of shared object
2899 + * ------------------------------------------------------------------------- */
2900 +void olsr_plugin_exit()
2901 +{
2902 + CloseBmf();
2903 +}
2904 +
2905 +/* -------------------------------------------------------------------------
2906 + * Function : olsrd_plugin_register_param
2907 + * Description: Register parameters from config file
2908 + * Input : key - the parameter name
2909 + * value - the parameter value
2910 + * Output : none
2911 + * Return : fatal error (<0), minor error (0) or success (>0)
2912 + * Data Used : none
2913 + * Notes : Called by main OLSR (init_olsr_plugin) for all plugin parameters
2914 + * ------------------------------------------------------------------------- */
2915 +int olsrd_plugin_register_param(char* key, char* value)
2916 +{
2917 + assert(key != NULL && value != NULL);
2918 +
2919 + return RegisterBmfParameter(key, value);
2920 +}
2921 +
2922 +/* -------------------------------------------------------------------------
2923 + * Function : my_init
2924 + * Description: Plugin constructor
2925 + * Input : none
2926 + * Output : none
2927 + * Return : none
2928 + * Data Used : none
2929 + * Notes : Called at load of shared object
2930 + * ------------------------------------------------------------------------- */
2931 +static void my_init()
2932 +{
2933 + /* Print plugin info to stdout */
2934 + printf("%s\n", MOD_DESC);
2935 +
2936 + return;
2937 +}
2938 +
2939 +/* -------------------------------------------------------------------------
2940 + * Function : my_fini
2941 + * Description: Plugin destructor
2942 + * Input : none
2943 + * Output : none
2944 + * Return : none
2945 + * Data Used : none
2946 + * Notes : Called at unload of shared object
2947 + * ------------------------------------------------------------------------- */
2948 +static void my_fini()
2949 +{
2950 + olsr_plugin_exit();
2951 +}
2952 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.c olsrd-0.4.10/lib/bmf/src/Packet.c
2953 --- olsrd-0.4.10.orig/lib/bmf/src/Packet.c 1970-01-01 01:00:00.000000000 +0100
2954 +++ olsrd-0.4.10/lib/bmf/src/Packet.c 2006-12-01 08:26:58.000000000 +0100
2955 @@ -0,0 +1,133 @@
2956 +/*
2957 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2958 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
2959 + * Written by Erik Tromp.
2960 + * All rights reserved.
2961 + *
2962 + * Redistribution and use in source and binary forms, with or without
2963 + * modification, are permitted provided that the following conditions
2964 + * are met:
2965 + *
2966 + * * Redistributions of source code must retain the above copyright
2967 + * notice, this list of conditions and the following disclaimer.
2968 + * * Redistributions in binary form must reproduce the above copyright
2969 + * notice, this list of conditions and the following disclaimer in
2970 + * the documentation and/or other materials provided with the
2971 + * distribution.
2972 + * * Neither the name of Thales, BMF nor the names of its
2973 + * contributors may be used to endorse or promote products derived
2974 + * from this software without specific prior written permission.
2975 + *
2976 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2977 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2978 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2979 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2980 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2981 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2982 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2983 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2984 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2985 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2986 + */
2987 +
2988 +/* -------------------------------------------------------------------------
2989 + * File : Packet.c
2990 + * Description: BMF and IP packet processing functions
2991 + * Created : 29 Jun 2006
2992 + *
2993 + * $Id$
2994 + *
2995 + * $Log$
2996 + * ------------------------------------------------------------------------- */
2997 +
2998 +#include "Packet.h"
2999 +
3000 +/* System includes */
3001 +#include <assert.h> /* assert() */
3002 +#include <sys/types.h> /* u_int32_t */
3003 +#include <netinet/in.h> /* ntohs(), htons() */
3004 +#include <linux/ip.h>
3005 +
3006 +/* -------------------------------------------------------------------------
3007 + * Function : GetIpTtl
3008 + * Description: Retrieve the TTL (Time To Live) value from the IP header of
3009 + * the passed ethernet-IP packet
3010 + * Input : buffer - the ethernet-IP packet
3011 + * Output : none
3012 + * Return : TTL value
3013 + * Data Used : none
3014 + * ------------------------------------------------------------------------- */
3015 +int GetIpTtl(unsigned char* buffer)
3016 +{
3017 + struct iphdr* iph;
3018 +
3019 + assert(buffer != NULL);
3020 +
3021 + iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
3022 + return iph->ttl;
3023 +}
3024 +
3025 +/* -------------------------------------------------------------------------
3026 + * Function : SaveTtlAndChecksum
3027 + * Description: Save the TTL (Time To Live) value and IP checksum as found in
3028 + * the IP header of the passed ethernet-IP packet
3029 + * Input : buffer - the ethernet-IP packet
3030 + * Output : sttl - the TTL and checksum values
3031 + * Return : none
3032 + * Data Used : none
3033 + * ------------------------------------------------------------------------- */
3034 +void SaveTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl)
3035 +{
3036 + struct iphdr* iph;
3037 +
3038 + assert(buffer != NULL && sttl != NULL);
3039 +
3040 + iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
3041 + sttl->ttl = iph->ttl;
3042 + sttl->check = ntohs(iph->check);
3043 +}
3044 +
3045 +/* -------------------------------------------------------------------------
3046 + * Function : RestoreTtlAndChecksum
3047 + * Description: Restore the TTL (Time To Live) value and IP checksum in
3048 + * the IP header of the passed ethernet-IP packet
3049 + * Input : buffer - the ethernet-IP packet
3050 + * sttl - the TTL and checksum values
3051 + * Output : none
3052 + * Return : none
3053 + * Data Used : none
3054 + * ------------------------------------------------------------------------- */
3055 +void RestoreTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl)
3056 +{
3057 + struct iphdr* iph;
3058 +
3059 + assert(buffer != NULL && sttl != NULL);
3060 +
3061 + iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
3062 + iph->ttl = sttl->ttl;
3063 + iph->check = htons(sttl->check);
3064 +}
3065 +
3066 +/* -------------------------------------------------------------------------
3067 + * Function : DecreaseTtlAndUpdateHeaderChecksum
3068 + * Description: For an IP packet, decrement the TTL value and update the IP header
3069 + * checksum accordingly.
3070 + * Input : buffer - the ethernet-IP packet
3071 + * Output : none
3072 + * Return : none
3073 + * Data Used : none
3074 + * Notes : See also RFC1141
3075 + * ------------------------------------------------------------------------- */
3076 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* buffer)
3077 +{
3078 + struct iphdr* iph;
3079 + u_int32_t sum;
3080 +
3081 + assert(buffer != NULL);
3082 +
3083 + iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
3084 +
3085 + iph->ttl--; /* decrement ttl */
3086 + sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
3087 + iph->check = htons(sum + (sum>>16)); /* add carry */
3088 +}
3089 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.h olsrd-0.4.10/lib/bmf/src/Packet.h
3090 --- olsrd-0.4.10.orig/lib/bmf/src/Packet.h 1970-01-01 01:00:00.000000000 +0100
3091 +++ olsrd-0.4.10/lib/bmf/src/Packet.h 2006-12-01 08:26:58.000000000 +0100
3092 @@ -0,0 +1,85 @@
3093 +#ifndef _BMF_PACKET_H
3094 +#define _BMF_PACKET_H
3095 +
3096 +/*
3097 + * OLSR Basic Multicast Forwarding (BMF) plugin.
3098 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
3099 + * Written by Erik Tromp.
3100 + * All rights reserved.
3101 + *
3102 + * Redistribution and use in source and binary forms, with or without
3103 + * modification, are permitted provided that the following conditions
3104 + * are met:
3105 + *
3106 + * * Redistributions of source code must retain the above copyright
3107 + * notice, this list of conditions and the following disclaimer.
3108 + * * Redistributions in binary form must reproduce the above copyright
3109 + * notice, this list of conditions and the following disclaimer in
3110 + * the documentation and/or other materials provided with the
3111 + * distribution.
3112 + * * Neither the name of Thales, BMF nor the names of its
3113 + * contributors may be used to endorse or promote products derived
3114 + * from this software without specific prior written permission.
3115 + *
3116 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3117 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3118 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3119 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
3120 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
3121 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3122 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
3123 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
3124 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
3125 + * OF THE POSSIBILITY OF SUCH DAMAGE.
3126 + */
3127 +
3128 +/* -------------------------------------------------------------------------
3129 + * File : Packet.h
3130 + * Description: BMF and IP packet processing functions
3131 + * Created : 29 Jun 2006
3132 + *
3133 + * $Id$
3134 + *
3135 + * $Log$
3136 + * ------------------------------------------------------------------------- */
3137 +
3138 +/* System includes */
3139 +#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
3140 +#include <sys/types.h> /* u_int8_t, u_int16_t */
3141 +
3142 +/* Offsets and sizes into IP-ethernet packets */
3143 +#define IPV4_ADDR_SIZE 4
3144 +#define ETH_TYPE_OFFSET (2*IFHWADDRLEN)
3145 +#define ETH_TYPE_LEN 2
3146 +#define IP_HDR_OFFSET (ETH_TYPE_OFFSET + ETH_TYPE_LEN)
3147 +#define IPV4_OFFSET_SRCIP 12
3148 +#define IPV4_OFFSET_DSTIP (IPV4_OFFSET_SRCIP + IPV4_ADDR_SIZE)
3149 +
3150 +#define IPV4_TYPE 0x0800
3151 +
3152 +/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
3153 + * with a 16-bytes BMF header (struct TEncapHeader), followed by the
3154 + * encapsulated Ethernet-IP packet itself */
3155 +
3156 +struct TEncapHeader
3157 +{
3158 + u_int32_t crc32;
3159 + u_int32_t futureExpansion1;
3160 + u_int32_t futureExpansion2;
3161 + u_int32_t futureExpansion3;
3162 +} __attribute__((__packed__));
3163 +
3164 +#define ENCAP_HDR_LEN sizeof(struct TEncapHeader)
3165 +
3166 +struct TSaveTtl
3167 +{
3168 + u_int8_t ttl;
3169 + u_int16_t check;
3170 +} __attribute__((__packed__));
3171 +
3172 +int GetIpTtl(unsigned char* buffer);
3173 +void SaveTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl);
3174 +void RestoreTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl);
3175 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* buffer);
3176 +
3177 +#endif /* _BMF_PACKET_H */
3178 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.c olsrd-0.4.10/lib/bmf/src/PacketHistory.c
3179 --- olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.c 1970-01-01 01:00:00.000000000 +0100
3180 +++ olsrd-0.4.10/lib/bmf/src/PacketHistory.c 2006-12-01 08:26:58.000000000 +0100
3181 @@ -0,0 +1,293 @@
3182 +/*
3183 + * OLSR Basic Multicast Forwarding (BMF) plugin.
3184 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
3185 + * Written by Erik Tromp.
3186 + * All rights reserved.
3187 + *
3188 + * Redistribution and use in source and binary forms, with or without
3189 + * modification, are permitted provided that the following conditions
3190 + * are met:
3191 + *
3192 + * * Redistributions of source code must retain the above copyright
3193 + * notice, this list of conditions and the following disclaimer.
3194 + * * Redistributions in binary form must reproduce the above copyright
3195 + * notice, this list of conditions and the following disclaimer in
3196 + * the documentation and/or other materials provided with the
3197 + * distribution.
3198 + * * Neither the name of Thales, BMF nor the names of its
3199 + * contributors may be used to endorse or promote products derived
3200 + * from this software without specific prior written permission.
3201 + *
3202 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3203 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3204 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3205 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
3206 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
3207 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3208 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
3209 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
3210 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
3211 + * OF THE POSSIBILITY OF SUCH DAMAGE.
3212 + */
3213 +
3214 +/* -------------------------------------------------------------------------
3215 + * File : PacketHistory.c
3216 + * Description: Functions for keeping and accessing the history of processed
3217 + * multicast IP packets.
3218 + * Created : 29 Jun 2006
3219 + *
3220 + * $Id$
3221 + *
3222 + * $Log$
3223 + * ------------------------------------------------------------------------- */
3224 +
3225 +#include "PacketHistory.h"
3226 +
3227 +/* System includes */
3228 +#include <assert.h> /* assert() */
3229 +#include <sys/types.h> /* u_int16_t, u_int32_t */
3230 +#include <string.h> /* memset */
3231 +
3232 +/* OLSRD includes */
3233 +#include "olsr.h" /* olsr_printf */
3234 +
3235 +/* Plugin includes */
3236 +#include "Packet.h"
3237 +
3238 +static u_int32_t PacketHistory[HISTORY_TABLE_SIZE];
3239 +
3240 +#define CRC_UPTO_NBYTES 256
3241 +
3242 +/* -------------------------------------------------------------------------
3243 + * Function : CalcCrcCcitt
3244 + * Description: Calculate 16-bits CRC according to CRC-CCITT specification
3245 + * Input : buffer - the bytes to calculate the CRC value over
3246 + * len - the number of bytes to calculate the CRC value over
3247 + * Output : none
3248 + * Return : CRC-16 value
3249 + * Data Used : none
3250 + * ------------------------------------------------------------------------- */
3251 +static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)
3252 +{
3253 + /* Initial value of 0xFFFF should be 0x1D0F according to
3254 + * www.joegeluso.com/software/articles/ccitt.htm */
3255 + u_int16_t crc = 0xFFFF;
3256 + int i;
3257 +
3258 + assert(buffer != NULL);
3259 +
3260 + for (i = 0; i < len; i++)
3261 + {
3262 + crc = (unsigned char)(crc >> 8) | (crc << 8);
3263 + crc ^= buffer[i];
3264 + crc ^= (unsigned char)(crc & 0xff) >> 4;
3265 + crc ^= (crc << 8) << 4;
3266 + crc ^= ((crc & 0xff) << 4) << 1;
3267 + }
3268 + return crc;
3269 +}
3270 +
3271 +
3272 +/* -------------------------------------------------------------------------
3273 + * Function : GenerateCrc32Table
3274 + * Description: Generate the table of CRC remainders for all possible bytes,
3275 + * according to CRC-32-IEEE 802.3
3276 + * Input : none
3277 + * Output : none
3278 + * Return : none
3279 + * Data Used : none
3280 + * ------------------------------------------------------------------------- */
3281 +#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */
3282 +
3283 +static unsigned long CrcTable[256];
3284 +
3285 +static void GenerateCrc32Table(void)
3286 +{
3287 + int i, j;
3288 + u_int32_t crc;
3289 + for (i = 0; i < 256; i++)
3290 + {
3291 + crc = (u_int32_t) i;
3292 + for (j = 0; j < 8; j++)
3293 + {
3294 + if (crc & 1)
3295 + {
3296 + crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
3297 + }
3298 + else
3299 + {
3300 + crc = (crc >> 1);
3301 + }
3302 + }
3303 + CrcTable[i] = crc;
3304 + }
3305 +}
3306 +
3307 +/* -------------------------------------------------------------------------
3308 + * Function : CalcCrc32
3309 + * Description: Calculate CRC-32 according to CRC-32-IEEE 802.3
3310 + * Input : buffer - the bytes to calculate the CRC value over
3311 + * len - the number of bytes to calculate the CRC value over
3312 + * Output : none
3313 + * Return : CRC-32 value
3314 + * Data Used : none
3315 + * ------------------------------------------------------------------------- */
3316 +static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)
3317 +{
3318 + int i, j;
3319 + u_int32_t crc = 0xffffffffUL;
3320 + for (i = 0; i < len; i++)
3321 + {
3322 + /* Skip IP header checksum; we want to avoid as much as possible
3323 + * calculating a checksum over data containing a checksum */
3324 + // if (i >= 12 && i < 14) continue;
3325 +
3326 + j = ((int) (crc & 0xFF) ^ *buffer++);
3327 + crc = (crc >> 8) ^ CrcTable[j];
3328 + }
3329 + return crc ^ 0xffffffffUL;
3330 +}
3331 +
3332 +/* */
3333 +/* -------------------------------------------------------------------------
3334 + * Function : PacketCrc32
3335 + * Description: Calculates the CRC-32 value for an Ethernet packet
3336 + * Input : ethPkt - the Ethernet packet
3337 + * len - the number of octets in the Ethernet packet
3338 + * Output : none
3339 + * Return : 32-bits hash value
3340 + * Data Used : none
3341 + * Notes : The source and destination MAC address are not taken into account
3342 + * in the CRC calculation.
3343 + * ------------------------------------------------------------------------- */
3344 +u_int32_t PacketCrc32(unsigned char* ethPkt, ssize_t len)
3345 +{
3346 + assert(ethPkt != NULL);
3347 + assert(len > ETH_TYPE_OFFSET);
3348 +
3349 + /* Start CRC calculation at ethertype; skip source and destination MAC
3350 + * addresses. Clip number of bytes over which CRC is calculated to prevent
3351 + * long packets from possibly claiming too much CPU resources. */
3352 + ssize_t nCrcBytes = len - ETH_TYPE_OFFSET;
3353 + if (nCrcBytes > CRC_UPTO_NBYTES)
3354 + {
3355 + nCrcBytes = CRC_UPTO_NBYTES;
3356 + }
3357 + return CalcCrc32(ethPkt + ETH_TYPE_OFFSET, nCrcBytes);
3358 +}
3359 +
3360 +/* Calculates a 16-bit hash value from a 32-bit hash value */
3361 +u_int16_t Hash16(u_int32_t hash32)
3362 +{
3363 + return ((hash32 >> 16) + hash32) & 0xFFFFU;
3364 +}
3365 +
3366 +/* -------------------------------------------------------------------------
3367 + * Function : InitPacketHistory
3368 + * Description: Initialize the packet history table and CRC-32 table
3369 + * Input : none
3370 + * Output : none
3371 + * Return : none
3372 + * Data Used : PacketHistory
3373 + * ------------------------------------------------------------------------- */
3374 +void InitPacketHistory()
3375 +{
3376 + memset(PacketHistory, 0, sizeof(PacketHistory));
3377 + GenerateCrc32Table();
3378 +}
3379 +
3380 +/* -------------------------------------------------------------------------
3381 + * Function : MarkRecentPacket
3382 + * Description: Record the fact that this packet was seen recently
3383 + * Input : hash16
3384 + * Output : none
3385 + * Return : none
3386 + * Data Used : PacketHistory
3387 + * ------------------------------------------------------------------------- */
3388 +void MarkRecentPacket(u_int16_t hash16)
3389 +{
3390 + u_int32_t index;
3391 + uint offset;
3392 +
3393 + index = hash16 / NPACKETS_PER_ENTRY;
3394 + assert(index < HISTORY_TABLE_SIZE);
3395 +
3396 + offset = (hash16 % NPACKETS_PER_ENTRY) * NBITS_PER_PACKET;
3397 + assert(offset <= NBITS_IN_UINT32 - NBITS_PER_PACKET);
3398 +
3399 + /* Mark as "seen recently" */
3400 + PacketHistory[index] = PacketHistory[index] | (0x3u << offset);
3401 +}
3402 +
3403 +/* -------------------------------------------------------------------------
3404 + * Function : CheckAndMarkRecentPacket
3405 + * Description: Check if this packet was seen recently, then record the fact
3406 + * that this packet was seen recently.
3407 + * Input : hash16
3408 + * Output : none
3409 + * Return : not recently seen (0), recently seen (1)
3410 + * Data Used : PacketHistory
3411 + * ------------------------------------------------------------------------- */
3412 +int CheckAndMarkRecentPacket(u_int16_t hash16)
3413 +{
3414 + u_int32_t index;
3415 + uint offset;
3416 + u_int32_t bitMask;
3417 + int result;
3418 +
3419 + index = hash16 / NPACKETS_PER_ENTRY;
3420 + assert(index < HISTORY_TABLE_SIZE);
3421 +
3422 + offset = (hash16 % NPACKETS_PER_ENTRY) * NBITS_PER_PACKET;
3423 + assert(offset <= NBITS_IN_UINT32 - NBITS_PER_PACKET);
3424 +
3425 + bitMask = 0x1u << offset;
3426 + result = ((PacketHistory[index] & bitMask) == bitMask);
3427 +
3428 + /* Always mark as "seen recently" */
3429 + PacketHistory[index] = PacketHistory[index] | (0x3u << offset);
3430 +
3431 + return result;
3432 +}
3433 +
3434 +/* -------------------------------------------------------------------------
3435 + * Function : PrunePacketHistory
3436 + * Description: Prune the packet history table.
3437 + * Input : useless - not used
3438 + * Output : none
3439 + * Return : none
3440 + * Data Used : PacketHistory
3441 + * ------------------------------------------------------------------------- */
3442 +void PrunePacketHistory(void* useless)
3443 +{
3444 + uint i;
3445 + for (i = 0; i < HISTORY_TABLE_SIZE; i++)
3446 + {
3447 + if (PacketHistory[i] > 0)
3448 + {
3449 + uint j;
3450 + for (j = 0; j < NPACKETS_PER_ENTRY; j++)
3451 + {
3452 + uint offset = j * NBITS_PER_PACKET;
3453 +
3454 + u_int32_t bitMask = 0x3u << offset;
3455 + u_int32_t bitsSeenRecenty = 0x3u << offset;
3456 + u_int32_t bitsTimingOut = 0x1u << offset;
3457 +
3458 + /* 10 should never occur */
3459 + assert ((PacketHistory[i] & bitMask) != (0x2u << offset));
3460 +
3461 + if ((PacketHistory[i] & bitMask) == bitsSeenRecenty)
3462 + {
3463 + /* 11 -> 01 */
3464 + PacketHistory[i] &= ~bitMask | bitsTimingOut;
3465 + }
3466 + else if ((PacketHistory[i] & bitMask) == bitsTimingOut)
3467 + {
3468 + /* 01 -> 00 */
3469 + PacketHistory[i] &= ~bitMask;
3470 + }
3471 + } /* for (j = ...) */
3472 + } /* if (PacketHistory[i] > 0) */
3473 + } /* for (i = ...) */
3474 +}
3475 diff -Nur olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.h olsrd-0.4.10/lib/bmf/src/PacketHistory.h
3476 --- olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.h 1970-01-01 01:00:00.000000000 +0100
3477 +++ olsrd-0.4.10/lib/bmf/src/PacketHistory.h 2006-12-01 08:26:58.000000000 +0100
3478 @@ -0,0 +1,67 @@
3479 +#ifndef _BMF_PACKETHISTORY_H
3480 +#define _BMF_PACKETHISTORY_H
3481 +
3482 +/*
3483 + * OLSR Basic Multicast Forwarding (BMF) plugin.
3484 + * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
3485 + * Written by Erik Tromp.
3486 + * All rights reserved.
3487 + *
3488 + * Redistribution and use in source and binary forms, with or without
3489 + * modification, are permitted provided that the following conditions
3490 + * are met:
3491 + *
3492 + * * Redistributions of source code must retain the above copyright
3493 + * notice, this list of conditions and the following disclaimer.
3494 + * * Redistributions in binary form must reproduce the above copyright
3495 + * notice, this list of conditions and the following disclaimer in
3496 + * the documentation and/or other materials provided with the
3497 + * distribution.
3498 + * * Neither the name of Thales, BMF nor the names of its
3499 + * contributors may be used to endorse or promote products derived
3500 + * from this software without specific prior written permission.
3501 + *
3502 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3503 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3504 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3505 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
3506 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
3507 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3508 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
3509 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
3510 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
3511 + * OF THE POSSIBILITY OF SUCH DAMAGE.
3512 + */
3513 +
3514 +/* -------------------------------------------------------------------------
3515 + * File : PacketHistory.h
3516 + * Description: Functions for keeping and accessing the history of processed
3517 + * multicast IP packets.
3518 + * Created : 29 Jun 2006
3519 + *
3520 + * $Id$
3521 + *
3522 + * $Log$
3523 + * ------------------------------------------------------------------------- */
3524 +
3525 +#include <sys/types.h> /* ssize_t */
3526 +
3527 +/* 2 bits per seen packet:
3528 + * 11 = "seen recently",
3529 + * 01 = "timing out"
3530 + * 00 = "not seen recently"
3531 + * Note that 10 is unused */
3532 +#define NBITS_PER_PACKET 2
3533 +#define NBITS_IN_UINT16 (sizeof(u_int16_t) * 8)
3534 +#define NBITS_IN_UINT32 (sizeof(u_int32_t) * 8)
3535 +#define NPACKETS_PER_ENTRY (NBITS_IN_UINT32 / NBITS_PER_PACKET)
3536 +#define HISTORY_TABLE_SIZE ((1 << NBITS_IN_UINT16) / NPACKETS_PER_ENTRY)
3537 +
3538 +void InitPacketHistory(void);
3539 +u_int32_t PacketCrc32(unsigned char* ethPkt, ssize_t len);
3540 +u_int16_t Hash16(u_int32_t hash32);
3541 +void MarkRecentPacket(u_int16_t hash16);
3542 +int CheckAndMarkRecentPacket(u_int16_t hash16);
3543 +void PrunePacketHistory(void*);
3544 +
3545 +#endif /* _BMF_PACKETHISTORY_H */
3546 diff -Nur olsrd-0.4.10.orig/lib/bmf/version-script.txt olsrd-0.4.10/lib/bmf/version-script.txt
3547 --- olsrd-0.4.10.orig/lib/bmf/version-script.txt 1970-01-01 01:00:00.000000000 +0100
3548 +++ olsrd-0.4.10/lib/bmf/version-script.txt 2006-12-01 08:26:58.000000000 +0100
3549 @@ -0,0 +1,10 @@
3550 +VERS_1.0
3551 +{
3552 + global:
3553 + olsrd_plugin_interface_version;
3554 + olsrd_plugin_register_param;
3555 + olsrd_plugin_init;
3556 +
3557 + local:
3558 + *;
3559 +};
3560 diff -Nur olsrd-0.4.10.orig/Makefile olsrd-0.4.10/Makefile
3561 --- olsrd-0.4.10.orig/Makefile 2006-12-01 08:26:58.000000000 +0100
3562 +++ olsrd-0.4.10/Makefile 2006-12-01 08:26:58.000000000 +0100
3563 @@ -164,5 +164,10 @@
3564 $(MAKE) -C lib/pgraph
3565 $(MAKE) -C lib/pgraph install
3566
3567 +bmf:
3568 + $(MAKE) -C lib/bmf clean
3569 + $(MAKE) -C lib/bmf
3570 + $(MAKE) -C lib/bmf install
3571 +
3572 build_all: cfgparser olsrd libs
3573 install_all: install install_libs