003061119448877f5b03a86fe8ed231e51e69f9f
[project/luci.git] / contrib / package / olsrd-luci / patches / 160-add-mdns.patch
1 --- a/Makefile
2 +++ b/Makefile
3 @@ -154,7 +154,7 @@
4 # nameservice: no regex
5 SUBDIRS := bmf dot_draw dyn_gw_plain httpinfo mini quagga secure tas txtinfo watchdog
6 else
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
9 endif
10 endif
11 endif
12 @@ -241,6 +241,11 @@
13 $(MAKECMD) -C lib/watchdog
14 $(MAKECMD) -C lib/watchdog DESTDIR=$(DESTDIR) install
15
16 +mdns:
17 + $(MAKECMD) -C lib/mdns clean
18 + $(MAKECMD) -C lib/mdns
19 + $(MAKECMD) -C lib/mdns DESTDIR=$(DESTDIR) install
20 +
21 build_all: all switch libs
22 install_all: install install_libs
23 clean_all: uberclean clean_libs
24 --- /dev/null
25 +++ b/lib/mdns/Makefile
26 @@ -0,0 +1,66 @@
27 +#
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.
32 +#
33 +# Redistribution and use in source and binary forms, with or without
34 +# modification, are permitted provided that the following conditions
35 +# are met:
36 +#
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
42 +# distribution.
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.
46 +#
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.
59 +#
60 +
61 +OLSRD_PLUGIN = true
62 +PLUGIN_NAME = olsrd_mdns
63 +PLUGIN_VER = 1.0.0
64 +
65 +TOPDIR = ../..
66 +include $(TOPDIR)/Makefile.inc
67 +
68 +LIBS += $(OS_LIB_PTHREAD)
69 +
70 +# Must be specified along with -lpthread on linux
71 +CPPFLAGS += $(OS_CFLAG_PTHREAD)
72 +
73 +ifneq ($(OS),linux)
74 +
75 +default_target install clean:
76 + @echo "*** BMF Plugin only supported on Linux, sorry!"
77 +
78 +else
79 +
80 +default_target: $(PLUGIN_FULLNAME)
81 +
82 +$(PLUGIN_FULLNAME): $(OBJS) version-script.txt
83 + $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
84 +
85 +install: $(PLUGIN_FULLNAME)
86 + $(STRIP) $(PLUGIN_FULLNAME)
87 + $(INSTALL_LIB)
88 +
89 +clean:
90 + rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
91 +
92 +endif
93 --- /dev/null
94 +++ b/lib/mdns/src/Address.c
95 @@ -0,0 +1,164 @@
96 +/*
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.
101 + *
102 + * Redistribution and use in source and binary forms, with or without
103 + * modification, are permitted provided that the following conditions
104 + * are met:
105 + *
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
111 + * distribution.
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.
115 + *
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.
126 + */
127 +
128 +/* -------------------------------------------------------------------------
129 + * File : Address.c
130 + * Description: IP packet characterization functions
131 + * Created : 29 Jun 2006
132 + *
133 + * ------------------------------------------------------------------------- */
134 +
135 +#include "Address.h"
136 +
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 */
143 +
144 +/* OLSRD includes */
145 +#include "defs.h" /* ipequal */
146 +#include "olsr_protocol.h" /* OLSRPORT */
147 +
148 +/* Plugin includes */
149 +#include "mdns.h" /* BMF_ENCAP_PORT */
150 +#include "NetworkInterfaces.h" /* TBmfInterface */
151 +
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;
156 +
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"
162 + * data - not used
163 + * addon - not used
164 + * Output : none
165 + * Return : success (0) or fail (1)
166 + * Data Used : none
167 + * ------------------------------------------------------------------------- */
168 +int DoLocalBroadcast(
169 + const char* enable,
170 + void* data __attribute__((unused)),
171 + set_plugin_parameter_addon addon __attribute__((unused)))
172 +{
173 + if (strcmp(enable, "yes") == 0)
174 + {
175 + EnableLocalBroadcast = 1;
176 + return 0;
177 + }
178 + else if (strcmp(enable, "no") == 0)
179 + {
180 + EnableLocalBroadcast = 0;
181 + return 0;
182 + }
183 +
184 + /* Value not recognized */
185 + return 1;
186 +}
187 +
188 +/* -------------------------------------------------------------------------
189 + * Function : IsMulticast
190 + * Description: Check if an IP address is a multicast address
191 + * Input : ipAddress
192 + * Output : none
193 + * Return : true (1) or false (0)
194 + * Data Used : none
195 + * ------------------------------------------------------------------------- */
196 +int IsMulticast(union olsr_ip_addr* ipAddress)
197 +{
198 + assert(ipAddress != NULL);
199 +
200 + return (ntohl(ipAddress->v4.s_addr) & 0xF0000000) == 0xE0000000;
201 +}
202 +
203 +/* -------------------------------------------------------------------------
204 + * Function : IsOlsrOrBmfPacket
205 + * Description: Check if an IP packet is either an OLSR packet or a BMF packet
206 + * Input : ipPacket
207 + * Output : none
208 + * Return : true (1) or false (0)
209 + * Data Used : none
210 + * ------------------------------------------------------------------------- */
211 +//int IsOlsrOrBmfPacket(unsigned char* ipPacket)
212 +//{//MODIFICATA
213 +// struct ip* ipHeader;
214 +// unsigned int ipHeaderLen;
215 +// struct udphdr* udpHeader;
216 +// u_int16_t destPort;
217 +//
218 +// assert(ipPacket != NULL);
219 +//
220 +// /* OLSR packets are UDP - port 698
221 +// * OLSR-BMF packets are UDP - port 50698
222 +// * OLSR-Autodetect probe packets are UDP - port 51698 */
223 +//
224 +// /* Check if UDP */
225 +// ipHeader = (struct ip*) ipPacket;
226 +// if (ipHeader->ip_p != SOL_UDP)
227 +// {
228 +// /* Not UDP */
229 +// return 0;
230 +// }
231 +//
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))
235 +// {
236 +// /* Not long enough */
237 +// return 0;
238 +// }
239 +//
240 +// /* Go into the UDP header and check port number */
241 +// udpHeader = (struct udphdr*) (ipPacket + ipHeaderLen);
242 +// destPort = ntohs(udpHeader->dest);
243 +//
244 +// //if (destPort == OLSRPORT || destPort == BMF_ENCAP_PORT || destPort == 51698)
245 +// if (destPort == 5353)
246 +// /* TODO: #define for 51698 */
247 +// {
248 +// return 1;
249 +// }
250 +//
251 +// return 0;
252 +//}
253 +//
254 +/*
255 + * Local Variables:
256 + * c-basic-offset: 2
257 + * indent-tabs-mode: nil
258 + * End:
259 + */
260 --- /dev/null
261 +++ b/lib/mdns/src/Address.h
262 @@ -0,0 +1,62 @@
263 +#ifndef _BMF_ADDRESS_H
264 +#define _BMF_ADDRESS_H
265 +
266 +/*
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.
271 + *
272 + * Redistribution and use in source and binary forms, with or without
273 + * modification, are permitted provided that the following conditions
274 + * are met:
275 + *
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
281 + * distribution.
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.
285 + *
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.
296 + */
297 +
298 +/* -------------------------------------------------------------------------
299 + * File : Address.h
300 + * Description: IP packet characterization functions
301 + * Created : 29 Jun 2006
302 + *
303 + * ------------------------------------------------------------------------- */
304 +
305 +#include "olsr_types.h" /* olsr_ip_addr */
306 +#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
307 +#include "interfaces.h" /* struct interface */
308 +
309 +struct TBmfInterface;
310 +
311 +extern int EnableLocalBroadcast;
312 +
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);
316 +
317 +#endif /* _BMF_ADDRESS_H */
318 +
319 +/*
320 + * Local Variables:
321 + * c-basic-offset: 2
322 + * indent-tabs-mode: nil
323 + * End:
324 + */
325 --- /dev/null
326 +++ b/lib/mdns/src/NetworkInterfaces.c
327 @@ -0,0 +1,1703 @@
328 +/*
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.
333 + *
334 + * Redistribution and use in source and binary forms, with or without
335 + * modification, are permitted provided that the following conditions
336 + * are met:
337 + *
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
343 + * distribution.
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.
347 + *
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.
358 + */
359 +
360 +/* -------------------------------------------------------------------------
361 + * File : NetworkInterfaces.c
362 + * Description: Functions to open and close sockets
363 + * Created : 29 Jun 2006
364 + *
365 + * ------------------------------------------------------------------------- */
366 +
367 +#include "NetworkInterfaces.h"
368 +
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 */
386 +
387 +/* OLSRD includes */
388 +#include "olsr.h" /* OLSR_PRINTF() */
389 +#include "ipcalc.h"
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"
395 +
396 +
397 +/* Plugin includes */
398 +#include "Packet.h" /* IFHWADDRLEN */
399 +#include "mdns.h" /* PLUGIN_NAME, MainAddressOf() */
400 +#include "Address.h" /* IsMulticast() */
401 +
402 +/* List of network interface objects used by BMF plugin */
403 +struct TBmfInterface* BmfInterfaces = NULL;
404 +struct TBmfInterface* LastBmfInterface = NULL;
405 +
406 +/* Highest-numbered open socket file descriptor. To be used as first
407 + * parameter in calls to select(...). */
408 +int HighestSkfd = -1;
409 +
410 +/* Set of socket file descriptors */
411 +fd_set InputSet;
412 +
413 +/* File descriptor of EtherTunTap interface */
414 +int EtherTunTapFd = -1;
415 +
416 +/* Network interface name of EtherTunTap interface. May be overruled by
417 + * setting the plugin parameter "BmfInterface". */
418 +char EtherTunTapIfName[IFNAMSIZ] = "bmf0";
419 +
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;
425 +
426 +#define ETHERTUNTAPIPNOTSET 0
427 +
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;
431 +
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;
435 +
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;
439 +
440 +/* Whether or not the configuration has overruled the default IP
441 + * configuration of the EtherTunTap interface */
442 +int TunTapIpOverruled = 0;
443 +
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;
448 +
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")
454 + * data - not used
455 + * addon - not used
456 + * Output : none
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)))
464 +{
465 + strncpy(EtherTunTapIfName, ifname, IFNAMSIZ - 1);
466 + EtherTunTapIfName[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
467 + return 0;
468 +} /* SetBmfInterfaceName */
469 +
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
475 + * data - not used
476 + * addon - not used
477 + * Output : none
478 + * Return : success (0) or fail (1)
479 + * Data Used : EtherTunTapIp, EtherTunTapIpMask, EtherTunTapIpBroadcast,
480 + * TunTapIpOverruled
481 + * ------------------------------------------------------------------------- */
482 +int SetBmfInterfaceIp(
483 + const char* ip,
484 + void* data __attribute__((unused)),
485 + set_plugin_parameter_addon addon __attribute__((unused)))
486 +{
487 +#define IPV4_MAX_ADDRLEN 16
488 +#define IPV4_MAX_PREFIXLEN 32
489 + char* slashAt;
490 + char ipAddr[IPV4_MAX_ADDRLEN];
491 + struct in_addr sinaddr;
492 + int prefixLen;
493 + int i;
494 +
495 + /* Inspired by function str2prefix_ipv4 as found in Quagga source
496 + * file lib/prefix.c */
497 +
498 + /* Find slash inside string. */
499 + slashAt = strchr(ip, '/');
500 +
501 + /* String doesn't contain slash. */
502 + if (slashAt == NULL || slashAt - ip >= IPV4_MAX_ADDRLEN)
503 + {
504 + /* No prefix length specified, or IP address too long */
505 + return 1;
506 + }
507 +
508 + strncpy(ipAddr, ip, slashAt - ip);
509 + *(ipAddr + (slashAt - ip)) = '\0';
510 + if (inet_aton(ipAddr, &sinaddr) == 0)
511 + {
512 + /* Invalid address passed */
513 + return 1;
514 + }
515 +
516 + EtherTunTapIp = ntohl(sinaddr.s_addr);
517 +
518 + /* Get prefix length. */
519 + prefixLen = atoi(++slashAt);
520 + if (prefixLen <= 0 || prefixLen > IPV4_MAX_PREFIXLEN)
521 + {
522 + return 1;
523 + }
524 +
525 + /* Compose IP subnet mask in host byte order */
526 + EtherTunTapIpMask = 0;
527 + for (i = 0; i < prefixLen; i++)
528 + {
529 + EtherTunTapIpMask |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
530 + }
531 +
532 + /* Compose IP broadcast address in host byte order */
533 + EtherTunTapIpBroadcast = EtherTunTapIp;
534 + for (i = prefixLen; i < IPV4_MAX_PREFIXLEN; i++)
535 + {
536 + EtherTunTapIpBroadcast |= (1 << (IPV4_MAX_PREFIXLEN - 1 - i));
537 + }
538 +
539 + TunTapIpOverruled = 1;
540 +
541 + return 0;
542 +} /* SetBmfInterfaceIp */
543 +
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"
549 + * data - not used
550 + * addon - not used
551 + * Output : none
552 + * Return : success (0) or fail (1)
553 + * Data Used : none
554 + * ------------------------------------------------------------------------- */
555 +int SetCapturePacketsOnOlsrInterfaces(
556 + const char* enable,
557 + void* data __attribute__((unused)),
558 + set_plugin_parameter_addon addon __attribute__((unused)))
559 +{
560 + if (strcmp(enable, "yes") == 0)
561 + {
562 + CapturePacketsOnOlsrInterfaces = 1;
563 + return 0;
564 + }
565 + else if (strcmp(enable, "no") == 0)
566 + {
567 + CapturePacketsOnOlsrInterfaces = 0;
568 + return 0;
569 + }
570 +
571 + /* Value not recognized */
572 + return 1;
573 +} /* SetCapturePacketsOnOlsrInterfaces */
574 +
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"
580 + * data - not used
581 + * addon - not used
582 + * Output : none
583 + * Return : success (0) or fail (1)
584 + * Data Used : none
585 + * ------------------------------------------------------------------------- */
586 +int SetBmfMechanism(
587 + const char* mechanism,
588 + void* data __attribute__((unused)),
589 + set_plugin_parameter_addon addon __attribute__((unused)))
590 +{
591 + if (strcmp(mechanism, "Broadcast") == 0)
592 + {
593 + BmfMechanism = BM_BROADCAST;
594 + return 0;
595 + }
596 + else if (strcmp(mechanism, "UnicastPromiscuous") == 0)
597 + {
598 + BmfMechanism = BM_UNICAST_PROMISCUOUS;
599 + return 0;
600 + }
601 +
602 + /* Value not recognized */
603 + return 1;
604 +} /* SetBmfMechanism */
605 +
606 +/* -------------------------------------------------------------------------
607 + * Function : AddDescriptorToInputSet
608 + * Description: Add a socket descriptor to the global set of socket file descriptors
609 + * Input : skfd - socket file descriptor
610 + * Output : none
611 + * Return : none
612 + * Data Used : HighestSkfd, InputSet
613 + * Notes : Keeps track of the highest-numbered descriptor
614 + * ------------------------------------------------------------------------- */
615 +static void AddDescriptorToInputSet(int skfd)
616 +{
617 + /* Keep the highest-numbered descriptor */
618 + if (skfd > HighestSkfd)
619 + {
620 + HighestSkfd = skfd;
621 + }
622 +
623 + /* Add descriptor to input set */
624 + FD_SET(skfd, &InputSet);
625 +} /* AddDescriptorToInputSet */
626 +
627 +/* To save the state of the IP spoof filter for the EtherTunTap interface */
628 +static char EthTapSpoofState = '1';
629 +
630 +/* -------------------------------------------------------------------------
631 + * Function : DeactivateSpoofFilter
632 + * Description: Deactivates the Linux anti-spoofing filter for the tuntap
633 + * interface
634 + * Input : none
635 + * Output : none
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)
641 +{
642 + FILE* procSpoof;
643 + char procFile[FILENAME_MAX];
644 +
645 + /* Generate the procfile name */
646 + sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
647 +
648 + /* Open procfile for reading */
649 + procSpoof = fopen(procFile, "r");
650 + if (procSpoof == NULL)
651 + {
652 + fprintf(
653 + stderr,
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",
659 + procFile);
660 +
661 + sleep(3);
662 + return 0;
663 + }
664 +
665 + EthTapSpoofState = fgetc(procSpoof);
666 + fclose(procSpoof);
667 +
668 + /* Open procfile for writing */
669 + procSpoof = fopen(procFile, "w");
670 + if (procSpoof == NULL)
671 + {
672 + fprintf(stderr, "Could not open %s for writing!\n", procFile);
673 + fprintf(
674 + stderr,
675 + "I will continue (in 3 sec) - but you should manually ensure that IP"
676 + " spoof filtering is disabled!\n\n");
677 + sleep(3);
678 + return 0;
679 + }
680 +
681 + syslog(LOG_INFO, "Writing \"0\" to %s", procFile);
682 + fputs("0", procSpoof);
683 +
684 + fclose(procSpoof);
685 +
686 + return 1;
687 +} /* DeactivateSpoofFilter */
688 +
689 +/* -------------------------------------------------------------------------
690 + * Function : RestoreSpoofFilter
691 + * Description: Restores the Linux anti-spoofing filter setting for the tuntap
692 + * interface
693 + * Input : none
694 + * Output : none
695 + * Return : none
696 + * Data Used : EtherTunTapIfName, EthTapSpoofState
697 + * ------------------------------------------------------------------------- */
698 +void RestoreSpoofFilter(void)
699 +{
700 + FILE* procSpoof;
701 + char procFile[FILENAME_MAX];
702 +
703 + /* Generate the procfile name */
704 + sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", EtherTunTapIfName);
705 +
706 + /* Open procfile for writing */
707 + procSpoof = fopen(procFile, "w");
708 + if (procSpoof == NULL)
709 + {
710 + fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procFile);
711 + }
712 + else
713 + {
714 + syslog(LOG_INFO, "Resetting %s to %c\n", procFile, EthTapSpoofState);
715 +
716 + fputc(EthTapSpoofState, procSpoof);
717 + fclose(procSpoof);
718 + }
719 +} /* RestoreSpoofFilter */
720 +
721 +/* -------------------------------------------------------------------------
722 + * Function : FindNeighbors
723 + * Description: Find the neighbors on a network interface to forward a BMF
724 + * packet to
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
728 + * packet
729 + * forwardedTo - the IP address of the node to which the BMF packet
730 + * was directed
731 + * Output : neighbors - list of (up to a number of 'FanOutLimit') neighbors.
732 + * bestNeighbor - the best neighbor (in terms of lowest cost or ETX
733 + * value)
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)
745 +//{
746 +// struct link_entry* walker;
747 +// olsr_linkcost previousLinkEtx = LINK_COST_BROKEN;
748 +// olsr_linkcost bestEtx = LINK_COST_BROKEN;
749 +//
750 +// int i;
751 +//
752 +// /* Initialize */
753 +// *bestNeighbor = NULL;
754 +// for (i = 0; i < MAX_UNICAST_NEIGHBORS; i++)
755 +// {
756 +// neighbors->links[i] = NULL;
757 +// }
758 +// *nPossibleNeighbors = 0;
759 +//
760 +// if (forwardedBy != NULL)
761 +// {
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)
765 +// {
766 +// previousLinkEtx = bestLinkFromForwarder->linkcost;
767 +// }
768 +// }
769 +//
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;
775 +// float currEtx;
776 +//
777 +// /* Consider only links from the specified interface */
778 +// if (! olsr_ipequal(&intf->intAddr, &walker->local_iface_addr))
779 +// {
780 +// continue; /* for */
781 +// }
782 +//
783 +// OLSR_PRINTF(
784 +// 9,
785 +// "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
786 +// PLUGIN_NAME_SHORT,
787 +// intf->ifName,
788 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
789 +//
790 +// neighborMainIp = MainAddressOf(&walker->neighbor_iface_addr);
791 +//
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)))
795 +// {
796 +// OLSR_PRINTF(
797 +// 9,
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));
801 +//
802 +// continue; /* for */
803 +// }
804 +//
805 +// /* Rely on short-circuit boolean evaluation */
806 +// if (forwardedBy != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
807 +// {
808 +// OLSR_PRINTF(
809 +// 9,
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));
813 +//
814 +// continue; /* for */
815 +// }
816 +//
817 +// /* Rely on short-circuit boolean evaluation */
818 +// if (forwardedTo != NULL && olsr_ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
819 +// {
820 +// OLSR_PRINTF(
821 +// 9,
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));
825 +//
826 +// continue; /* for */
827 +// }
828 +//
829 +// /* Found a candidate neighbor to direct our packet to */
830 +//
831 +// /* Calculate the link quality (ETX) of the link to the found neighbor */
832 +// currEtx = walker->linkcost;
833 +//
834 +// if (currEtx >= LINK_COST_BROKEN)
835 +// {
836 +// OLSR_PRINTF(
837 +// 9,
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));
841 +//
842 +// continue; /* for */
843 +// }
844 +//
845 +// /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
846 +// OLSR_PRINTF(
847 +// 9,
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),
851 +// currEtx);
852 +//
853 +// /*
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.
857 +// */
858 +// bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
859 +//
860 +// if (walker != bestLinkToNeighbor)
861 +// {
862 +// if (bestLinkToNeighbor == NULL)
863 +// {
864 +// OLSR_PRINTF(
865 +// 9,
866 +// "%s: ----> Not forwarding to %s: no link found\n",
867 +// PLUGIN_NAME_SHORT,
868 +// olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
869 +// }
870 +// else
871 +// {
872 +//#ifndef NODEBUG
873 +// struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
874 +// struct lqtextbuffer lqbuffer;
875 +//#endif
876 +// OLSR_PRINTF(
877 +// 9,
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));
883 +// }
884 +//
885 +// continue; /* for */
886 +// }
887 +//
888 +// if (forwardedBy != NULL)
889 +// {
890 +//#ifndef NODEBUG
891 +// struct ipaddr_str forwardedByBuf, niaBuf;
892 +// struct lqtextbuffer lqbuffer;
893 +//#endif
894 +// OLSR_PRINTF(
895 +// 9,
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));
901 +// }
902 +//
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)
908 +// {
909 +// tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
910 +// if (tcLastHop != NULL)
911 +// {
912 +// struct tc_edge_entry* tc_edge;
913 +//
914 +// tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
915 +//
916 +// /* We are not interested in dead-end edges. */
917 +// if (tc_edge) {
918 +// olsr_linkcost tcEtx = tc_edge->cost;
919 +//
920 +// if (previousLinkEtx + currEtx > tcEtx)
921 +// {
922 +//#ifndef NODEBUG
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);
926 +//#endif
927 +// OLSR_PRINTF(
928 +// 9,
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));
935 +//
936 +// continue; /* for */
937 +// } /* if */
938 +// } /* if */
939 +// } /* if */
940 +// } /* if */
941 +//
942 +// /* Remember the best neighbor. If all are very bad, remember none. */
943 +// if (currEtx < bestEtx)
944 +// {
945 +// *bestNeighbor = walker;
946 +// bestEtx = currEtx;
947 +// }
948 +//
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)
953 +// {
954 +// neighbors->links[*nPossibleNeighbors] = walker;
955 +// }
956 +//
957 +// *nPossibleNeighbors += 1;
958 +// } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
959 +//
960 +// /* Display the result of the neighbor search */
961 +// if (*nPossibleNeighbors == 0)
962 +// {
963 +// OLSR_PRINTF(
964 +// 9,
965 +// "%s: ----> No suitable neighbor found to forward to on \"%s\"\n",
966 +// PLUGIN_NAME_SHORT,
967 +// intf->ifName);
968 +// }
969 +// else
970 +// {
971 +// struct ipaddr_str buf;
972 +// OLSR_PRINTF(
973 +// 9,
974 +// "%s: ----> %d neighbors found on \"%s\"; best neighbor to forward to: %s\n",
975 +// PLUGIN_NAME_SHORT,
976 +// *nPossibleNeighbors,
977 +// intf->ifName,
978 +// olsr_ip_to_string(&buf, &(*bestNeighbor)->neighbor_iface_addr));
979 +// } /* if */
980 +//
981 +//} /* FindNeighbors */
982 +
983 +/* -------------------------------------------------------------------------
984 + * Function : CreateCaptureSocket
985 + * Description: Create socket for promiscuously capturing multicast IP traffic
986 + * Input : ifname - network interface (e.g. "eth0")
987 + * Output : none
988 + * Return : the socket descriptor ( >= 0), or -1 if an error occurred
989 + * Data Used : none
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)
994 +{
995 + int ifIndex = if_nametoindex(ifName);
996 + struct packet_mreq mreq;
997 + struct ifreq req;
998 + struct sockaddr_ll bindTo;
999 + int skfd = 0;
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));
1003 + }
1004 + else {
1005 + skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
1006 + }
1007 + if (skfd < 0)
1008 + {
1009 + BmfPError("socket(PF_PACKET) error");
1010 + return -1;
1011 + }
1012 +
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)
1018 + {
1019 + BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1020 + close(skfd);
1021 + return -1;
1022 + }
1023 +
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)
1029 + {
1030 + BmfPError("error retrieving MAC address");
1031 + close(skfd);
1032 + return -1;
1033 + }
1034 +
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);
1040 + }
1041 + else{
1042 + bindTo.sll_protocol = htons(ETH_P_IPV6);
1043 + }
1044 + bindTo.sll_ifindex = ifIndex;
1045 + memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
1046 + bindTo.sll_halen = IFHWADDRLEN;
1047 +
1048 + if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1049 + {
1050 + BmfPError("bind() error");
1051 + close(skfd);
1052 + return -1;
1053 + }
1054 +
1055 + /* Set socket to blocking operation */
1056 + if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1057 + {
1058 + BmfPError("fcntl() error");
1059 + close(skfd);
1060 + return -1;
1061 + }
1062 +
1063 + AddDescriptorToInputSet(skfd);
1064 + add_olsr_socket(skfd,&DoMDNS);
1065 +
1066 + return skfd;
1067 +} /* CreateCaptureSocket */
1068 +
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")
1074 + * Output : none
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)
1081 +//{
1082 +// int ifIndex = if_nametoindex(ifName);
1083 +// struct packet_mreq mreq;
1084 +// struct ifreq req;
1085 +// struct sockaddr_ll bindTo;
1086 +//
1087 +// /* Open cooked IP packet socket */
1088 +// int skfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1089 +// if (skfd < 0)
1090 +// {
1091 +// BmfPError("socket(PF_PACKET) error");
1092 +// return -1;
1093 +// }
1094 +//
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)
1100 +// {
1101 +// BmfPError("setsockopt(PACKET_MR_PROMISC) error");
1102 +// close(skfd);
1103 +// return -1;
1104 +// }
1105 +//
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)
1111 +// {
1112 +// BmfPError("error retrieving MAC address");
1113 +// close(skfd);
1114 +// return -1;
1115 +// }
1116 +//
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;
1124 +//
1125 +// if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1126 +// {
1127 +// BmfPError("bind() error");
1128 +// close(skfd);
1129 +// return -1;
1130 +// }
1131 +//
1132 +// /* Set socket to blocking operation */
1133 +// if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1134 +// {
1135 +// BmfPError("fcntl() error");
1136 +// close(skfd);
1137 +// return -1;
1138 +// }
1139 +//
1140 +// AddDescriptorToInputSet(skfd);
1141 +//
1142 +// return skfd;
1143 +//} /* CreateListeningSocket */
1144 +
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")
1150 + * Output : none
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)
1157 +//{
1158 +// int on = 1;
1159 +// struct sockaddr_in bindTo;
1160 +//
1161 +// /* Open UDP-IP socket */
1162 +// int skfd = socket(PF_INET, SOCK_DGRAM, 0);
1163 +// if (skfd < 0)
1164 +// {
1165 +// BmfPError("socket(PF_INET) error");
1166 +// return -1;
1167 +// }
1168 +//
1169 +// /* Enable sending to broadcast addresses */
1170 +// if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
1171 +// {
1172 +// BmfPError("setsockopt(SO_BROADCAST) error");
1173 +// close(skfd);
1174 +// return -1;
1175 +// }
1176 +//
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)
1180 +// {
1181 +// BmfPError("setsockopt(SO_BINDTODEVICE) error");
1182 +// close(skfd);
1183 +// return -1;
1184 +// }
1185 +//
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);
1191 +//
1192 +// if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
1193 +// {
1194 +// BmfPError("bind() error");
1195 +// close(skfd);
1196 +// return -1;
1197 +// }
1198 +//
1199 +// /* Set socket to blocking operation */
1200 +// if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
1201 +// {
1202 +// BmfPError("fcntl() error");
1203 +// close(skfd);
1204 +// return -1;
1205 +// }
1206 +//
1207 +// AddDescriptorToInputSet(skfd);
1208 +//
1209 +// return skfd;
1210 +//} /* CreateEncapsulateSocket */
1211 +
1212 +/* -------------------------------------------------------------------------
1213 + * Function : CreateLocalEtherTunTap
1214 + * Description: Creates and brings up an EtherTunTap interface
1215 + * Input : none
1216 + * Output : none
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.
1219 + * "bmf0")
1220 + * EtherTunTapIp
1221 + * EtherTunTapIpMask
1222 + * EtherTunTapIpBroadcast
1223 + * BmfInterfaces
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)
1228 +//{
1229 +// static const char deviceName[] = "/dev/net/tun";
1230 +// struct ifreq ifreq;
1231 +// int etfd;
1232 +// int ioctlSkfd;
1233 +// int ioctlres;
1234 +//
1235 +// etfd = open(deviceName, O_RDWR | O_NONBLOCK);
1236 +// if (etfd < 0)
1237 +// {
1238 +// BmfPError("error opening %s", deviceName);
1239 +// return -1;
1240 +// }
1241 +//
1242 +// memset(&ifreq, 0, sizeof(ifreq));
1243 +// strncpy(ifreq.ifr_name, EtherTunTapIfName, IFNAMSIZ - 1);
1244 +// ifreq.ifr_name[IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1245 +//
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;
1250 +//
1251 +// if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
1252 +// {
1253 +// BmfPError("ioctl(TUNSETIFF) error on %s", deviceName);
1254 +// close(etfd);
1255 +// return -1;
1256 +// }
1257 +//
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;
1262 +//
1263 +// ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1264 +// if (ioctlSkfd < 0)
1265 +// {
1266 +// BmfPError("socket(PF_INET) error on %s", deviceName);
1267 +// close(etfd);
1268 +// return -1;
1269 +// }
1270 +//
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)
1276 +// {
1277 +// struct TBmfInterface* nextBmfIf = BmfInterfaces;
1278 +// while (nextBmfIf != NULL)
1279 +// {
1280 +// struct TBmfInterface* bmfIf = nextBmfIf;
1281 +// nextBmfIf = bmfIf->next;
1282 +//
1283 +// if (bmfIf->olsrIntf != NULL)
1284 +// {
1285 +// EtherTunTapIp = ntohl(bmfIf->intAddr.v4.s_addr);
1286 +// EtherTunTapIpBroadcast = EtherTunTapIp;
1287 +// }
1288 +// }
1289 +// }
1290 +//
1291 +// if (EtherTunTapIp == ETHERTUNTAPIPNOTSET)
1292 +// {
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;
1296 +// }
1297 +//
1298 +// ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp);
1299 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq);
1300 +// if (ioctlres >= 0)
1301 +// {
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)
1306 +// {
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)
1311 +// {
1312 +// /* Bring EtherTunTap interface up (if not already) */
1313 +// ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1314 +// if (ioctlres >= 0)
1315 +// {
1316 +// ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_BROADCAST);
1317 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1318 +// }
1319 +// }
1320 +// }
1321 +// }
1322 +//
1323 +// if (ioctlres < 0)
1324 +// {
1325 +// /* Any of the above ioctl() calls failed */
1326 +// BmfPError("error bringing up EtherTunTap interface \"%s\"", EtherTunTapIfName);
1327 +//
1328 +// close(etfd);
1329 +// close(ioctlSkfd);
1330 +// return -1;
1331 +// } /* if (ioctlres < 0) */
1332 +//
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 */
1337 +//
1338 +// ioctlres = ioctl(ioctlSkfd, SIOCGIFFLAGS, &ifreq);
1339 +// if (ioctlres >= 0)
1340 +// {
1341 +// ifreq.ifr_flags |= IFF_MULTICAST;
1342 +// ioctlres = ioctl(ioctlSkfd, SIOCSIFFLAGS, &ifreq);
1343 +// }
1344 +// if (ioctlres < 0)
1345 +// {
1346 +// /* Any of the two above ioctl() calls failed */
1347 +// BmfPError("error setting multicast flag on EtherTunTap interface \"%s\"", EtherTunTapIfName);
1348 +//
1349 +// /* Continue anyway */
1350 +// }
1351 +//
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)
1356 +// {
1357 +// BmfPError("error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName);
1358 +//
1359 +// /* Continue anyway */
1360 +// }
1361 +//
1362 +// OLSR_PRINTF(8, "%s: opened 1 socket on \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1363 +//
1364 +// AddDescriptorToInputSet(etfd);
1365 +//
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)
1370 +// {
1371 +// union olsr_ip_addr temp_net;
1372 +//
1373 +// temp_net.v4.s_addr = htonl(EtherTunTapIp);
1374 +// ip_prefix_list_add(&olsr_cnf->hna_entries, &temp_net, 32);
1375 +// }
1376 +//
1377 +// close(ioctlSkfd);
1378 +//
1379 +// return etfd;
1380 +//} /* CreateLocalEtherTunTap */
1381 +
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
1389 + * Output : none
1390 + * Return : the number of opened sockets
1391 + * Data Used : BmfInterfaces, LastBmfInterface
1392 + * ------------------------------------------------------------------------- */
1393 +
1394 +//FOR MDNS IS ALWAYS CALLED WITH NULL AS SECOND ARG
1395 +
1396 +static int CreateInterface(
1397 + const char* ifName,
1398 + struct interface* olsrIntf)
1399 +{
1400 + int capturingSkfd = -1;
1401 + int encapsulatingSkfd = -1;
1402 + int listeningSkfd = -1;
1403 + int ioctlSkfd;
1404 + struct ifreq ifr;
1405 + int nOpened = 0;
1406 + struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
1407 +
1408 + assert(ifName != NULL);
1409 +
1410 + if (newIf == NULL)
1411 + {
1412 + return 0;
1413 + }
1414 +
1415 +//TODO: assert interface is not talking OLSR
1416 +
1417 +// if (olsrIntf != NULL)
1418 +// {
1419 +// /* On OLSR-enabled interfaces, create socket for encapsulating and forwarding
1420 +// * multicast packets */
1421 +// encapsulatingSkfd = CreateEncapsulateSocket(ifName);
1422 +// if (encapsulatingSkfd < 0)
1423 +// {
1424 +// free(newIf);
1425 +// return 0;
1426 +// }
1427 +// nOpened++;
1428 +// }
1429 +
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))
1433 + {
1434 + capturingSkfd = CreateCaptureSocket(ifName);
1435 + if (capturingSkfd < 0)
1436 + {
1437 + close(encapsulatingSkfd);
1438 + free(newIf);
1439 + return 0;
1440 + }
1441 +
1442 + nOpened++;
1443 + }
1444 +
1445 +// /* Create promiscuous mode listening interface if BMF uses IP unicast
1446 +// * as underlying forwarding mechanism */
1447 +// if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
1448 +// {
1449 +// listeningSkfd = CreateListeningSocket(ifName);
1450 +// if (listeningSkfd < 0)
1451 +// {
1452 +// close(listeningSkfd);
1453 +// close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */
1454 +// free(newIf);
1455 +// return 0;
1456 +// }
1457 +//
1458 +// nOpened++;
1459 +// }
1460 +
1461 + /* For ioctl operations on the network interface, use either capturingSkfd
1462 + * or encapsulatingSkfd, whichever is available */
1463 + ioctlSkfd = (capturingSkfd >= 0) ? capturingSkfd : encapsulatingSkfd;
1464 +
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)
1470 + {
1471 + BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
1472 + close(capturingSkfd);
1473 + close(encapsulatingSkfd);
1474 + free(newIf);
1475 + return 0;
1476 + }
1477 +
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)
1486 + {
1487 + /* For an OLSR-interface, copy the interface address and broadcast
1488 + * address from the OLSR interface object. Downcast to correct sockaddr
1489 + * subtype. */
1490 + newIf->intAddr.v4 = olsrIntf->int_addr.sin_addr;
1491 + newIf->broadAddr.v4 = olsrIntf->int_broadaddr.sin_addr;
1492 + }
1493 + else
1494 + {
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)
1500 + {
1501 + BmfPError("ioctl(SIOCGIFADDR) error for interface \"%s\"", ifName);
1502 +
1503 + newIf->intAddr.v4.s_addr = inet_addr("0.0.0.0");
1504 + }
1505 + else
1506 + {
1507 + /* Downcast to correct sockaddr subtype */
1508 + newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
1509 + }
1510 +
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)
1516 + {
1517 + BmfPError("ioctl(SIOCGIFBRDADDR) error for interface \"%s\"", ifName);
1518 +
1519 + newIf->broadAddr.v4.s_addr = inet_addr("0.0.0.0");
1520 + }
1521 + else
1522 + {
1523 + /* Downcast to correct sockaddr subtype */
1524 + newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
1525 + }
1526 + }
1527 +
1528 + /* Initialize fragment history table */
1529 + //memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
1530 + //newIf->nextFragmentHistoryEntry = 0;
1531 +
1532 + /* Reset counters */
1533 + //newIf->nBmfPacketsRx = 0;
1534 + //newIf->nBmfPacketsRxDup = 0;
1535 + //newIf->nBmfPacketsTx = 0;
1536 +
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)
1540 + {
1541 + /* First TBmfInterface object in list */
1542 + BmfInterfaces = newIf;
1543 + LastBmfInterface = newIf;
1544 + }
1545 + else if (olsrIntf != NULL)
1546 + {
1547 + /* Add new TBmfInterface object at front of list */
1548 + newIf->next = BmfInterfaces;
1549 + BmfInterfaces = newIf;
1550 + }
1551 + else
1552 + {
1553 + /* Add new TBmfInterface object at back of list */
1554 + newIf->next = NULL;
1555 + LastBmfInterface->next= newIf;
1556 + LastBmfInterface = newIf;
1557 + }
1558 +
1559 + OLSR_PRINTF(
1560 + 8,
1561 + "%s: opened %d socket%s on %s interface \"%s\"\n",
1562 + PLUGIN_NAME_SHORT,
1563 + nOpened,
1564 + nOpened == 1 ? "" : "s",
1565 + olsrIntf != NULL ? "OLSR" : "non-OLSR",
1566 + ifName);
1567 +
1568 + return nOpened;
1569 +} /* CreateInterface */
1570 +
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
1576 + * Output : none
1577 + * Return : fail (-1) or success (0)
1578 + * Data Used : none
1579 + * ------------------------------------------------------------------------- */
1580 +int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
1581 +{
1582 + int skfd;
1583 + struct ifconf ifc;
1584 + int numreqs = 30;
1585 + struct ifreq* ifr;
1586 + int n;
1587 + int nOpenedSockets = 0;
1588 +
1589 + /* Clear input descriptor set */
1590 + FD_ZERO(&InputSet);
1591 +
1592 + skfd = socket(PF_INET, SOCK_DGRAM, 0);
1593 + if (skfd < 0)
1594 + {
1595 + BmfPError("no inet socket available to retrieve interface list");
1596 + return -1;
1597 + }
1598 +
1599 + /* Retrieve the network interface configuration list */
1600 + ifc.ifc_buf = NULL;
1601 + for (;;)
1602 + {
1603 + ifc.ifc_len = sizeof(struct ifreq) * numreqs;
1604 + ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
1605 +
1606 + if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
1607 + {
1608 + BmfPError("ioctl(SIOCGIFCONF) error");
1609 +
1610 + close(skfd);
1611 + free(ifc.ifc_buf);
1612 + return -1;
1613 + }
1614 + if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
1615 + {
1616 + /* Assume it overflowed; double the space and try again */
1617 + numreqs *= 2;
1618 + assert(numreqs < 1024);
1619 + continue; /* for (;;) */
1620 + }
1621 + break; /* for (;;) */
1622 + } /* for (;;) */
1623 +
1624 + close(skfd);
1625 +
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++)
1629 + {
1630 + struct interface* olsrIntf;
1631 + union olsr_ip_addr ipAddr;
1632 +
1633 + /* Skip the BMF network interface itself */
1634 + //if (strncmp(ifr->ifr_name, EtherTunTapIfName, IFNAMSIZ) == 0)
1635 + //{
1636 + // continue; /* for (n = ...) */
1637 + //}
1638 +
1639 + /* ...find the OLSR interface structure, if any */
1640 + ipAddr.v4 = ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr;
1641 + olsrIntf = if_ifwithaddr(&ipAddr);
1642 +
1643 + if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
1644 + {
1645 + continue; /* for (n = ...) */
1646 + }
1647 +
1648 + if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
1649 + {
1650 + /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
1651 + * interface in the BMF plugin parameter list */
1652 + continue; /* for (n = ...) */
1653 + }
1654 +
1655 + if (! IsNonOlsrBmfIf(ifr->ifr_name))
1656 + {
1657 + //If the interface is not specified in the configuration file then go ahead
1658 + continue; /* for (n = ...) */
1659 + }
1660 + //TODO: asser if->ifr_name is not talking OLSR
1661 + //nOpenedSockets += CreateInterface(ifr->ifr_name, olsrIntf);
1662 + nOpenedSockets += CreateInterface(ifr->ifr_name, NULL);
1663 +
1664 + } /* for (n = ...) */
1665 +
1666 + free(ifc.ifc_buf);
1667 +
1668 + /* Create the BMF network interface */
1669 + //EtherTunTapFd = CreateLocalEtherTunTap();
1670 + //if (EtherTunTapFd >= 0)
1671 + //{
1672 + // nOpenedSockets++;
1673 + //}
1674 +
1675 + if (BmfInterfaces == NULL)
1676 + {
1677 + OLSR_PRINTF(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
1678 + }
1679 + else
1680 + {
1681 + OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpenedSockets);
1682 + }
1683 + return 0;
1684 +} /* CreateBmfNetworkInterfaces */
1685 +
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
1691 + * Output : none
1692 + * Return : none
1693 + * Data Used : none
1694 + * ------------------------------------------------------------------------- */
1695 +void AddInterface(struct interface* newIntf)
1696 +{
1697 + int nOpened;
1698 +
1699 + assert(newIntf != NULL);
1700 +
1701 + nOpened = CreateInterface(newIntf->int_name, newIntf);
1702 +
1703 + OLSR_PRINTF(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
1704 +} /* AddInterface */
1705 +
1706 +/* -------------------------------------------------------------------------
1707 + * Function : CloseBmfNetworkInterfaces
1708 + * Description: Closes every socket on each network interface used by BMF
1709 + * Input : none
1710 + * Output : none
1711 + * Return : none
1712 + * Data Used : none
1713 + * Notes : Closes
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
1720 + * was started.
1721 + * ------------------------------------------------------------------------- */
1722 +void CloseBmfNetworkInterfaces(void)
1723 +{
1724 + int nClosed = 0;
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;
1731 +
1732 + /* Close all opened sockets */
1733 + struct TBmfInterface* nextBmfIf = BmfInterfaces;
1734 + while (nextBmfIf != NULL)
1735 + {
1736 + struct TBmfInterface* bmfIf = nextBmfIf;
1737 + nextBmfIf = bmfIf->next;
1738 +
1739 + if (bmfIf->capturingSkfd >= 0)
1740 + {
1741 + close(bmfIf->capturingSkfd);
1742 + nClosed++;
1743 + }
1744 + if (bmfIf->encapsulatingSkfd >= 0)
1745 + {
1746 + close(bmfIf->encapsulatingSkfd);
1747 + nClosed++;
1748 + }
1749 +
1750 + OLSR_PRINTF(
1751 + 7,
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",
1755 + bmfIf->ifName,
1756 + bmfIf->nBmfPacketsRx,
1757 + bmfIf->nBmfPacketsRxDup,
1758 + bmfIf->nBmfPacketsTx);
1759 +
1760 + OLSR_PRINTF(
1761 + 1,
1762 + "%s: closed %s interface \"%s\"\n",
1763 + PLUGIN_NAME_SHORT,
1764 + bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
1765 + bmfIf->ifName);
1766 +
1767 + /* Add totals */
1768 + if (bmfIf->olsrIntf != NULL)
1769 + {
1770 + totalOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1771 + totalOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1772 + totalOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1773 + }
1774 + else
1775 + {
1776 + totalNonOlsrBmfPacketsRx += bmfIf->nBmfPacketsRx;
1777 + totalNonOlsrBmfPacketsRxDup += bmfIf->nBmfPacketsRxDup;
1778 + totalNonOlsrBmfPacketsTx += bmfIf->nBmfPacketsTx;
1779 + }
1780 +
1781 + free(bmfIf);
1782 + } /* while */
1783 +
1784 + if (EtherTunTapFd >= 0)
1785 + {
1786 + close(EtherTunTapFd);
1787 + nClosed++;
1788 +
1789 + OLSR_PRINTF(7, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
1790 + }
1791 +
1792 + BmfInterfaces = NULL;
1793 +
1794 + OLSR_PRINTF(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
1795 +
1796 + OLSR_PRINTF(
1797 + 7,
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);
1803 + OLSR_PRINTF(
1804 + 7,
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 */
1811 +
1812 +#define MAX_NON_OLSR_IFS 32
1813 +static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
1814 +static int nNonOlsrIfs = 0;
1815 +
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")
1821 + * data - not used
1822 + * addon - not used
1823 + * Output : none
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)))
1831 +{
1832 + assert(ifName != NULL);
1833 +
1834 + if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
1835 + {
1836 + OLSR_PRINTF(
1837 + 1,
1838 + "%s: too many non-OLSR interfaces specified, maximum is %d\n",
1839 + PLUGIN_NAME,
1840 + MAX_NON_OLSR_IFS);
1841 + return 1;
1842 + }
1843 +
1844 + strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ - 1);
1845 + NonOlsrIfNames[nNonOlsrIfs][IFNAMSIZ - 1] = '\0'; /* Ensures null termination */
1846 + nNonOlsrIfs++;
1847 + return 0;
1848 +} /* AddNonOlsrBmfIf */
1849 +
1850 +/* -------------------------------------------------------------------------
1851 + * Function : IsNonOlsrBmfIf
1852 + * Description: Checks if a network interface is OLSR-enabled
1853 + * Input : ifName - network interface (e.g. "eth0")
1854 + * Output : none
1855 + * Return : true (1) or false (0)
1856 + * Data Used : NonOlsrIfNames
1857 + * ------------------------------------------------------------------------- */
1858 +int IsNonOlsrBmfIf(const char* ifName)
1859 +{
1860 + int i;
1861 +
1862 + assert(ifName != NULL);
1863 +
1864 + for (i = 0; i < nNonOlsrIfs; i++)
1865 + {
1866 + if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
1867 + }
1868 + return 0;
1869 +} /* IsNonOlsrBmfIf */
1870 +
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
1879 + * Output : none
1880 + * Return : none
1881 + * Data Used : none
1882 + * Notes : See also RFC1141
1883 + * ------------------------------------------------------------------------- */
1884 +void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* broadAddr)
1885 +{
1886 + struct iphdr* iph;
1887 + union olsr_ip_addr destIp;
1888 +
1889 + assert(ipPacket != NULL && broadAddr != NULL);
1890 +
1891 + iph = (struct iphdr*) ipPacket;
1892 + destIp.v4.s_addr = iph->daddr;
1893 + if (! IsMulticast(&destIp))
1894 + {
1895 + u_int32_t origDaddr, newDaddr;
1896 + u_int32_t check;
1897 +
1898 + origDaddr = ntohl(iph->daddr);
1899 +
1900 + iph->daddr = broadAddr->v4.s_addr;
1901 + newDaddr = ntohl(iph->daddr);
1902 +
1903 + /* Re-calculate IP header checksum for new destination */
1904 + check = ntohs(iph->check);
1905 +
1906 + check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1907 + check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1908 +
1909 + /* Add carry */
1910 + check = check + (check >> 16);
1911 +
1912 + iph->check = htons(check);
1913 +
1914 + if (iph->protocol == SOL_UDP)
1915 + {
1916 + /* Re-calculate UDP/IP checksum for new destination */
1917 +
1918 + int ipHeaderLen = GetIpHeaderLength(ipPacket);
1919 + struct udphdr* udph = (struct udphdr*) (ipPacket + ipHeaderLen);
1920 +
1921 + /* RFC 1624, Eq. 3: HC' = ~(~HC - m + m') */
1922 +
1923 + check = ntohs(udph->check);
1924 +
1925 + check = ~ (~ check - ((origDaddr >> 16) & 0xFFFF) + ((newDaddr >> 16) & 0xFFFF));
1926 + check = ~ (~ check - (origDaddr & 0xFFFF) + (newDaddr & 0xFFFF));
1927 +
1928 + /* Add carry */
1929 + check = check + (check >> 16);
1930 +
1931 + udph->check = htons(check);
1932 + } /* if */
1933 + } /* if */
1934 +} /* CheckAndUpdateLocalBroadcast */
1935 +
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.
1940 + * Input : none
1941 + * Output : none
1942 + * Return : none
1943 + * Data Used : none
1944 + * ------------------------------------------------------------------------- */
1945 +void AddMulticastRoute(void)
1946 +{
1947 + struct rtentry kernel_route;
1948 + int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1949 + if (ioctlSkfd < 0)
1950 + {
1951 + BmfPError("socket(PF_INET) error");
1952 + return;
1953 + }
1954 +
1955 + memset(&kernel_route, 0, sizeof(struct rtentry));
1956 +
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;
1960 +
1961 + /* 224.0.0.0/4 */
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);
1964 +
1965 + kernel_route.rt_metric = 0;
1966 + kernel_route.rt_flags = RTF_UP;
1967 +
1968 + kernel_route.rt_dev = EtherTunTapIfName;
1969 +
1970 + if (ioctl(ioctlSkfd, SIOCADDRT, &kernel_route) < 0)
1971 + {
1972 + BmfPError("error setting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
1973 +
1974 + /* Continue anyway */
1975 + }
1976 + close(ioctlSkfd);
1977 +} /* AddMulticastRoute */
1978 +
1979 +/* -------------------------------------------------------------------------
1980 + * Function : DeleteMulticastRoute
1981 + * Description: Delete the route to all multicast addresses from the kernel
1982 + * routing table
1983 + * Input : none
1984 + * Output : none
1985 + * Return : none
1986 + * Data Used : none
1987 + * ------------------------------------------------------------------------- */
1988 +void DeleteMulticastRoute(void)
1989 +{
1990 + if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP)
1991 + {
1992 + struct rtentry kernel_route;
1993 + int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0);
1994 + if (ioctlSkfd < 0)
1995 + {
1996 + BmfPError("socket(PF_INET) error");
1997 + return;
1998 + }
1999 +
2000 + memset(&kernel_route, 0, sizeof(struct rtentry));
2001 +
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;
2005 +
2006 + /* 224.0.0.0/4 */
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);
2009 +
2010 + kernel_route.rt_metric = 0;
2011 + kernel_route.rt_flags = RTF_UP;
2012 +
2013 + kernel_route.rt_dev = EtherTunTapIfName;
2014 +
2015 + if (ioctl(ioctlSkfd, SIOCDELRT, &kernel_route) < 0)
2016 + {
2017 + BmfPError("error deleting multicast route via EtherTunTap interface \"%s\"", EtherTunTapIfName);
2018 +
2019 + /* Continue anyway */
2020 + }
2021 + close(ioctlSkfd);
2022 + } /* if */
2023 +} /* DeleteMulticastRoute */
2024 +
2025 +/*
2026 + * Local Variables:
2027 + * c-basic-offset: 2
2028 + * indent-tabs-mode: nil
2029 + * End:
2030 + */
2031 --- /dev/null
2032 +++ b/lib/mdns/src/NetworkInterfaces.h
2033 @@ -0,0 +1,162 @@
2034 +#ifndef _BMF_NETWORKINTERFACES_H
2035 +#define _BMF_NETWORKINTERFACES_H
2036 +
2037 +/*
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.
2042 + *
2043 + * Redistribution and use in source and binary forms, with or without
2044 + * modification, are permitted provided that the following conditions
2045 + * are met:
2046 + *
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
2052 + * distribution.
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.
2056 + *
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.
2067 + */
2068 +
2069 +/* -------------------------------------------------------------------------
2070 + * File : NetworkInterfaces.h
2071 + * Description: Functions to open and close sockets
2072 + * Created : 29 Jun 2006
2073 + *
2074 + * ------------------------------------------------------------------------- */
2075 +
2076 +/* System includes */
2077 +#include <netinet/in.h> /* struct in_addr */
2078 +
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 */
2085 +#include "mdns.h"
2086 +/* Size of buffer in which packets are received */
2087 +#define BMF_BUFFER_SIZE 2048
2088 +
2089 +struct TBmfInterface
2090 +{
2091 + /* File descriptor of raw packet socket, used for capturing multicast packets */
2092 + int capturingSkfd;
2093 +
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;
2097 +
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;
2101 +
2102 + unsigned char macAddr[IFHWADDRLEN];
2103 +
2104 + char ifName[IFNAMSIZ];
2105 +
2106 + /* OLSRs idea of this network interface. NULL if this interface is not
2107 + * OLSR-enabled. */
2108 + struct interface* olsrIntf;
2109 +
2110 + /* IP address of this network interface */
2111 + union olsr_ip_addr intAddr;
2112 +
2113 + /* Broadcast address of this network interface */
2114 + union olsr_ip_addr broadAddr;
2115 +
2116 + #define FRAGMENT_HISTORY_SIZE 10
2117 + struct TFragmentHistory
2118 + {
2119 + u_int16_t ipId;
2120 + u_int8_t ipProto;
2121 + struct in_addr ipSrc;
2122 + struct in_addr ipDst;
2123 + } fragmentHistory [FRAGMENT_HISTORY_SIZE];
2124 +
2125 + int nextFragmentHistoryEntry;
2126 +
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;
2131 +
2132 + /* Next element in list */
2133 + struct TBmfInterface* next;
2134 +};
2135 +
2136 +extern struct TBmfInterface* BmfInterfaces;
2137 +
2138 +extern int HighestSkfd;
2139 +extern fd_set InputSet;
2140 +
2141 +extern int EtherTunTapFd;
2142 +
2143 +extern char EtherTunTapIfName[];
2144 +
2145 +/* 10.255.255.253 in host byte order */
2146 +#define ETHERTUNTAPDEFAULTIP 0x0AFFFFFD
2147 +
2148 +extern u_int32_t EtherTunTapIp;
2149 +extern u_int32_t EtherTunTapIpMask;
2150 +extern u_int32_t EtherTunTapIpBroadcast;
2151 +
2152 +extern int CapturePacketsOnOlsrInterfaces;
2153 +
2154 +enum TBmfMechanism { BM_BROADCAST = 0, BM_UNICAST_PROMISCUOUS };
2155 +extern enum TBmfMechanism BmfMechanism;
2156 +
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);
2163 +
2164 +#define MAX_UNICAST_NEIGHBORS 10
2165 +struct TBestNeighbors
2166 +{
2167 + struct link_entry* links[MAX_UNICAST_NEIGHBORS];
2168 +};
2169 +
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);
2178 +
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);
2187 +
2188 +#endif /* _BMF_NETWORKINTERFACES_H */
2189 +
2190 +/*
2191 + * Local Variables:
2192 + * c-basic-offset: 2
2193 + * indent-tabs-mode: nil
2194 + * End:
2195 + */
2196 --- /dev/null
2197 +++ b/lib/mdns/src/Packet.c
2198 @@ -0,0 +1,238 @@
2199 +/*
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.
2204 + *
2205 + * Redistribution and use in source and binary forms, with or without
2206 + * modification, are permitted provided that the following conditions
2207 + * are met:
2208 + *
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
2214 + * distribution.
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.
2218 + *
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.
2229 + */
2230 +
2231 +/* -------------------------------------------------------------------------
2232 + * File : Packet.c
2233 + * Description: IP packet and Ethernet frame processing functions
2234 + * Created : 29 Jun 2006
2235 + *
2236 + * ------------------------------------------------------------------------- */
2237 +
2238 +#include "Packet.h"
2239 +
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 */
2247 +
2248 +/* -------------------------------------------------------------------------
2249 + * Function : IsIpFragment
2250 + * Description: Check if an IP packet is an IP fragment
2251 + * Input : ipPacket - the IP packet
2252 + * Output : none
2253 + * Return : true (1) or false (0)
2254 + * Data Used : none
2255 + * ------------------------------------------------------------------------- */
2256 +int IsIpFragment(unsigned char* ipPacket)
2257 +{
2258 + struct ip* iph;
2259 +
2260 + assert(ipPacket != NULL);
2261 +
2262 + iph = (struct ip*) ipPacket;
2263 + if ((ntohs(iph->ip_off) & IP_OFFMASK) != 0)
2264 + {
2265 + return 1;
2266 + }
2267 + return 0;
2268 +} /* IsIpFragment */
2269 +
2270 +/* -------------------------------------------------------------------------
2271 + * Function : GetIpTotalLength
2272 + * Description: Retrieve the total length of the IP packet (in bytes) of
2273 + * an IP packet
2274 + * Input : ipPacket - the IP packet
2275 + * Output : none
2276 + * Return : IP packet length
2277 + * Data Used : none
2278 + * ------------------------------------------------------------------------- */
2279 +u_int16_t GetIpTotalLength(unsigned char* ipPacket)
2280 +{
2281 + struct iphdr* iph;
2282 +
2283 + assert(ipPacket != NULL);
2284 +
2285 + iph = (struct iphdr*) ipPacket;
2286 + return ntohs(iph->tot_len);
2287 +} /* GetIpTotalLength */
2288 +
2289 +/* -------------------------------------------------------------------------
2290 + * Function : GetIpHeaderLength
2291 + * Description: Retrieve the IP header length (in bytes) of an IP packet
2292 + * Input : ipPacket - the IP packet
2293 + * Output : none
2294 + * Return : IP header length
2295 + * Data Used : none
2296 + * ------------------------------------------------------------------------- */
2297 +unsigned int GetIpHeaderLength(unsigned char* ipPacket)
2298 +{
2299 + struct iphdr* iph;
2300 +
2301 + assert(ipPacket != NULL);
2302 +
2303 + iph = (struct iphdr*) ipPacket;
2304 + return iph->ihl << 2;
2305 +} /* GetIpHeaderLength */
2306 +
2307 +/* -------------------------------------------------------------------------
2308 + * Function : GetTtl
2309 + * Description: Retrieve the TTL (Time To Live) value from the IP header of
2310 + * an IP packet
2311 + * Input : ipPacket - the IP packet
2312 + * Output : none
2313 + * Return : TTL value
2314 + * Data Used : none
2315 + * ------------------------------------------------------------------------- */
2316 +u_int8_t GetTtl(unsigned char* ipPacket)
2317 +{
2318 + struct iphdr* iph;
2319 +
2320 + assert(ipPacket != NULL);
2321 +
2322 + iph = (struct iphdr*) ipPacket;
2323 + return iph->ttl;
2324 +} /* GetTtl */
2325 +
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
2332 + * Return : none
2333 + * Data Used : none
2334 + * ------------------------------------------------------------------------- */
2335 +void SaveTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
2336 +{
2337 + struct iphdr* iph;
2338 +
2339 + assert(ipPacket != NULL && sttl != NULL);
2340 +
2341 + iph = (struct iphdr*) ipPacket;
2342 + sttl->ttl = iph->ttl;
2343 + sttl->check = ntohs(iph->check);
2344 +} /* SaveTtlAndChecksum */
2345 +
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
2352 + * Output : none
2353 + * Return : none
2354 + * Data Used : none
2355 + * ------------------------------------------------------------------------- */
2356 +void RestoreTtlAndChecksum(unsigned char* ipPacket, struct TSaveTtl* sttl)
2357 +{
2358 + struct iphdr* iph;
2359 +
2360 + assert(ipPacket != NULL && sttl != NULL);
2361 +
2362 + iph = (struct iphdr*) ipPacket;
2363 + iph->ttl = sttl->ttl;
2364 + iph->check = htons(sttl->check);
2365 +} /* RestoreTtlAndChecksum */
2366 +
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
2372 + * Output : none
2373 + * Return : none
2374 + * Data Used : none
2375 + * Notes : See also RFC1141
2376 + * ------------------------------------------------------------------------- */
2377 +void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* ipPacket)
2378 +{
2379 + struct iphdr* iph;
2380 + u_int32_t sum;
2381 +
2382 + assert(ipPacket != NULL);
2383 +
2384 + iph = (struct iphdr*) ipPacket;
2385 +
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 */
2390 +
2391 +/* -------------------------------------------------------------------------
2392 + * Function : GetIpHeader
2393 + * Description: Retrieve the IP header from BMF encapsulation UDP data
2394 + * Input : encapsulationUdpData - the encapsulation UDP data
2395 + * Output : none
2396 + * Return : IP header
2397 + * Data Used : none
2398 + * ------------------------------------------------------------------------- */
2399 +struct ip* GetIpHeader(unsigned char* encapsulationUdpData)
2400 +{
2401 + return (struct ip*)(encapsulationUdpData + ENCAP_HDR_LEN);
2402 +} /* GetIpHeader */
2403 +
2404 +/* -------------------------------------------------------------------------
2405 + * Function : GetIpPacket
2406 + * Description: Retrieve the IP packet from BMF encapsulation UDP data
2407 + * Input : encapsulationUdpData - the encapsulation UDP data
2408 + * Output : none
2409 + * Return : The IP packet
2410 + * Data Used : none
2411 + * ------------------------------------------------------------------------- */
2412 +unsigned char* GetIpPacket(unsigned char* encapsulationUdpData)
2413 +{
2414 + return encapsulationUdpData + ENCAP_HDR_LEN;
2415 +} /* GetIpPacket */
2416 +
2417 +/* -------------------------------------------------------------------------
2418 + * Function : GetEncapsulationUdpDataLength
2419 + * Description: Return the length of BMF encapsulation UDP data
2420 + * Input : encapsulationUdpData - the encapsulation UDP data
2421 + * Output : none
2422 + * Return : The encapsulation data length
2423 + * Data Used : none
2424 + * ------------------------------------------------------------------------- */
2425 +u_int16_t GetEncapsulationUdpDataLength(unsigned char* encapsulationUdpData)
2426 +{
2427 + return GetIpTotalLength(GetIpPacket(encapsulationUdpData)) + ENCAP_HDR_LEN;
2428 +} /* GetEncapsulationUdpDataLength */
2429 +
2430 +
2431 +/*
2432 + * Local Variables:
2433 + * c-basic-offset: 2
2434 + * indent-tabs-mode: nil
2435 + * End:
2436 + */
2437 --- /dev/null
2438 +++ b/lib/mdns/src/Packet.h
2439 @@ -0,0 +1,88 @@
2440 +#ifndef _BMF_PACKET_H
2441 +#define _BMF_PACKET_H
2442 +
2443 +/*
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.
2448 + *
2449 + * Redistribution and use in source and binary forms, with or without
2450 + * modification, are permitted provided that the following conditions
2451 + * are met:
2452 + *
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
2458 + * distribution.
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.
2462 + *
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.
2473 + */
2474 +
2475 +/* -------------------------------------------------------------------------
2476 + * File : Packet.h
2477 + * Description: BMF and IP packet processing functions
2478 + * Created : 29 Jun 2006
2479 + *
2480 + * ------------------------------------------------------------------------- */
2481 +
2482 +/* System includes */
2483 +#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
2484 +#include <sys/types.h> /* u_int8_t, u_int16_t */
2485 +
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 */
2489 +
2490 +struct TEncapHeader
2491 +{
2492 + /* Use a standard Type-Length-Value (TLV) element */
2493 + u_int8_t type;
2494 + u_int8_t len;
2495 + u_int16_t reserved; /* Always 0 */
2496 + u_int32_t crc32;
2497 +} __attribute__((__packed__));
2498 +
2499 +#define ENCAP_HDR_LEN ((int)sizeof(struct TEncapHeader))
2500 +#define BMF_ENCAP_TYPE 1
2501 +#define BMF_ENCAP_LEN 6
2502 +
2503 +struct TSaveTtl
2504 +{
2505 + u_int8_t ttl;
2506 + u_int16_t check;
2507 +} __attribute__((__packed__));
2508 +
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);
2519 +
2520 +#endif /* _BMF_PACKET_H */
2521 +
2522 +/*
2523 + * Local Variables:
2524 + * c-basic-offset: 2
2525 + * indent-tabs-mode: nil
2526 + * End:
2527 + */
2528 --- /dev/null
2529 +++ b/lib/mdns/src/PacketHistory.c
2530 @@ -0,0 +1,324 @@
2531 +/*
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.
2536 + *
2537 + * Redistribution and use in source and binary forms, with or without
2538 + * modification, are permitted provided that the following conditions
2539 + * are met:
2540 + *
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
2546 + * distribution.
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.
2550 + *
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.
2561 + */
2562 +
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
2568 + *
2569 + * ------------------------------------------------------------------------- */
2570 +
2571 +#include "PacketHistory.h"
2572 +
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 */
2580 +
2581 +/* OLSRD includes */
2582 +#include "defs.h" /* GET_TIMESTAMP, TIMED_OUT */
2583 +#include "olsr.h" /* OLSR_PRINTF */
2584 +#include "scheduler.h" /* now_times */
2585 +
2586 +/* Plugin includes */
2587 +#include "Packet.h"
2588 +
2589 +static struct TDupEntry* PacketHistory[HISTORY_HASH_SIZE];
2590 +
2591 +#define CRC_UPTO_NBYTES 256
2592 +
2593 +#if 0
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
2599 + * Output : none
2600 + * Return : CRC-16 value
2601 + * Data Used : none
2602 + * ------------------------------------------------------------------------- */
2603 +static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)
2604 +{
2605 + /* Initial value of 0xFFFF should be 0x1D0F according to
2606 + * www.joegeluso.com/software/articles/ccitt.htm */
2607 + u_int16_t crc = 0xFFFF;
2608 + int i;
2609 +
2610 + assert(buffer != NULL);
2611 +
2612 + for (i = 0; i < len; i++)
2613 + {
2614 + crc = (unsigned char)(crc >> 8) | (crc << 8);
2615 + crc ^= buffer[i];
2616 + crc ^= (unsigned char)(crc & 0xff) >> 4;
2617 + crc ^= (crc << 8) << 4;
2618 + crc ^= ((crc & 0xff) << 4) << 1;
2619 + }
2620 + return crc;
2621 +} /* CalcCrcCcitt */
2622 +#endif
2623 +
2624 +/* -------------------------------------------------------------------------
2625 + * Function : GenerateCrc32Table
2626 + * Description: Generate the table of CRC remainders for all possible bytes,
2627 + * according to CRC-32-IEEE 802.3
2628 + * Input : none
2629 + * Output : none
2630 + * Return : none
2631 + * Data Used : none
2632 + * ------------------------------------------------------------------------- */
2633 +#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */
2634 +
2635 +static unsigned long CrcTable[256];
2636 +
2637 +static void GenerateCrc32Table(void)
2638 +{
2639 + int i, j;
2640 + u_int32_t crc;
2641 + for (i = 0; i < 256; i++)
2642 + {
2643 + crc = (u_int32_t) i;
2644 + for (j = 0; j < 8; j++)
2645 + {
2646 + if (crc & 1)
2647 + {
2648 + crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
2649 + }
2650 + else
2651 + {
2652 + crc = (crc >> 1);
2653 + }
2654 + }
2655 + CrcTable[i] = crc;
2656 + } /* for */
2657 +} /* GenerateCrc32Table */
2658 +
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
2664 + * Output : none
2665 + * Return : CRC-32 value
2666 + * Data Used : none
2667 + * ------------------------------------------------------------------------- */
2668 +static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)
2669 +{
2670 + int i, j;
2671 + u_int32_t crc = 0xffffffffUL;
2672 + for (i = 0; i < len; i++)
2673 + {
2674 + j = ((int) (crc & 0xFF) ^ *buffer++);
2675 + crc = (crc >> 8) ^ CrcTable[j];
2676 + }
2677 + return crc ^ 0xffffffffUL;
2678 +} /* CalcCrc32 */
2679 +
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
2685 + * Output : none
2686 + * Return : 32-bits CRC value
2687 + * Data Used : none
2688 + * ------------------------------------------------------------------------- */
2689 +u_int32_t PacketCrc32(unsigned char* ipPacket, ssize_t len)
2690 +{
2691 + struct TSaveTtl sttl;
2692 + struct ip* ipHeader;
2693 + u_int32_t result;
2694 +
2695 + assert(ipPacket != NULL);
2696 +
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.
2703 + *
2704 + * Clip number of bytes over which CRC is calculated to prevent
2705 + * long packets from possibly claiming too much CPU resources. */
2706 + assert(len > 0);
2707 + if (len > CRC_UPTO_NBYTES)
2708 + {
2709 + len = CRC_UPTO_NBYTES;
2710 + }
2711 +
2712 + SaveTtlAndChecksum(ipPacket, &sttl);
2713 +
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 */
2717 +
2718 + result = CalcCrc32(ipPacket, len);
2719 +
2720 + RestoreTtlAndChecksum(ipPacket, &sttl);
2721 + return result;
2722 +} /* PacketCrc32 */
2723 +
2724 +/* -------------------------------------------------------------------------
2725 + * Function : Hash
2726 + * Description: Calculates a hash value from a 32-bit value
2727 + * Input : from32 - 32-bit value
2728 + * Output : none
2729 + * Return : hash value
2730 + * Data Used : none
2731 + * ------------------------------------------------------------------------- */
2732 +u_int32_t Hash(u_int32_t from32)
2733 +{
2734 + return ((from32 >> N_HASH_BITS) + from32) & ((1 << N_HASH_BITS) - 1);
2735 +} /* Hash */
2736 +
2737 +/* -------------------------------------------------------------------------
2738 + * Function : InitPacketHistory
2739 + * Description: Initialize the packet history table and CRC-32 table
2740 + * Input : none
2741 + * Output : none
2742 + * Return : none
2743 + * Data Used : PacketHistory
2744 + * ------------------------------------------------------------------------- */
2745 +void InitPacketHistory(void)
2746 +{
2747 + int i;
2748 +
2749 + GenerateCrc32Table();
2750 +
2751 + for(i = 0; i < HISTORY_HASH_SIZE; i++)
2752 + {
2753 + PacketHistory[i] = NULL;
2754 + }
2755 +} /* InitPacketHistory */
2756 +
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
2762 + * Output : none
2763 + * Return : not recently seen (0), recently seen (1)
2764 + * Data Used : PacketHistory
2765 + * ------------------------------------------------------------------------- */
2766 +int CheckAndMarkRecentPacket(u_int32_t crc32)
2767 +{
2768 + u_int32_t idx;
2769 + struct TDupEntry* walker;
2770 + struct TDupEntry* newEntry;
2771 +
2772 + idx = Hash(crc32);
2773 + assert(idx < HISTORY_HASH_SIZE);
2774 +
2775 + for (walker = PacketHistory[idx]; walker != NULL; walker = walker->next)
2776 + {
2777 + if (walker->crc32 == crc32)
2778 + {
2779 + /* Found duplicate entry */
2780 +
2781 + /* Always mark as "seen recently": refresh time-out */
2782 + walker->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
2783 +
2784 + return 1;
2785 + } /* if */
2786 + } /* for */
2787 +
2788 + /* No duplicate entry found: create one */
2789 + newEntry = malloc(sizeof(struct TDupEntry));
2790 + if (newEntry != NULL)
2791 + {
2792 + newEntry->crc32 = crc32;
2793 + newEntry->timeOut = GET_TIMESTAMP(HISTORY_HOLD_TIME);
2794 +
2795 + /* Add new entry at the front of the list */
2796 + newEntry->next = PacketHistory[idx];
2797 + PacketHistory[idx] = newEntry;
2798 + }
2799 +
2800 + return 0;
2801 +} /* CheckAndMarkRecentPacket */
2802 +
2803 +/* -------------------------------------------------------------------------
2804 + * Function : PrunePacketHistory
2805 + * Description: Prune the packet history table.
2806 + * Input : useless - not used
2807 + * Output : none
2808 + * Return : none
2809 + * Data Used : PacketHistory
2810 + * ------------------------------------------------------------------------- */
2811 +void PrunePacketHistory(void* useless __attribute__((unused)))
2812 +{
2813 + uint i;
2814 + for (i = 0; i < HISTORY_HASH_SIZE; i++)
2815 + {
2816 + if (PacketHistory[i] != NULL)
2817 + {
2818 + struct TDupEntry* nextEntry = PacketHistory[i];
2819 + struct TDupEntry* prevEntry = NULL;
2820 + while (nextEntry != NULL)
2821 + {
2822 + struct TDupEntry* entry = nextEntry;
2823 + nextEntry = entry->next;
2824 +
2825 + if (TIMED_OUT(entry->timeOut))
2826 + {
2827 + /* De-queue */
2828 + if (prevEntry != NULL)
2829 + {
2830 + prevEntry->next = entry->next;
2831 + }
2832 + else
2833 + {
2834 + PacketHistory[i] = entry->next;
2835 + } /* if */
2836 +
2837 + /* De-allocate memory */
2838 + free(entry);
2839 + }
2840 + else
2841 + {
2842 + prevEntry = entry;
2843 + } /* if */
2844 + } /* while */
2845 + } /* if (PacketHistory[i] != NULL) */
2846 + } /* for (i = ...) */
2847 +} /* PrunePacketHistory */
2848 +
2849 +/*
2850 + * Local Variables:
2851 + * c-basic-offset: 2
2852 + * indent-tabs-mode: nil
2853 + * End:
2854 + */
2855 --- /dev/null
2856 +++ b/lib/mdns/src/PacketHistory.h
2857 @@ -0,0 +1,75 @@
2858 +#ifndef _BMF_PACKETHISTORY_H
2859 +#define _BMF_PACKETHISTORY_H
2860 +
2861 +/*
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.
2866 + *
2867 + * Redistribution and use in source and binary forms, with or without
2868 + * modification, are permitted provided that the following conditions
2869 + * are met:
2870 + *
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
2876 + * distribution.
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.
2880 + *
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.
2891 + */
2892 +
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
2898 + *
2899 + * ------------------------------------------------------------------------- */
2900 +
2901 +/* System includes */
2902 +#include <sys/types.h> /* ssize_t */
2903 +#include <sys/times.h> /* clock_t */
2904 +
2905 +#define N_HASH_BITS 12
2906 +#define HISTORY_HASH_SIZE (1 << N_HASH_BITS)
2907 +
2908 +/* Time-out of duplicate entries, in milliseconds */
2909 +#define HISTORY_HOLD_TIME 3000
2910 +
2911 +struct TDupEntry
2912 +{
2913 + u_int32_t crc32;
2914 + clock_t timeOut;
2915 + struct TDupEntry* next;
2916 +};
2917 +
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*);
2924 +
2925 +#endif /* _BMF_PACKETHISTORY_H */
2926 +
2927 +/*
2928 + * Local Variables:
2929 + * c-basic-offset: 2
2930 + * indent-tabs-mode: nil
2931 + * End:
2932 + */
2933 --- /dev/null
2934 +++ b/lib/mdns/src/mdns.c
2935 @@ -0,0 +1,1174 @@
2936 +/*
2937 + * OLSR MDNS plugin.
2938 + * Written by Saverio Proto.
2939 + *
2940 + * Redistribution and use in source and binary forms, with or without
2941 + * modification, are permitted provided that the following conditions
2942 + * are met:
2943 + *
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
2949 + * distribution.
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.
2953 + *
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.
2964 + */
2965 +
2966 +
2967 +//#define _MULTI_THREADED
2968 +
2969 +#include "mdns.h"
2970 +
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() */
2985 +
2986 +#include <netinet/in.h>
2987 +#include <netinet/ip6.h>
2988 +
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 */
2998 +
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() */
3004 +
3005 +//static pthread_t mdnsThread;
3006 +//static int mdnsThreadRunning = 0;
3007 +
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
3012 + * Output : none
3013 + * Return : none
3014 + * Data Used : BmfInterfaces
3015 + * ------------------------------------------------------------------------- */
3016 +static void PacketReceivedFromOLSR(
3017 + unsigned char* encapsulationUdpData, int len)
3018 +{
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;
3026 +
3027 + OLSR_PRINTF(3, "MDNS PLUGIN got packet from OLSR message\n");
3028 +
3029 +
3030 + /* Check with each network interface what needs to be done on it */
3031 + for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3032 + {
3033 + /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
3034 + if (walker->olsrIntf == NULL)
3035 + {
3036 + int nBytesWritten;
3037 + struct sockaddr_ll dest;
3038 +
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;
3046 +
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);
3054 +
3055 + nBytesWritten = sendto(
3056 + walker->capturingSkfd,
3057 + encapsulationUdpData,
3058 + len,
3059 + 0,
3060 + (struct sockaddr*) &dest,
3061 + sizeof(dest));
3062 + if (nBytesWritten != len)
3063 + {
3064 + BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
3065 + }
3066 + else
3067 + {
3068 +
3069 + OLSR_PRINTF(
3070 + 2,
3071 + "%s: --> unpacked and forwarded on \"%s\"\n",
3072 + PLUGIN_NAME_SHORT,
3073 + walker->ifName);
3074 + }
3075 + } /* if (walker->olsrIntf == NULL) */
3076 +}
3077 +} /* PacketReceivedFromOLSR */
3078 +
3079 +
3080 +
3081 +bool
3082 +olsr_parser(union olsr_message *m,
3083 + struct interface *in_if __attribute__((unused)),
3084 + union olsr_ip_addr *ipaddr)
3085 +{
3086 + union olsr_ip_addr originator;
3087 + int size;
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);
3095 + } else {
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);
3099 + }
3100 +
3101 + /* Check if message originated from this node.
3102 + * If so - back off */
3103 + if(ipequal(&originator, &olsr_cnf->main_addr))
3104 + return false;
3105 +
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));
3111 + return false;
3112 + }
3113 +
3114 + if(olsr_cnf->ip_version == AF_INET){
3115 + PacketReceivedFromOLSR((unsigned char*) &m->v4.message,size-12);
3116 + }
3117 + else {
3118 + PacketReceivedFromOLSR((unsigned char*) &m->v6.message,size-12-96);
3119 + }
3120 + /* Forward the message */
3121 + return 1;
3122 +}
3123 +
3124 +//Sends a packet in the OLSR network
3125 +void
3126 +olsr_mdns_gen(unsigned char* packet, int len)
3127 +{
3128 + /* send buffer: huge */
3129 + char buffer[10240];
3130 + union olsr_message *message = (union olsr_message *)buffer;
3131 + struct interface *ifn;
3132 + //int namesize;
3133 +
3134 + /* fill message */
3135 + if(olsr_cnf->ip_version == AF_INET)
3136 + {
3137 + /* IPv4 */
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());
3144 +
3145 + message->v4.olsr_msgsize = htons(len+12);
3146 +
3147 + memcpy(&message->v4.message,packet,len);
3148 + len=len+12;
3149 + }
3150 + else
3151 + {
3152 + /* IPv6 */
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());
3159 +
3160 + message->v6.olsr_msgsize = htons(len+12+96);
3161 + memcpy(&message->v6.message,packet,len);
3162 + len=len+12+96;
3163 + }
3164 +
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);
3168 +
3169 + if(net_outbuffer_push(ifn, message, len) != len) {
3170 + /* send data and try again */
3171 + net_output(ifn);
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);
3174 + }
3175 + }
3176 + }
3177 +}
3178 +
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
3186 + * Output : none
3187 + * Return : none
3188 + * Data Used : none
3189 + * ------------------------------------------------------------------------- */
3190 +
3191 +void BmfPError(const char* format, ...)
3192 +{
3193 +#define MAX_STR_DESC 255
3194 +#ifndef NODEBUG
3195 + char* strErr = strerror(errno);
3196 +#endif
3197 + char strDesc[MAX_STR_DESC];
3198 +
3199 + /* Rely on short-circuit boolean evaluation */
3200 + if (format == NULL || *format == '\0')
3201 + {
3202 + OLSR_PRINTF(1, "%s: %s\n", PLUGIN_NAME, strErr);
3203 + }
3204 + else
3205 + {
3206 + va_list arglist;
3207 +
3208 + OLSR_PRINTF(1, "%s: ", PLUGIN_NAME);
3209 +
3210 + va_start(arglist, format);
3211 + vsnprintf(strDesc, MAX_STR_DESC, format, arglist);
3212 + va_end(arglist);
3213 +
3214 + strDesc[MAX_STR_DESC - 1] = '\0'; /* Ensures null termination */
3215 +
3216 + OLSR_PRINTF(1, "%s: %s\n", strDesc, strErr);
3217 + }
3218 +} /* BmfPError */
3219 +
3220 +/* -------------------------------------------------------------------------
3221 + * Function : MainAddressOf
3222 + * Description: Lookup the main address of a node
3223 + * Input : ip - IP address of the node
3224 + * Output : none
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)
3229 +{
3230 + union olsr_ip_addr* result;
3231 +
3232 + /* TODO: mid_lookup_main_addr() is not thread-safe! */
3233 + result = mid_lookup_main_addr(ip);
3234 + if (result == NULL)
3235 + {
3236 + result = ip;
3237 + }
3238 + return result;
3239 +} /* MainAddressOf */
3240 +
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
3247 + * Output : none
3248 + * Return : none
3249 + * Data Used : none
3250 + * ------------------------------------------------------------------------- */
3251 +//static void EncapsulateAndForwardPacket(
3252 +// struct TBmfInterface* intf,
3253 +// unsigned char* encapsulationUdpData)
3254 +//{
3255 +//// /* The packet */
3256 +// u_int16_t udpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
3257 +//
3258 +// /* The next destination(s) */
3259 +// struct TBestNeighbors bestNeighborLinks;
3260 +// struct link_entry* bestNeighbor;
3261 +//
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 */
3266 +//
3267 +// int i;
3268 +//
3269 +// /* Find at most 'FanOutLimit' best neigbors to forward the packet to */
3270 +// FindNeighbors(&bestNeighborLinks, &bestNeighbor, intf, NULL, NULL, NULL, &nPossibleNeighbors);
3271 +//
3272 +// if (nPossibleNeighbors <= 0)
3273 +// {
3274 +// OLSR_PRINTF(
3275 +// 8,
3276 +// "%s: --> not encap-forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
3277 +// PLUGIN_NAME_SHORT,
3278 +// intf->ifName);
3279 +// return;
3280 +// }
3281 +//
3282 +// /* Compose destination of encapsulation packet */
3283 +//
3284 +// memset(&forwardTo, 0, sizeof(forwardTo));
3285 +// forwardTo.sin_family = AF_INET;
3286 +// forwardTo.sin_port = htons(BMF_ENCAP_PORT);
3287 +//
3288 +// /* Start by filling in the local broadcast address. This may be overwritten later. */
3289 +// forwardTo.sin_addr = intf->broadAddr.v4;
3290 +//
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)
3299 +// {
3300 +// /* One unicast packet to the best neighbor */
3301 +// nPacketsToSend = 1;
3302 +// sendUnicast = 1;
3303 +// bestNeighborLinks.links[0] = bestNeighbor;
3304 +// }
3305 +// else /* BmfMechanism == BM_BROADCAST */
3306 +// {
3307 +// if (nPossibleNeighbors <= FanOutLimit)
3308 +// {
3309 +// /* 'nPossibleNeighbors' unicast packets */
3310 +// nPacketsToSend = nPossibleNeighbors;
3311 +// sendUnicast = 1;
3312 +// }
3313 +// else /* nPossibleNeighbors > FanOutLimit */
3314 +// {
3315 +// /* One broadcast packet, possibly retransmitted as specified in the
3316 +// * 'BroadcastRetransmitCount' plugin parameter */
3317 +// nPacketsToSend = BroadcastRetransmitCount;
3318 +// sendUnicast = 0;
3319 +// } /* if */
3320 +// } /* if */
3321 +//
3322 +// for (i = 0; i < nPacketsToSend; i++)
3323 +// {
3324 +// int nBytesWritten;
3325 +//
3326 +// if (sendUnicast == 1)
3327 +// {
3328 +// /* For unicast, overwrite the local broadcast address which was filled in above */
3329 +// forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
3330 +// }
3331 +//
3332 +// /* Forward the BMF packet via the encapsulation socket */
3333 +// nBytesWritten = sendto(
3334 +// intf->encapsulatingSkfd,
3335 +// encapsulationUdpData,
3336 +// udpDataLen,
3337 +// MSG_DONTROUTE,
3338 +// (struct sockaddr*) &forwardTo,
3339 +// sizeof(forwardTo));
3340 +//
3341 +// /* Evaluate and display result */
3342 +// if (nBytesWritten != udpDataLen)
3343 +// {
3344 +// BmfPError("sendto() error forwarding pkt on \"%s\"", intf->ifName);
3345 +// }
3346 +// else
3347 +// {
3348 +// /* Increase counter */
3349 +// intf->nBmfPacketsTx++;
3350 +//
3351 +// OLSR_PRINTF(
3352 +// 8,
3353 +// "%s: --> encapsulated and forwarded on \"%s\" to %s\n",
3354 +// PLUGIN_NAME_SHORT,
3355 +// intf->ifName,
3356 +// inet_ntoa(forwardTo.sin_addr));
3357 +// } /* if (nBytesWritten != udpDataLen) */
3358 +// } /* for */
3359 +//} /* EncapsulateAndForwardPacket */
3360 +
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
3369 + * Output : none
3370 + * Return : none
3371 + * Data Used : BmfInterfaces
3372 + * Notes : The IP packet is assumed to be captured on a socket of family
3373 + * PF_PACKET and type SOCK_DGRAM (cooked).
3374 + * ------------------------------------------------------------------------- */
3375 +static void BmfPacketCaptured(
3376 + //struct TBmfInterface* intf,
3377 + //unsigned char sllPkttype,
3378 + unsigned char* encapsulationUdpData,
3379 + int nBytes)
3380 +{
3381 + union olsr_ip_addr src; /* Source IP address in captured packet */
3382 + union olsr_ip_addr dst; /* Destination IP address in captured packet */
3383 + union olsr_ip_addr* origIp; /* Main OLSR address of source of captured packet */
3384 + //struct TBmfInterface* walker;
3385 + //int isFromOlsrIntf;
3386 + //int isFromOlsrNeighbor;
3387 + //int iAmMpr;
3388 + //unsigned char* ipPacket; /* The captured IP packet... */
3389 + //u_int16_t ipPacketLen; /* ...and its length */
3390 + struct ip* ipHeader; /* The IP header inside the captured IP packet */
3391 + struct ip6_hdr* ipHeader6; /* The IP header inside the captured IP packet */
3392 + //u_int32_t crc32;
3393 + //struct TEncapHeader* encapHdr;
3394 + //struct ipaddr_str srcBuf, dstBuf;
3395 + struct udphdr* udpHeader;
3396 + u_int16_t destPort;
3397 +
3398 + if ((encapsulationUdpData[0] & 0xf0) == 0x40) { //IPV4
3399 +
3400 + ipHeader = (struct ip*) encapsulationUdpData;
3401 +
3402 + dst.v4 = ipHeader->ip_dst;
3403 +
3404 + /* Only forward multicast packets. If configured, also forward local broadcast packets */
3405 + if (IsMulticast(&dst))
3406 + {
3407 + /* continue */
3408 + }
3409 + else
3410 + {
3411 + return;
3412 + }
3413 + if (ipHeader->ip_p != SOL_UDP)
3414 + {
3415 + /* Not UDP */
3416 + OLSR_PRINTF(1,"NON UDP PACKET\n");
3417 + return; /* for */
3418 + }
3419 + udpHeader = (struct udphdr*)(encapsulationUdpData + GetIpHeaderLength(encapsulationUdpData));
3420 + destPort = ntohs(udpHeader->dest);
3421 + if (destPort != 5353)
3422 + {
3423 + return;
3424 + }
3425 + }//END IPV4
3426 +
3427 + else if ((encapsulationUdpData[0] & 0xf0) == 0x60) { //IPv6
3428 +
3429 + ipHeader6 = (struct ip6_hdr*) encapsulationUdpData;
3430 + if (ipHeader6->ip6_dst.s6_addr[0] == 0xff) //Multicast
3431 + {
3432 + //Continua
3433 + }
3434 + else
3435 + {
3436 + return; //not multicast
3437 + }
3438 + if (ipHeader6->ip6_nxt != SOL_UDP)
3439 + {
3440 + /* Not UDP */
3441 + OLSR_PRINTF(1,"NON UDP PACKET\n");
3442 + return; /* for */
3443 + }
3444 + udpHeader = (struct udphdr*)(encapsulationUdpData + 40);
3445 + destPort = ntohs(udpHeader->dest);
3446 + if (destPort != 5353)
3447 + {
3448 + return;
3449 + }
3450 + } //END IPV6
3451 + else return; //Is not IP packet
3452 +
3453 + /* Check if the frame is captured on an OLSR-enabled interface */
3454 + //isFromOlsrIntf = (intf->olsrIntf != NULL); TODO: put again this check
3455 +
3456 + /* Retrieve the length of the captured packet */
3457 + //ipPacketLen = GetIpTotalLength(ipPacket);
3458 +
3459 + //src.v4 = ipHeader->ip_src;
3460 +
3461 + //OLSR_PRINTF(
3462 + // 1,
3463 + // "%s: %s pkt of %ld bytes captured on %s interface \"%s\": %s->%s\n",
3464 + // PLUGIN_NAME_SHORT,
3465 + // sllPkttype == PACKET_OUTGOING ? "outgoing" : "incoming",
3466 + // (long)ipPacketLen,
3467 + // isFromOlsrIntf ? "OLSR" : "non-OLSR",
3468 + // intf->ifName,
3469 + // olsr_ip_to_string(&srcBuf, &src),
3470 + // olsr_ip_to_string(&dstBuf, &dst));
3471 +
3472 + /* Lookup main address of source in the MID table of OLSR */
3473 + origIp = MainAddressOf(&src);
3474 +
3475 + // send the packet to OLSR forward mechanism
3476 + olsr_mdns_gen(encapsulationUdpData,nBytes);
3477 +} /* BmfPacketCaptured */
3478 +
3479 +
3480 +/* -------------------------------------------------------------------------
3481 + * Function : BmfEncapsulationPacketReceived
3482 + * Description: Handle a received BMF-encapsulation packet
3483 + * Input : intf - the network interface on which the packet was received
3484 + * forwardedBy - the IP node that forwarded the packet to me
3485 + * forwardedTo - the destination IP address of the encapsulation
3486 + * packet, in case the packet was received promiscuously.
3487 + * Pass NULL if the packet is received normally (unicast or
3488 + * broadcast).
3489 + * encapsulationUdpData - the encapsulating IP UDP data, containting
3490 + * the BMF encapsulation header, followed by the encapsulated
3491 + * IP packet
3492 + * Output : none
3493 + * Return : none
3494 + * Data Used : BmfInterfaces
3495 + * ------------------------------------------------------------------------- */
3496 +//static void BmfEncapsulationPacketReceived(
3497 +// struct TBmfInterface* intf,
3498 +// union olsr_ip_addr* forwardedBy,
3499 +// union olsr_ip_addr* forwardedTo,
3500 +// unsigned char* encapsulationUdpData)
3501 +//{
3502 +// int iAmMpr; /* True (1) if I am selected as MPR by 'forwardedBy' */
3503 +// struct sockaddr_in forwardTo; /* Next destination of encapsulation packet */
3504 +// unsigned char* ipPacket; /* The encapsulated IP packet */
3505 +// u_int16_t ipPacketLen; /* Length of the encapsulated IP packet */
3506 +// struct ip* ipHeader; /* IP header inside the encapsulated IP packet */
3507 +// union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */
3508 +// union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */
3509 +// struct TEncapHeader* encapsulationHdr;
3510 +// u_int16_t encapsulationUdpDataLen;
3511 +// struct TBmfInterface* walker;
3512 +// struct ipaddr_str mcSrcBuf, mcDstBuf, forwardedByBuf, forwardedToBuf;
3513 +// /* Are we talking to ourselves? */
3514 +// if (if_ifwithaddr(forwardedBy) != NULL)
3515 +// {
3516 +// return;
3517 +// }
3518 +//
3519 +// /* Discard encapsulated packets received on a non-OLSR interface */
3520 +// if (intf->olsrIntf == NULL)
3521 +// {
3522 +// return;
3523 +// }
3524 +//
3525 +// /* Retrieve details about the encapsulated IP packet */
3526 +// ipPacket = GetIpPacket(encapsulationUdpData);
3527 +// ipPacketLen = GetIpTotalLength(ipPacket);
3528 +// ipHeader = GetIpHeader(encapsulationUdpData);
3529 +//
3530 +// mcSrc.v4 = ipHeader->ip_src;
3531 +// mcDst.v4 = ipHeader->ip_dst;
3532 +//
3533 +// /* Increase counter */
3534 +// intf->nBmfPacketsRx++;
3535 +//
3536 +// /* Beware: not possible to call olsr_ip_to_string more than 4 times in same printf */
3537 +// OLSR_PRINTF(
3538 +// 8,
3539 +// "%s: encapsulated pkt of %ld bytes incoming on \"%s\": %s->%s, forwarded by %s to %s\n",
3540 +// PLUGIN_NAME_SHORT,
3541 +// (long)ipPacketLen,
3542 +// intf->ifName,
3543 +// olsr_ip_to_string(&mcSrcBuf, &mcSrc),
3544 +// olsr_ip_to_string(&mcDstBuf, &mcDst),
3545 +// olsr_ip_to_string(&forwardedByBuf, forwardedBy),
3546 +// forwardedTo != NULL ? olsr_ip_to_string(&forwardedToBuf, forwardedTo) : "me");
3547 +//
3548 +// /* Get encapsulation header */
3549 +// encapsulationHdr = (struct TEncapHeader*) encapsulationUdpData;
3550 +//
3551 +// /* Verify correct format of BMF encapsulation header */
3552 +// if (encapsulationHdr->type != BMF_ENCAP_TYPE ||
3553 +// encapsulationHdr->len != BMF_ENCAP_LEN ||
3554 +// ntohs(encapsulationHdr->reserved != 0))
3555 +// {
3556 +// OLSR_PRINTF(
3557 +// 8,
3558 +// "%s: --> discarding: format of BMF encapsulation header not recognized\n",
3559 +// PLUGIN_NAME_SHORT);
3560 +// return;
3561 +// }
3562 +//
3563 +// /* Check if this packet was seen recently */
3564 +// if (CheckAndMarkRecentPacket(ntohl(encapsulationHdr->crc32)))
3565 +// {
3566 +// /* Increase counter */
3567 +// intf->nBmfPacketsRxDup++;
3568 +//
3569 +// OLSR_PRINTF(
3570 +// 8,
3571 +// "%s: --> discarding: packet is duplicate\n",
3572 +// PLUGIN_NAME_SHORT);
3573 +// return;
3574 +// }
3575 +//
3576 +// if (EtherTunTapFd >= 0)
3577 +// {
3578 +// /* Unpack the encapsulated IP packet and deliver it locally, by sending
3579 +// * a copy into the local IP stack via the EtherTunTap interface */
3580 +//
3581 +// union olsr_ip_addr broadAddr;
3582 +// int nBytesToWrite, nBytesWritten;
3583 +// unsigned char* bufferToWrite;
3584 +//
3585 +// /* If the encapsulated IP packet is a local broadcast packet,
3586 +// * update its destination address to match the subnet of the EtherTunTap
3587 +// * interface */
3588 +// broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
3589 +// CheckAndUpdateLocalBroadcast(ipPacket, &broadAddr);
3590 +//
3591 +// bufferToWrite = ipPacket;
3592 +// nBytesToWrite = ipPacketLen;
3593 +//
3594 +// /* Write the packet into the EtherTunTap interface for local delivery */
3595 +// nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);
3596 +// if (nBytesWritten != nBytesToWrite)
3597 +// {
3598 +// BmfPError("write() error forwarding encapsulated pkt on \"%s\"", EtherTunTapIfName);
3599 +// }
3600 +// else
3601 +// {
3602 +// OLSR_PRINTF(
3603 +// 8,
3604 +// "%s: --> unpacked and delivered locally on \"%s\"\n",
3605 +// PLUGIN_NAME_SHORT,
3606 +// EtherTunTapIfName);
3607 +// }
3608 +// } /* if (EtherTunTapFd >= 0) */
3609 +//
3610 +// /* Check if I am MPR for the forwarder */
3611 +// /* TODO: olsr_lookup_mprs_set() is not thread-safe! */
3612 +// iAmMpr = (olsr_lookup_mprs_set(MainAddressOf(forwardedBy)) != NULL);
3613 +//
3614 +// /* Compose destination address for next hop */
3615 +// memset(&forwardTo, 0, sizeof(forwardTo));
3616 +// forwardTo.sin_family = AF_INET;
3617 +// forwardTo.sin_port = htons(BMF_ENCAP_PORT);
3618 +//
3619 +// /* Retrieve the number of bytes to be forwarded via the encapsulation socket */
3620 +// encapsulationUdpDataLen = GetEncapsulationUdpDataLength(encapsulationUdpData);
3621 +//
3622 +// /* Check with each network interface what needs to be done on it */
3623 +// for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3624 +// {
3625 +// /* What to do with the packet on a non-OLSR interface? Unpack
3626 +// * encapsulated packet, and forward it.
3627 +// *
3628 +// * What to do with the packet on an OLSR interface? Forward it only
3629 +// * if the forwarding node has selected us as MPR (iAmMpr).
3630 +// *
3631 +// * Note that the packet is always coming in on an OLSR interface, because
3632 +// * it is an encapsulated BMF packet. */
3633 +//
3634 +// /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */
3635 +// if (walker->olsrIntf == NULL)
3636 +// {
3637 +// int nBytesWritten;
3638 +// struct sockaddr_ll dest;
3639 +//
3640 +// /* If the encapsulated IP packet is a local broadcast packet,
3641 +// * update its destination address to match the subnet of the network
3642 +// * interface on which the packet is being sent. */
3643 +// CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
3644 +//
3645 +// memset(&dest, 0, sizeof(dest));
3646 +// dest.sll_family = AF_PACKET;
3647 +// dest.sll_protocol = htons(ETH_P_IP);
3648 +// dest.sll_ifindex = if_nametoindex(walker->ifName);
3649 +// dest.sll_halen = IFHWADDRLEN;
3650 +//
3651 +// /* Use all-ones as destination MAC address. When the IP destination is
3652 +// * a multicast address, the destination MAC address should normally also
3653 +// * be a multicast address. E.g., when the destination IP is 224.0.0.1,
3654 +// * the destination MAC should be 01:00:5e:00:00:01. However, it does not
3655 +// * seem to matter when the destination MAC address is set to all-ones
3656 +// * in that case. */
3657 +// memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
3658 +//
3659 +// nBytesWritten = sendto(
3660 +// walker->capturingSkfd,
3661 +// ipPacket,
3662 +// ipPacketLen,
3663 +// 0,
3664 +// (struct sockaddr*) &dest,
3665 +// sizeof(dest));
3666 +// if (nBytesWritten != ipPacketLen)
3667 +// {
3668 +// BmfPError("sendto() error forwarding unpacked encapsulated pkt on \"%s\"", walker->ifName);
3669 +// }
3670 +// else
3671 +// {
3672 +// /* Increase counter */
3673 +// walker->nBmfPacketsTx++;
3674 +//
3675 +// OLSR_PRINTF(
3676 +// 8,
3677 +// "%s: --> unpacked and forwarded on \"%s\"\n",
3678 +// PLUGIN_NAME_SHORT,
3679 +// walker->ifName);
3680 +// }
3681 +// } /* if (walker->olsrIntf == NULL) */
3682 +//
3683 +// /* To an OLSR interface: forward the packet, but only if this node is
3684 +// * selected as MPR by the forwarding node */
3685 +// else if (iAmMpr)
3686 +// {
3687 +// struct TBestNeighbors bestNeighborLinks;
3688 +// struct link_entry* bestNeighbor;
3689 +// int nPossibleNeighbors;
3690 +// int nPacketsToSend;
3691 +// int sendUnicast; /* 0 = send broadcast; 1 = send unicast */
3692 +// int i;
3693 +//
3694 +// /* Retrieve at most two best neigbors to forward the packet to */
3695 +// FindNeighbors(
3696 +// &bestNeighborLinks,
3697 +// &bestNeighbor,
3698 +// walker,
3699 +// &mcSrc,
3700 +// forwardedBy,
3701 +// forwardedTo,
3702 +// &nPossibleNeighbors);
3703 +//
3704 +// if (nPossibleNeighbors <= 0)
3705 +// {
3706 +// OLSR_PRINTF(
3707 +// 8,
3708 +// "%s: --> not forwarding on \"%s\": there is no neighbor that needs my retransmission\n",
3709 +// PLUGIN_NAME_SHORT,
3710 +// walker->ifName);
3711 +//
3712 +// continue; /* for */
3713 +// }
3714 +//
3715 +// /* Compose destination of encapsulation packet.
3716 +// * Start by filling in the local broadcast address. This may be overwritten later. */
3717 +// forwardTo.sin_addr = walker->broadAddr.v4;
3718 +//
3719 +// /* - If the BMF mechanism is BM_UNICAST_PROMISCUOUS, always send just one
3720 +// * unicast packet (to the best neighbor).
3721 +// * - But if the BMF mechanism is BM_BROADCAST,
3722 +// * - send 'nPossibleNeighbors' unicast packets if there are up to
3723 +// * 'FanOutLimit' possible neighbors,
3724 +// * - if there are more than 'FanOutLimit' possible neighbors, then
3725 +// * send a (WLAN-air-expensive, less reliable) broadcast packet. */
3726 +// if (BmfMechanism == BM_UNICAST_PROMISCUOUS)
3727 +// {
3728 +// /* One unicast packet to the best neighbor */
3729 +// nPacketsToSend = 1;
3730 +// sendUnicast = 1;
3731 +// bestNeighborLinks.links[0] = bestNeighbor;
3732 +// }
3733 +// else /* BmfMechanism == BM_BROADCAST */
3734 +// {
3735 +// if (nPossibleNeighbors <= FanOutLimit)
3736 +// {
3737 +// /* 'nPossibleNeighbors' unicast packets */
3738 +// nPacketsToSend = nPossibleNeighbors;
3739 +// sendUnicast = 1;
3740 +// }
3741 +// else /* nPossibleNeighbors > FanOutLimit */
3742 +// {
3743 +// /* One broadcast packet, possibly retransmitted as specified in the
3744 +// * 'BroadcastRetransmitCount' plugin parameter */
3745 +// nPacketsToSend = BroadcastRetransmitCount;
3746 +// sendUnicast = 0;
3747 +// } /* if */
3748 +// } /* if */
3749 +//
3750 +// for (i = 0; i < nPacketsToSend; i++)
3751 +// {
3752 +// int nBytesWritten;
3753 +//
3754 +// if (sendUnicast)
3755 +// {
3756 +// /* For unicast, overwrite the local broadcast address which was filled in above */
3757 +// forwardTo.sin_addr = bestNeighborLinks.links[i]->neighbor_iface_addr.v4;
3758 +// }
3759 +//
3760 +// /* Forward the BMF packet via the encapsulation socket */
3761 +// nBytesWritten = sendto(
3762 +// walker->encapsulatingSkfd,
3763 +// encapsulationUdpData,
3764 +// encapsulationUdpDataLen,
3765 +// MSG_DONTROUTE,
3766 +// (struct sockaddr*) &forwardTo,
3767 +// sizeof(forwardTo));
3768 +//
3769 +// /* Evaluate and display result */
3770 +// if (nBytesWritten != encapsulationUdpDataLen)
3771 +// {
3772 +// BmfPError("sendto() error forwarding encapsulated pkt on \"%s\"", walker->ifName);
3773 +// }
3774 +// else
3775 +// {
3776 +// /* Increase counter */
3777 +// walker->nBmfPacketsTx++;
3778 +//
3779 +// OLSR_PRINTF(
3780 +// 8,
3781 +// "%s: --> forwarded on \"%s\" to %s\n",
3782 +// PLUGIN_NAME_SHORT,
3783 +// walker->ifName,
3784 +// inet_ntoa(forwardTo.sin_addr));
3785 +// } /* if */
3786 +// } /* for */
3787 +// } /* else if (iAmMpr) */
3788 +//
3789 +// else /* walker->olsrIntf != NULL && !iAmMpr */
3790 +// {
3791 +// struct ipaddr_str buf;
3792 +// /* 'walker' is an OLSR interface, but I am not selected as MPR. In that
3793 +// * case, don't forward. */
3794 +// OLSR_PRINTF(
3795 +// 8,
3796 +// "%s: --> not forwarding on \"%s\": I am not selected as MPR by %s\n",
3797 +// PLUGIN_NAME_SHORT,
3798 +// walker->ifName,
3799 +// olsr_ip_to_string(&buf, forwardedBy));
3800 +// } /* else */
3801 +// } /* for */
3802 +//} /* BmfEncapsulationPacketReceived */
3803 +//
3804 +/* -------------------------------------------------------------------------
3805 + * Function : BmfTunPacketCaptured
3806 + * Description: Handle an IP packet, captured outgoing on the tuntap interface
3807 + * Input : encapsulationUdpData - space for the encapsulation header, followed by
3808 + * the captured outgoing IP packet
3809 + * Output : none
3810 + * Return : none
3811 + * Data Used : none
3812 + * Notes : The packet is assumed to be captured on a socket of family
3813 + * PF_PACKET and type SOCK_DGRAM (cooked).
3814 + * ------------------------------------------------------------------------- */
3815 +//static void BmfTunPacketCaptured(unsigned char* encapsulationUdpData)
3816 +//{
3817 +// union olsr_ip_addr srcIp;
3818 +// union olsr_ip_addr dstIp;
3819 +// union olsr_ip_addr broadAddr;
3820 +// struct TBmfInterface* walker;
3821 +// unsigned char* ipPacket;
3822 +// u_int16_t ipPacketLen;
3823 +// struct ip* ipHeader;
3824 +// u_int32_t crc32;
3825 +// struct TEncapHeader* encapHdr;
3826 +// struct ipaddr_str srcIpBuf, dstIpBuf;
3827 +// ipPacket = GetIpPacket(encapsulationUdpData);
3828 +// ipPacketLen = GetIpTotalLength(ipPacket);
3829 +// ipHeader = GetIpHeader(encapsulationUdpData);
3830 +//
3831 +// dstIp.v4 = ipHeader->ip_dst;
3832 +// broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast);
3833 +//
3834 +// /* Only forward multicast packets. If configured, also forward local broadcast packets */
3835 +// if (IsMulticast(&dstIp) ||
3836 +// (EnableLocalBroadcast != 0 && olsr_ipequal(&dstIp, &broadAddr)))
3837 +// {
3838 +// /* continue */
3839 +// }
3840 +// else
3841 +// {
3842 +// return;
3843 +// }
3844 +//
3845 +// srcIp.v4 = ipHeader->ip_src;
3846 +//
3847 +// OLSR_PRINTF(
3848 +// 8,
3849 +// "%s: outgoing pkt of %ld bytes captured on tuntap interface \"%s\": %s->%s\n",
3850 +// PLUGIN_NAME_SHORT,
3851 +// (long)ipPacketLen,
3852 +// EtherTunTapIfName,
3853 +// olsr_ip_to_string(&srcIpBuf, &srcIp),
3854 +// olsr_ip_to_string(&dstIpBuf, &dstIp));
3855 +//
3856 +// /* Calculate packet fingerprint */
3857 +// crc32 = PacketCrc32(ipPacket, ipPacketLen);
3858 +//
3859 +// /* Check if this packet was seen recently */
3860 +// if (CheckAndMarkRecentPacket(crc32))
3861 +// {
3862 +// OLSR_PRINTF(
3863 +// 8,
3864 +// "%s: --> discarding: packet is duplicate\n",
3865 +// PLUGIN_NAME_SHORT);
3866 +// return;
3867 +// }
3868 +//
3869 +// /* Compose encapsulation header */
3870 +// encapHdr = (struct TEncapHeader*) encapsulationUdpData;
3871 +// memset (encapHdr, 0, ENCAP_HDR_LEN);
3872 +// encapHdr->type = BMF_ENCAP_TYPE;
3873 +// encapHdr->len = BMF_ENCAP_LEN;
3874 +// encapHdr->reserved = 0;
3875 +// encapHdr->crc32 = htonl(crc32);
3876 +//
3877 +// /* Check with each network interface what needs to be done on it */
3878 +// for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3879 +// {
3880 +// /* Is the forwarding interface OLSR-enabled? */
3881 +// if (walker->olsrIntf != NULL)
3882 +// {
3883 +// /* On an OLSR interface: encapsulate and forward packet. */
3884 +//
3885 +// EncapsulateAndForwardPacket(walker, encapsulationUdpData);
3886 +// }
3887 +// else
3888 +// {
3889 +// /* On a non-OLSR interface: what to do?
3890 +// * Answer 1: nothing. Multicast routing between non-OLSR interfaces
3891 +// * is to be done by other protocols (e.g. PIM, DVMRP).
3892 +// * Answer 2 (better): Forward it. */
3893 +//
3894 +// int nBytesWritten;
3895 +// struct sockaddr_ll dest;
3896 +//
3897 +// /* If the encapsulated IP packet is a local broadcast packet,
3898 +// * update its destination address to match the subnet of the network
3899 +// * interface on which the packet is being sent. */
3900 +// CheckAndUpdateLocalBroadcast(ipPacket, &walker->broadAddr);
3901 +//
3902 +// memset(&dest, 0, sizeof(dest));
3903 +// dest.sll_family = AF_PACKET;
3904 +// dest.sll_protocol = htons(ETH_P_IP);
3905 +// dest.sll_ifindex = if_nametoindex(walker->ifName);
3906 +// dest.sll_halen = IFHWADDRLEN;
3907 +//
3908 +// /* Use all-ones as destination MAC address. When the IP destination is
3909 +// * a multicast address, the destination MAC address should normally also
3910 +// * be a multicast address. E.g., when the destination IP is 224.0.0.1,
3911 +// * the destination MAC should be 01:00:5e:00:00:01. However, it does not
3912 +// * seem to matter when the destination MAC address is set to all-ones
3913 +// * in that case. */
3914 +// memset(dest.sll_addr, 0xFF, IFHWADDRLEN);
3915 +//
3916 +// nBytesWritten = sendto(
3917 +// walker->capturingSkfd,
3918 +// ipPacket,
3919 +// ipPacketLen,
3920 +// 0,
3921 +// (struct sockaddr*) &dest,
3922 +// sizeof(dest));
3923 +// if (nBytesWritten != ipPacketLen)
3924 +// {
3925 +// BmfPError("sendto() error forwarding pkt on \"%s\"", walker->ifName);
3926 +// }
3927 +// else
3928 +// {
3929 +// /* Increase counter */
3930 +// walker->nBmfPacketsTx++;
3931 +//
3932 +// OLSR_PRINTF(
3933 +// 8,
3934 +// "%s: --> forwarded from non-OLSR to non-OLSR \"%s\"\n",
3935 +// PLUGIN_NAME_SHORT,
3936 +// walker->ifName);
3937 +// } /* if */
3938 +// } /* if */
3939 +// } /* for */
3940 +//} /* BmfTunPacketCaptured */
3941 +//
3942 +/* -------------------------------------------------------------------------
3943 + * Function : DoBmf
3944 + * Description: Wait (blocking) for IP packets, then call the handler for each
3945 + * received packet
3946 + * Input : none
3947 + * Output : none
3948 + * Return : none
3949 + * Data Used : BmfInterfaces
3950 + * ------------------------------------------------------------------------- */
3951 +void DoMDNS(int skfd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
3952 +
3953 +{
3954 +// int nFdBitsSet;
3955 + unsigned char rxBuffer[BMF_BUFFER_SIZE];
3956 +// fd_set rxFdSet;
3957 +// OLSR_PRINTF(1,"ENTERING DoMDNS\n");
3958 +// assert(HighestSkfd >= 0);
3959 +//
3960 +// /* Make a local copy of the set of file descriptors that select() can
3961 +// * modify to indicate which descriptors actually changed status */
3962 +// rxFdSet = InputSet;
3963 +//
3964 +// /* Wait (blocking) for packets received on any of the sockets.
3965 +// * NOTE: don't use a timeout (last parameter). It causes a high system CPU load! */
3966 +// nFdBitsSet = select(HighestSkfd + 1, &rxFdSet, NULL, NULL, NULL);
3967 +// if (nFdBitsSet < 0)
3968 +// {
3969 +// if (errno != EINTR)
3970 +// {
3971 +// BmfPError("select() error");
3972 +// }
3973 +// return;
3974 +// }
3975 +//
3976 + //while (nFdBitsSet > 0)
3977 + //{
3978 + //struct TBmfInterface* walker;
3979 +
3980 + /* Check if a packet was received on the capturing socket (if any)
3981 + * of each network interface */
3982 + //for (walker = BmfInterfaces; walker != NULL; walker = walker->next)
3983 + //{
3984 + //int skfd = walker->capturingSkfd;
3985 + //if (skfd >= 0 && (FD_ISSET(skfd, &rxFdSet)))
3986 + if (skfd >= 0)
3987 + {
3988 + struct sockaddr_ll pktAddr;
3989 + socklen_t addrLen = sizeof(pktAddr);
3990 + int nBytes;
3991 + unsigned char* ipPacket;
3992 +
3993 + /* Receive the captured Ethernet frame, leaving space for the BMF
3994 + * encapsulation header */
3995 + ipPacket = GetIpPacket(rxBuffer);
3996 + nBytes = recvfrom(
3997 + skfd,
3998 + ipPacket,
3999 + //BMF_BUFFER_SIZE - ENCAP_HDR_LEN, //TODO: understand how to change this
4000 + BMF_BUFFER_SIZE, //TODO: understand how to change this
4001 + 0,
4002 + (struct sockaddr*)&pktAddr,
4003 + &addrLen);
4004 + if (nBytes < 0)
4005 + {
4006 + //BmfPError("recvfrom() error on \"%s\"", walker->ifName);
4007 +
4008 + return; /* for */
4009 + } /* if (nBytes < 0) */
4010 +
4011 + /* Check if the number of received bytes is large enough for an IP
4012 + * packet which contains at least a minimum-size IP header.
4013 + * Note: There is an apparent bug in the packet socket implementation in
4014 + * combination with VLAN interfaces. On a VLAN interface, the value returned
4015 + * by 'recvfrom' may (but need not) be 4 (bytes) larger than the value
4016 + * returned on a non-VLAN interface, for the same ethernet frame. */
4017 + if (nBytes < (int)sizeof(struct ip))
4018 + {
4019 + //OLSR_PRINTF(
4020 + // 1,
4021 + // "%s: captured frame too short (%d bytes) on \"%s\"\n",
4022 + // PLUGIN_NAME,
4023 + // nBytes,
4024 + // walker->ifName);
4025 +
4026 + return; /* for */
4027 + }
4028 +
4029 + if (pktAddr.sll_pkttype == PACKET_OUTGOING ||
4030 + pktAddr.sll_pkttype == PACKET_MULTICAST ||
4031 + pktAddr.sll_pkttype == PACKET_BROADCAST)
4032 + {
4033 + /* A multicast or broadcast packet was captured */
4034 +
4035 + //OLSR_PRINTF(
4036 + // 1,
4037 + // "%s: captured frame (%d bytes) on \"%s\"\n",
4038 + // PLUGIN_NAME,
4039 + // nBytes,
4040 + // walker->ifName);
4041 + //BmfPacketCaptured(walker, pktAddr.sll_pkttype, rxBuffer);
4042 + BmfPacketCaptured(ipPacket,nBytes);
4043 +
4044 + } /* if (pktAddr.sll_pkttype == ...) */
4045 + } /* if (skfd >= 0 && (FD_ISSET...)) */
4046 +// } /* for */
4047 +
4048 +// } /* while (nFdBitsSet > 0) */
4049 +} /* DoMDNS */
4050 +
4051 +int InitMDNS(struct interface* skipThisIntf)
4052 +{
4053 +
4054 +
4055 + //Tells OLSR to launch olsr_parser when the packets for this plugin arrive
4056 + olsr_parser_add_function(&olsr_parser, PARSER_TYPE);
4057 + CreateBmfNetworkInterfaces(skipThisIntf);
4058 +
4059 + return 0;
4060 +} /* InitBmf */
4061 +
4062 +/* -------------------------------------------------------------------------
4063 + * Function : CloseBmf
4064 + * Description: Close the BMF plugin and clean up
4065 + * Input : none
4066 + * Output : none
4067 + * Return : none
4068 + * Data Used : BmfThread
4069 + * ------------------------------------------------------------------------- */
4070 +void CloseMDNS(void)
4071 +{
4072 +// if (EtherTunTapFd >= 0)
4073 +// {
4074 +// /* If there is a multicast route, try to delete it first */
4075 +// DeleteMulticastRoute();
4076 +//
4077 +// /* Restore IP spoof filter for EtherTunTap interface */
4078 +// RestoreSpoofFilter();
4079 +// }
4080 +//
4081 +// if (mdnsThreadRunning)
4082 +// {
4083 +// /* Signal BmfThread to exit */
4084 +// /* Strangely enough, all running threads receive the SIGALRM signal. But only the
4085 +// * BMF thread is affected by this signal, having specified a handler for this
4086 +// * signal in its thread entry function BmfRun(...). */
4087 +// if (pthread_kill(mdnsThread, SIGALRM) != 0)
4088 +// {
4089 +// BmfPError("pthread_kill() error");
4090 +// }
4091 +//
4092 +// /* Wait for BmfThread to acknowledge */
4093 +// if (pthread_join(mdnsThread, NULL) != 0)
4094 +// {
4095 +// BmfPError("pthread_join() error");
4096 +// }
4097 +// }
4098 +//
4099 +// /* Clean up after the BmfThread has been killed */
4100 + CloseBmfNetworkInterfaces();
4101 +} /* CloseBmf */
4102 +
4103 +
4104 +/*
4105 + * Local Variables:
4106 + * c-basic-offset: 2
4107 + * indent-tabs-mode: nil
4108 + * End:
4109 + */
4110 --- /dev/null
4111 +++ b/lib/mdns/src/mdns.h
4112 @@ -0,0 +1,95 @@
4113 +#ifndef _BMF_BMF_H
4114 +#define _BMF_BMF_H
4115 +
4116 +/*
4117 + * OLSR Basic Multicast Forwarding (BMF) plugin.
4118 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
4119 + * Written by Erik Tromp.
4120 + * All rights reserved.
4121 + *
4122 + * Redistribution and use in source and binary forms, with or without
4123 + * modification, are permitted provided that the following conditions
4124 + * are met:
4125 + *
4126 + * * Redistributions of source code must retain the above copyright
4127 + * notice, this list of conditions and the following disclaimer.
4128 + * * Redistributions in binary form must reproduce the above copyright
4129 + * notice, this list of conditions and the following disclaimer in
4130 + * the documentation and/or other materials provided with the
4131 + * distribution.
4132 + * * Neither the name of Thales, BMF nor the names of its
4133 + * contributors may be used to endorse or promote products derived
4134 + * from this software without specific prior written permission.
4135 + *
4136 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
4137 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4138 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
4139 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
4140 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
4141 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
4142 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
4143 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
4144 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4145 + * OF THE POSSIBILITY OF SUCH DAMAGE.
4146 + */
4147 +
4148 +/* -------------------------------------------------------------------------
4149 + * File : Bmf.h
4150 + * Description: Multicast forwarding functions
4151 + * Created : 29 Jun 2006
4152 + *
4153 + * ------------------------------------------------------------------------- */
4154 +
4155 +#include "olsrd_plugin.h" /* union set_plugin_parameter_addon */
4156 +
4157 +#include "parser.h"
4158 +#include <socket_parser.h>
4159 +
4160 +#define MESSAGE_TYPE 132
4161 +#define PARSER_TYPE MESSAGE_TYPE
4162 +#define EMISSION_INTERVAL 10 /* seconds */
4163 +#define EMISSION_JITTER 25 /* percent */
4164 +#define MDNS_VALID_TIME 1800 /* seconds */
4165 +
4166 +/* BMF plugin data */
4167 +#define PLUGIN_NAME "OLSRD MDNS plugin"
4168 +#define PLUGIN_NAME_SHORT "OLSRD MDNS"
4169 +#define PLUGIN_VERSION "1.0.0 (" __DATE__ " " __TIME__ ")"
4170 +#define PLUGIN_COPYRIGHT " (C) Ninux.org"
4171 +#define PLUGIN_AUTHOR " Saverio Proto (zioproto@gmail.com)"
4172 +#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION "\n" PLUGIN_COPYRIGHT "\n" PLUGIN_AUTHOR
4173 +#define PLUGIN_INTERFACE_VERSION 5
4174 +
4175 +/* UDP-Port on which multicast packets are encapsulated */
4176 +//#define BMF_ENCAP_PORT 50698
4177 +
4178 +/* Forward declaration of OLSR interface type */
4179 +struct interface;
4180 +
4181 +//extern int FanOutLimit;
4182 +//extern int BroadcastRetransmitCount;
4183 +
4184 +void DoMDNS(int sd, void * x, unsigned int y);
4185 +void BmfPError(const char* format, ...) __attribute__((format(printf, 1, 2)));
4186 +union olsr_ip_addr* MainAddressOf(union olsr_ip_addr* ip);
4187 +//int InterfaceChange(struct interface* interf, int action);
4188 +//int SetFanOutLimit(const char* value, void* data, set_plugin_parameter_addon addon);
4189 +//int InitBmf(struct interface* skipThisIntf);
4190 +//void CloseBmf(void);
4191 +int InitMDNS(struct interface* skipThisIntf);
4192 +void CloseMDNS(void);
4193 +
4194 +void olsr_mdns_gen(unsigned char* packet, int len);
4195 +
4196 +/* Parser function to register with the scheduler */
4197 +bool
4198 +olsr_parser(union olsr_message *, struct interface *, union olsr_ip_addr *);
4199 +
4200 +#endif /* _BMF_BMF_H */
4201 +
4202 +/*
4203 + * Local Variables:
4204 + * c-basic-offset: 2
4205 + * indent-tabs-mode: nil
4206 + * End:
4207 + */
4208 --- /dev/null
4209 +++ b/lib/mdns/src/olsrd_plugin.c
4210 @@ -0,0 +1,185 @@
4211 +/*
4212 + * OLSR Basic Multicast Forwarding (BMF) plugin.
4213 + * Copyright (c) 2005 - 2007, Thales Communications, Huizen, The Netherlands.
4214 + * Written by Erik Tromp.
4215 + * All rights reserved.
4216 + *
4217 + * Redistribution and use in source and binary forms, with or without
4218 + * modification, are permitted provided that the following conditions
4219 + * are met:
4220 + *
4221 + * * Redistributions of source code must retain the above copyright
4222 + * notice, this list of conditions and the following disclaimer.
4223 + * * Redistributions in binary form must reproduce the above copyright
4224 + * notice, this list of conditions and the following disclaimer in
4225 + * the documentation and/or other materials provided with the
4226 + * distribution.
4227 + * * Neither the name of Thales, BMF nor the names of its
4228 + * contributors may be used to endorse or promote products derived
4229 + * from this software without specific prior written permission.
4230 + *
4231 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
4232 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4233 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
4234 + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
4235 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
4236 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
4237 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
4238 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
4239 + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4240 + * OF THE POSSIBILITY OF SUCH DAMAGE.
4241 + */
4242 +
4243 +/* -------------------------------------------------------------------------
4244 + * File : olsrd_plugin.c
4245 + * Description: Interface to the OLSRD plugin system
4246 + * Created : 29 Jun 2006
4247 + *
4248 + * ------------------------------------------------------------------------- */
4249 +
4250 +/* System includes */
4251 +#include <assert.h> /* assert() */
4252 +#include <stddef.h> /* NULL */
4253 +
4254 +/* OLSRD includes */
4255 +#include "olsrd_plugin.h"
4256 +#include "plugin_util.h"
4257 +#include "defs.h" /* uint8_t, olsr_cnf */
4258 +#include "scheduler.h" /* olsr_start_timer() */
4259 +#include "olsr_cfg.h" /* olsr_cnf() */
4260 +#include "olsr_cookie.h" /* olsr_alloc_cookie() */
4261 +
4262 +/* BMF includes */
4263 +#include "mdns.h" /* InitBmf(), CloseBmf() */
4264 +#include "PacketHistory.h" /* InitPacketHistory() */
4265 +#include "NetworkInterfaces.h" /* AddNonOlsrBmfIf(), SetBmfInterfaceIp(), ... */
4266 +#include "Address.h" /* DoLocalBroadcast() */
4267 +
4268 +static void __attribute__ ((constructor)) my_init(void);
4269 +static void __attribute__ ((destructor)) my_fini(void);
4270 +
4271 +//static struct olsr_cookie_info *prune_packet_history_timer_cookie;
4272 +
4273 +void olsr_plugin_exit(void);
4274 +
4275 +/* -------------------------------------------------------------------------
4276 + * Function : olsrd_plugin_interface_version
4277 + * Description: Plugin interface version
4278 + * Input : none
4279 + * Output : none
4280 + * Return : BMF plugin interface version number
4281 + * Data Used : none
4282 + * Notes : Called by main OLSRD (olsr_load_dl) to check plugin interface
4283 + * version
4284 + * ------------------------------------------------------------------------- */
4285 +int olsrd_plugin_interface_version(void)
4286 +{
4287 + return PLUGIN_INTERFACE_VERSION;
4288 +}
4289 +
4290 +/* -------------------------------------------------------------------------
4291 + * Function : olsrd_plugin_init
4292 + * Description: Plugin initialisation
4293 + * Input : none
4294 + * Output : none
4295 + * Return : fail (0) or success (1)
4296 + * Data Used : olsr_cnf
4297 + * Notes : Called by main OLSRD (init_olsr_plugin) to initialize plugin
4298 + * ------------------------------------------------------------------------- */
4299 +int olsrd_plugin_init(void)
4300 +{
4301 + /* Clear the packet history */
4302 + //InitPacketHistory();
4303 +
4304 + /* Register ifchange function */
4305 + //add_ifchgf(&InterfaceChange);
4306 +
4307 + /* create the cookie */
4308 + //prune_packet_history_timer_cookie = olsr_alloc_cookie("BMF: Prune Packet History", OLSR_COOKIE_TYPE_TIMER);
4309 +
4310 + /* Register the duplicate registration pruning process */
4311 + //olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
4312 + // &PrunePacketHistory, NULL, prune_packet_history_timer_cookie->ci_id);
4313 +
4314 +
4315 + return InitMDNS(NULL);
4316 +}
4317 +
4318 +/* -------------------------------------------------------------------------
4319 + * Function : olsr_plugin_exit
4320 + * Description: Plugin cleanup
4321 + * Input : none
4322 + * Output : none
4323 + * Return : none
4324 + * Data Used : none
4325 + * Notes : Called by my_fini() at unload of shared object
4326 + * ------------------------------------------------------------------------- */
4327 +void olsr_plugin_exit(void)
4328 +{
4329 + CloseMDNS();
4330 +}
4331 +
4332 +static const struct olsrd_plugin_parameters plugin_parameters[] = {
4333 + { .name = "NonOlsrIf", .set_plugin_parameter = &AddNonOlsrBmfIf, .data = NULL },
4334 + //{ .name = "DoLocalBroadcast", .set_plugin_parameter = &DoLocalBroadcast, .data = NULL },
4335 + //{ .name = "BmfInterface", .set_plugin_parameter = &SetBmfInterfaceName, .data = NULL },
4336 + //{ .name = "BmfInterfaceIp", .set_plugin_parameter = &SetBmfInterfaceIp, .data = NULL },
4337 + //{ .name = "CapturePacketsOnOlsrInterfaces", .set_plugin_parameter = &SetCapturePacketsOnOlsrInterfaces, .data = NULL },
4338 + //{ .name = "BmfMechanism", .set_plugin_parameter = &SetBmfMechanism, .data = NULL },
4339 + //{ .name = "FanOutLimit", .set_plugin_parameter = &SetFanOutLimit, .data = NULL },
4340 + //{ .name = "BroadcastRetransmitCount", .set_plugin_parameter = &set_plugin_int, .data = &BroadcastRetransmitCount},
4341 +};
4342 +
4343 +/* -------------------------------------------------------------------------
4344 + * Function : olsrd_get_plugin_parameters
4345 + * Description: Return the parameter table and its size
4346 + * Input : none
4347 + * Output : params - the parameter table
4348 + * size - its size in no. of entries
4349 + * Return : none
4350 + * Data Used : plugin_parameters
4351 + * Notes : Called by main OLSR (init_olsr_plugin) for all plugins
4352 + * ------------------------------------------------------------------------- */
4353 +void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
4354 +{
4355 + *params = plugin_parameters;
4356 + *size = ARRAYSIZE(plugin_parameters);
4357 +}
4358 +
4359 +/* -------------------------------------------------------------------------
4360 + * Function : my_init
4361 + * Description: Plugin constructor
4362 + * Input : none
4363 + * Output : none
4364 + * Return : none
4365 + * Data Used : none
4366 + * Notes : Called at load of shared object
4367 + * ------------------------------------------------------------------------- */
4368 +static void my_init(void)
4369 +{
4370 + /* Print plugin info to stdout */
4371 + printf("%s\n", MOD_DESC);
4372 +
4373 + return;
4374 +}
4375 +
4376 +/* -------------------------------------------------------------------------
4377 + * Function : my_fini
4378 + * Description: Plugin destructor
4379 + * Input : none
4380 + * Output : none
4381 + * Return : none
4382 + * Data Used : none
4383 + * Notes : Called at unload of shared object
4384 + * ------------------------------------------------------------------------- */
4385 +static void my_fini(void)
4386 +{
4387 + olsr_plugin_exit();
4388 +}
4389 +
4390 +/*
4391 + * Local Variables:
4392 + * c-basic-offset: 2
4393 + * indent-tabs-mode: nil
4394 + * End:
4395 + */
4396 --- /dev/null
4397 +++ b/lib/mdns/version-script.txt
4398 @@ -0,0 +1,10 @@
4399 +VERS_1.0
4400 +{
4401 + global:
4402 + olsrd_plugin_interface_version;
4403 + olsrd_plugin_init;
4404 + olsrd_get_plugin_parameters;
4405 +
4406 + local:
4407 + *;
4408 +};