4 # nameservice: no regex
5 SUBDIRS := bmf dot_draw dyn_gw_plain httpinfo mini quagga secure tas txtinfo watchdog
7 -SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo mini nameservice pgraph secure txtinfo watchdog
8 +SUBDIRS := bmf dot_draw dyn_gw dyn_gw_plain httpinfo mini nameservice pgraph secure txtinfo watchdog mdns
13 $(MAKECMD) -C lib/watchdog
14 $(MAKECMD) -C lib/watchdog DESTDIR=$(DESTDIR) install
17 + $(MAKECMD) -C lib/mdns clean
18 + $(MAKECMD) -C lib/mdns
19 + $(MAKECMD) -C lib/mdns DESTDIR=$(DESTDIR) install
21 build_all: all switch libs
22 install_all: install install_libs
23 clean_all: uberclean clean_libs
25 +++ b/lib/mdns/Makefile
28 +# OLSR Basic Multicast Forwarding (BMF) plugin.
29 +# Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
30 +# Written by Erik Tromp.
31 +# All rights reserved.
33 +# Redistribution and use in source and binary forms, with or without
34 +# modification, are permitted provided that the following conditions
37 +# * Redistributions of source code must retain the above copyright
38 +# notice, this list of conditions and the following disclaimer.
39 +# * Redistributions in binary form must reproduce the above copyright
40 +# notice, this list of conditions and the following disclaimer in
41 +# the documentation and/or other materials provided with the
43 +# * Neither the name of Thales, BMF nor the names of its
44 +# contributors may be used to endorse or promote products derived
45 +# from this software without specific prior written permission.
47 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
50 +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
51 +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
52 +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
53 +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
55 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
57 +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58 +# POSSIBILITY OF SUCH DAMAGE.
62 +PLUGIN_NAME = olsrd_mdns
66 +include $(TOPDIR)/Makefile.inc
68 +LIBS += $(OS_LIB_PTHREAD)
70 +# Must be specified along with -lpthread on linux
71 +CPPFLAGS += $(OS_CFLAG_PTHREAD)
75 +default_target install clean:
76 + @echo "*** BMF Plugin only supported on Linux, sorry!"
80 +default_target: $(PLUGIN_FULLNAME)
82 +$(PLUGIN_FULLNAME): $(OBJS) version-script.txt
83 + $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
85 +install: $(PLUGIN_FULLNAME)
86 + $(STRIP) $(PLUGIN_FULLNAME)
90 + rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
94 +++ b/lib/mdns/src/Address.c
97 + * OLSR Basic Multicast Forwarding (BMF) plugin.
98 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
99 + * Written by Erik Tromp.
100 + * All rights reserved.
102 + * Redistribution and use in source and binary forms, with or without
103 + * modification, are permitted provided that the following conditions
106 + * * Redistributions of source code must retain the above copyright
107 + * notice, this list of conditions and the following disclaimer.
108 + * * Redistributions in binary form must reproduce the above copyright
109 + * notice, this list of conditions and the following disclaimer in
110 + * the documentation and/or other materials provided with the
112 + * * Neither the name of Thales, BMF nor the names of its
113 + * contributors may be used to endorse or promote products derived
114 + * from this software without specific prior written permission.
116 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
117 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
119 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
120 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
121 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
122 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
123 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
124 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
125 + * OF THE POSSIBILITY OF SUCH DAMAGE.
128 +/* -------------------------------------------------------------------------
130 + * Description: IP packet characterization functions
131 + * Created : 29 Jun 2006
133 + * ------------------------------------------------------------------------- */
135 +#include "Address.h"
137 +/* System includes */
138 +#include <stddef.h> /* NULL */
139 +#include <string.h> /* strcmp */
140 +#include <assert.h> /* assert() */
141 +#include <netinet/ip.h> /* struct ip */
142 +#include <netinet/udp.h> /* struct udphdr */
144 +/* OLSRD includes */
145 +#include "defs.h" /* ipequal */
146 +#include "olsr_protocol.h" /* OLSRPORT */
148 +/* Plugin includes */
149 +#include "mdns.h" /* BMF_ENCAP_PORT */
150 +#include "NetworkInterfaces.h" /* TBmfInterface */
152 +/* Whether or not to flood local broadcast packets (e.g. packets with IP
153 + * destination 192.168.1.255). May be overruled by setting the plugin
154 + * parameter "DoLocalBroadcast" to "no" */
155 +int EnableLocalBroadcast = 1;
157 +/* -------------------------------------------------------------------------
158 + * Function : DoLocalBroadcast
159 + * Description: Overrule the default setting, enabling or disabling the
160 + * flooding of local broadcast packets
161 + * Input : enable - either "yes" or "no"
165 + * Return : success (0) or fail (1)
167 + * ------------------------------------------------------------------------- */
168 +int DoLocalBroadcast(
169 + const char* enable,
170 + void* data __attribute__((unused)),
171 + set_plugin_parameter_addon addon __attribute__((unused)))
173 + if (strcmp(enable, "yes") == 0)
175 + EnableLocalBroadcast = 1;
178 + else if (strcmp(enable, "no") == 0)
180 + EnableLocalBroadcast = 0;
184 + /* Value not recognized */
188 +/* -------------------------------------------------------------------------
189 + * Function : IsMulticast
190 + * Description: Check if an IP address is a multicast address
191 + * Input : ipAddress
193 + * Return : true (1) or false (0)
195 + * ------------------------------------------------------------------------- */
196 +int IsMulticast(union olsr_ip_addr* ipAddress)
198 + assert(ipAddress != NULL);
200 + return (ntohl(ipAddress->v4.s_addr) & 0xF0000000) == 0xE0000000;
203 +/* -------------------------------------------------------------------------
204 + * Function : IsOlsrOrBmfPacket
205 + * Description: Check if an IP packet is either an OLSR packet or a BMF packet
208 + * Return : true (1) or false (0)
210 + * ------------------------------------------------------------------------- */
211 +//int IsOlsrOrBmfPacket(unsigned char* ipPacket)
213 +// struct ip* ipHeader;
214 +// unsigned int ipHeaderLen;
215 +// struct udphdr* udpHeader;
216 +// u_int16_t destPort;
218 +// assert(ipPacket != NULL);
220 +// /* OLSR packets are UDP - port 698
221 +// * OLSR-BMF packets are UDP - port 50698
222 +// * OLSR-Autodetect probe packets are UDP - port 51698 */
224 +// /* Check if UDP */
225 +// ipHeader = (struct ip*) ipPacket;
226 +// if (ipHeader->ip_p != SOL_UDP)
232 +// /* The total length must be at least large enough to store the UDP header */
233 +// ipHeaderLen = GetIpHeaderLength(ipPacket);
234 +// if (GetIpTotalLength(ipPacket) < ipHeaderLen + sizeof(struct udphdr))
236 +// /* Not long enough */
240 +// /* Go into the UDP header and check port number */
241 +// udpHeader = (struct udphdr*) (ipPacket + ipHeaderLen);
242 +// destPort = ntohs(udpHeader->dest);
244 +// //if (destPort == OLSRPORT || destPort == BMF_ENCAP_PORT || destPort == 51698)
245 +// if (destPort == 5353)
246 +// /* TODO: #define for 51698 */
256 + * c-basic-offset: 2
257 + * indent-tabs-mode: nil
261 +++ b/lib/mdns/src/Address.h
263 +#ifndef _BMF_ADDRESS_H
264 +#define _BMF_ADDRESS_H
267 + * OLSR Basic Multicast Forwarding (BMF) plugin.
268 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
269 + * Written by Erik Tromp.
270 + * All rights reserved.
272 + * Redistribution and use in source and binary forms, with or without
273 + * modification, are permitted provided that the following conditions
276 + * * Redistributions of source code must retain the above copyright
277 + * notice, this list of conditions and the following disclaimer.
278 + * * Redistributions in binary form must reproduce the above copyright
279 + * notice, this list of conditions and the following disclaimer in
280 + * the documentation and/or other materials provided with the
282 + * * Neither the name of Thales, BMF nor the names of its
283 + * contributors may be used to endorse or promote products derived
284 + * from this software without specific prior written permission.
286 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
287 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
288 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
289 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
290 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
291 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
292 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
293 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
294 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
295 + * OF THE POSSIBILITY OF SUCH DAMAGE.
298 +/* -------------------------------------------------------------------------
300 + * Description: IP packet characterization functions
301 + * Created : 29 Jun 2006
303 + * ------------------------------------------------------------------------- */
305 +#include "olsr_types.h" /* olsr_ip_addr */
306 +#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
307 +#include "interfaces.h" /* struct interface */
309 +struct TBmfInterface;
311 +extern int EnableLocalBroadcast;
313 +int DoLocalBroadcast(const char* enable, void* data, set_plugin_parameter_addon addon);
314 +int IsMulticast(union olsr_ip_addr* ipAddress);
315 +int IsOlsrOrBmfPacket(unsigned char* ipPacket);
317 +#endif /* _BMF_ADDRESS_H */
321 + * c-basic-offset: 2
322 + * indent-tabs-mode: nil
326 +++ b/lib/mdns/src/NetworkInterfaces.c
329 + * OLSR Basic Multicast Forwarding (BMF) plugin.
330 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
331 + * Written by Erik Tromp.
332 + * All rights reserved.
334 + * Redistribution and use in source and binary forms, with or without
335 + * modification, are permitted provided that the following conditions
338 + * * Redistributions of source code must retain the above copyright
339 + * notice, this list of conditions and the following disclaimer.
340 + * * Redistributions in binary form must reproduce the above copyright
341 + * notice, this list of conditions and the following disclaimer in
342 + * the documentation and/or other materials provided with the
344 + * * Neither the name of Thales, BMF nor the names of its
345 + * contributors may be used to endorse or promote products derived
346 + * from this software without specific prior written permission.
348 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
349 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
350 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
351 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
352 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
353 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
354 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
355 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
356 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
357 + * OF THE POSSIBILITY OF SUCH DAMAGE.
360 +/* -------------------------------------------------------------------------
361 + * File : NetworkInterfaces.c
362 + * Description: Functions to open and close sockets
363 + * Created : 29 Jun 2006
365 + * ------------------------------------------------------------------------- */
367 +#include "NetworkInterfaces.h"
369 +/* System includes */
370 +#include <stddef.h> /* NULL */
371 +#include <syslog.h> /* syslog() */
372 +#include <string.h> /* strerror(), strchr(), strcmp() */
373 +#include <errno.h> /* errno */
374 +#include <unistd.h> /* close() */
375 +#include <sys/ioctl.h> /* ioctl() */
376 +#include <fcntl.h> /* fcntl() */
377 +#include <assert.h> /* assert() */
378 +#include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
379 +#include <netinet/in.h> /* htons() */
380 +#include <linux/if_ether.h> /* ETH_P_IP */
381 +#include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
382 +#include <linux/if_tun.h> /* IFF_TAP */
383 +#include <netinet/ip.h> /* struct ip */
384 +#include <netinet/udp.h> /* SOL_UDP */
385 +#include <stdlib.h> /* atoi, malloc */
387 +/* OLSRD includes */
388 +#include "olsr.h" /* OLSR_PRINTF() */
390 +#include "defs.h" /* olsr_cnf */
391 +#include "link_set.h" /* get_link_set() */
392 +#include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
393 +#include "net_olsr.h" /* ipequal */
394 +#include "lq_plugin.h"
397 +/* Plugin includes */
398 +#include "Packet.h" /* IFHWADDRLEN */
399 +#include "mdns.h" /* PLUGIN_NAME, MainAddressOf() */
400 +#include "Address.h" /* IsMulticast() */
402 +/* List of network interface objects used by BMF plugin */
403 +struct TBmfInterface* BmfInterfaces = NULL;
404 +struct TBmfInterface* LastBmfInterface = NULL;
406 +/* Highest-numbered open socket file descriptor. To be used as first
407 + * parameter in calls to select(...). */
408 +int HighestSkfd = -1;
410 +/* Set of socket file descriptors */
413 +/* File descriptor of EtherTunTap interface */
414 +int EtherTunTapFd = -1;
416 +/* Network interface name of EtherTunTap interface. May be overruled by
417 + * setting the plugin parameter "BmfInterface". */
418 +char EtherTunTapIfName[IFNAMSIZ] = "bmf0";
420 +/* The underlying mechanism to forward multicast packets. Either:
421 + * - BM_BROADCAST: BMF uses the IP local broadcast as destination address
422 + * - BM_UNICAST_PROMISCUOUS: BMF uses the IP address of the best neighbor as
423 + * destination address. The other neighbors listen promiscuously. */
424 +enum TBmfMechanism BmfMechanism = BM_BROADCAST;
426 +#define ETHERTUNTAPIPNOTSET 0
428 +/* The IP address of the BMF network interface in host byte order.
429 + * May be overruled by setting the plugin parameter "BmfInterfaceIp". */
430 +u_int32_t EtherTunTapIp = ETHERTUNTAPIPNOTSET;
432 +/* 255.255.255.255 in host byte order. May be overruled by
433 + * setting the plugin parameter "BmfInterfaceIp". */
434 +u_int32_t EtherTunTapIpMask = 0xFFFFFFFF;
436 +/* The IP broadcast address of the BMF network interface in host byte order.
437 + * May be overruled by setting the plugin parameter "BmfinterfaceIp". */
438 +u_int32_t EtherTunTapIpBroadcast = ETHERTUNTAPIPNOTSET;
440 +/* Whether or not the configuration has overruled the default IP
441 + * configuration of the EtherTunTap interface */
442 +int TunTapIpOverruled = 0;
444 +/* Whether or not to capture packets on the OLSR-enabled
445 + * interfaces (in promiscuous mode). May be overruled by setting the plugin
446 + * parameter "CapturePacketsOnOlsrInterfaces" to "yes". */
447 +int CapturePacketsOnOlsrInterfaces = 0;
449 +/* -------------------------------------------------------------------------
450 + * Function : SetBmfInterfaceName
451 + * Description: Overrule the default network interface name ("bmf0") of the
452 + * EtherTunTap interface
453 + * Input : ifname - network interface name (e.g. "mybmf0")
457 + * Return : success (0) or fail (1)
458 + * Data Used : EtherTunTapIfName
459 + * ------------------------------------------------------------------------- */
460 +int SetBmfInterfaceName(
461 + const char* ifname,
462 + void* data __attribute__((unused)),
463 + set_plugin_parameter_addon addon __attribute__((unused)))
465 + strncpy(EtherTunTapIfName, ifname, IFNAMSIZ - 1);
466 + EtherTunTapIfName[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
468 +} /* SetBmfInterfaceName */
470 +/* -------------------------------------------------------------------------
471 + * Function : SetBmfInterfaceIp
472 + * Description: Overrule the default IP address and prefix length
473 + * ("10.255.255.253/30") of the EtherTunTap interface
474 + * Input : ip - IP address string, followed by '/' and prefix length
478 + * Return : success (0) or fail (1)
479 + * Data Used : EtherTunTapIp, EtherTunTapIpMask, EtherTunTapIpBroadcast,
480 + * TunTapIpOverruled
481 + * ------------------------------------------------------------------------- */
482 +int SetBmfInterfaceIp(
484 + void* data __attribute__((unused)),
485 + set_plugin_parameter_addon addon __attribute__((unused)))
487 +#define IPV4_MAX_ADDRLEN 16
488 +#define IPV4_MAX_PREFIXLEN 32
490 + char ipAddr[IPV4_MAX_ADDRLEN];
491 + struct in_addr sinaddr;
495 + /* Inspired by function str2prefix_ipv4 as found in Quagga source
496 + * file lib/prefix.c */
498 + /* Find slash inside string. */
499 + slashAt = strchr(ip, '/');
501 + /* String doesn't contain slash. */
502 + if (slashAt == NULL || slashAt - ip >= IPV4_MAX_ADDRLEN)
504 + /* No prefix length specified, or IP address too long */
508 + strncpy(ipAddr, ip, slashAt - ip);
509 + *(ipAddr + (slashAt - ip)) = '\0';
510 + if (inet_aton(ipAddr, &sinaddr) == 0)
512 + /* Invalid address passed */
516 + EtherTunTapIp = ntohl(sinaddr.s_addr);
518 + /* Get prefix length. */
519 + prefixLen = atoi(++slashAt);
520 + if (prefixLen <= 0 || prefixLen > IPV4_MAX_PREFIXLEN)
525 + /* Compose IP subnet mask in host byte order */
526 + EtherTunTapIpMask = 0;
527 + for (i = 0; i < prefixLen; i++)
529 + EtherTunTapIpMask |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
532 + /* Compose IP broadcast address in host byte order */
533 + EtherTunTapIpBroadcast = EtherTunTapIp;
534 + for (i = prefixLen; i < IPV4_MAX_PREFIXLEN; i++)
536 + EtherTunTapIpBroadcast |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
539 + TunTapIpOverruled = 1;
542 +} /* SetBmfInterfaceIp */
544 +/* -------------------------------------------------------------------------
545 + * Function : SetCapturePacketsOnOlsrInterfaces
546 + * Description: Overrule the default setting, enabling or disabling the
547 + * capturing of packets on OLSR-enabled interfaces.
548 + * Input : enable - either "yes" or "no"
552 + * Return : success (0) or fail (1)
554 + * ------------------------------------------------------------------------- */
555 +int SetCapturePacketsOnOlsrInterfaces(
556 + const char* enable,
557 + void* data __attribute__((unused)),
558 + set_plugin_parameter_addon addon __attribute__((unused)))
560 + if (strcmp(enable, "yes") == 0)
562 + CapturePacketsOnOlsrInterfaces = 1;
565 + else if (strcmp(enable, "no") == 0)
567 + CapturePacketsOnOlsrInterfaces = 0;
571 + /* Value not recognized */
573 +} /* SetCapturePacketsOnOlsrInterfaces */
575 +/* -------------------------------------------------------------------------
576 + * Function : SetBmfMechanism
577 + * Description: Overrule the default BMF mechanism to either BM_BROADCAST or
578 + * BM_UNICAST_PROMISCUOUS.
579 + * Input : mechanism - either "Broadcast" or "UnicastPromiscuous"
583 + * Return : success (0) or fail (1)
585 + * ------------------------------------------------------------------------- */
586 +int SetBmfMechanism(
587 + const char* mechanism,
588 + void* data __attribute__((unused)),
589 + set_plugin_parameter_addon addon __attribute__((unused)))
591 + if (strcmp(mechanism, "Broadcast") == 0)
593 + BmfMechanism = BM_BROADCAST;
596 + else if (strcmp(mechanism, "UnicastPromiscuous") == 0)
598 + BmfMechanism = BM_UNICAST_PROMISCUOUS;
602 + /* Value not recognized */
604 +} /* SetBmfMechanism */
606 +/* -------------------------------------------------------------------------
607 + * Function : AddDescriptorToInputSet
608 + * Description: Add a socket descriptor to the global set of socket file descriptors
609 + * Input : skfd - socket file descriptor
612 + * Data Used : HighestSkfd, InputSet
613 + * Notes : Keeps track of the highest-numbered descriptor
614 + * ------------------------------------------------------------------------- */
615 +static void AddDescriptorToInputSet(int skfd)
617 + /* Keep the highest-numbered descriptor */
618 + if (skfd > HighestSkfd)
620 + HighestSkfd = skfd;
623 + /* Add descriptor to input set */
624 + FD_SET(skfd, &InputSet);
625 +} /* AddDescriptorToInputSet */
627 +/* To save the state of the IP spoof filter for the EtherTunTap interface */
628 +static char EthTapSpoofState = '1';
630 +/* -------------------------------------------------------------------------
631 + * Function : DeactivateSpoofFilter
632 + * Description: Deactivates the Linux anti-spoofing filter for the tuntap
636 + * Return : fail (0) or success (1)
637 + * Data Used : EtherTunTapIfName, EthTapSpoofState
638 + * Notes : Saves the current filter state for later restoring
639 + * ------------------------------------------------------------------------- */
640 +int DeactivateSpoofFilter(void)
643 + char procFile[FILENAME_MAX];
645 + /* Generate the procfile name */
646 + sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
648 + /* Open procfile for reading */
649 + procSpoof = fopen(procFile, "r");
650 + if (procSpoof == NULL)
654 + "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
655 + "Are you using the procfile filesystem?\n"
656 + "Does your system support IPv4?\n"
657 + "I will continue (in 3 sec) - but you should manually ensure that IP spoof\n"
658 + "filtering is disabled!\n\n",
665 + EthTapSpoofState = fgetc(procSpoof);
668 + /* Open procfile for writing */
669 + procSpoof = fopen(procFile, "w");
670 + if (procSpoof == NULL)
672 + fprintf(stderr, "Could not open %s for writing!\n", procFile);
675 + "I will continue (in 3 sec) - but you should manually ensure that IP"
676 + " spoof filtering is disabled!\n\n");
681 + syslog(LOG_INFO, "Writing \"0\" to %s", procFile);
682 + fputs("0", procSpoof);
687 +} /* DeactivateSpoofFilter */
689 +/* -------------------------------------------------------------------------
690 + * Function : RestoreSpoofFilter
691 + * Description: Restores the Linux anti-spoofing filter setting for the tuntap
696 + * Data Used : EtherTunTapIfName, EthTapSpoofState
697 + * ------------------------------------------------------------------------- */
698 +void RestoreSpoofFilter(void)
701 + char procFile[FILENAME_MAX];
703 + /* Generate the procfile name */
704 + sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
706 + /* Open procfile for writing */
707 + procSpoof = fopen(procFile, "w");
708 + if (procSpoof == NULL)
710 + fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procFile);
714 + syslog(LOG_INFO, "Resetting %s to %c\n", procFile, EthTapSpoofState);
716 + fputc(EthTapSpoofState, procSpoof);
719 +} /* RestoreSpoofFilter */
721 +/* -------------------------------------------------------------------------
722 + * Function : FindNeighbors
723 + * Description: Find the neighbors on a network interface to forward a BMF
725 + * Input : intf - the network interface
726 + * source - the source IP address of the BMF packet
727 + * forwardedBy - the IP address of the node that forwarded the BMF
729 + * forwardedTo - the IP address of the node to which the BMF packet
731 + * Output : neighbors - list of (up to a number of 'FanOutLimit') neighbors.
732 + * bestNeighbor - the best neighbor (in terms of lowest cost or ETX
734 + * nPossibleNeighbors - number of found possible neighbors
735 + * Data Used : FanOutLimit
736 + * ------------------------------------------------------------------------- */
737 +//void FindNeighbors(
738 +// struct TBestNeighbors* neighbors,
739 +// struct link_entry** bestNeighbor,
740 +// struct TBmfInterface* intf,
741 +// union olsr_ip_addr* source,
742 +// union olsr_ip_addr* forwardedBy,
743 +// union olsr_ip_addr* forwardedTo,
744 +// int* nPossibleNeighbors)
746 +// struct link_entry* walker;
747 +// olsr_linkcost previousLinkEtx = LINK_COST_BROKEN;
748 +// olsr_linkcost bestEtx = LINK_COST_BROKEN;
753 +// *bestNeighbor = NULL;
754 +// for (i = 0; i < MAX_UNICAST_NEIGHBORS; i++)
756 +// neighbors->links[i] = NULL;
758 +// *nPossibleNeighbors = 0;
760 +// if (forwardedBy != NULL)
762 +// /* Retrieve the cost of the link from 'forwardedBy' to myself */
763 +// struct link_entry* bestLinkFromForwarder = get_best_link_to_neighbor(forwardedBy);
764 +// if (bestLinkFromForwarder != NULL)
766 +// previousLinkEtx = bestLinkFromForwarder->linkcost;
770 +// OLSR_FOR_ALL_LINK_ENTRIES(walker) {
771 +// struct ipaddr_str buf;
772 +// union olsr_ip_addr* neighborMainIp;
773 +// struct link_entry* bestLinkToNeighbor;
774 +// struct tc_entry* tcLastHop;
777 +// /* Consider only links from the specified interface */
778 +// if (! olsr_ipequal(&intf->intAddr, &walker->local_iface_addr))
780 +// continue; /* for */
785 +// "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
786 +// PLUGIN_NAME_SHORT,
788 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
790 +// neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
792 +// /* Consider only neighbors with an IP address that differs from the
793 +// * passed IP addresses (if passed). Rely on short-circuit boolean evaluation. */
794 +// if (source != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(source)))
798 +// "%s: ----> Not forwarding to %s: is source of pkt\n",
799 +// PLUGIN_NAME_SHORT,
800 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
802 +// continue; /* for */
805 +// /* Rely on short-circuit boolean evaluation */
806 +// if (forwardedBy != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
810 +// "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
811 +// PLUGIN_NAME_SHORT,
812 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
814 +// continue; /* for */
817 +// /* Rely on short-circuit boolean evaluation */
818 +// if (forwardedTo != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
822 +// "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
823 +// PLUGIN_NAME_SHORT,
824 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
826 +// continue; /* for */
829 +// /* Found a candidate neighbor to direct our packet to */
831 +// /* Calculate the link quality (ETX) of the link to the found neighbor */
832 +// currEtx = walker->linkcost;
834 +// if (currEtx >= LINK_COST_BROKEN)
838 +// "%s: ----> Not forwarding to %s: link is timing out\n",
839 +// PLUGIN_NAME_SHORT,
840 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
842 +// continue; /* for */
845 +// /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
848 +// "%s: ----> Forwarding pkt to %s will cost ETX %5.2f\n",
849 +// PLUGIN_NAME_SHORT,
850 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
854 +// * If the candidate neighbor is best reached via another interface, then skip
855 +// * the candidate neighbor; the candidate neighbor has been / will be selected via that
856 +// * other interface.
858 +// bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
860 +// if (walker != bestLinkToNeighbor)
862 +// if (bestLinkToNeighbor == NULL)
866 +// "%s: ----> Not forwarding to %s: no link found\n",
867 +// PLUGIN_NAME_SHORT,
868 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
873 +// struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
874 +// struct lqtextbuffer lqbuffer;
878 +// "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
879 +// PLUGIN_NAME_SHORT,
880 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
881 +// bestIntf->int_name,
882 +// get_linkcost_text(bestLinkToNeighbor->linkcost, 0, &lqbuffer));
885 +// continue; /* for */
888 +// if (forwardedBy != NULL)
891 +// struct ipaddr_str forwardedByBuf, niaBuf;
892 +// struct lqtextbuffer lqbuffer;
896 +// "%s: ----> 2-hop path from %s via me to %s will cost ETX %s\n",
897 +// PLUGIN_NAME_SHORT,
898 +// olsr_ip_to_string(&forwardedByBuf, forwardedBy),
899 +// olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
900 +// get_linkcost_text(previousLinkEtx + currEtx, 1, &lqbuffer));
903 +// /* Check the topology table whether the 'forwardedBy' node is itself a direct
904 +// * neighbor of the candidate neighbor, at a lower cost than the 2-hop route
905 +// * via myself. If so, we do not need to forward the BMF packet to the candidate
906 +// * neighbor, because the 'forwardedBy' node will forward the packet. */
907 +// if (forwardedBy != NULL)
909 +// tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
910 +// if (tcLastHop != NULL)
912 +// struct tc_edge_entry* tc_edge;
914 +// tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
916 +// /* We are not interested in dead-end edges. */
918 +// olsr_linkcost tcEtx = tc_edge->cost;
920 +// if (previousLinkEtx + currEtx > tcEtx)
923 +// struct ipaddr_str neighbor_iface_buf, forw_buf;
924 +// struct lqtextbuffer lqbuffer;
925 +// olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
929 +// "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
930 +// PLUGIN_NAME_SHORT,
931 +// neighbor_iface_buf.buf,
932 +// olsr_ip_to_string(&forw_buf, forwardedBy),
933 +// neighbor_iface_buf.buf,
934 +// get_linkcost_text(tcEtx, 0, &lqbuffer));
936 +// continue; /* for */
942 +// /* Remember the best neighbor. If all are very bad, remember none. */
943 +// if (currEtx < bestEtx)
945 +// *bestNeighbor = walker;
946 +// bestEtx = currEtx;
949 +// /* Fill the list with up to 'FanOutLimit' neighbors. If there
950 +// * are more neighbors, broadcast is used instead of unicast. In that
951 +// * case we do not need the list of neighbors. */
952 +// if (*nPossibleNeighbors < FanOutLimit)
954 +// neighbors->links[*nPossibleNeighbors] = walker;
957 +// *nPossibleNeighbors += 1;
958 +// } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
960 +// /* Display the result of the neighbor search */
961 +// if (*nPossibleNeighbors == 0)
965 +// "%s: ----> No suitable neighbor found to forward to on \"%s\"\n",
966 +// PLUGIN_NAME_SHORT,
971 +// struct ipaddr_str buf;
974 +// "%s: ----> %d neighbors found on \"%s\"; best neighbor to forward to: %s\n",
975 +// PLUGIN_NAME_SHORT,
976 +// *nPossibleNeighbors,
978 +// olsr_ip_to_string(&buf, &(*bestNeighbor)->neighbor_iface_addr));
981 +//} /* FindNeighbors */
983 +/* -------------------------------------------------------------------------
984 + * Function : CreateCaptureSocket
985 + * Description: Create socket for promiscuously capturing multicast IP traffic
986 + * Input : ifname - network interface (e.g. "eth0")
988 + * Return : the socket descriptor ( >= 0), or -1 if an error occurred
990 + * Notes : The socket is a cooked IP packet socket, bound to the specified
991 + * network interface
992 + * ------------------------------------------------------------------------- */
993 +static int CreateCaptureSocket(const char* ifName)
995 + int ifIndex = if_nametoindex(ifName);
996 + struct packet_mreq mreq;
998 + struct sockaddr_ll bindTo;
1000 + /* Open cooked IP packet socket */
1001 + if (olsr_cnf->ip_version == AF_INET){
1002 + skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1005 + skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
1009 + BmfPError("socket(PF_PACKET) error");
1013 + /* Set interface to promiscuous mode */
1014 + memset(&mreq, 0, sizeof(struct packet_mreq));
1015 + mreq.mr_ifindex = ifIndex;
1016 + mreq.mr_type = PACKET_MR_PROMISC;
1017 + if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
1019 + BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1024 + /* Get hardware (MAC) address */
1025 + memset(&req, 0, sizeof(struct ifreq));
1026 + strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
1027 + req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
1028 + if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
1030 + BmfPError("error retrieving MAC address");
1035 + /* Bind the socket to the specified interface */
1036 + memset(&bindTo, 0, sizeof(bindTo));
1037 + bindTo.sll_family = AF_PACKET;
1038 + if (olsr_cnf->ip_version == AF_INET){
1039 + bindTo.sll_protocol = htons(ETH_P_IP);
1042 + bindTo.sll_protocol = htons(ETH_P_IPV6);
1044 + bindTo.sll_ifindex = ifIndex;
1045 + memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1046 + bindTo.sll_halen = IFHWADDRLEN;
1048 + if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1050 + BmfPError("bind() error");
1055 + /* Set socket to blocking operation */
1056 + if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1058 + BmfPError("fcntl() error");
1063 + AddDescriptorToInputSet(skfd);
1064 + add_olsr_socket(skfd,&DoMDNS);
1067 +} /* CreateCaptureSocket */
1069 +/* -------------------------------------------------------------------------
1070 + * Function : CreateListeningSocket
1071 + * Description: Create socket for promiscuously listening to BMF packets.
1072 + * Used only when 'BmfMechanism' is BM_UNICAST_PROMISCUOUS
1073 + * Input : ifname - network interface (e.g. "eth0")
1075 + * Return : the socket descriptor ( >= 0), or -1 if an error occurred
1076 + * Data Used : none
1077 + * Notes : The socket is a cooked IP packet socket, bound to the specified
1078 + * network interface
1079 + * ------------------------------------------------------------------------- */
1080 +//static int CreateListeningSocket(const char* ifName)
1082 +// int ifIndex = if_nametoindex(ifName);
1083 +// struct packet_mreq mreq;
1084 +// struct ifreq req;
1085 +// struct sockaddr_ll bindTo;
1087 +// /* Open cooked IP packet socket */
1088 +// int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1091 +// BmfPError("socket(PF_PACKET) error");
1095 +// /* Set interface to promiscuous mode */
1096 +// memset(&mreq, 0, sizeof(struct packet_mreq));
1097 +// mreq.mr_ifindex = ifIndex;
1098 +// mreq.mr_type = PACKET_MR_PROMISC;
1099 +// if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
1101 +// BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1106 +// /* Get hardware (MAC) address */
1107 +// memset(&req, 0, sizeof(struct ifreq));
1108 +// strncpy(req.ifr_name, ifName, IFNAMSIZ - 1);
1109 +// req.ifr_name[IFNAMSIZ-1] = '\0'; /* Ensures null termination */
1110 +// if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
1112 +// BmfPError("error retrieving MAC address");
1117 +// /* Bind the socket to the specified interface */
1118 +// memset(&bindTo, 0, sizeof(bindTo));
1119 +// bindTo.sll_family = AF_PACKET;
1120 +// bindTo.sll_protocol = htons(ETH_P_IP);
1121 +// bindTo.sll_ifindex = ifIndex;
1122 +// memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1123 +// bindTo.sll_halen = IFHWADDRLEN;
1125 +// if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1127 +// BmfPError("bind() error");
1132 +// /* Set socket to blocking operation */
1133 +// if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1135 +// BmfPError("fcntl() error");
1140 +// AddDescriptorToInputSet(skfd);
1143 +//} /* CreateListeningSocket */
1145 +/* -------------------------------------------------------------------------
1146 + * Function : CreateEncapsulateSocket
1147 + * Description: Create a socket for sending and receiving encapsulated
1148 + * multicast packets
1149 + * Input : ifname - network interface (e.g. "eth0")
1151 + * Return : the socket descriptor ( >= 0), or -1 if an error occurred
1152 + * Data Used : none
1153 + * Notes : The socket is an UDP (datagram) over IP socket, bound to the
1154 + * specified network interface
1155 + * ------------------------------------------------------------------------- */
1156 +//static int CreateEncapsulateSocket(const char* ifName)
1159 +// struct sockaddr_in bindTo;
1161 +// /* Open UDP-IP socket */
1162 +// int skfd = socket(PF_INET, SOCK_DGRAM, 0);
1165 +// BmfPError("socket(PF_INET) error");
1169 +// /* Enable sending to broadcast addresses */
1170 +// if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
1172 +// BmfPError("setsockopt(SO_BROADCAST) error");
1177 +// /* Bind to the specific network interfaces indicated by ifName. */
1178 +// /* When using Kernel 2.6 this must happer prior to the port binding! */
1179 +// if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0)
1181 +// BmfPError("setsockopt(SO_BINDTODEVICE) error");
1186 +// /* Bind to BMF port */
1187 +// memset(&bindTo, 0, sizeof(bindTo));
1188 +// bindTo.sin_family = AF_INET;
1189 +// bindTo.sin_port = htons(BMF_ENCAP_PORT);
1190 +// bindTo.sin_addr.s_addr = htonl(INADDR_ANY);
1192 +// if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1194 +// BmfPError("bind() error");
1199 +// /* Set socket to blocking operation */
1200 +// if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1202 +// BmfPError("fcntl() error");
1207 +// AddDescriptorToInputSet(skfd);
1210 +//} /* CreateEncapsulateSocket */
1212 +/* -------------------------------------------------------------------------
1213 + * Function : CreateLocalEtherTunTap
1214 + * Description: Creates and brings up an EtherTunTap interface
1217 + * Return : the socket file descriptor (>= 0), or -1 in case of failure
1218 + * Data Used : EtherTunTapIfName - name used for the tuntap interface (e.g.
1221 + * EtherTunTapIpMask
1222 + * EtherTunTapIpBroadcast
1224 + * Note : Order dependency: call this function only if BmfInterfaces
1225 + * is filled with a list of network interfaces.
1226 + * ------------------------------------------------------------------------- */
1227 +//static int CreateLocalEtherTunTap(void)
1229 +// static const char deviceName[] = "/dev/net/tun";
1230 +// struct ifreq ifreq;
1235 +// etfd = open(deviceName, O_RDWR | O_NONBLOCK);
1238 +// BmfPError("error opening %s", deviceName);
1242 +// memset(&ifreq, 0, sizeof(ifreq));
1243 +// strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1244 +// ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1246 +// /* Specify the IFF_TUN flag for IP packets.
1247 +// * Specify IFF_NO_PI for not receiving extra meta packet information. */
1248 +// ifreq.ifr_flags = IFF_TUN;
1249 +// ifreq.ifr_flags |= IFF_NO_PI;
1251 +// if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
1253 +// BmfPError("ioctl(TUNSETIFF) error on %s", deviceName);
1258 +// memset(&ifreq, 0, sizeof(ifreq));
1259 +// strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1260 +// ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1261 +// ifreq.ifr_addr.sa_family = AF_INET;
1263 +// ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1264 +// if (ioctlSkfd < 0)
1266 +// BmfPError("socket(PF_INET) error on %s", deviceName);
1271 +// /* Give the EtherTunTap interface an IP address.
1272 +// * The default IP address is the address of the first OLSR interface;
1273 +// * the default netmask is 255.255.255.255 . Having an all-ones netmask prevents
1274 +// * automatic entry of the BMF network interface in the routing table. */
1275 +// if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
1277 +// struct TBmfInterface* nextBmfIf = BmfInterfaces;
1278 +// while (nextBmfIf != NULL)
1280 +// struct TBmfInterface* bmfIf = nextBmfIf;
1281 +// nextBmfIf = bmfIf->next;
1283 +// if (bmfIf->olsrIntf != NULL)
1285 +// EtherTunTapIp = ntohl(bmfIf->intAddr.v4.s_addr);
1286 +// EtherTunTapIpBroadcast = EtherTunTapIp;
1291 +// if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
1293 +// /* No IP address configured for BMF network interface, and no OLSR interface found to
1294 +// * copy IP address from. Fall back to default: 10.255.255.253 . */
1295 +// EtherTunTapIp = ETHERTUNTAPDEFAULTIP;
1298 +// ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp);
1299 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq);
1300 +// if (ioctlres >= 0)
1302 +// /* Set net mask */
1303 +// ((struct sockaddr_in*)&ifreq.ifr_netmask)->sin_addr.s_addr = htonl(EtherTunTapIpMask);
1304 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq);
1305 +// if (ioctlres >= 0)
1307 +// /* Set broadcast IP */
1308 +// ((struct sockaddr_in*)&ifreq.ifr_broadaddr)->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast);
1309 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq);
1310 +// if (ioctlres >= 0)
1312 +// /* Bring EtherTunTap interface up (if not already) */
1313 +// ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1314 +// if (ioctlres >= 0)
1316 +// ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_BROADCAST);
1317 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1323 +// if (ioctlres < 0)
1325 +// /* Any of the above ioctl() calls failed */
1326 +// BmfPError("error bringing up EtherTunTap interface \"%s\"", EtherTunTapIfName);
1329 +// close(ioctlSkfd);
1331 +// } /* if (ioctlres < 0) */
1333 +// /* Set the multicast flag on the interface */
1334 +// memset(&ifreq, 0, sizeof(ifreq));
1335 +// strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1336 +// ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1338 +// ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1339 +// if (ioctlres >= 0)
1341 +// ifreq.ifr_flags |= IFF_MULTICAST;
1342 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1344 +// if (ioctlres < 0)
1346 +// /* Any of the two above ioctl() calls failed */
1347 +// BmfPError("error setting multicast flag on EtherTunTap interface \"%s\"", EtherTunTapIfName);
1349 +// /* Continue anyway */
1352 +// /* Use ioctl to make the tuntap persistent. Otherwise it will disappear
1353 +// * when this program exits. That is not desirable, since a multicast
1354 +// * daemon (e.g. mrouted) may be using the tuntap interface. */
1355 +// if (ioctl(etfd, TUNSETPERSIST, (void *)&ifreq) < 0)
1357 +// BmfPError("error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName);
1359 +// /* Continue anyway */
1362 +// OLSR_PRINTF(8, "%s: opened 1 socket on \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1364 +// AddDescriptorToInputSet(etfd);
1366 +// /* If the user configured a specific IP address for the BMF network interface,
1367 +// * help the user and advertise the IP address of the BMF network interface
1368 +// * on the OLSR network via HNA */
1369 +// if (TunTapIpOverruled != 0)
1371 +// union olsr_ip_addr temp_net;
1373 +// temp_net.v4.s_addr = htonl(EtherTunTapIp);
1374 +// ip_prefix_list_add(&olsr_cnf->hna_entries, &temp_net, 32);
1377 +// close(ioctlSkfd);
1380 +//} /* CreateLocalEtherTunTap */
1382 +/* -------------------------------------------------------------------------
1383 + * Function : CreateInterface
1384 + * Description: Create a new TBmfInterface object and adds it to the global
1385 + * BmfInterfaces list
1386 + * Input : ifName - name of the network interface (e.g. "eth0")
1387 + * : olsrIntf - OLSR interface object of the network interface, or
1388 + * NULL if the network interface is not OLSR-enabled
1390 + * Return : the number of opened sockets
1391 + * Data Used : BmfInterfaces, LastBmfInterface
1392 + * ------------------------------------------------------------------------- */
1394 +//FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
1396 +static int CreateInterface(
1397 + const char* ifName,
1398 + struct interface* olsrIntf)
1400 + int capturingSkfd = -1;
1401 + int encapsulatingSkfd = -1;
1402 + int listeningSkfd = -1;
1406 + struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
1408 + assert(ifName != NULL);
1410 + if (newIf == NULL)
1415 +//TODO: assert interface is not talking OLSR
1417 +// if (olsrIntf != NULL)
1419 +// /* On OLSR-enabled interfaces, create socket for encapsulating and forwarding
1420 +// * multicast packets */
1421 +// encapsulatingSkfd = CreateEncapsulateSocket(ifName);
1422 +// if (encapsulatingSkfd < 0)
1430 + /* Create socket for capturing and sending of multicast packets on
1431 + * non-OLSR interfaces, and on OLSR-interfaces if configured. */
1432 + if ((olsrIntf == NULL) || (CapturePacketsOnOlsrInterfaces != 0))
1434 + capturingSkfd = CreateCaptureSocket(ifName);
1435 + if (capturingSkfd < 0)
1437 + close(encapsulatingSkfd);
1445 +// /* Create promiscuous mode listening interface if BMF uses IP unicast
1446 +// * as underlying forwarding mechanism */
1447 +// if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
1449 +// listeningSkfd = CreateListeningSocket(ifName);
1450 +// if (listeningSkfd < 0)
1452 +// close(listeningSkfd);
1453 +// close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */
1461 + /* For ioctl operations on the network interface, use either capturingSkfd
1462 + * or encapsulatingSkfd, whichever is available */
1463 + ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
1465 + /* Retrieve the MAC address of the interface. */
1466 + memset(&ifr, 0, sizeof(struct ifreq));
1467 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1468 + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1469 + if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0)
1471 + BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
1472 + close(capturingSkfd);
1473 + close(encapsulatingSkfd);
1478 + /* Copy data into TBmfInterface object */
1479 + newIf->capturingSkfd = capturingSkfd;
1480 + newIf->encapsulatingSkfd = encapsulatingSkfd;
1481 + newIf->listeningSkfd = listeningSkfd;
1482 + memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
1483 + memcpy(newIf->ifName, ifName, IFNAMSIZ);
1484 + newIf->olsrIntf = olsrIntf;
1485 + if (olsrIntf != NULL)
1487 + /* For an OLSR-interface, copy the interface address and broadcast
1488 + * address from the OLSR interface object. Downcast to correct sockaddr
1490 + newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
1491 + newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
1495 + /* For a non-OLSR interface, retrieve the IP address ourselves */
1496 + memset(&ifr, 0, sizeof(struct ifreq));
1497 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1498 + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1499 + if (ioctl(ioctlSkfd, SIOCGIFADDR, &ifr) < 0)
1501 + BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
1503 + newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
1507 + /* Downcast to correct sockaddr subtype */
1508 + newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
1511 + /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
1512 + memset(&ifr, 0, sizeof(struct ifreq));
1513 + strncpy(ifr.ifr_name, ifName, IFNAMSIZ - 1);
1514 + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1515 + if (ioctl(ioctlSkfd, SIOCGIFBRDADDR, &ifr) < 0)
1517 + BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
1519 + newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
1523 + /* Downcast to correct sockaddr subtype */
1524 + newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
1528 + /* Initialize fragment history table */
1529 + //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
1530 + //newIf->nextFragmentHistoryEntry = 0;
1532 + /* Reset counters */
1533 + //newIf->nBmfPacketsRx = 0;
1534 + //newIf->nBmfPacketsRxDup = 0;
1535 + //newIf->nBmfPacketsTx = 0;
1537 + /* Add new TBmfInterface object to global list. OLSR interfaces are
1538 + * added at the front of the list, non-OLSR interfaces at the back. */
1539 + if (BmfInterfaces == NULL)
1541 + /* First TBmfInterface object in list */
1542 + BmfInterfaces = newIf;
1543 + LastBmfInterface = newIf;
1545 + else if (olsrIntf != NULL)
1547 + /* Add new TBmfInterface object at front of list */
1548 + newIf->next = BmfInterfaces;
1549 + BmfInterfaces = newIf;
1553 + /* Add new TBmfInterface object at back of list */
1554 + newIf->next = NULL;
1555 + LastBmfInterface->next= newIf;
1556 + LastBmfInterface = newIf;
1561 + "%s: opened %d socket%s on %s interface \"%s\"\n",
1562 + PLUGIN_NAME_SHORT,
1564 + nOpened == 1 ? "" : "s",
1565 + olsrIntf != NULL ? "OLSR" : "non-OLSR",
1569 +} /* CreateInterface */
1571 +/* -------------------------------------------------------------------------
1572 + * Function : CreateBmfNetworkInterfaces
1573 + * Description: Create a list of TBmfInterface objects, one for each network
1574 + * interface on which BMF runs
1575 + * Input : skipThisIntf - network interface to skip, if seen
1577 + * Return : fail (-1) or success (0)
1578 + * Data Used : none
1579 + * ------------------------------------------------------------------------- */
1580 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
1583 + struct ifconf ifc;
1585 + struct ifreq* ifr;
1587 + int nOpenedSockets = 0;
1589 + /* Clear input descriptor set */
1590 + FD_ZERO(&InputSet);
1592 + skfd = socket(PF_INET, SOCK_DGRAM, 0);
1595 + BmfPError("no inet socket available to retrieve interface list");
1599 + /* Retrieve the network interface configuration list */
1600 + ifc.ifc_buf = NULL;
1603 + ifc.ifc_len = sizeof(struct ifreq) * numreqs;
1604 + ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
1606 + if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
1608 + BmfPError("ioctl(SIOCGIFCONF) error");
1611 + free(ifc.ifc_buf);
1614 + if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
1616 + /* Assume it overflowed; double the space and try again */
1618 + assert(numreqs < 1024);
1619 + continue; /* for (;;) */
1621 + break; /* for (;;) */
1626 + /* For each item in the interface configuration list... */
1627 + ifr = ifc.ifc_req;
1628 + for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++)
1630 + struct interface* olsrIntf;
1631 + union olsr_ip_addr ipAddr;
1633 + /* Skip the BMF network interface itself */
1634 + //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
1636 + // continue; /* for (n = ...) */
1639 + /* ...find the OLSR interface structure, if any */
1640 + ipAddr.v4 = ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr;
1641 + olsrIntf = if_ifwithaddr(&ipAddr);
1643 + if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
1645 + continue; /* for (n = ...) */
1648 + if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
1650 + /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
1651 + * interface in the BMF plugin parameter list */
1652 + continue; /* for (n = ...) */
1655 + if (! IsNonOlsrBmfIf(ifr->ifr_name))
1657 + //If the interface is not specified in the configuration file then go ahead
1658 + continue; /* for (n = ...) */
1660 + //TODO: asser if->ifr_name is not talking OLSR
1661 + //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
1662 + nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
1664 + } /* for (n = ...) */
1666 + free(ifc.ifc_buf);
1668 + /* Create the BMF network interface */
1669 + //EtherTunTapFd = CreateLocalEtherTunTap();
1670 + //if (EtherTunTapFd >= 0)
1672 + // nOpenedSockets++;
1675 + if (BmfInterfaces == NULL)
1677 + OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
1681 + OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
1684 +} /* CreateBmfNetworkInterfaces */
1686 +/* -------------------------------------------------------------------------
1687 + * Function : AddInterface
1688 + * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
1689 + * network interfaces
1690 + * Input : newIntf - network interface to add
1693 + * Data Used : none
1694 + * ------------------------------------------------------------------------- */
1695 +void AddInterface(struct interface* newIntf)
1699 + assert(newIntf != NULL);
1701 + nOpened = CreateInterface(newIntf->int_name, newIntf);
1703 + OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
1704 +} /* AddInterface */
1706 +/* -------------------------------------------------------------------------
1707 + * Function : CloseBmfNetworkInterfaces
1708 + * Description: Closes every socket on each network interface used by BMF
1712 + * Data Used : none
1714 + * - the local EtherTunTap interface (e.g. "tun0" or "tap0")
1715 + * - for each BMF-enabled interface, the socket used for
1716 + * capturing multicast packets
1717 + * - for each OLSR-enabled interface, the socket used for
1718 + * encapsulating packets
1719 + * Also restores the network state to the situation before BMF
1721 + * ------------------------------------------------------------------------- */
1722 +void CloseBmfNetworkInterfaces(void)
1725 + u_int32_t totalOlsrBmfPacketsRx = 0;
1726 + u_int32_t totalOlsrBmfPacketsRxDup = 0;
1727 + u_int32_t totalOlsrBmfPacketsTx = 0;
1728 + u_int32_t totalNonOlsrBmfPacketsRx = 0;
1729 + u_int32_t totalNonOlsrBmfPacketsRxDup = 0;
1730 + u_int32_t totalNonOlsrBmfPacketsTx = 0;
1732 + /* Close all opened sockets */
1733 + struct TBmfInterface* nextBmfIf = BmfInterfaces;
1734 + while (nextBmfIf != NULL)
1736 + struct TBmfInterface* bmfIf = nextBmfIf;
1737 + nextBmfIf = bmfIf->next;
1739 + if (bmfIf->capturingSkfd >= 0)
1741 + close(bmfIf->capturingSkfd);
1744 + if (bmfIf->encapsulatingSkfd >= 0)
1746 + close(bmfIf->encapsulatingSkfd);
1752 + "%s: %s interface \"%s\": RX pkts %u (%u dups); TX pkts %u\n",
1753 + PLUGIN_NAME_SHORT,
1754 + bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
1756 + bmfIf->nBmfPacketsRx,
1757 + bmfIf->nBmfPacketsRxDup,
1758 + bmfIf->nBmfPacketsTx);
1762 + "%s: closed %s interface \"%s\"\n",
1763 + PLUGIN_NAME_SHORT,
1764 + bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
1768 + if (bmfIf->olsrIntf != NULL)
1770 + totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1771 + totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1772 + totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1776 + totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1777 + totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1778 + totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1784 + if (EtherTunTapFd >= 0)
1786 + close(EtherTunTapFd);
1789 + OLSR_PRINTF(7, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1792 + BmfInterfaces = NULL;
1794 + OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
1798 + "%s: Total all OLSR interfaces : RX pkts %u (%u dups); TX pkts %u\n",
1799 + PLUGIN_NAME_SHORT,
1800 + totalOlsrBmfPacketsRx,
1801 + totalOlsrBmfPacketsRxDup,
1802 + totalOlsrBmfPacketsTx);
1805 + "%s: Total all non-OLSR interfaces: RX pkts %u (%u dups); TX pkts %u\n",
1806 + PLUGIN_NAME_SHORT,
1807 + totalNonOlsrBmfPacketsRx,
1808 + totalNonOlsrBmfPacketsRxDup,
1809 + totalNonOlsrBmfPacketsTx);
1810 +} /* CloseBmfNetworkInterfaces */
1812 +#define MAX_NON_OLSR_IFS 32
1813 +static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
1814 +static int nNonOlsrIfs = 0;
1816 +/* -------------------------------------------------------------------------
1817 + * Function : AddNonOlsrBmfIf
1818 + * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
1819 + * network interfaces
1820 + * Input : ifName - network interface (e.g. "eth0")
1822 + * addon - not used
1824 + * Return : success (0) or fail (1)
1825 + * Data Used : NonOlsrIfNames
1826 + * ------------------------------------------------------------------------- */
1827 +int AddNonOlsrBmfIf(
1828 + const char* ifName,
1829 + void* data __attribute__((unused)),
1830 + set_plugin_parameter_addon addon __attribute__((unused)))
1832 + assert(ifName != NULL);
1834 + if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
1838 + "%s: too many non-OLSR interfaces specified, maximum is %d\n",
1840 + MAX_NON_OLSR_IFS);
1844 + strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
1845 + NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1848 +} /* AddNonOlsrBmfIf */
1850 +/* -------------------------------------------------------------------------
1851 + * Function : IsNonOlsrBmfIf
1852 + * Description: Checks if a network interface is OLSR-enabled
1853 + * Input : ifName - network interface (e.g. "eth0")
1855 + * Return : true (1) or false (0)
1856 + * Data Used : NonOlsrIfNames
1857 + * ------------------------------------------------------------------------- */
1858 +int IsNonOlsrBmfIf(const char* ifName)
1862 + assert(ifName != NULL);
1864 + for (i = 0; i < nNonOlsrIfs; i++)
1866 + if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
1869 +} /* IsNonOlsrBmfIf */
1871 +/* -------------------------------------------------------------------------
1872 + * Function : CheckAndUpdateLocalBroadcast
1873 + * Description: For an IP packet, check if the destination address is not a
1874 + * multicast address. If it is not, the packet is assumed to be
1875 + * a local broadcast packet. In that case, set the destination
1876 + * address of the IP packet to the passed broadcast address.
1877 + * Input : ipPacket - the IP packet
1878 + * broadAddr - the broadcast address to fill in
1881 + * Data Used : none
1882 + * Notes : See also RFC1141
1883 + * ------------------------------------------------------------------------- */
1884 +void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr)
1886 + struct iphdr* iph;
1887 + union olsr_ip_addr destIp;
1889 + assert(ipPacket != NULL && broadAddr != NULL);
1891 + iph = (struct iphdr*) ipPacket;
1892 + destIp.v4.s_addr = iph->daddr;
1893 + if (! IsMulticast(&destIp))
1895 + u_int32_t origDaddr, newDaddr;
1898 + origDaddr = ntohl(iph->daddr);
1900 + iph->daddr = broadAddr->v4.s_addr;
1901 + newDaddr = ntohl(iph->daddr);
1903 + /* Re-calculate IP header checksum for new destination */
1904 + check = ntohs(iph->check);
1906 + check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1907 + check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1910 + check = check + (check >> 16);
1912 + iph->check = htons(check);
1914 + if (iph->protocol == SOL_UDP)
1916 + /* Re-calculate UDP/IP checksum for new destination */
1918 + int ipHeaderLen = GetIpHeaderLength(ipPacket);
1919 + struct udphdr* udph = (struct udphdr*) (ipPacket + ipHeaderLen);
1921 + /* RFC 1624, Eq. 3: HC' = ~(~HC - m + m') */
1923 + check = ntohs(udph->check);
1925 + check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1926 + check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1929 + check = check + (check >> 16);
1931 + udph->check = htons(check);
1934 +} /* CheckAndUpdateLocalBroadcast */
1936 +/* -------------------------------------------------------------------------
1937 + * Function : AddMulticastRoute
1938 + * Description: Insert a route to all multicast addresses in the kernel
1939 + * routing table. The route will be via the BMF network interface.
1943 + * Data Used : none
1944 + * ------------------------------------------------------------------------- */
1945 +void AddMulticastRoute(void)
1947 + struct rtentry kernel_route;
1948 + int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1949 + if (ioctlSkfd < 0)
1951 + BmfPError("socket(PF_INET) error");
1955 + memset(&kernel_route, 0, sizeof(struct rtentry));
1957 + ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
1958 + ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
1959 + ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
1962 + ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
1963 + ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
1965 + kernel_route.rt_metric = 0;
1966 + kernel_route.rt_flags = RTF_UP;
1968 + kernel_route.rt_dev = EtherTunTapIfName;
1970 + if (ioctl(ioctlSkfd, SIOCADDRT, &kernel_route) < 0)
1972 + BmfPError("error setting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
1974 + /* Continue anyway */
1977 +} /* AddMulticastRoute */
1979 +/* -------------------------------------------------------------------------
1980 + * Function : DeleteMulticastRoute
1981 + * Description: Delete the route to all multicast addresses from the kernel
1986 + * Data Used : none
1987 + * ------------------------------------------------------------------------- */
1988 +void DeleteMulticastRoute(void)
1990 + if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP)
1992 + struct rtentry kernel_route;
1993 + int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1994 + if (ioctlSkfd < 0)
1996 + BmfPError("socket(PF_INET) error");
2000 + memset(&kernel_route, 0, sizeof(struct rtentry));
2002 + ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
2003 + ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
2004 + ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
2007 + ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
2008 + ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
2010 + kernel_route.rt_metric = 0;
2011 + kernel_route.rt_flags = RTF_UP;
2013 + kernel_route.rt_dev = EtherTunTapIfName;
2015 + if (ioctl(ioctlSkfd, SIOCDELRT, &kernel_route) < 0)
2017 + BmfPError("error deleting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
2019 + /* Continue anyway */
2023 +} /* DeleteMulticastRoute */
2026 + * Local Variables:
2027 + * c-basic-offset: 2
2028 + * indent-tabs-mode: nil
2032 +++ b/lib/mdns/src/NetworkInterfaces.h
2034 +#ifndef _BMF_NETWORKINTERFACES_H
2035 +#define _BMF_NETWORKINTERFACES_H
2038 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2039 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2040 + * Written by Erik Tromp.
2041 + * All rights reserved.
2043 + * Redistribution and use in source and binary forms, with or without
2044 + * modification, are permitted provided that the following conditions
2047 + * * Redistributions of source code must retain the above copyright
2048 + * notice, this list of conditions and the following disclaimer.
2049 + * * Redistributions in binary form must reproduce the above copyright
2050 + * notice, this list of conditions and the following disclaimer in
2051 + * the documentation and/or other materials provided with the
2053 + * * Neither the name of Thales, BMF nor the names of its
2054 + * contributors may be used to endorse or promote products derived
2055 + * from this software without specific prior written permission.
2057 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2058 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2059 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2060 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2061 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2062 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2063 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2064 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2065 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2066 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2069 +/* -------------------------------------------------------------------------
2070 + * File : NetworkInterfaces.h
2071 + * Description: Functions to open and close sockets
2072 + * Created : 29 Jun 2006
2074 + * ------------------------------------------------------------------------- */
2076 +/* System includes */
2077 +#include <netinet/in.h> /* struct in_addr */
2079 +/* OLSR includes */
2080 +#include "olsr_types.h" /* olsr_ip_addr */
2081 +#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
2082 +#include "socket_parser.h"
2083 +/* Plugin includes */
2084 +#include "Packet.h" /* IFHWADDRLEN */
2086 +/* Size of buffer in which packets are received */
2087 +#define BMF_BUFFER_SIZE 2048
2089 +struct TBmfInterface
2091 + /* File descriptor of raw packet socket, used for capturing multicast packets */
2092 + int capturingSkfd;
2094 + /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.
2095 + * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */
2096 + int encapsulatingSkfd;
2098 + /* File descriptor of UDP packet socket, used for listening to encapsulation packets.
2099 + * Used only when PlParam "BmfMechanism" is set to "UnicastPromiscuous". */
2100 + int listeningSkfd;
2102 + unsigned char macAddr[IFHWADDRLEN];
2104 + char ifName[IFNAMSIZ];
2106 + /* OLSRs idea of this network interface. NULL if this interface is not
2107 + * OLSR-enabled. */
2108 + struct interface* olsrIntf;
2110 + /* IP address of this network interface */
2111 + union olsr_ip_addr intAddr;
2113 + /* Broadcast address of this network interface */
2114 + union olsr_ip_addr broadAddr;
2116 + #define FRAGMENT_HISTORY_SIZE 10
2117 + struct TFragmentHistory
2121 + struct in_addr ipSrc;
2122 + struct in_addr ipDst;
2123 + } fragmentHistory [FRAGMENT_HISTORY_SIZE];
2125 + int nextFragmentHistoryEntry;
2127 + /* Number of received and transmitted BMF packets on this interface */
2128 + u_int32_t nBmfPacketsRx;
2129 + u_int32_t nBmfPacketsRxDup;
2130 + u_int32_t nBmfPacketsTx;
2132 + /* Next element in list */
2133 + struct TBmfInterface* next;
2136 +extern struct TBmfInterface* BmfInterfaces;
2138 +extern int HighestSkfd;
2139 +extern fd_set InputSet;
2141 +extern int EtherTunTapFd;
2143 +extern char EtherTunTapIfName[];
2145 +/* 10.255.255.253 in host byte order */
2146 +#define ETHERTUNTAPDEFAULTIP 0x0AFFFFFD
2148 +extern u_int32_t EtherTunTapIp;
2149 +extern u_int32_t EtherTunTapIpMask;
2150 +extern u_int32_t EtherTunTapIpBroadcast;
2152 +extern int CapturePacketsOnOlsrInterfaces;
2154 +enum TBmfMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };
2155 +extern enum TBmfMechanism BmfMechanism;
2157 +int SetBmfInterfaceName(const char* ifname, void* data, set_plugin_parameter_addon addon);
2158 +int SetBmfInterfaceIp(const char* ip, void* data, set_plugin_parameter_addon addon);
2159 +int SetCapturePacketsOnOlsrInterfaces(const char* enable, void* data, set_plugin_parameter_addon addon);
2160 +int SetBmfMechanism(const char* mechanism, void* data, set_plugin_parameter_addon addon);
2161 +int DeactivateSpoofFilter(void);
2162 +void RestoreSpoofFilter(void);
2164 +#define MAX_UNICAST_NEIGHBORS 10
2165 +struct TBestNeighbors
2167 + struct link_entry* links[MAX_UNICAST_NEIGHBORS];
2170 +void FindNeighbors(
2171 + struct TBestNeighbors* neighbors,
2172 + struct link_entry** bestNeighbor,
2173 + struct TBmfInterface* intf,
2174 + union olsr_ip_addr* source,
2175 + union olsr_ip_addr* forwardedBy,
2176 + union olsr_ip_addr* forwardedTo,
2177 + int* nPossibleNeighbors);
2179 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
2180 +void AddInterface(struct interface* newIntf);
2181 +void CloseBmfNetworkInterfaces(void);
2182 +int AddNonOlsrBmfIf(const char* ifName, void* data, set_plugin_parameter_addon addon);
2183 +int IsNonOlsrBmfIf(const char* ifName);
2184 +void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr);
2185 +void AddMulticastRoute(void);
2186 +void DeleteMulticastRoute(void);
2188 +#endif /* _BMF_NETWORKINTERFACES_H */
2191 + * Local Variables:
2192 + * c-basic-offset: 2
2193 + * indent-tabs-mode: nil
2197 +++ b/lib/mdns/src/Packet.c
2200 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2201 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2202 + * Written by Erik Tromp.
2203 + * All rights reserved.
2205 + * Redistribution and use in source and binary forms, with or without
2206 + * modification, are permitted provided that the following conditions
2209 + * * Redistributions of source code must retain the above copyright
2210 + * notice, this list of conditions and the following disclaimer.
2211 + * * Redistributions in binary form must reproduce the above copyright
2212 + * notice, this list of conditions and the following disclaimer in
2213 + * the documentation and/or other materials provided with the
2215 + * * Neither the name of Thales, BMF nor the names of its
2216 + * contributors may be used to endorse or promote products derived
2217 + * from this software without specific prior written permission.
2219 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2220 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2221 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2222 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2223 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2224 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2225 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2226 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2227 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2228 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2231 +/* -------------------------------------------------------------------------
2233 + * Description: IP packet and Ethernet frame processing functions
2234 + * Created : 29 Jun 2006
2236 + * ------------------------------------------------------------------------- */
2238 +#include "Packet.h"
2240 +/* System includes */
2241 +#include <stddef.h> /* NULL */
2242 +#include <assert.h> /* assert() */
2243 +#include <string.h> /* memcpy() */
2244 +#include <sys/types.h> /* u_int8_t, u_int16_t, u_int32_t */
2245 +#include <netinet/in.h> /* ntohs(), htons() */
2246 +#include <netinet/ip.h> /* struct iphdr */
2248 +/* -------------------------------------------------------------------------
2249 + * Function : IsIpFragment
2250 + * Description: Check if an IP packet is an IP fragment
2251 + * Input : ipPacket - the IP packet
2253 + * Return : true (1) or false (0)
2254 + * Data Used : none
2255 + * ------------------------------------------------------------------------- */
2256 +int IsIpFragment(unsigned char* ipPacket)
2260 + assert(ipPacket != NULL);
2262 + iph = (struct ip*) ipPacket;
2263 + if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
2268 +} /* IsIpFragment */
2270 +/* -------------------------------------------------------------------------
2271 + * Function : GetIpTotalLength
2272 + * Description: Retrieve the total length of the IP packet (in bytes) of
2274 + * Input : ipPacket - the IP packet
2276 + * Return : IP packet length
2277 + * Data Used : none
2278 + * ------------------------------------------------------------------------- */
2279 +u_int16_t GetIpTotalLength(unsigned char* ipPacket)
2281 + struct iphdr* iph;
2283 + assert(ipPacket != NULL);
2285 + iph = (struct iphdr*) ipPacket;
2286 + return ntohs(iph->tot_len);
2287 +} /* GetIpTotalLength */
2289 +/* -------------------------------------------------------------------------
2290 + * Function : GetIpHeaderLength
2291 + * Description: Retrieve the IP header length (in bytes) of an IP packet
2292 + * Input : ipPacket - the IP packet
2294 + * Return : IP header length
2295 + * Data Used : none
2296 + * ------------------------------------------------------------------------- */
2297 +unsigned int GetIpHeaderLength(unsigned char* ipPacket)
2299 + struct iphdr* iph;
2301 + assert(ipPacket != NULL);
2303 + iph = (struct iphdr*) ipPacket;
2304 + return iph->ihl << 2;
2305 +} /* GetIpHeaderLength */
2307 +/* -------------------------------------------------------------------------
2308 + * Function : GetTtl
2309 + * Description: Retrieve the TTL (Time To Live) value from the IP header of
2311 + * Input : ipPacket - the IP packet
2313 + * Return : TTL value
2314 + * Data Used : none
2315 + * ------------------------------------------------------------------------- */
2316 +u_int8_t GetTtl(unsigned char* ipPacket)
2318 + struct iphdr* iph;
2320 + assert(ipPacket != NULL);
2322 + iph = (struct iphdr*) ipPacket;
2326 +/* -------------------------------------------------------------------------
2327 + * Function : SaveTtlAndChecksum
2328 + * Description: Save the TTL (Time To Live) value and IP checksum as found in
2329 + * the IP header of an IP packet
2330 + * Input : ipPacket - the IP packet
2331 + * Output : sttl - the TTL and checksum values
2333 + * Data Used : none
2334 + * ------------------------------------------------------------------------- */
2335 +void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
2337 + struct iphdr* iph;
2339 + assert(ipPacket != NULL && sttl != NULL);
2341 + iph = (struct iphdr*) ipPacket;
2342 + sttl->ttl = iph->ttl;
2343 + sttl->check = ntohs(iph->check);
2344 +} /* SaveTtlAndChecksum */
2346 +/* -------------------------------------------------------------------------
2347 + * Function : RestoreTtlAndChecksum
2348 + * Description: Restore the TTL (Time To Live) value and IP checksum in
2349 + * the IP header of an IP packet
2350 + * Input : ipPacket - the IP packet
2351 + * sttl - the TTL and checksum values
2354 + * Data Used : none
2355 + * ------------------------------------------------------------------------- */
2356 +void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
2358 + struct iphdr* iph;
2360 + assert(ipPacket != NULL && sttl != NULL);
2362 + iph = (struct iphdr*) ipPacket;
2363 + iph->ttl = sttl->ttl;
2364 + iph->check = htons(sttl->check);
2365 +} /* RestoreTtlAndChecksum */
2367 +/* -------------------------------------------------------------------------
2368 + * Function : DecreaseTtlAndUpdateHeaderChecksum
2369 + * Description: For an IP packet, decrement the TTL value and update the IP header
2370 + * checksum accordingly.
2371 + * Input : ipPacket - the IP packet
2374 + * Data Used : none
2375 + * Notes : See also RFC1141
2376 + * ------------------------------------------------------------------------- */
2377 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
2379 + struct iphdr* iph;
2382 + assert(ipPacket != NULL);
2384 + iph = (struct iphdr*) ipPacket;
2386 + iph->ttl--; /* decrement ttl */
2387 + sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
2388 + iph->check = htons(sum + (sum>>16)); /* add carry */
2389 +} /* DecreaseTtlAndUpdateHeaderChecksum */
2391 +/* -------------------------------------------------------------------------
2392 + * Function : GetIpHeader
2393 + * Description: Retrieve the IP header from BMF encapsulation UDP data
2394 + * Input : encapsulationUdpData - the encapsulation UDP data
2396 + * Return : IP header
2397 + * Data Used : none
2398 + * ------------------------------------------------------------------------- */
2399 +struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
2401 + return (struct ip*)(encapsulationUdpData + ENCAP_HDR_LEN);
2402 +} /* GetIpHeader */
2404 +/* -------------------------------------------------------------------------
2405 + * Function : GetIpPacket
2406 + * Description: Retrieve the IP packet from BMF encapsulation UDP data
2407 + * Input : encapsulationUdpData - the encapsulation UDP data
2409 + * Return : The IP packet
2410 + * Data Used : none
2411 + * ------------------------------------------------------------------------- */
2412 +unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
2414 + return encapsulationUdpData + ENCAP_HDR_LEN;
2415 +} /* GetIpPacket */
2417 +/* -------------------------------------------------------------------------
2418 + * Function : GetEncapsulationUdpDataLength
2419 + * Description: Return the length of BMF encapsulation UDP data
2420 + * Input : encapsulationUdpData - the encapsulation UDP data
2422 + * Return : The encapsulation data length
2423 + * Data Used : none
2424 + * ------------------------------------------------------------------------- */
2425 +u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData)
2427 + return GetIpTotalLength(GetIpPacket(encapsulationUdpData)) + ENCAP_HDR_LEN;
2428 +} /* GetEncapsulationUdpDataLength */
2432 + * Local Variables:
2433 + * c-basic-offset: 2
2434 + * indent-tabs-mode: nil
2438 +++ b/lib/mdns/src/Packet.h
2440 +#ifndef _BMF_PACKET_H
2441 +#define _BMF_PACKET_H
2444 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2445 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2446 + * Written by Erik Tromp.
2447 + * All rights reserved.
2449 + * Redistribution and use in source and binary forms, with or without
2450 + * modification, are permitted provided that the following conditions
2453 + * * Redistributions of source code must retain the above copyright
2454 + * notice, this list of conditions and the following disclaimer.
2455 + * * Redistributions in binary form must reproduce the above copyright
2456 + * notice, this list of conditions and the following disclaimer in
2457 + * the documentation and/or other materials provided with the
2459 + * * Neither the name of Thales, BMF nor the names of its
2460 + * contributors may be used to endorse or promote products derived
2461 + * from this software without specific prior written permission.
2463 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2464 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2465 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2466 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2467 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2468 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2469 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2470 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2471 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2472 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2475 +/* -------------------------------------------------------------------------
2477 + * Description: BMF and IP packet processing functions
2478 + * Created : 29 Jun 2006
2480 + * ------------------------------------------------------------------------- */
2482 +/* System includes */
2483 +#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
2484 +#include <sys/types.h> /* u_int8_t, u_int16_t */
2486 +/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
2487 + * with a 8-bytes BMF header (struct TEncapHeader), followed by the
2488 + * encapsulated Ethernet-IP packet itself */
2490 +struct TEncapHeader
2492 + /* Use a standard Type-Length-Value (TLV) element */
2495 + u_int16_t reserved; /* Always 0 */
2497 +} __attribute__((__packed__));
2499 +#define ENCAP_HDR_LEN ((int)sizeof(struct TEncapHeader))
2500 +#define BMF_ENCAP_TYPE 1
2501 +#define BMF_ENCAP_LEN 6
2507 +} __attribute__((__packed__));
2509 +int IsIpFragment(unsigned char* ipPacket);
2510 +u_int16_t GetIpTotalLength(unsigned char* ipPacket);
2511 +unsigned int GetIpHeaderLength(unsigned char* ipPacket);
2512 +u_int8_t GetTtl(unsigned char* ipPacket);
2513 +void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
2514 +void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl);
2515 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket);
2516 +struct ip* GetIpHeader(unsigned char* encapsulationUdpData);
2517 +unsigned char* GetIpPacket(unsigned char* encapsulationUdpData);
2518 +u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData);
2520 +#endif /* _BMF_PACKET_H */
2523 + * Local Variables:
2524 + * c-basic-offset: 2
2525 + * indent-tabs-mode: nil
2529 +++ b/lib/mdns/src/PacketHistory.c
2532 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2533 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2534 + * Written by Erik Tromp.
2535 + * All rights reserved.
2537 + * Redistribution and use in source and binary forms, with or without
2538 + * modification, are permitted provided that the following conditions
2541 + * * Redistributions of source code must retain the above copyright
2542 + * notice, this list of conditions and the following disclaimer.
2543 + * * Redistributions in binary form must reproduce the above copyright
2544 + * notice, this list of conditions and the following disclaimer in
2545 + * the documentation and/or other materials provided with the
2547 + * * Neither the name of Thales, BMF nor the names of its
2548 + * contributors may be used to endorse or promote products derived
2549 + * from this software without specific prior written permission.
2551 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2552 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2553 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2554 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2555 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2556 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2557 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2558 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2559 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2560 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2563 +/* -------------------------------------------------------------------------
2564 + * File : PacketHistory.c
2565 + * Description: Functions for keeping and accessing the history of processed
2566 + * multicast IP packets.
2567 + * Created : 29 Jun 2006
2569 + * ------------------------------------------------------------------------- */
2571 +#include "PacketHistory.h"
2573 +/* System includes */
2574 +#include <stddef.h> /* NULL */
2575 +#include <assert.h> /* assert() */
2576 +#include <string.h> /* memset */
2577 +#include <sys/types.h> /* u_int16_t, u_int32_t */
2578 +#include <netinet/ip.h> /* struct iphdr */
2579 +#include <stdlib.h> /* atoi, malloc */
2581 +/* OLSRD includes */
2582 +#include "defs.h" /* GET_TIMESTAMP, TIMED_OUT */
2583 +#include "olsr.h" /* OLSR_PRINTF */
2584 +#include "scheduler.h" /* now_times */
2586 +/* Plugin includes */
2587 +#include "Packet.h"
2589 +static struct TDupEntry* PacketHistory[HISTORY_HASH_SIZE];
2591 +#define CRC_UPTO_NBYTES 256
2594 +/* -------------------------------------------------------------------------
2595 + * Function : CalcCrcCcitt
2596 + * Description: Calculate 16-bits CRC according to CRC-CCITT specification
2597 + * Input : buffer - the bytes to calculate the CRC value over
2598 + * len - the number of bytes to calculate the CRC value over
2600 + * Return : CRC-16 value
2601 + * Data Used : none
2602 + * ------------------------------------------------------------------------- */
2603 +static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)
2605 + /* Initial value of 0xFFFF should be 0x1D0F according to
2606 + * www.joegeluso.com/software/articles/ccitt.htm */
2607 + u_int16_t crc = 0xFFFF;
2610 + assert(buffer != NULL);
2612 + for (i = 0; i < len; i++)
2614 + crc = (unsigned char)(crc >> 8) | (crc << 8);
2616 + crc ^= (unsigned char)(crc & 0xff) >> 4;
2617 + crc ^= (crc << 8) << 4;
2618 + crc ^= ((crc & 0xff) << 4) << 1;
2621 +} /* CalcCrcCcitt */
2624 +/* -------------------------------------------------------------------------
2625 + * Function : GenerateCrc32Table
2626 + * Description: Generate the table of CRC remainders for all possible bytes,
2627 + * according to CRC-32-IEEE 802.3
2631 + * Data Used : none
2632 + * ------------------------------------------------------------------------- */
2633 +#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */
2635 +static unsigned long CrcTable[256];
2637 +static void GenerateCrc32Table(void)
2641 + for (i = 0; i < 256; i++)
2643 + crc = (u_int32_t) i;
2644 + for (j = 0; j < 8; j++)
2648 + crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
2655 + CrcTable[i] = crc;
2657 +} /* GenerateCrc32Table */
2659 +/* -------------------------------------------------------------------------
2660 + * Function : CalcCrc32
2661 + * Description: Calculate CRC-32 according to CRC-32-IEEE 802.3
2662 + * Input : buffer - the bytes to calculate the CRC value over
2663 + * len - the number of bytes to calculate the CRC value over
2665 + * Return : CRC-32 value
2666 + * Data Used : none
2667 + * ------------------------------------------------------------------------- */
2668 +static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)
2671 + u_int32_t crc = 0xffffffffUL;
2672 + for (i = 0; i < len; i++)
2674 + j = ((int) (crc & 0xFF) ^ *buffer++);
2675 + crc = (crc >> 8) ^ CrcTable[j];
2677 + return crc ^ 0xffffffffUL;
2680 +/* -------------------------------------------------------------------------
2681 + * Function : PacketCrc32
2682 + * Description: Calculates the CRC-32 value for an IP packet
2683 + * Input : ipPacket - the IP packet
2684 + * len - the number of octets in the IP packet
2686 + * Return : 32-bits CRC value
2687 + * Data Used : none
2688 + * ------------------------------------------------------------------------- */
2689 +u_int32_t PacketCrc32(unsigned char* ipPacket, ssize_t len)
2691 + struct TSaveTtl sttl;
2692 + struct ip* ipHeader;
2695 + assert(ipPacket != NULL);
2697 + /* Skip TTL: in a multi-homed OLSR-network, the same multicast packet
2698 + * may enter the network multiple times, each copy differing only in its
2699 + * TTL value. BMF must not calculate a different CRC for packets that
2700 + * differ only in TTL. Skip also the IP-header checksum, because it changes
2701 + * along with TTL. Besides, it is not a good idea to calculate a CRC over
2702 + * data that already contains a checksum.
2704 + * Clip number of bytes over which CRC is calculated to prevent
2705 + * long packets from possibly claiming too much CPU resources. */
2707 + if (len > CRC_UPTO_NBYTES)
2709 + len = CRC_UPTO_NBYTES;
2712 + SaveTtlAndChecksum(ipPacket, &sttl);
2714 + ipHeader = (struct ip*)ipPacket;
2715 + ipHeader->ip_ttl = 0xFF; /* fixed value of TTL for CRC-32 calculation */
2716 + ipHeader->ip_sum = 0x5A5A; /* fixed value of IP header checksum for CRC-32 calculation */
2718 + result = CalcCrc32(ipPacket, len);
2720 + RestoreTtlAndChecksum(ipPacket, &sttl);
2722 +} /* PacketCrc32 */
2724 +/* -------------------------------------------------------------------------
2726 + * Description: Calculates a hash value from a 32-bit value
2727 + * Input : from32 - 32-bit value
2729 + * Return : hash value
2730 + * Data Used : none
2731 + * ------------------------------------------------------------------------- */
2732 +u_int32_t Hash(u_int32_t from32)
2734 + return ((from32 >> N_HASH_BITS) + from32) & ((1 << N_HASH_BITS) - 1);
2737 +/* -------------------------------------------------------------------------
2738 + * Function : InitPacketHistory
2739 + * Description: Initialize the packet history table and CRC-32 table
2743 + * Data Used : PacketHistory
2744 + * ------------------------------------------------------------------------- */
2745 +void InitPacketHistory(void)
2749 + GenerateCrc32Table();
2751 + for(i = 0; i < HISTORY_HASH_SIZE; i++)
2753 + PacketHistory[i] = NULL;
2755 +} /* InitPacketHistory */
2757 +/* -------------------------------------------------------------------------
2758 + * Function : CheckAndMarkRecentPacket
2759 + * Description: Check if this packet was seen recently, then record the fact
2760 + * that this packet was seen recently.
2761 + * Input : crc32 - 32-bits crc value of the packet
2763 + * Return : not recently seen (0), recently seen (1)
2764 + * Data Used : PacketHistory
2765 + * ------------------------------------------------------------------------- */
2766 +int CheckAndMarkRecentPacket(u_int32_t crc32)
2769 + struct TDupEntry* walker;
2770 + struct TDupEntry* newEntry;
2772 + idx = Hash(crc32);
2773 + assert(idx < HISTORY_HASH_SIZE);
2775 + for (walker = PacketHistory[idx]; walker != NULL; walker = walker->next)
2777 + if (walker->crc32 == crc32)
2779 + /* Found duplicate entry */
2781 + /* Always mark as "seen recently": refresh time-out */
2782 + walker->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
2788 + /* No duplicate entry found: create one */
2789 + newEntry = malloc(sizeof(struct TDupEntry));
2790 + if (newEntry != NULL)
2792 + newEntry->crc32 = crc32;
2793 + newEntry->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
2795 + /* Add new entry at the front of the list */
2796 + newEntry->next = PacketHistory[idx];
2797 + PacketHistory[idx] = newEntry;
2801 +} /* CheckAndMarkRecentPacket */
2803 +/* -------------------------------------------------------------------------
2804 + * Function : PrunePacketHistory
2805 + * Description: Prune the packet history table.
2806 + * Input : useless - not used
2809 + * Data Used : PacketHistory
2810 + * ------------------------------------------------------------------------- */
2811 +void PrunePacketHistory(void* useless __attribute__((unused)))
2814 + for (i = 0; i < HISTORY_HASH_SIZE; i++)
2816 + if (PacketHistory[i] != NULL)
2818 + struct TDupEntry* nextEntry = PacketHistory[i];
2819 + struct TDupEntry* prevEntry = NULL;
2820 + while (nextEntry != NULL)
2822 + struct TDupEntry* entry = nextEntry;
2823 + nextEntry = entry->next;
2825 + if (TIMED_OUT(entry->timeOut))
2828 + if (prevEntry != NULL)
2830 + prevEntry->next = entry->next;
2834 + PacketHistory[i] = entry->next;
2837 + /* De-allocate memory */
2842 + prevEntry = entry;
2845 + } /* if (PacketHistory[i] != NULL) */
2846 + } /* for (i = ...) */
2847 +} /* PrunePacketHistory */
2850 + * Local Variables:
2851 + * c-basic-offset: 2
2852 + * indent-tabs-mode: nil
2856 +++ b/lib/mdns/src/PacketHistory.h
2858 +#ifndef _BMF_PACKETHISTORY_H
2859 +#define _BMF_PACKETHISTORY_H
2862 + * OLSR Basic Multicast Forwarding (BMF) plugin.
2863 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
2864 + * Written by Erik Tromp.
2865 + * All rights reserved.
2867 + * Redistribution and use in source and binary forms, with or without
2868 + * modification, are permitted provided that the following conditions
2871 + * * Redistributions of source code must retain the above copyright
2872 + * notice, this list of conditions and the following disclaimer.
2873 + * * Redistributions in binary form must reproduce the above copyright
2874 + * notice, this list of conditions and the following disclaimer in
2875 + * the documentation and/or other materials provided with the
2877 + * * Neither the name of Thales, BMF nor the names of its
2878 + * contributors may be used to endorse or promote products derived
2879 + * from this software without specific prior written permission.
2881 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2882 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2883 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2884 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2885 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2886 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2887 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2888 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2889 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2890 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2893 +/* -------------------------------------------------------------------------
2894 + * File : PacketHistory.h
2895 + * Description: Functions for keeping and accessing the history of processed
2896 + * multicast IP packets.
2897 + * Created : 29 Jun 2006
2899 + * ------------------------------------------------------------------------- */
2901 +/* System includes */
2902 +#include <sys/types.h> /* ssize_t */
2903 +#include <sys/times.h> /* clock_t */
2905 +#define N_HASH_BITS 12
2906 +#define HISTORY_HASH_SIZE (1 << N_HASH_BITS)
2908 +/* Time-out of duplicate entries, in milliseconds */
2909 +#define HISTORY_HOLD_TIME 3000
2915 + struct TDupEntry* next;
2918 +void InitPacketHistory(void);
2919 +u_int32_t PacketCrc32(unsigned char* ipPkt, ssize_t len);
2920 +u_int32_t Hash(u_int32_t from32);
2921 +void MarkRecentPacket(u_int32_t crc32);
2922 +int CheckAndMarkRecentPacket(u_int32_t crc32);
2923 +void PrunePacketHistory(void*);
2925 +#endif /* _BMF_PACKETHISTORY_H */
2928 + * Local Variables:
2929 + * c-basic-offset: 2
2930 + * indent-tabs-mode: nil
2934 +++ b/lib/mdns/src/mdns.c
2937 + * OLSR MDNS plugin.
2938 + * Written by Saverio Proto.
2940 + * Redistribution and use in source and binary forms, with or without
2941 + * modification, are permitted provided that the following conditions
2944 + * * Redistributions of source code must retain the above copyright
2945 + * notice, this list of conditions and the following disclaimer.
2946 + * * Redistributions in binary form must reproduce the above copyright
2947 + * notice, this list of conditions and the following disclaimer in
2948 + * the documentation and/or other materials provided with the
2950 + * * Neither the name of Thales, BMF nor the names of its
2951 + * contributors may be used to endorse or promote products derived
2952 + * from this software without specific prior written permission.
2954 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2955 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2956 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2957 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2958 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2959 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2960 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2961 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2962 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
2963 + * OF THE POSSIBILITY OF SUCH DAMAGE.
2967 +//#define _MULTI_THREADED
2971 +/* System includes */
2972 +#include <stddef.h> /* NULL */
2973 +#include <sys/types.h> /* ssize_t */
2974 +#include <string.h> /* strerror() */
2975 +#include <stdarg.h> /* va_list, va_start, va_end */
2976 +#include <errno.h> /* errno */
2977 +#include <assert.h> /* assert() */
2978 +#include <linux/if_ether.h> /* ETH_P_IP */
2979 +#include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
2980 +//#include <pthread.h> /* pthread_t, pthread_create() */
2981 +#include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
2982 +#include <netinet/ip.h> /* struct ip */
2983 +#include <netinet/udp.h> /* struct udphdr */
2984 +#include <unistd.h> /* close() */
2986 +#include <netinet/in.h>
2987 +#include <netinet/ip6.h>
2989 +/* OLSRD includes */
2990 +#include "plugin_util.h" /* set_plugin_int */
2991 +#include "defs.h" /* olsr_cnf, OLSR_PRINTF */
2992 +#include "ipcalc.h"
2993 +#include "olsr.h" /* OLSR_PRINTF */
2994 +#include "mid_set.h" /* mid_lookup_main_addr() */
2995 +#include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
2996 +#include "link_set.h" /* get_best_link_to_neighbor() */
2997 +#include "net_olsr.h" /* ipequal */
2999 +/* plugin includes */
3000 +#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
3001 +#include "Address.h" /* IsMulticast() */
3002 +#include "Packet.h" /* ENCAP_HDR_LEN, BMF_ENCAP_TYPE, BMF_ENCAP_LEN etc. */
3003 +#include "PacketHistory.h" /* InitPacketHistory() */
3005 +//static pthread_t mdnsThread;
3006 +//static int mdnsThreadRunning = 0;
3008 +/* -------------------------------------------------------------------------
3009 + * Function : PacketReceivedFromOLSR
3010 + * Description: Handle a received packet from a OLSR message
3011 + * Input : ipPacket into an unsigned char and the lenght of the packet
3014 + * Data Used : BmfInterfaces
3015 + * ------------------------------------------------------------------------- */
3016 +static void PacketReceivedFromOLSR(
3017 + unsigned char* encapsulationUdpData, int len)
3019 + struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
3020 + union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
3021 + union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
3022 + struct TBmfInterface* walker;
3023 + ipHeader = (struct ip*) encapsulationUdpData;
3024 + mcSrc.v4 = ipHeader->ip_src;
3025 + mcDst.v4 = ipHeader->ip_dst;
3027 + OLSR_PRINTF(3, "MDNS PLUGIN got packet from OLSR message\n");
3030 + /* Check with each network interface what needs to be done on it */
3031 + for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3033 + /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
3034 + if (walker->olsrIntf == NULL)
3036 + int nBytesWritten;
3037 + struct sockaddr_ll dest;
3039 + memset(&dest, 0, sizeof(dest));
3040 + dest.sll_family = AF_PACKET;
3041 + if ((encapsulationUdpData[0] & 0xf0) == 0x40) dest.sll_protocol = htons(ETH_P_IP);
3042 + if ((encapsulationUdpData[0] & 0xf0) == 0x60) dest.sll_protocol = htons(ETH_P_IPV6);
3043 + //TODO: if packet is not IP die here
3044 + dest.sll_ifindex = if_nametoindex(walker->ifName);
3045 + dest.sll_halen = IFHWADDRLEN;
3047 + /* Use all-ones as destination MAC address. When the IP destination is
3048 + * a multicast address, the destination MAC address should normally also
3049 + * be a multicast address. E.g., when the destination IP is 224.0.0.1,
3050 + * the destination MAC should be 01:00:5e:00:00:01. However, it does not
3051 + * seem to matter when the destination MAC address is set to all-ones
3052 + * in that case. */
3053 + memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
3055 + nBytesWritten = sendto(
3056 + walker->capturingSkfd,
3057 + encapsulationUdpData,
3060 + (struct sockaddr*) &dest,
3062 + if (nBytesWritten != len)
3064 + BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
3071 + "%s: --> unpacked and forwarded on \"%s\"\n",
3072 + PLUGIN_NAME_SHORT,
3075 + } /* if (walker->olsrIntf == NULL) */
3077 +} /* PacketReceivedFromOLSR */
3082 +olsr_parser(union olsr_message *m,
3083 + struct interface *in_if __attribute__((unused)),
3084 + union olsr_ip_addr *ipaddr)
3086 + union olsr_ip_addr originator;
3088 + olsr_reltime vtime;
3089 + OLSR_PRINTF(2, "MDNS PLUGIN: Received msg in parser\n");
3090 + /* Fetch the originator of the messsage */
3091 + if(olsr_cnf->ip_version == AF_INET) {
3092 + memcpy(&originator, &m->v4.originator, olsr_cnf->ipsize);
3093 + vtime = me_to_reltime(m->v4.olsr_vtime);
3094 + size = ntohs(m->v4.olsr_msgsize);
3096 + memcpy(&originator, &m->v6.originator, olsr_cnf->ipsize);
3097 + vtime = me_to_reltime(m->v6.olsr_vtime);
3098 + size = ntohs(m->v6.olsr_msgsize);
3101 + /* Check if message originated from this node.
3102 + * If so - back off */
3103 + if(ipequal(&originator, &olsr_cnf->main_addr))
3106 + /* Check that the neighbor this message was received from is symmetric.
3107 + * If not - back off*/
3108 + if(check_neighbor_link(ipaddr) != SYM_LINK) {
3109 + struct ipaddr_str strbuf;
3110 + OLSR_PRINTF(3, "NAME PLUGIN: Received msg from NON SYM neighbor %s\n", olsr_ip_to_string(&strbuf, ipaddr));
3114 + if(olsr_cnf->ip_version == AF_INET){
3115 + PacketReceivedFromOLSR((unsigned char*) &m->v4.message,size-12);
3118 + PacketReceivedFromOLSR((unsigned char*) &m->v6.message,size-12-96);
3120 + /* Forward the message */
3124 +//Sends a packet in the OLSR network
3126 +olsr_mdns_gen(unsigned char* packet, int len)
3128 + /* send buffer: huge */
3129 + char buffer[10240];
3130 + union olsr_message *message = (union olsr_message *)buffer;
3131 + struct interface *ifn;
3134 + /* fill message */
3135 + if(olsr_cnf->ip_version == AF_INET)
3138 + message->v4.olsr_msgtype = MESSAGE_TYPE;
3139 + message->v4.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
3140 + memcpy(&message->v4.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
3141 + message->v4.ttl = MAX_TTL;
3142 + message->v4.hopcnt = 0;
3143 + message->v4.seqno = htons(get_msg_seqno());
3145 + message->v4.olsr_msgsize = htons(len+12);
3147 + memcpy(&message->v4.message,packet,len);
3153 + message->v6.olsr_msgtype = MESSAGE_TYPE;
3154 + message->v6.olsr_vtime = reltime_to_me(MDNS_VALID_TIME * MSEC_PER_SEC);
3155 + memcpy(&message->v6.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
3156 + message->v6.ttl = MAX_TTL;
3157 + message->v6.hopcnt = 0;
3158 + message->v6.seqno = htons(get_msg_seqno());
3160 + message->v6.olsr_msgsize = htons(len+12+96);
3161 + memcpy(&message->v6.message,packet,len);
3165 + /* looping trough interfaces */
3166 + for (ifn = ifnet; ifn; ifn = ifn->int_next) {
3167 + OLSR_PRINTF(1, "MDNS PLUGIN: Generating packet - [%s]\n", ifn->int_name);
3169 + if(net_outbuffer_push(ifn, message, len) != len) {
3170 + /* send data and try again */
3172 + if(net_outbuffer_push(ifn, message, len) != len) {
3173 + OLSR_PRINTF(1, "MDNS PLUGIN: could not send on interface: %s\n", ifn->int_name);
3179 +/* -------------------------------------------------------------------------
3180 + * Function : BmfPError
3181 + * Description: Prints an error message at OLSR debug level 1.
3182 + * First the plug-in name is printed. Then (if format is not NULL
3183 + * and *format is not empty) the arguments are printed, followed
3184 + * by a colon and a blank. Then the message and a new-line.
3185 + * Input : format, arguments
3188 + * Data Used : none
3189 + * ------------------------------------------------------------------------- */
3191 +void BmfPError(const char* format, ...)
3193 +#define MAX_STR_DESC 255
3195 + char* strErr = strerror(errno);
3197 + char strDesc[MAX_STR_DESC];
3199 + /* Rely on short-circuit boolean evaluation */
3200 + if (format == NULL || *format == '\0')
3202 + OLSR_PRINTF(1, "%s: %s\n", PLUGIN_NAME, strErr);
3208 + OLSR_PRINTF(1, "%s: ", PLUGIN_NAME);
3210 + va_start(arglist, format);
3211 + vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
3214 + strDesc[MAX_STR_DESC - 1] = '\0'; /* Ensures null termination */
3216 + OLSR_PRINTF(1, "%s: %s\n", strDesc, strErr);
3220 +/* -------------------------------------------------------------------------
3221 + * Function : MainAddressOf
3222 + * Description: Lookup the main address of a node
3223 + * Input : ip - IP address of the node
3225 + * Return : The main IP address of the node
3226 + * Data Used : none
3227 + * ------------------------------------------------------------------------- */
3228 +union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip)
3230 + union olsr_ip_addr* result;
3232 + /* TODO: mid_lookup_main_addr() is not thread-safe! */
3233 + result = mid_lookup_main_addr(ip);
3234 + if (result == NULL)
3239 +} /* MainAddressOf */
3241 +/* -------------------------------------------------------------------------
3242 + * Function : EncapsulateAndForwardPacket
3243 + * Description: Encapsulate a captured raw IP packet and forward it
3244 + * Input : intf - the network interface on which to forward the packet
3245 + * encapsulationUdpData - The encapsulation header, followed by
3246 + * the encapsulated IP packet
3249 + * Data Used : none
3250 + * ------------------------------------------------------------------------- */
3251 +//static void EncapsulateAndForwardPacket(
3252 +// struct TBmfInterface* intf,
3253 +// unsigned char* encapsulationUdpData)
3255 +//// /* The packet */
3256 +// u_int16_t udpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
3258 +// /* The next destination(s) */
3259 +// struct TBestNeighbors bestNeighborLinks;
3260 +// struct link_entry* bestNeighbor;
3262 +// int nPossibleNeighbors = 0;
3263 +// struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
3264 +// int nPacketsToSend;
3265 +// int sendUnicast; /* 0 = send broadcast; 1 = send unicast */
3269 +// /* Find at most 'FanOutLimit' best neigbors to forward the packet to */
3270 +// FindNeighbors(&bestNeighborLinks, &bestNeighbor, intf, NULL, NULL, NULL, &nPossibleNeighbors);
3272 +// if (nPossibleNeighbors <= 0)
3276 +// "%s: --> not encap-forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
3277 +// PLUGIN_NAME_SHORT,
3282 +// /* Compose destination of encapsulation packet */
3284 +// memset(&forwardTo, 0, sizeof(forwardTo));
3285 +// forwardTo.sin_family = AF_INET;
3286 +// forwardTo.sin_port = htons(BMF_ENCAP_PORT);
3288 +// /* Start by filling in the local broadcast address. This may be overwritten later. */
3289 +// forwardTo.sin_addr = intf->broadAddr.v4;
3291 +// /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
3292 +// * unicast packet (to the best neighbor).
3293 +// * - But if the BMF mechanism is BM_BROADCAST,
3294 +// * - send 'nPossibleNeighbors' unicast packets if there are up to
3295 +// * 'FanOutLimit' possible neighbors,
3296 +// * - if there are more than 'FanOutLimit' possible neighbors, then
3297 +// * send a (WLAN-air-expensive, less reliable) broadcast packet. */
3298 +// if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
3300 +// /* One unicast packet to the best neighbor */
3301 +// nPacketsToSend = 1;
3302 +// sendUnicast = 1;
3303 +// bestNeighborLinks.links[0] = bestNeighbor;
3305 +// else /* BmfMechanism == BM_BROADCAST */
3307 +// if (nPossibleNeighbors <= FanOutLimit)
3309 +// /* 'nPossibleNeighbors' unicast packets */
3310 +// nPacketsToSend = nPossibleNeighbors;
3311 +// sendUnicast = 1;
3313 +// else /* nPossibleNeighbors > FanOutLimit */
3315 +// /* One broadcast packet, possibly retransmitted as specified in the
3316 +// * 'BroadcastRetransmitCount' plugin parameter */
3317 +// nPacketsToSend = BroadcastRetransmitCount;
3318 +// sendUnicast = 0;
3322 +// for (i = 0; i < nPacketsToSend; i++)
3324 +// int nBytesWritten;
3326 +// if (sendUnicast == 1)
3328 +// /* For unicast, overwrite the local broadcast address which was filled in above */
3329 +// forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
3332 +// /* Forward the BMF packet via the encapsulation socket */
3333 +// nBytesWritten = sendto(
3334 +// intf->encapsulatingSkfd,
3335 +// encapsulationUdpData,
3338 +// (struct sockaddr*) &forwardTo,
3339 +// sizeof(forwardTo));
3341 +// /* Evaluate and display result */
3342 +// if (nBytesWritten != udpDataLen)
3344 +// BmfPError("sendto() error forwarding pkt on \"%s\"", intf->ifName);
3348 +// /* Increase counter */
3349 +// intf->nBmfPacketsTx++;
3353 +// "%s: --> encapsulated and forwarded on \"%s\" to %s\n",
3354 +// PLUGIN_NAME_SHORT,
3356 +// inet_ntoa(forwardTo.sin_addr));
3357 +// } /* if (nBytesWritten != udpDataLen) */
3359 +//} /* EncapsulateAndForwardPacket */
3361 +/* -------------------------------------------------------------------------
3362 + * Function : BmfPacketCaptured
3363 + * Description: Handle a captured IP packet
3364 + * Input : intf - the network interface on which the packet was captured
3365 + * sllPkttype - the type of packet. Either PACKET_OUTGOING,
3366 + * PACKET_BROADCAST or PACKET_MULTICAST.
3367 + * encapsulationUdpData - space for the encapsulation header, followed by
3368 + * the captured IP packet