include $(TOPDIR)/rules.mk
PKG_NAME:=olsrd
-PKG_VERSION:=0.4.10
+PKG_VERSION:=0.5.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=http://www.olsr.org/releases/0.4
-PKG_MD5SUM:=9807d4451e65cb4ec385155eef7bf3cf
+PKG_SOURCE_URL:=http://www.olsr.org/releases/0.5
+PKG_MD5SUM:=c82c72d7a55a423aa9d9e571084f041b
PKG_CAT:=bzcat
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
MENU:=0
endef
-define Package/olsrd-mod-power
- $(call Package/olsrd)
- DEPENDS:=olsrd
- TITLE:=Power status plugin
- MENU:=0
-endef
-
define Package/olsrd-mod-secure
$(call Package/olsrd)
DEPENDS:=olsrd
OS="linux" \
INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \
LIBDIR="$(PKG_INSTALL_DIR)/usr/lib" \
+ SBINDIR="$(PKG_INSTALL_DIR)/usr/sbin/" \
+ ETCDIR="$(PKG_INSTALL_DIR)/etc" \
+ MANDIR="$(PKG_INSTALL_DIR)/usr/share/man" \
STRIP="/bin/true" \
all libs install install_libs
endef
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/olsrd_nameservice.so.* $(1)/usr/lib/
endef
-define Package/olsrd-mod-power/install
- $(INSTALL_DIR) $(1)/usr/lib
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/olsrd_power.so.* $(1)/usr/lib/
-endef
-
define Package/olsrd-mod-secure/install
$(INSTALL_DIR) $(1)/etc/olsrd.d
$(CP) ./files/olsrd_secure_key $(1)/etc/olsrd.d/
$(eval $(call BuildPackage,olsrd-mod-dyn-gw))
$(eval $(call BuildPackage,olsrd-mod-httpinfo))
$(eval $(call BuildPackage,olsrd-mod-nameservice))
-$(eval $(call BuildPackage,olsrd-mod-power))
$(eval $(call BuildPackage,olsrd-mod-secure))
$(eval $(call BuildPackage,olsrd-mod-tas))
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/Makefile olsrd-0.4.10/lib/Makefile
---- olsrd-0.4.10.orig/lib/Makefile 2005-05-26 18:09:25.000000000 +0200
-+++ olsrd-0.4.10/lib/Makefile 2006-12-01 08:18:12.000000000 +0100
-@@ -1,4 +1,4 @@
--SUBDIRS = dot_draw dyn_gw httpinfo mini nameservice powerinfo secure tas
-+SUBDIRS = $(shell find -maxdepth 1 -type d -not -name ".*" -not -name "CVS" -printf "%f\n")
-
- .PHONY: $(SUBDIRS)
-
+++ /dev/null
-diff -ruN olsrd-0.4.10-old/Makefile.inc olsrd-0.4.10-new/Makefile.inc
---- olsrd-0.4.10-old/Makefile.inc 2006-01-01 16:58:20.000000000 +0100
-+++ olsrd-0.4.10-new/Makefile.inc 2006-01-05 17:57:23.000000000 +0100
-@@ -21,7 +21,7 @@
- ifndef CFLAGS
- CFLAGS += -Wall -Wmissing-prototypes -Wstrict-prototypes \
- -Wmissing-declarations -Wsign-compare
--CFLAGS += -O2 -g
-+CFLAGS += $(OFLAGS)
- endif
-
- ifdef OLSRD_PLUGIN
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/dyn_gw_plain/Makefile olsrd-0.4.10/lib/dyn_gw_plain/Makefile
---- olsrd-0.4.10.orig/lib/dyn_gw_plain/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/dyn_gw_plain/Makefile 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,57 @@
-+# The olsr.org Optimized Link-State Routing daemon(olsrd)
-+# Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+# All rights reserved.
-+#
-+# Redistribution and use in source and binary forms, with or without
-+# modification, are permitted provided that the following conditions
-+# are met:
-+#
-+# * Redistributions of source code must retain the above copyright
-+# notice, this list of conditions and the following disclaimer.
-+# * Redistributions in binary form must reproduce the above copyright
-+# notice, this list of conditions and the following disclaimer in
-+# the documentation and/or other materials provided with the
-+# distribution.
-+# * Neither the name of olsr.org, olsrd nor the names of its
-+# contributors may be used to endorse or promote products derived
-+# from this software without specific prior written permission.
-+#
-+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+# POSSIBILITY OF SUCH DAMAGE.
-+#
-+# Visit http://www.olsr.org for more information.
-+#
-+# If you find this software useful feel free to make a donation
-+# to the project. For more information see the website or contact
-+# the copyright holders.
-+#
-+# $Id: olsrd-dyngwplain.patch,v 1.5 2006/12/04 08:33:46 sven-ola Exp $
-+
-+OLSRD_PLUGIN = true
-+PLUGIN_NAME = olsrd_dyn_gw_plain
-+PLUGIN_VER = 0.4
-+
-+TOPDIR = ../..
-+include $(TOPDIR)/Makefile.inc
-+
-+default_target: $(PLUGIN_FULLNAME)
-+
-+$(PLUGIN_FULLNAME): $(OBJS)
-+ $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
-+
-+install: $(PLUGIN_FULLNAME)
-+ $(STRIP) $(PLUGIN_FULLNAME)
-+ $(INSTALL_LIB)
-+
-+clean:
-+ rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
-diff -Nur olsrd-0.4.10.orig/lib/dyn_gw_plain/README_DYN_GW_PLAIN olsrd-0.4.10/lib/dyn_gw_plain/README_DYN_GW_PLAIN
---- olsrd-0.4.10.orig/lib/dyn_gw_plain/README_DYN_GW_PLAIN 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/dyn_gw_plain/README_DYN_GW_PLAIN 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,17 @@
-+DYNAMIC INTERNET GATEWAY PLAIN PLUGIN FOR olsr.org olsrd
-+by Andreas Tønnesen(andreto@olsr.org)
-+additions by Sven-Ola Tuecke
-+
-+This plugin is without Ping/libthread. It is the plain dyn_gw!
-+
-+HOW TO USE
-+
-+Add an entry like this to your olsrd configuration file:
-+
-+LoadPlugin "olsrd_dyn_gw_plain.so.0.4"
-+{
-+}
-+
-+ABOUT
-+
-+Plugin is IPv4 only.
-diff -Nur olsrd-0.4.10.orig/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.c olsrd-0.4.10/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.c
---- olsrd-0.4.10.orig/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,186 @@
-+/*
-+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
-+ * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of olsr.org, olsrd nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * Visit http://www.olsr.org for more information.
-+ *
-+ * If you find this software useful feel free to make a donation
-+ * to the project. For more information see the website or contact
-+ * the copyright holders.
-+ */
-+
-+#include "olsr_types.h"
-+#include "olsrd_dyn_gw_plain.h"
-+#include "scheduler.h"
-+#include "olsr.h"
-+#include "local_hna_set.h"
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <net/route.h>
-+#include <linux/in_route.h>
-+#include <unistd.h>
-+#include <errno.h>
-+
-+#define DEBUGLEV 1
-+
-+static int has_inet_gateway;
-+
-+/**
-+ * Plugin interface version
-+ * Used by main olsrd to check plugin interface version
-+ */
-+int
-+olsrd_plugin_interface_version()
-+{
-+ return OLSRD_PLUGIN_INTERFACE_VERSION;
-+}
-+
-+/**
-+ * Register parameters from config file
-+ * Called for all plugin parameters
-+ */
-+int
-+olsrd_plugin_register_param(char *key, char *value)
-+{
-+ return 1;
-+}
-+
-+/**
-+ * Initialize plugin
-+ * Called after all parameters are passed
-+ */
-+int
-+olsrd_plugin_init()
-+{
-+ gw_net.v4 = INET_NET;
-+ gw_netmask.v4 = INET_PREFIX;
-+
-+ has_inet_gateway = 0;
-+
-+ /* Remove all local Inet HNA entries */
-+ while(remove_local_hna4_entry(&gw_net, &gw_netmask)) {
-+ olsr_printf(DEBUGLEV, "HNA Internet gateway deleted\n");
-+ }
-+
-+ /* Register the GW check */
-+ olsr_register_scheduler_event(&olsr_event, NULL, 3, 4, NULL);
-+
-+ return 1;
-+}
-+
-+int
-+check_gw(union olsr_ip_addr *net, union olsr_ip_addr *mask)
-+{
-+ char buff[1024], iface[16];
-+ olsr_u32_t gate_addr, dest_addr, netmask;
-+ unsigned int iflags;
-+ int num, metric, refcnt, use;
-+ int retval = 0;
-+
-+ FILE *fp = fopen(PROCENTRY_ROUTE, "r");
-+
-+ if (!fp)
-+ {
-+ perror(PROCENTRY_ROUTE);
-+ olsr_printf(DEBUGLEV, "INET (IPv4) not configured in this system.\n");
-+ return -1;
-+ }
-+
-+ rewind(fp);
-+
-+ /*
-+ olsr_printf(DEBUGLEV, "Genmask Destination Gateway "
-+ "Flags Metric Ref Use Iface\n");
-+ /**/
-+ while (fgets(buff, 1023, fp))
-+ {
-+ num = sscanf(buff, "%16s %128X %128X %X %d %d %d %128X \n",
-+ iface, &dest_addr, &gate_addr,
-+ &iflags, &refcnt, &use, &metric, &netmask);
-+
-+ if (num < 8)
-+ {
-+ continue;
-+ }
-+
-+ /*
-+ olsr_printf(DEBUGLEV, "%-15s ", olsr_ip_to_string((union olsr_ip_addr *)&netmask));
-+
-+ olsr_printf(DEBUGLEV, "%-15s ", olsr_ip_to_string((union olsr_ip_addr *)&dest_addr));
-+
-+ olsr_printf(DEBUGLEV, "%-15s %-6d %-2d %7d %s\n",
-+ olsr_ip_to_string((union olsr_ip_addr *)&gate_addr),
-+ metric, refcnt, use, iface);
-+ /**/
-+
-+ if(//(iflags & RTF_GATEWAY) &&
-+ (iflags & RTF_UP) &&
-+ (metric == 0) &&
-+ (netmask == mask->v4) &&
-+ (dest_addr == net->v4))
-+ {
-+ olsr_printf(DEBUGLEV, "INTERNET GATEWAY VIA %s detected in routing table.\n", iface);
-+ retval=1;
-+ }
-+
-+ }
-+
-+ fclose(fp);
-+
-+ if(retval == 0)
-+ {
-+ olsr_printf(DEBUGLEV, "No Internet GWs detected...\n");
-+ }
-+
-+ return retval;
-+}
-+
-+/**
-+ * Scheduled event to update the hna table,
-+ * called from olsrd main thread to keep the hna table thread-safe
-+ */
-+void olsr_event(void* foo)
-+{
-+ int res = check_gw(&gw_net, &gw_netmask);
-+ if (1 == res && 0 == has_inet_gateway) {
-+ olsr_printf(DEBUGLEV, "Adding OLSR local HNA entry for Internet\n");
-+ add_local_hna4_entry(&gw_net, &gw_netmask);
-+ has_inet_gateway = 1;
-+ }
-+ else if (0 == res && 1 == has_inet_gateway) {
-+ /* Remove all local Inet HNA entries */
-+ while(remove_local_hna4_entry(&gw_net, &gw_netmask)) {
-+ olsr_printf(DEBUGLEV, "Removing OLSR local HNA entry for Internet\n");
-+ }
-+ has_inet_gateway = 0;
-+ }
-+}
-diff -Nur olsrd-0.4.10.orig/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.h olsrd-0.4.10/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.h
---- olsrd-0.4.10.orig/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,59 @@
-+/*
-+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
-+ * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of olsr.org, olsrd nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * Visit http://www.olsr.org for more information.
-+ *
-+ * If you find this software useful feel free to make a donation
-+ * to the project. For more information see the website or contact
-+ * the copyright holders.
-+ */
-+
-+#ifndef _OLSRD_PLUGIN_TEST
-+#define _OLSRD_PLUGIN_TEST
-+
-+#include "olsrd_plugin.h"
-+#include "olsr.h"
-+
-+#define INET_NET 0
-+#define INET_PREFIX 0
-+
-+#define PROCENTRY_ROUTE "/proc/net/route"
-+
-+union olsr_ip_addr gw_net;
-+union olsr_ip_addr gw_netmask;
-+
-+int check_gw(union olsr_ip_addr *net, union olsr_ip_addr *mask);
-+
-+/* Event function to register with the scheduler */
-+void olsr_event(void* foo);
-+
-+#endif
-diff -Nur olsrd-0.4.10.orig/lib/dyn_gw_plain/version-script.txt olsrd-0.4.10/lib/dyn_gw_plain/version-script.txt
---- olsrd-0.4.10.orig/lib/dyn_gw_plain/version-script.txt 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/dyn_gw_plain/version-script.txt 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,10 @@
-+VERS_1.0
-+{
-+ global:
-+ olsrd_plugin_interface_version;
-+ olsrd_plugin_register_param;
-+ olsrd_plugin_init;
-+
-+ local:
-+ *;
-+};
-diff -Nur olsrd-0.4.10.orig/Makefile olsrd-0.4.10/Makefile
---- olsrd-0.4.10.orig/Makefile 2006-01-04 09:45:38.000000000 +0100
-+++ olsrd-0.4.10/Makefile 2006-12-01 08:26:58.000000000 +0100
-@@ -144,6 +144,11 @@
- $(MAKE) -C lib/dyn_gw
- $(MAKE) -C lib/dyn_gw install
-
-+dyn_gw_plain:
-+ $(MAKE) -C lib/dyn_gw_plain clean
-+ $(MAKE) -C lib/dyn_gw_plain
-+ $(MAKE) -C lib/dyn_gw_plain install
-+
- powerinfo:
- $(MAKE) -C lib/powerinfo clean
- $(MAKE) -C lib/powerinfo
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/nameservice/src/nameservice.c olsrd-0.4.10/lib/nameservice/src/nameservice.c
---- olsrd-0.4.10.orig/lib/nameservice/src/nameservice.c 2005-05-29 14:47:42.000000000 +0200
-+++ olsrd-0.4.10/lib/nameservice/src/nameservice.c 2006-12-01 08:26:58.000000000 +0100
-@@ -1,4 +1,5 @@
- /*
-+ * Copyright (c) 2006, Jens Nachtigall <nachtigall@web.de>
- * Copyright (c) 2005, Bruno Randolf <bruno.randolf@4g-systems.biz>
- * Copyright (c) 2004, Andreas Tønnesen(andreto-at-olsr.org)
- * All rights reserved.
-@@ -39,6 +40,9 @@
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
-+#include <ctype.h>
-+#include <sys/types.h>
-+#include <regex.h>
-
- #include "olsr.h"
- #include "net_olsr.h"
-@@ -53,6 +57,7 @@
- #include "olsrd_copy.h"
- #include "compat.h"
-
-+
- /* send buffer: huge */
- static char buffer[10240];
-
-@@ -62,15 +67,35 @@
- static char my_suffix[MAX_SUFFIX];
- static int my_interval = EMISSION_INTERVAL;
- static double my_timeout = NAME_VALID_TIME;
--static olsr_bool have_dns_server = OLSR_FALSE;
--static union olsr_ip_addr my_dns_server;
- static char my_resolv_file[MAX_FILE +1];
-+static char my_services_file[MAX_FILE + 1];
-
--/* the database (using hashing) */
-+/* the databases (using hashing)
-+ * for hostnames, service_lines and dns-servers
-+ *
-+ * my own hostnames, service_lines and dns-servers
-+ * are store in a linked list (without hashing)
-+ * */
- struct db_entry* list[HASHSIZE];
- struct name_entry *my_names = NULL;
- olsr_bool name_table_changed = OLSR_TRUE;
-
-+struct db_entry* service_list[HASHSIZE];
-+struct name_entry *my_services = NULL;
-+olsr_bool service_table_changed = OLSR_TRUE;
-+
-+struct db_entry* forwarder_list[HASHSIZE];
-+struct name_entry *my_forwarders = NULL;
-+olsr_bool forwarder_table_changed = OLSR_TRUE;
-+
-+/* regualar expression to be matched by valid hostnames, compiled in name_init() */
-+regex_t regex_t_name;
-+regmatch_t regmatch_t_name;
-+
-+/* regualar expression to be matched by valid service_lines, compiled in name_init() */
-+regex_t regex_t_service;
-+int pmatch_service = 10;
-+regmatch_t regmatch_t_service[10];
-
- /**
- * do initialization
-@@ -84,27 +109,39 @@
- int len;
-
- GetWindowsDirectory(my_hosts_file, MAX_FILE - 12);
-+ GetWindowsDirectory(my_services_file, MAX_FILE - 12);
-
- len = strlen(my_hosts_file);
--
- if (my_hosts_file[len - 1] != '\\')
- my_hosts_file[len++] = '\\';
--
- strcpy(my_hosts_file + len, "hosts_olsr");
-+
-+ len = strlen(my_services_file);
-+ if (my_services_file[len - 1] != '\\')
-+ my_services_file[len++] = '\\';
-+ strcpy(my_services_file + len, "services_olsr");
-+
-+ len = strlen(my_resolv_file);
-+ if (my_resolv_file[len - 1] != '\\')
-+ my_resolv_file[len++] = '\\';
-+ strcpy(my_resolv_file + len, "resolvconf_olsr");
- #else
- strcpy(my_hosts_file, "/var/run/hosts_olsr");
-+ strcpy(my_services_file, "/var/run/services_olsr");
-+ strcpy(my_resolv_file, "/var/run/resolvconf_olsr");
- #endif
-
- my_suffix[0] = '\0';
- my_add_hosts[0] = '\0';
-- my_resolv_file[0] = '\0';
-
-- /* init list */
-+ /* init lists */
- for(i = 0; i < HASHSIZE; i++) {
- list[i] = NULL;
-+ forwarder_list[i] = NULL;
-+ service_list[i] = NULL;
- }
-
-- memset(&my_dns_server, 0, sizeof(my_dns_server));
-+
- }
-
-
-@@ -116,56 +153,53 @@
- {
- if(!strcmp(key, "interval")) {
- my_interval = atoi(value);
-- printf("\nNAME PLUGIN: parameter interval: %d\n", my_interval);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter interval: %d", my_interval);
- }
- else if(!strcmp(key, "timeout")) {
- my_timeout = atof(value);
-- printf("\nNAME PLUGIN: parameter timeout: %f\n", my_timeout);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter timeout: %f", my_timeout);
- }
- else if(!strcmp(key, "hosts-file")) {
- strncpy( my_hosts_file, value, MAX_FILE );
-- printf("\nNAME PLUGIN: parameter filename: %s\n", my_hosts_file);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter filename: %s", my_hosts_file);
- }
- else if(!strcmp(key, "resolv-file")) {
- strncpy(my_resolv_file, value, MAX_FILE);
-- printf("\nNAME PLUGIN: parameter resolv file: %s\n", my_resolv_file);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter resolv-file: %s", my_resolv_file);
- }
- else if(!strcmp(key, "suffix")) {
- strncpy(my_suffix, value, MAX_SUFFIX);
-- printf("\nNAME PLUGIN: parameter suffix: %s\n", my_suffix);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter suffix: %s", my_suffix);
- }
- else if(!strcmp(key, "add-hosts")) {
- strncpy(my_add_hosts, value, MAX_FILE);
-- printf("\nNAME PLUGIN: parameter additional host: %s\n", my_add_hosts);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter additional host: %s", my_add_hosts);
-+ }
-+ else if(!strcmp(key, "services-file")) {
-+ strncpy(my_services_file, value, MAX_FILE);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter services-file: %s", my_services_file);
- }
- else if(!strcmp(key, "dns-server")) {
- struct in_addr ip;
- if (strlen(value) == 0) {
-- // set dns server ip to main address
-- // which is not known yet
-- have_dns_server = OLSR_TRUE;
-- }
-- else if (inet_aton(value, &ip)) {
-- my_dns_server.v4 = ip.s_addr;
-- have_dns_server = OLSR_TRUE;
-- }
-- else {
-- printf("\nNAME PLUGIN: invalid dns-server IP %s\n", value);
-- }
-+ my_forwarders = add_name_to_list(my_forwarders, "", NAME_FORWARDER, NULL);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter dns-server: (main address)");
-+ } else if (inet_aton(value, &ip)) {
-+ my_forwarders = add_name_to_list(my_forwarders, "", NAME_FORWARDER, &ip);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter dns-server: (%s)", value);
-+ } else {
-+ olsr_printf(1,"\nNAME PLUGIN: invalid parameter dns-server: %s ", value);
-+ }
- }
- else if(!strcmp(key, "name")) {
- // name for main address
-- struct name_entry *tmp;
-- tmp = malloc(sizeof(struct name_entry));
-- tmp->name = strndup( value, MAX_NAME );
-- tmp->len = strlen( tmp->name );
-- tmp->type = NAME_HOST;
-- // will be set to main_addr later
-- memset(&tmp->ip, 0, sizeof(tmp->ip));
-- tmp->next = my_names;
-- my_names = tmp;
--
-- printf("\nNAME PLUGIN: parameter name: %s (main address)\n", tmp->name);
-+ my_names = add_name_to_list(my_names, value, NAME_HOST, NULL);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter name: %s (main address)", value);
-+ }
-+ else if(!strcmp(key, "service")) {
-+ // name for main address
-+ my_services = add_name_to_list(my_services, value, NAME_SERVICE, NULL);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter service: %s (main address)", value);
- }
- else {
- // assume this is an IP address and hostname
-@@ -173,33 +207,46 @@
-
- if (inet_aton(key, &ip)) {
- // the IP is validated later
-- struct name_entry *tmp;
-- tmp = malloc(sizeof(struct name_entry));
-- tmp->name = strndup( value, MAX_NAME );
-- tmp->len = strlen( tmp->name );
-- tmp->type = NAME_HOST;
-- tmp->ip.v4 = ip.s_addr;
-- tmp->next = my_names;
-- my_names = tmp;
-- printf("\nNAME PLUGIN: parameter %s (%s)\n", tmp->name,
-- olsr_ip_to_string(&tmp->ip));
-+ my_names = add_name_to_list(my_names, value, NAME_HOST, &ip);
-+ olsr_printf(1,"\nNAME PLUGIN: parameter name %s (%s)", value, key);
- }
- else {
-- printf("\nNAME PLUGIN: invalid IP %s for name %s!\n", key, value);
-+ olsr_printf(1,"\nNAME PLUGIN: invalid parameter name: %s (%s)!", value, key);
- }
- }
-
- return 1;
- }
-
-+/**
-+ * queue the name/forwarder/service given in value
-+ * to the front of my_list
-+ */
-+struct name_entry*
-+add_name_to_list(struct name_entry *my_list, char *value, int type, struct in_addr *ip)
-+{
-+ struct name_entry *tmp;
-+ tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry add_name_to_list");
-+ tmp->name = strndup( value, MAX_NAME );
-+ tmp->len = strlen( tmp->name );
-+ tmp->type = type;
-+ // all IPs with value 0 will be set to main_addr later
-+ if (ip==NULL)
-+ memset(&tmp->ip, 0, sizeof(tmp->ip));
-+ else
-+ tmp->ip.v4 = ip->s_addr;
-+ tmp->next = my_list;
-+ return tmp;
-+}
-+
-
- /**
- * last initialization
- *
- * we have to do this here because some things like main_addr
-- * are not known before
-+ * or the dns suffix (for validation) are not known before
- *
-- * this is beause of the order in which the plugin is initzalized
-+ * this is beause of the order in which the plugin is initialized
- * by the plugin loader:
- * - first the parameters are sent
- * - then register_olsr_data() from olsrd_plugin.c is called
-@@ -210,50 +257,78 @@
- name_init()
- {
- struct name_entry *name;
-- struct name_entry *prev=NULL;
--
-- /* fixup names and IP addresses */
-+ int ret;
-+ //regex string for validating the hostnames
-+ char *regex_name = "^[[:alnum:]_.-]+$";
-+ //regex string for the service line
-+ char *regex_service = olsr_malloc(256*sizeof(char) + strlen(my_suffix), "new *char from name_init for regex_service");
-+
-+ //compile the regex from the string
-+ if ((ret = regcomp(®ex_t_name, regex_name , REG_EXTENDED)) != 0)
-+ {
-+ /* #2: call regerror() if regcomp failed
-+ * commented out, because only for debuggin needed
-+ *
-+ int errmsgsz = regerror(ret, ®ex_t_name, NULL, 0);
-+ char *errmsg = malloc(errmsgsz);
-+ regerror(ret, ®ex_t_name, errmsg, errmsgsz);
-+ fprintf(stderr, "regcomp: %s", errmsg);
-+ free(errmsg);
-+ regfree(®ex_t_name);
-+ * */
-+ olsr_printf(0, "compilation of regex \"%s\" for hostname failed", regex_name);
-+ }
-+
-+ // a service line is something like prot://hostname.suffix:port|tcp|my little description about this service
-+ // for example http://router.olsr:80|tcp|my homepage
-+ // prot :// (hostname.suffix OR ip)
-+ //regex_service = "^[[:alnum:]]+://(([[:alnum:]_.-]+.olsr)|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}))
-+ // : port /path |(tcp OR udp) |short description
-+ // :[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$";
-+ strcat (strcat (strcat(regex_service, "^[[:alnum:]]+://(([[:alnum:]_.-]+"),
-+ my_suffix),
-+ ")|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3})):[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$");
-+
-+ /* #1: call regcomp() to compile the regex */
-+ if ((ret = regcomp(®ex_t_service, regex_service , REG_EXTENDED )) != 0)
-+ {
-+ /* #2: call regerror() if regcomp failed
-+ * commented out, because only for debuggin needed
-+ *
-+ int errmsgsz = regerror(ret, ®ex_t_service, NULL, 0);
-+ char *errmsg = malloc(errmsgsz);
-+ regerror(ret, ®ex_t_service, errmsg, errmsgsz);
-+ fprintf(stderr, "regcomp: %s", errmsg);
-+ free(errmsg);
-+ regfree(®ex_t_service);
-+ * */
-+ olsr_printf(0, "compilation of regex \"%s\" for hostname failed", regex_name);
-+ }
-+ free(regex_service);
-+ regex_service = NULL;
-+
-+ //fill in main addr for all entries with ip==0
-+ //this does not matter for service, because the ip does not matter
-+ //for service
- for (name = my_names; name != NULL; name = name->next) {
-- if (name->ip.v4 == 0) {
-- // insert main_addr
-+ if (name->ip.v4 == 0) {
-+ olsr_printf(2, "NAME PLUGIN: insert main addr for name %s \n", name->name);
- memcpy(&name->ip, &main_addr, ipsize);
-- prev = name;
-- } else {
-- // IP from config file
-- // check if we are allowed to announce a name for this IP
-- // we can only do this if we also announce the IP
-- if (!allowed_ip(&name->ip)) {
-- olsr_printf(1, "NAME PLUGIN: name for unknown IP %s not allowed, fix your config!\n",
-- olsr_ip_to_string(&name->ip));
-- if (prev!=NULL) {
-- prev->next = name->next;
-- free(name->name);
-- free(name);
-- }
-- }
-- else {
-- prev = name;
-- }
-- }
-- }
-+ }
-+ }
-+ for (name = my_forwarders; name != NULL; name = name->next) {
-+ if (name->ip.v4 == 0) {
-+ olsr_printf(2, "NAME PLUGIN: insert main addr for name %s \n", name->name);
-+ memcpy(&name->ip, &main_addr, ipsize);
-+ }
-+ }
-+
-+ //check if entries I want to announce myself are valid and allowed
-+ my_names = remove_nonvalid_names_from_list(my_names, NAME_HOST);
-+ my_forwarders = remove_nonvalid_names_from_list(my_forwarders, NAME_FORWARDER);
-+ my_services = remove_nonvalid_names_from_list(my_services, NAME_SERVICE);
-+
-
-- if (have_dns_server) {
-- if (my_dns_server.v4 == 0) {
-- memcpy(&my_dns_server, &main_addr, ipsize);
-- printf("\nNAME PLUGIN: announcing upstream DNS server: %s\n",
-- olsr_ip_to_string(&my_dns_server));
-- }
-- else if (!allowed_ip(&my_dns_server)) {
-- printf("NAME PLUGIN: announcing DNS server on unknown IP %s is not allowed, fix your config!\n",
-- olsr_ip_to_string(&my_dns_server));
-- memset(&my_dns_server, 0, sizeof(my_dns_server));
-- have_dns_server = OLSR_FALSE;
-- }
-- else {
-- printf("\nNAME PLUGIN: announcing upstream DNS server: %s\n",
-- olsr_ip_to_string(&my_dns_server));
-- }
-- }
-
- /* register functions with olsrd */
- olsr_parser_add_function(&olsr_parser, PARSER_TYPE, 1);
-@@ -263,22 +338,75 @@
- return 1;
- }
-
-+struct name_entry*
-+remove_nonvalid_names_from_list(struct name_entry *my_list, int type)
-+{
-+ struct name_entry *next = my_list;
-+ olsr_bool valid = OLSR_FALSE;
-+ if (my_list == NULL) {
-+ return NULL;
-+ }
-+
-+ switch (type) {
-+ case NAME_HOST:
-+ valid = is_name_wellformed(my_list->name) && allowed_ip(&my_list->ip);
-+ break;
-+ case NAME_FORWARDER:
-+ valid = allowed_ip(&my_list->ip);
-+ break;
-+ case NAME_SERVICE:
-+ valid = allowed_service(my_list->name);
-+ break;
-+ }
-+
-+ if ( !valid ) {
-+ olsr_printf(1, "NAME PLUGIN: invalid or malformed parameter %s (%s), fix your config!\n", my_list->name, olsr_ip_to_string(&my_list->ip));
-+ next = my_list->next;
-+ free(my_list->name);
-+ my_list->name = NULL;
-+ free(my_list);
-+ my_list = NULL;
-+ return remove_nonvalid_names_from_list(next, type);
-+ } else {
-+ olsr_printf(2, "NAME PLUGIN: validate parameter %s (%s) -> OK\n", my_list->name, olsr_ip_to_string(&my_list->ip));
-+ my_list->next = remove_nonvalid_names_from_list(my_list->next, type);
-+ return my_list;
-+ }
-+}
-+
-+
-
- /**
- * called at unload: free everything
-+ *
-+ * XXX: should I delete the hosts/services/resolv.conf files on exit?
- */
- void
- name_destructor()
- {
-- int i;
-- struct db_entry **tmp;
-- struct db_entry *to_delete;
--
- olsr_printf(2, "NAME PLUGIN: exit. cleaning up...\n");
-
- free_name_entry_list(&my_names);
-+ free_name_entry_list(&my_services);
-+ free_name_entry_list(&my_forwarders);
-+
-+ free_all_list_entries(list);
-+ free_all_list_entries(service_list);
-+ free_all_list_entries(forwarder_list);
-+
-+ regfree(®ex_t_name);
-+ regfree(®ex_t_service);
-+
-+}
-+
-+/* free all list entries */
-+void
-+free_all_list_entries(struct db_entry **this_db_list)
-+{
-+ int i;
-+ struct db_entry **tmp;
-+ struct db_entry *to_delete;
-
-- /* free list entries */
- for(i = 0; i < HASHSIZE; i++)
- {
- tmp = &list[i];
-@@ -296,24 +424,41 @@
-
- /**
- * A timeout function called every time
-- * the scheduler is polled: time out old list entries
-+ *
-+ * XXX:the scheduler is polled (by default 10 times a sec,
-+ * which is far too often):
-+ *
-+ * time out old list entries
- * and write changes to file
- */
- void
- olsr_timeout()
- {
-+ timeout_old_names(list, &name_table_changed);
-+ timeout_old_names(forwarder_list, &forwarder_table_changed);
-+ timeout_old_names(service_list, &service_table_changed);
-+
-+ write_resolv_file();
-+ write_hosts_file();
-+ write_services_file();
-+}
-+
-+void
-+timeout_old_names(struct db_entry **this_list, olsr_bool *this_table_changed)
-+{
- struct db_entry **tmp;
- struct db_entry *to_delete;
- int index;
-
- for(index=0;index<HASHSIZE;index++)
- {
-- for (tmp = &list[index]; *tmp != NULL; )
-+ for (tmp = &this_list[index]; *tmp != NULL; )
- {
-- /* check if the entry is timed out */
-+ /* check if the entry for this ip is timed out */
- if (olsr_timed_out(&(*tmp)->timer))
- {
- to_delete = *tmp;
-+ /* update the pointer in the linked list */
- *tmp = (*tmp)->next;
-
- olsr_printf(2, "NAME PLUGIN: %s timed out... deleting\n",
-@@ -322,17 +467,17 @@
- /* Delete */
- free_name_entry_list(&to_delete->names);
- free(to_delete);
-- name_table_changed = OLSR_TRUE;
-+ *this_table_changed = OLSR_TRUE;
- } else {
- tmp = &(*tmp)->next;
- }
- }
- }
-- write_resolv_file();
-- write_hosts_file();
- }
-
-
-+
-+
- /**
- * Scheduled event: generate and send NAME packet
- */
-@@ -429,21 +574,19 @@
- return;
- }
-
-- /* Check if this message has been processed before
-- * Remeber that this also registeres the message as
-+ /* Check if this message has not been processed before
-+ * Remember that this also registers the message as
- * processed if nessecary
- */
-- if(!olsr_check_dup_table_proc(&originator, ntohs(m->v4.seqno))) {
-- /* If so - do not process */
-- goto forward;
-- }
--
-- update_name_entry(&originator, namemessage, size, vtime);
-+ if(olsr_check_dup_table_proc(&originator, ntohs(m->v4.seqno))) {
-+ /* If not already processed - do so */
-+ update_name_entry(&originator, namemessage, size, vtime);
-+ }
-+
-+ /* Forward the message if nessecary
-+ * default_fwd does all the work for us! */
-+ olsr_forward_message(m, &originator, ntohs(m->v4.seqno), in_if, in_addr);
-
--forward:
-- /* Forward the message if nessecary
-- * default_fwd does all the work for us! */
-- olsr_forward_message(m, &originator, ntohs(m->v4.seqno), in_if, in_addr);
- }
-
-
-@@ -457,152 +600,224 @@
- int
- encap_namemsg(struct namemsg* msg)
- {
-- struct name_entry *my_name = my_names;
-- struct name* to_packet;
-+ struct name_entry *my_name;
-+ struct name_entry *my_service;
-+
-+ // add the hostname, service and forwarder entries after the namemsg header
- char* pos = (char*)msg + sizeof(struct namemsg);
- short i=0;
-- int k;
--
-- // upstream dns server
-- if (have_dns_server) {
-- olsr_printf(3, "NAME PLUGIN: Announcing DNS server (%s)\n",
-- olsr_ip_to_string(&my_dns_server));
-- to_packet = (struct name*)pos;
-- to_packet->type = htons(NAME_FORWARDER);
-- to_packet->len = htons(0);
-- memcpy(&to_packet->ip, &my_dns_server, ipsize);
-- pos += sizeof(struct name);
-- i++;
-- }
-+
-
- // names
- for (my_name = my_names; my_name!=NULL; my_name = my_name->next)
- {
-- olsr_printf(3, "NAME PLUGIN: Announcing name %s (%s) %d\n",
-- my_name->name, olsr_ip_to_string(&my_name->ip), my_name->len);
--
-- to_packet = (struct name*)pos;
-- to_packet->type = htons(my_name->type);
-- to_packet->len = htons(my_name->len);
-- memcpy(&to_packet->ip, &my_name->ip, ipsize);
-- pos += sizeof(struct name);
-- strncpy(pos, my_name->name, my_name->len);
-- pos += my_name->len;
-- // padding to 4 byte boundaries
-- for (k = my_name->len; (k & 3) != 0; k++)
-- *pos++ = '\0';
-+ pos = create_packet( (struct name*) pos, my_name);
- i++;
- }
-+ // forwarders
-+ for (my_name = my_forwarders; my_name!=NULL; my_name = my_name->next)
-+ {
-+ pos = create_packet( (struct name*) pos, my_name);
-+ i++;
-+ }
-+ // services
-+ for (my_service = my_services; my_service!=NULL; my_service = my_service->next)
-+ {
-+ pos = create_packet( (struct name*) pos, my_service);
-+ i++;
-+ }
-+
-+ // write the namemsg header with the number of announced entries and the protocol version
- msg->nr_names = htons(i);
- msg->version = htons(NAME_PROTOCOL_VERSION);
-+
- return pos - (char*)msg; //length
- }
-
-
- /**
-- * decapsulate a name message and update name_entries if necessary
-+ * convert each of my to be announced name_entries into network
-+ * compatible format
-+ *
-+ * return the length of the name packet
-+ */
-+char*
-+create_packet(struct name* to, struct name_entry *from)
-+{
-+ char *pos = (char*) to;
-+ int k;
-+ olsr_printf(3, "NAME PLUGIN: Announcing name %s (%s) %d\n",
-+ from->name, olsr_ip_to_string(&from->ip), from->len);
-+ to->type = htons(from->type);
-+ to->len = htons(from->len);
-+ memcpy(&to->ip, &from->ip, ipsize);
-+ pos += sizeof(struct name);
-+ strncpy(pos, from->name, from->len);
-+ pos += from->len;
-+ for (k = from->len; (k & 3) != 0; k++)
-+ *pos++ = '\0';
-+ return pos;
-+}
-+
-+/**
-+ * decapsulate a received name, service or forwarder and update the corresponding hash table if necessary
-+ */
-+void
-+decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_table_changed )
-+{
-+ struct name_entry *tmp;
-+ struct name_entry *already_saved_name_entries;
-+ char *name = (char*)from_packet + sizeof(struct name);
-+ olsr_printf(4, "\nNAME PLUGIN: decapsulating received name, service or forwarder \n");
-+ int type_of_from_packet = ntohs(from_packet->type);
-+ unsigned int len_of_name = ntohs(from_packet->len);
-+
-+ // don't insert the received entry again, if it has already been inserted in the hash table.
-+ // Instead only the validity time is set in insert_new_name_in_list function, which calls this one
-+ for (already_saved_name_entries = (*to); already_saved_name_entries != NULL ; already_saved_name_entries = already_saved_name_entries->next)
-+ {
-+ if ( (type_of_from_packet==NAME_HOST || type_of_from_packet==NAME_SERVICE) && strncmp(already_saved_name_entries->name, name, len_of_name) == 0 ) {
-+ olsr_printf(4, "\nNAME PLUGIN: received name or service entry %s (%s) already in hash table\n", name, olsr_ip_to_string(&already_saved_name_entries->ip));
-+ return;
-+ } else if (type_of_from_packet==NAME_FORWARDER && COMP_IP(&already_saved_name_entries->ip, &from_packet->ip) ) {
-+ olsr_printf(4, "\nNAME PLUGIN: received forwarder entry %s (%s) already in hash table\n", name, olsr_ip_to_string(&already_saved_name_entries->ip));
-+ return;
-+ }
-+ }
-+
-+ //XXX: should I check the from_packet->ip here? If so, why not also check the ip fro HOST and SERVICE?
-+ if( (type_of_from_packet==NAME_HOST && !is_name_wellformed(name)) || (type_of_from_packet==NAME_SERVICE && !is_service_wellformed(name)) ) {
-+ olsr_printf(4, "\nNAME PLUGIN: invalid name [%s] received, skipping.\n", name );
-+ return;
-+ }
-+
-+ //ignore all packets with a too long name
-+ //or a spoofed len of its included name string
-+ if (len_of_name > MAX_NAME || strlen(name) != len_of_name) {
-+ olsr_printf(4, "\nNAME PLUGIN: from_packet->len %d > MAX_NAME %d or from_packet->len %d !0 strlen(name [%s] in packet)\n",
-+ len_of_name, MAX_NAME, len_of_name, name );
-+ return;
-+ }
-+
-+ //if not yet known entry
-+ tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry");
-+ tmp->type = ntohs(from_packet->type);
-+ tmp->len = len_of_name > MAX_NAME ? MAX_NAME : ntohs(from_packet->len);
-+ tmp->name = olsr_malloc(tmp->len+1, "new name_entry name");
-+ memcpy(&tmp->ip, &from_packet->ip, ipsize);
-+ strncpy(tmp->name, name, tmp->len);
-+ tmp->name[tmp->len] = '\0';
-+
-+ olsr_printf(3, "\nNAME PLUGIN: create new name/service/forwarder entry %s (%s) [len=%d] [type=%d] in linked list\n",
-+ tmp->name, olsr_ip_to_string(&tmp->ip), tmp->len, tmp->type);
-+
-+ *this_table_changed = OLSR_TRUE;
-+
-+ // queue to front
-+ tmp->next = *to;
-+ *to = tmp;
-+}
-+
-+
-+/**
-+ * unpack the received message and delegate to the decapsilation function for each
-+ * name/service/forwarder entry in the message
- */
- void
--decap_namemsg( struct namemsg *msg, int size, struct name_entry **to )
-+update_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_size, double vtime)
- {
- char *pos, *end_pos;
-- struct name_entry *tmp;
- struct name *from_packet;
- int i;
-+
-+ olsr_printf(3, "NAME PLUGIN: Received Message from %s\n",
-+ olsr_ip_to_string(originator));
-
-- olsr_printf(4, "NAME PLUGIN: decapsulating name msg (size %d)\n", size);
--
-- if (ntohs(msg->version) != NAME_PROTOCOL_VERSION) {
-+ if (ntohs(msg->version) != NAME_PROTOCOL_VERSION) {
- olsr_printf(3, "NAME PLUGIN: ignoring wrong version %d\n", msg->version);
- return;
- }
--
-- // for now ist easier to just delete everything, than
-- // to update selectively
-- free_name_entry_list(to);
-- name_table_changed = OLSR_TRUE;
--
-+
-+
- /* now add the names from the message */
- pos = (char*)msg + sizeof(struct namemsg);
-- end_pos = pos + size - sizeof(struct name*); // at least one struct name has to be left
--
-+ end_pos = pos + msg_size - sizeof(struct name*); // at least one struct name has to be left
-+
- for (i=ntohs(msg->nr_names); i > 0 && pos<end_pos; i--)
- {
- from_packet = (struct name*)pos;
--
-- tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry");
-- tmp->type = ntohs(from_packet->type);
-- tmp->len = ntohs(from_packet->len) > MAX_NAME ? MAX_NAME : ntohs(from_packet->len);
-- tmp->name = olsr_malloc(tmp->len+1, "new name_entry name");
-- memcpy(&tmp->ip, &from_packet->ip, ipsize);
-+
-+ switch (ntohs(from_packet->type)) {
-+ case NAME_HOST:
-+ insert_new_name_in_list(originator, list, from_packet, &name_table_changed, vtime);
-+ break;
-+ case NAME_FORWARDER:
-+ insert_new_name_in_list(originator, forwarder_list, from_packet, &forwarder_table_changed, vtime);
-+ break;
-+ case NAME_SERVICE:
-+ insert_new_name_in_list(originator, service_list, from_packet, &service_table_changed, vtime);
-+ break;
-+ default:
-+ olsr_printf(3, "NAME PLUGIN: Received Message of unknown type [%d] from (%s)\n", from_packet->type, olsr_ip_to_string(originator));
-+ break;
-+ }
- pos += sizeof(struct name);
-- strncpy(tmp->name, pos, tmp->len);
-- tmp->name[tmp->len] = '\0';
--
-- olsr_printf(3, "NAME PLUGIN: New name %s (%s) %d %d\n",
-- tmp->name, olsr_ip_to_string(&tmp->ip), tmp->len, tmp->type);
--
-- // queue to front
-- tmp->next = *to;
-- *to = tmp;
--
-- // name + padding
-- pos += 1 + ((tmp->len - 1) | 3);
-- }
-+ pos += 1 + (( ntohs(from_packet->len) - 1) | 3);
-+ }
- if (i!=0)
-- olsr_printf(4, "NAME PLUGIN: Lost %d names due to length inconsistency\n", i);
-+ olsr_printf(4, "NAME PLUGIN: Lost %d entries in received packet due to length inconsistency (%s)\n", i, olsr_ip_to_string(originator));
- }
-
-
- /**
-- * Update or register a new name entry
-+ * insert all the new names,services and forwarders from a received packet into the
-+ * corresponding entry for this ip in the corresponding hash table
- */
- void
--update_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_size, double vtime)
-+insert_new_name_in_list(union olsr_ip_addr *originator, struct db_entry **this_list, struct name *from_packet, olsr_bool *this_table_changed, double vtime)
- {
- int hash;
- struct db_entry *entry;
--
-- olsr_printf(3, "NAME PLUGIN: Received Name Message from %s\n",
-- olsr_ip_to_string(originator));
-+ olsr_bool entry_found = OLSR_FALSE;
-+ entry_found = OLSR_FALSE;
-
- hash = olsr_hashing(originator);
-
-- /* find the entry for originator */
-- for (entry = list[hash]; entry != NULL; entry = entry->next)
-- {
-- if (memcmp(originator, &entry->originator, ipsize) == 0) {
-- // found
-- olsr_printf(4, "NAME PLUGIN: %s found\n",
-- olsr_ip_to_string(originator));
--
-- decap_namemsg(msg, msg_size, &entry->names);
--
-- olsr_get_timestamp(vtime * 1000, &entry->timer);
--
-- return;
-- }
-- }
--
-- olsr_printf(3, "NAME PLUGIN: New entry %s\n",
-- olsr_ip_to_string(originator));
--
-- /* insert a new entry */
-- entry = olsr_malloc(sizeof(struct db_entry), "new db_entry");
--
-- memcpy(&entry->originator, originator, ipsize);
-- olsr_get_timestamp(vtime * 1000, &entry->timer);
-- entry->names = NULL;
-- // queue to front
-- entry->next = list[hash];
-- list[hash] = entry;
--
-- decap_namemsg(msg, msg_size, &entry->names);
--
-- name_table_changed = OLSR_TRUE;
-+ /* find the entry for originator, if there is already one */
-+ for (entry = this_list[hash]; entry != NULL; entry = entry->next)
-+ {
-+ if (memcmp(originator, &entry->originator, ipsize) == 0) {
-+ // found
-+ olsr_printf(4, "NAME PLUGIN: found entry for (%s) in its hash table\n", olsr_ip_to_string(originator));
-+
-+ //delegate to function for parsing the packet and linking it to entry->names
-+ decap_namemsg(from_packet, &entry->names, this_table_changed);
-+
-+ olsr_get_timestamp(vtime * 1000, &entry->timer);
-+
-+ entry_found = OLSR_TRUE;
-+ }
-+ }
-+ if (! entry_found)
-+ {
-+ olsr_printf(3, "NAME PLUGIN: create new db entry for ip (%s) in hash table\n", olsr_ip_to_string(originator));
-+
-+ /* insert a new entry */
-+ entry = olsr_malloc(sizeof(struct db_entry), "new db_entry");
-+
-+ memcpy(&entry->originator, originator, ipsize);
-+ olsr_get_timestamp(vtime * 1000, &entry->timer);
-+ entry->names = NULL;
-+
-+ // queue to front
-+ entry->next = this_list[hash];
-+ this_list[hash] = entry;
-+
-+ //delegate to function for parsing the packet and linking it to entry->names
-+ decap_namemsg(from_packet, &entry->names, this_table_changed);
-+ }
- }
-
--
- /**
- * write names to a file in /etc/hosts compatible format
- */
-@@ -650,8 +865,7 @@
-
- // write own names
- for (name = my_names; name != NULL; name = name->next) {
-- fprintf(hosts, "%s\t%s%s\t# myself\n", olsr_ip_to_string(&name->ip),
-- name->name, my_suffix );
-+ fprintf(hosts, "%s\t%s%s\t# myself\n", olsr_ip_to_string(&name->ip), name->name, my_suffix );
- }
-
- // write received names
-@@ -661,13 +875,11 @@
- {
- for (name = entry->names; name != NULL; name = name->next)
- {
-- if (name->type == NAME_HOST) {
-- olsr_printf(6, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
-- olsr_printf(6, "\t#%s\n", olsr_ip_to_string(&entry->originator));
--
-- fprintf(hosts, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
-- fprintf(hosts, "\t# %s\n", olsr_ip_to_string(&entry->originator));
-- }
-+ olsr_printf(6, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
-+ olsr_printf(6, "\t#%s\n", olsr_ip_to_string(&entry->originator));
-+
-+ fprintf(hosts, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
-+ fprintf(hosts, "\t# %s\n", olsr_ip_to_string(&entry->originator));
- }
- }
- }
-@@ -682,7 +894,70 @@
-
-
- /**
-- * write upstream DNS servers to resolv.conf file
-+ * write services to a file in the format:
-+ * service #originator ip
-+ *
-+ * since service has a special format
-+ * each line will look similar to e.g.
-+ * http://me.olsr:80|tcp|my little homepage
-+ */
-+void
-+write_services_file()
-+{
-+ int hash;
-+ struct name_entry *name;
-+ struct db_entry *entry;
-+ FILE* services_file;
-+ time_t currtime;
-+
-+
-+ if (!service_table_changed)
-+ return;
-+
-+ olsr_printf(2, "NAME PLUGIN: writing services file\n");
-+
-+ services_file = fopen( my_services_file, "w" );
-+ if (services_file == NULL) {
-+ olsr_printf(2, "NAME PLUGIN: cant write services_file file\n");
-+ return;
-+ }
-+
-+ fprintf(services_file, "### this file is overwritten regularly by olsrd\n");
-+ fprintf(services_file, "### do not edit\n\n");
-+
-+
-+ // write own services
-+ for (name = my_services; name != NULL; name = name->next) {
-+ fprintf(services_file, "%s\t# my own service\n", name->name);
-+ }
-+
-+ // write received services
-+ for (hash = 0; hash < HASHSIZE; hash++)
-+ {
-+ for(entry = service_list[hash]; entry != NULL; entry = entry->next)
-+ {
-+ for (name = entry->names; name != NULL; name = name->next)
-+ {
-+ olsr_printf(6, "%s\t", name->name);
-+ olsr_printf(6, "\t#%s\n", olsr_ip_to_string(&entry->originator));
-+
-+ fprintf(services_file, "%s\t", name->name );
-+ fprintf(services_file, "\t#%s\n", olsr_ip_to_string(&entry->originator));
-+ }
-+ }
-+ }
-+
-+ if (time(&currtime)) {
-+ fprintf(services_file, "\n### written by olsrd at %s", ctime(&currtime));
-+ }
-+
-+ fclose(services_file);
-+ service_table_changed = OLSR_FALSE;
-+}
-+
-+/**
-+ * write the 3 best upstream DNS servers to resolv.conf file
-+ * best means the 3 with the best etx value in routing table
- */
- void
- write_resolv_file()
-@@ -694,23 +969,17 @@
- struct rt_entry *route, *tmp, *last;
- FILE* resolv;
- int i=0;
-+ time_t currtime;
-
-- if (my_resolv_file[0] == '\0')
-- return;
--
-- if (!name_table_changed)
-+ if (!forwarder_table_changed || my_forwarders != NULL || my_resolv_file[0] == '\0')
- return;
-
-- olsr_printf(2, "NAME PLUGIN: writing resolv file\n");
--
- for (hash = 0; hash < HASHSIZE; hash++)
- {
-- for(entry = list[hash]; entry != NULL; entry = entry->next)
-+ for(entry = forwarder_list[hash]; entry != NULL; entry = entry->next)
- {
- for (name = entry->names; name != NULL; name = name->next)
- {
-- if (name->type != NAME_FORWARDER)
-- continue;
-
- /* find the nearest one */
- route = olsr_lookup_routing_table(&name->ip);
-@@ -762,18 +1031,25 @@
- return;
-
- /* write to file */
-+ olsr_printf(2, "NAME PLUGIN: try to write to resolv file\n");
- resolv = fopen( my_resolv_file, "w" );
- if (resolv == NULL) {
- olsr_printf(2, "NAME PLUGIN: can't write resolv file\n");
- return;
- }
-+ fprintf(resolv, "### this file is overwritten regularly by olsrd\n");
-+ fprintf(resolv, "### do not edit\n\n");
- i=0;
- for (tmp=best_routes; tmp!=NULL && i<3; tmp=tmp->next) {
- olsr_printf(6, "NAME PLUGIN: nameserver %s\n", olsr_ip_to_string(&tmp->rt_dst));
- fprintf(resolv, "nameserver %s\n", olsr_ip_to_string(&tmp->rt_dst));
- i++;
- }
-+ if (time(&currtime)) {
-+ fprintf(resolv, "\n### written by olsrd at %s", ctime(&currtime));
-+ }
- fclose(resolv);
-+ forwarder_table_changed = OLSR_FALSE;
- }
-
-
-@@ -789,6 +1065,7 @@
- to_delete = *tmp;
- *tmp = (*tmp)->next;
- free( to_delete->name );
-+ to_delete->name = NULL;
- free( to_delete );
- to_delete = NULL;
- }
-@@ -831,3 +1108,84 @@
- }
- return OLSR_FALSE;
- }
-+
-+/** check if name has the right syntax, i.e. it must adhere to a special regex
-+ * stored in regex_t_name
-+ * necessary to avaid names like "0.0.0.0 google.de\n etc"
-+ */
-+olsr_bool
-+is_name_wellformed(char *name) {
-+ return regexec(®ex_t_name, name, 1, ®match_t_name, 0) == 0 ;
-+}
-+
-+
-+/**
-+ * check if the service is in the right syntax and also that the hostname
-+ * or ip whithin the service is allowed
-+ */
-+olsr_bool
-+allowed_service(char *service_line)
-+{
-+ /* the call of is_service_wellformed generates the submatches stored in regmatch_t_service
-+ * these are then used by allowed_hostname_or_ip_in_service
-+ * see regexec(3) for more infos */
-+ if (!is_service_wellformed(service_line)) {
-+ return OLSR_FALSE;
-+ } else if (!allowed_hostname_or_ip_in_service(service_line, &(regmatch_t_service[1]))) {
-+ return OLSR_FALSE;
-+ }
-+
-+ return OLSR_TRUE;
-+}
-+
-+olsr_bool
-+allowed_hostname_or_ip_in_service(char *service_line, regmatch_t *hostname_or_ip_match)
-+{
-+ char *hostname_or_ip;
-+ struct in_addr ip;
-+ union olsr_ip_addr olsr_ip;
-+ struct name_entry *name;
-+ if (hostname_or_ip_match->rm_so < 0 || hostname_or_ip_match->rm_eo < 0) {
-+ return OLSR_FALSE;
-+ }
-+
-+ hostname_or_ip = strndup(&service_line[hostname_or_ip_match->rm_so], hostname_or_ip_match->rm_eo - hostname_or_ip_match->rm_so);
-+ //hostname is one of the names, that I announce (i.e. one that i am allowed to announce)
-+ for (name = my_names; name != NULL; name = name->next) {
-+ if (strncmp(name->name, hostname_or_ip, name->len - strlen(my_suffix)) == 0 ) {
-+ olsr_printf(4, "NAME PLUGIN: hostname %s in service %s is OK\n", hostname_or_ip, service_line);
-+ free(hostname_or_ip);
-+ hostname_or_ip = NULL;
-+ return OLSR_TRUE;
-+ }
-+ }
-+
-+ //ip in service-line is allowed
-+ if (inet_aton(hostname_or_ip, &ip)) {
-+ olsr_ip.v4 = ip.s_addr;
-+ if (allowed_ip(&olsr_ip)) {
-+ olsr_printf(2, "NAME PLUGIN: ip %s in service %s is OK\n", olsr_ip_to_string(&olsr_ip), service_line);
-+ free(hostname_or_ip);
-+ hostname_or_ip = NULL;
-+ return OLSR_TRUE;
-+ }
-+ }
-+
-+ olsr_printf(1, "NAME PLUGIN: ip or hostname %s in service %s is NOT allowed (does not belong to you)\n", hostname_or_ip, service_line);
-+ free(hostname_or_ip);
-+ hostname_or_ip = NULL;
-+
-+ return OLSR_FALSE;
-+}
-+
-+/**
-+ * check if the service matches the syntax
-+ * of "protocol://host:port/path|tcp_or_udp|a short description",
-+ * which is given in the regex regex_t_service
-+ */
-+olsr_bool
-+is_service_wellformed(char *service_line)
-+{
-+ return regexec(®ex_t_service, service_line, pmatch_service, regmatch_t_service, 0) == 0;
-+}
-+
-diff -Nur olsrd-0.4.10.orig/lib/nameservice/src/nameservice.h olsrd-0.4.10/lib/nameservice/src/nameservice.h
---- olsrd-0.4.10.orig/lib/nameservice/src/nameservice.h 2005-06-02 17:34:00.000000000 +0200
-+++ olsrd-0.4.10/lib/nameservice/src/nameservice.h 2006-12-01 08:26:58.000000000 +0100
-@@ -39,6 +39,7 @@
- #define _NAMESERVICE_PLUGIN
-
- #include <sys/time.h>
-+#include <regex.h>
-
- #include "olsr_types.h"
- #include "interfaces.h"
-@@ -51,19 +52,27 @@
- #define PLUGIN_VERSION "0.2"
- #define PLUGIN_AUTHOR "Bruno Randolf"
-
-+// useful to set for the freifunkfirmware to remove all
-+// calls to olsr_printf by the empty statement ";"
-+//#define olsr_printf(...) ;
-
- #define MESSAGE_TYPE 130
- #define PARSER_TYPE MESSAGE_TYPE
- #define EMISSION_INTERVAL 120 /* two minutes */
--#define NAME_VALID_TIME 3600 /* one hour */
-+#define NAME_VALID_TIME 1800 /* half one hour */
-
- #define NAME_PROTOCOL_VERSION 1
-
--#define MAX_NAME 255
-+#define MAX_NAME 127
- #define MAX_FILE 255
--#define MAX_SUFFIX 255
--
-+#define MAX_SUFFIX 63
-
-+/**
-+ * a linked list of name_entry
-+ * if type is NAME_HOST, name is a hostname and ip its IP addr
-+ * if type is NAME_FORWARDER, then ip is a dns-server (and name is irrelevant)
-+ * if type is NAME_SERVICE, then name is a service-line (and the ip is irrelevant)
-+ */
- struct name_entry
- {
- union olsr_ip_addr ip;
-@@ -73,7 +82,17 @@
- struct name_entry *next; /* linked list */
- };
-
--/* database entry */
-+/* *
-+ * linked list of db_entries for each originator with
-+ * originator being its main_addr
-+ *
-+ * names points to the name_entry with its hostname, dns-server or
-+ * service-line entry
-+ *
-+ * all the db_entries are hashed in nameservice.c to avoid a too long list
-+ * for many nodes in a net
-+ *
-+ * */
- struct db_entry
- {
- union olsr_ip_addr originator; /* IP address of the node this entry describes */
-@@ -98,8 +117,26 @@
- int
- encap_namemsg(struct namemsg *);
-
-+struct name_entry*
-+add_name_to_list(struct name_entry *my_list, char *value, int type, struct in_addr *ip);
-+
-+struct name_entry*
-+remove_nonvalid_names_from_list(struct name_entry *my_list, int type);
-+
-+void
-+free_all_list_entries(struct db_entry **this_db_list) ;
-+
- void
--decap_namemsg(struct namemsg *, int, struct name_entry**);
-+timeout_old_names(struct db_entry **this_list, olsr_bool *this_table_changed);
-+
-+void
-+decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_table_changed );
-+
-+void
-+insert_new_name_in_list(union olsr_ip_addr *originator, struct db_entry **this_list, struct name *from_packet, olsr_bool *this_table_changed, double vtime);
-+
-+olsr_bool
-+allowed_hostname_or_ip_in_service(char *service_line, regmatch_t *hostname_or_ip);
-
- void
- update_name_entry(union olsr_ip_addr *, struct namemsg *, int, double);
-@@ -108,6 +145,9 @@
- write_hosts_file(void);
-
- void
-+write_services_file(void);
-+
-+void
- write_resolv_file(void);
-
- int
-@@ -119,6 +159,18 @@
- olsr_bool
- allowed_ip(union olsr_ip_addr *addr);
-
-+olsr_bool
-+allowed_service(char *service_line);
-+
-+olsr_bool
-+is_name_wellformed(char *service_line);
-+
-+olsr_bool
-+is_service_wellformed(char *service_line);
-+
-+char*
-+create_packet(struct name *to, struct name_entry *from);
-+
- void
- name_constructor(void);
-
-diff -Nur olsrd-0.4.10.orig/lib/nameservice/src/nameservice_msg.h olsrd-0.4.10/lib/nameservice/src/nameservice_msg.h
---- olsrd-0.4.10.orig/lib/nameservice/src/nameservice_msg.h 2005-03-17 22:41:30.000000000 +0100
-+++ olsrd-0.4.10/lib/nameservice/src/nameservice_msg.h 2006-12-01 08:26:58.000000000 +0100
-@@ -38,29 +38,34 @@
- #ifndef _NAMESEVICE_MSG
- #define _NAMESEVICE_MSG
-
--
-+/* type of the packet of name_entry */
- typedef enum {
- NAME_HOST = 0,
- NAME_FORWARDER = 1,
-- NAME_SERVICE = 2
-+ NAME_SERVICE = 2,
- } NAME_TYPE;
-
--
-+/**
-+ * the name, forwarder or service entry as found in a packet within a
-+ * message
-+ **/
- struct name
- {
- olsr_u16_t type;
- olsr_u16_t len; // length of the name
-+ // the ip of the hostname, or the ip of the dns-server
-+ // ip is irrelevant for services
- union olsr_ip_addr ip;
- /*
-- * name is written in plain text after this struct and padded to 4 byte
-+ * name or service is written in plain text after this struct and padded to 4 byte
- */
- };
-
-
- struct namemsg
- {
-- olsr_u16_t version;
-- olsr_u16_t nr_names; // number of following name messages
-+ olsr_u16_t version; // version number of the nameservice plugin
-+ olsr_u16_t nr_names; // number of following packets including names, forwarders or services
- /*
- * at least one struct name following
- */
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/txtinfo/Makefile olsrd-0.4.10/lib/txtinfo/Makefile
---- olsrd-0.4.10.orig/lib/txtinfo/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/txtinfo/Makefile 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,57 @@
-+# The olsr.org Optimized Link-State Routing daemon(olsrd)
-+# Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+# All rights reserved.
-+#
-+# Redistribution and use in source and binary forms, with or without
-+# modification, are permitted provided that the following conditions
-+# are met:
-+#
-+# * Redistributions of source code must retain the above copyright
-+# notice, this list of conditions and the following disclaimer.
-+# * Redistributions in binary form must reproduce the above copyright
-+# notice, this list of conditions and the following disclaimer in
-+# the documentation and/or other materials provided with the
-+# distribution.
-+# * Neither the name of olsr.org, olsrd nor the names of its
-+# contributors may be used to endorse or promote products derived
-+# from this software without specific prior written permission.
-+#
-+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+# POSSIBILITY OF SUCH DAMAGE.
-+#
-+# Visit http://www.olsr.org for more information.
-+#
-+# If you find this software useful feel free to make a donation
-+# to the project. For more information see the website or contact
-+# the copyright holders.
-+#
-+# $Id: olsrd-txtinfo.patch,v 1.5 2006/12/04 08:33:46 sven-ola Exp $
-+
-+OLSRD_PLUGIN = true
-+PLUGIN_NAME = olsrd_txtinfo
-+PLUGIN_VER = 0.1
-+
-+TOPDIR = ../..
-+include $(TOPDIR)/Makefile.inc
-+
-+default_target: $(PLUGIN_FULLNAME)
-+
-+$(PLUGIN_FULLNAME): $(OBJS)
-+ $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
-+
-+install: $(PLUGIN_FULLNAME)
-+ $(STRIP) $(PLUGIN_FULLNAME)
-+ $(INSTALL_LIB)
-+
-+clean:
-+ rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
-diff -Nur olsrd-0.4.10.orig/lib/txtinfo/README_TXTINFO olsrd-0.4.10/lib/txtinfo/README_TXTINFO
---- olsrd-0.4.10.orig/lib/txtinfo/README_TXTINFO 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/txtinfo/README_TXTINFO 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,16 @@
-+LoadPlugin "olsrd_txtinfo.so.0.1"
-+{
-+ PlParam "accept" "10.247.200.4"
-+}
-+
-+ABOUT
-+
-+telnet 127.0.0.1 2006
-+or
-+wget localhost:2006 -qO -
-+
-+installation:
-+make
-+make install
-+
-+- Lorenz Schori
-diff -Nur olsrd-0.4.10.orig/lib/txtinfo/src/olsrd_plugin.c olsrd-0.4.10/lib/txtinfo/src/olsrd_plugin.c
---- olsrd-0.4.10.orig/lib/txtinfo/src/olsrd_plugin.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/txtinfo/src/olsrd_plugin.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,142 @@
-+/*
-+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
-+ * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of olsr.org, olsrd nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * Visit http://www.olsr.org for more information.
-+ *
-+ * If you find this software useful feel free to make a donation
-+ * to the project. For more information see the website or contact
-+ * the copyright holders.
-+ *
-+ * $Id: olsrd-txtinfo.patch,v 1.5 2006/12/04 08:33:46 sven-ola Exp $
-+ */
-+
-+/*
-+ * Dynamic linked library for the olsr.org olsr daemon
-+ */
-+
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <arpa/inet.h>
-+#include <sys/types.h>
-+#include <netinet/in.h>
-+
-+#include "olsrd_plugin.h"
-+#include "olsrd_txtinfo.h"
-+
-+
-+#define PLUGIN_NAME "OLSRD txtinfo plugin"
-+#define PLUGIN_VERSION "0.1"
-+#define PLUGIN_AUTHOR "Lorenz Schori"
-+#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION " by " PLUGIN_AUTHOR
-+#define PLUGIN_INTERFACE_VERSION 4
-+
-+
-+struct in_addr ipc_accept_ip;
-+int ipc_port;
-+int nompr;
-+
-+
-+static void __attribute__ ((constructor))
-+my_init(void);
-+
-+static void __attribute__ ((destructor))
-+my_fini(void);
-+
-+
-+/**
-+ *Constructor
-+ */
-+static void
-+my_init()
-+{
-+ /* Print plugin info to stdout */
-+ printf("%s\n", MOD_DESC);
-+
-+ /* defaults for parameters */
-+ ipc_port = 2006;
-+ ipc_accept_ip.s_addr = htonl(INADDR_LOOPBACK);
-+
-+ /* highlite neighbours by default */
-+ nompr = 0;
-+}
-+
-+
-+/**
-+ *Destructor
-+ */
-+static void
-+my_fini()
-+{
-+ /* Calls the destruction function
-+ * olsr_plugin_exit()
-+ * This function should be present in your
-+ * sourcefile and all data destruction
-+ * should happen there - NOT HERE!
-+ */
-+ olsr_plugin_exit();
-+}
-+
-+
-+int
-+olsrd_plugin_interface_version()
-+{
-+ return PLUGIN_INTERFACE_VERSION;
-+}
-+
-+
-+int
-+olsrd_plugin_register_param(char *key, char *value)
-+{
-+ if(!strcmp(key, "port"))
-+ {
-+ ipc_port = atoi(value);
-+ printf("(TXTINFO) listening on port: %d\n", ipc_port);
-+ }
-+
-+ if(!strcmp(key, "accept"))
-+ {
-+ inet_aton(value, &ipc_accept_ip);
-+ printf("(TXTINFO) accept only: %s\n", inet_ntoa(ipc_accept_ip));
-+ }
-+/*
-+ if(!strcmp(key, "hilitemprneighbours"))
-+ {
-+ if(!strcmp(value, "false") || !strcmp(value, "0"))
-+ {
-+ nompr=1;
-+ }
-+ }
-+ */
-+ return 1;
-+}
-diff -Nur olsrd-0.4.10.orig/lib/txtinfo/src/olsrd_txtinfo.c olsrd-0.4.10/lib/txtinfo/src/olsrd_txtinfo.c
---- olsrd-0.4.10.orig/lib/txtinfo/src/olsrd_txtinfo.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/txtinfo/src/olsrd_txtinfo.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,542 @@
-+/*
-+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
-+ * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+ * includes code by Bruno Randolf
-+ * includes code by Andreas Lopatic
-+ * includes code by Sven-Ola Tuecke
-+ * includes code by Lorenz Schori
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of olsr.org, olsrd nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * Visit http://www.olsr.org for more information.
-+ *
-+ * If you find this software useful feel free to make a donation
-+ * to the project. For more information see the website or contact
-+ * the copyright holders.
-+ *
-+ * $Id: olsrd-txtinfo.patch,v 1.5 2006/12/04 08:33:46 sven-ola Exp $
-+ */
-+
-+/*
-+ * Dynamic linked library for the olsr.org olsr daemon
-+ */
-+
-+
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <sys/select.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <sys/time.h>
-+#include <time.h>
-+#include <math.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdarg.h>
-+#include <unistd.h>
-+#include <errno.h>
-+
-+#include "olsr.h"
-+#include "olsr_types.h"
-+#include "neighbor_table.h"
-+#include "two_hop_neighbor_table.h"
-+#include "mpr_selector_set.h"
-+#include "tc_set.h"
-+#include "hna_set.h"
-+#include "mid_set.h"
-+#include "link_set.h"
-+#include "socket_parser.h"
-+
-+#include "olsrd_txtinfo.h"
-+#include "olsrd_plugin.h"
-+
-+
-+#ifdef WIN32
-+#define close(x) closesocket(x)
-+#endif
-+
-+
-+static int ipc_socket;
-+static int ipc_open;
-+static int ipc_connection;
-+static int ipc_socket_up;
-+
-+
-+/* IPC initialization function */
-+static int
-+plugin_ipc_init(void);
-+
-+static void
-+send_info(int neighonly);
-+
-+static void
-+ipc_action(int);
-+
-+static void inline
-+ipc_print_neigh_link(void);
-+
-+static void inline
-+ipc_print_routes(void);
-+
-+static void inline
-+ipc_print_topology(void);
-+
-+static void inline
-+ipc_print_hna(void);
-+
-+#define TXT_IPC_BUFSIZE 256
-+static int
-+ipc_sendf(const char* format, ...);
-+
-+/**
-+ *Do initialization here
-+ *
-+ *This function is called by the my_init
-+ *function in uolsrd_plugin.c
-+ */
-+int
-+olsrd_plugin_init()
-+{
-+ /* Initial IPC value */
-+ ipc_open = 0;
-+ ipc_socket_up = 0;
-+
-+ plugin_ipc_init();
-+ return 1;
-+}
-+
-+
-+/**
-+ * destructor - called at unload
-+ */
-+void
-+olsr_plugin_exit()
-+{
-+ if(ipc_open)
-+ close(ipc_socket);
-+}
-+
-+
-+
-+static int
-+plugin_ipc_init()
-+{
-+ struct sockaddr_in sin;
-+ olsr_u32_t yes = 1;
-+
-+ /* Init ipc socket */
-+ if ((ipc_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
-+ {
-+#ifndef NODEBUG
-+ olsr_printf(1, "(TXTINFO) socket()=%s\n", strerror(errno));
-+#endif
-+ return 0;
-+ }
-+ else
-+ {
-+ if (setsockopt(ipc_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0)
-+ {
-+#ifndef NODEBUG
-+ olsr_printf(1, "(TXTINFO) setsockopt()=%s\n", strerror(errno));
-+#endif
-+ return 0;
-+ }
-+
-+#if defined __FreeBSD__ && defined SO_NOSIGPIPE
-+ if (setsockopt(ipc_socket, SOL_SOCKET, SO_NOSIGPIPE, (char *)&yes, sizeof(yes)) < 0)
-+ {
-+ perror("SO_REUSEADDR failed");
-+ return 0;
-+ }
-+#endif
-+
-+ /* Bind the socket */
-+
-+ /* complete the socket structure */
-+ memset(&sin, 0, sizeof(sin));
-+ sin.sin_family = AF_INET;
-+ sin.sin_addr.s_addr = INADDR_ANY;
-+ sin.sin_port = htons(ipc_port);
-+
-+ /* bind the socket to the port number */
-+ if (bind(ipc_socket, (struct sockaddr *) &sin, sizeof(sin)) == -1)
-+ {
-+#ifndef NODEBUG
-+ olsr_printf(1, "(TXTINFO) bind()=%s\n", strerror(errno));
-+#endif
-+ return 0;
-+ }
-+
-+ /* show that we are willing to listen */
-+ if (listen(ipc_socket, 1) == -1)
-+ {
-+#ifndef NODEBUG
-+ olsr_printf(1, "(TXTINFO) listen()=%s\n", strerror(errno));
-+#endif
-+ return 0;
-+ }
-+
-+ /* Register with olsrd */
-+ add_olsr_socket(ipc_socket, &ipc_action);
-+
-+#ifndef NODEBUG
-+ olsr_printf(2, "(TXTINFO) listening on port %d\n",ipc_port);
-+#endif
-+ ipc_socket_up = 1;
-+ }
-+
-+ return 1;
-+}
-+
-+
-+static void
-+ipc_action(int fd)
-+{
-+ struct sockaddr_in pin;
-+ socklen_t addrlen;
-+ char *addr;
-+
-+ addrlen = sizeof(struct sockaddr_in);
-+
-+ if(ipc_open)
-+ return;
-+
-+ if ((ipc_connection = accept(fd, (struct sockaddr *) &pin, &addrlen)) == -1)
-+ {
-+#ifndef NODEBUG
-+ olsr_printf(1, "(TXTINFO) accept()=%s\n", strerror(errno));
-+#endif
-+ exit(1);
-+ }
-+ else
-+ {
-+ addr = inet_ntoa(pin.sin_addr);
-+ if(ntohl(pin.sin_addr.s_addr) != ntohl(ipc_accept_ip.s_addr))
-+ {
-+ olsr_printf(1, "(TXTINFO) From host(%s) not allowed!\n", addr);
-+ close(ipc_connection);
-+ return;
-+ }
-+ else
-+ {
-+ ipc_open = 1;
-+#ifndef NODEBUG
-+ olsr_printf(2, "(TXTINFO) Connect from %s\n",addr);
-+#endif
-+
-+ /* purge read buffer to prevent blocking on linux*/
-+ fd_set rfds;
-+ FD_ZERO(&rfds);
-+ FD_SET(ipc_connection, &rfds);
-+ struct timeval tv = {0,0};
-+ int neighonly = 0;
-+ if(select(ipc_connection+1, &rfds, NULL, NULL, &tv)) {
-+ char requ[128];
-+ ssize_t s = recv(ipc_connection, &requ, sizeof(requ), 0);
-+ if (0 < s) {
-+ requ[s] = 0;
-+ /* To print out neighbours only on the Freifunk Status
-+ * page the normal output is somewhat lengthy. The
-+ * header parsing is sufficient for standard wget.
-+ */
-+ neighonly = (0 != strstr(requ, "/neighbours"));
-+ }
-+ }
-+
-+ send_info(neighonly);
-+
-+ close(ipc_connection);
-+ ipc_open = 0;
-+ }
-+ }
-+}
-+
-+static void inline
-+ipc_print_neigh_link(void)
-+{
-+ struct neighbor_entry *neigh;
-+ struct neighbor_2_list_entry *list_2;
-+ struct link_entry *link = NULL;
-+ int index, thop_cnt;
-+
-+ ipc_sendf("Table: Links\nLocal IP\tremote IP\tHysteresis\tLinkQuality\tlost\ttotal\tNLQ\tETX\n");
-+
-+ /* Link set */
-+ link = link_set;
-+ while(link)
-+ {
-+ ipc_sendf( "%s\t%s\t%0.2f\t%0.2f\t%d\t%d\t%0.2f\t%0.2f\t\n",
-+ olsr_ip_to_string(&link->local_iface_addr),
-+ olsr_ip_to_string(&link->neighbor_iface_addr),
-+ link->L_link_quality,
-+ link->loss_link_quality,
-+ link->lost_packets,
-+ link->total_packets,
-+ link->neigh_link_quality,
-+ (link->loss_link_quality * link->neigh_link_quality) ? 1.0 / (link->loss_link_quality * link->neigh_link_quality) : 0.0);
-+ link = link->next;
-+ }
-+ ipc_sendf("\nTable: Neighbors\nIP address\tSYM\tMPR\tMPRS\tWillingness\t2 Hop Neighbors\n");
-+
-+ /* Neighbors */
-+ for(index=0;index<HASHSIZE;index++)
-+ {
-+ for(neigh = neighbortable[index].next;
-+ neigh != &neighbortable[index];
-+ neigh = neigh->next)
-+ {
-+ ipc_sendf(
-+ "%s\t%s\t%s\t%s\t%d\t",
-+ olsr_ip_to_string(&neigh->neighbor_main_addr),
-+ (neigh->status == SYM) ? "YES" : "NO",
-+ neigh->is_mpr ? "YES" : "NO",
-+ olsr_lookup_mprs_set(&neigh->neighbor_main_addr) ? "YES" : "NO",
-+ neigh->willingness);
-+
-+ thop_cnt = 0;
-+
-+ for(list_2 = neigh->neighbor_2_list.next;
-+ list_2 != &neigh->neighbor_2_list;
-+ list_2 = list_2->next)
-+ {
-+ //size += sprintf(&buf[size], "<option>%s</option>\n", olsr_ip_to_string(&list_2->neighbor_2->neighbor_2_addr));
-+ thop_cnt ++;
-+ }
-+ ipc_sendf("%d\n", thop_cnt);
-+ }
-+ }
-+
-+ ipc_sendf("\n");
-+}
-+
-+
-+static void inline
-+ipc_print_routes(void)
-+{
-+ int size = 0, index;
-+ struct rt_entry *routes;
-+
-+ ipc_sendf("Table: Routes\nDestination\tGateway\tMetric\tETX\tInterface\tType\n");
-+
-+ /* Neighbors */
-+ for(index = 0;index < HASHSIZE;index++)
-+ {
-+ for(routes = routingtable[index].next;
-+ routes != &routingtable[index];
-+ routes = routes->next)
-+ {
-+ size = 0;
-+ ipc_sendf( "%s\t%s\t%d\t%.2f\t%s\tHOST\n",
-+ olsr_ip_to_string(&routes->rt_dst),
-+ olsr_ip_to_string(&routes->rt_router),
-+ routes->rt_metric,
-+ routes->rt_etx,
-+ routes->rt_if->int_name);
-+ }
-+ }
-+
-+ /* HNA */
-+ for(index = 0;index < HASHSIZE;index++)
-+ {
-+ for(routes = hna_routes[index].next;
-+ routes != &hna_routes[index];
-+ routes = routes->next)
-+ {
-+ ipc_sendf("%s\t%s\t%d\t%s\t\tHNA\n",
-+ olsr_ip_to_string(&routes->rt_dst),
-+ olsr_ip_to_string(&routes->rt_router),
-+ routes->rt_metric,
-+ routes->rt_if->int_name);
-+ }
-+ }
-+
-+ ipc_sendf("\n");
-+
-+}
-+
-+static void inline
-+ipc_print_topology(void)
-+{
-+ olsr_u8_t index;
-+ struct tc_entry *entry;
-+ struct topo_dst *dst_entry;
-+
-+
-+ ipc_sendf("Table: Topology\nDestination IP\tLast hop IP\tLQ\tILQ\tETX\n");
-+
-+ /* Topology */
-+ for(index=0;index<HASHSIZE;index++)
-+ {
-+ /* For all TC entries */
-+ entry = tc_table[index].next;
-+ while(entry != &tc_table[index])
-+ {
-+ /* For all destination entries of that TC entry */
-+ dst_entry = entry->destinations.next;
-+ while(dst_entry != &entry->destinations)
-+ {
-+ ipc_sendf( "%s\t%s\t%0.2f\t%0.2f\t%0.2f\n",
-+ olsr_ip_to_string(&dst_entry->T_dest_addr),
-+ olsr_ip_to_string(&entry->T_last_addr),
-+ dst_entry->link_quality,
-+ dst_entry->inverse_link_quality,
-+ (dst_entry->link_quality * dst_entry->inverse_link_quality) ? 1.0 / (dst_entry->link_quality * dst_entry->inverse_link_quality) : 0.0);
-+
-+ dst_entry = dst_entry->next;
-+ }
-+ entry = entry->next;
-+ }
-+ }
-+
-+ ipc_sendf("\n");
-+}
-+
-+static void inline
-+ipc_print_hna(void)
-+{
-+ int size;
-+ olsr_u8_t index;
-+ struct hna_entry *tmp_hna;
-+ struct hna_net *tmp_net;
-+
-+ size = 0;
-+
-+ ipc_sendf("Table: HNA\nNetwork\tNetmask\tGateway\n");
-+
-+ /* Announced HNA entries */
-+ struct hna4_entry *hna4;
-+ for(hna4 = olsr_cnf->hna4_entries; hna4; hna4 = hna4->next)
-+ {
-+ ipc_sendf("%s\t%s\t%s\n",
-+ olsr_ip_to_string((union olsr_ip_addr *)&hna4->net),
-+ olsr_ip_to_string((union olsr_ip_addr *)&hna4->netmask),
-+ olsr_ip_to_string((union olsr_ip_addr *)&main_addr));
-+ }
-+ struct hna6_entry *hna6;
-+ for(hna6 = olsr_cnf->hna6_entries; hna6; hna6 = hna6->next)
-+ {
-+ ipc_sendf("%s\t%d\t%s\n",
-+ olsr_ip_to_string((union olsr_ip_addr *)&hna6->net),
-+ hna6->prefix_len,
-+ olsr_ip_to_string((union olsr_ip_addr *)&main_addr));
-+ }
-+
-+ /* HNA entries */
-+ for(index=0;index<HASHSIZE;index++)
-+ {
-+ tmp_hna = hna_set[index].next;
-+ /* Check all entrys */
-+ while(tmp_hna != &hna_set[index])
-+ {
-+ /* Check all networks */
-+ tmp_net = tmp_hna->networks.next;
-+
-+ while(tmp_net != &tmp_hna->networks)
-+ {
-+ if (AF_INET == olsr_cnf->ip_version) {
-+ ipc_sendf("%s\t%s\t%s\n",
-+ olsr_ip_to_string(&tmp_net->A_network_addr),
-+ olsr_ip_to_string((union olsr_ip_addr *)&tmp_net->A_netmask.v4),
-+ olsr_ip_to_string(&tmp_hna->A_gateway_addr));
-+ }
-+ else {
-+ ipc_sendf("%s\t%d\t%s\n",
-+ olsr_ip_to_string(&tmp_net->A_network_addr),
-+ tmp_net->A_netmask.v6,
-+ olsr_ip_to_string(&tmp_hna->A_gateway_addr));
-+ }
-+ tmp_net = tmp_net->next;
-+ }
-+
-+ tmp_hna = tmp_hna->next;
-+ }
-+ }
-+
-+ ipc_sendf("\n");
-+
-+}
-+
-+
-+static void
-+send_info(int neighonly)
-+{
-+
-+ /* Print minimal http header */
-+ ipc_sendf("HTTP/1.0 200 OK\n");
-+ ipc_sendf("Content-type: text/plain\n\n");
-+
-+ /* Print tables to IPC socket */
-+
-+ /* links + Neighbors */
-+ ipc_print_neigh_link();
-+
-+ /* topology */
-+ if (!neighonly) ipc_print_topology();
-+
-+ /* hna */
-+ if (!neighonly) ipc_print_hna();
-+
-+ /* routes */
-+ if (!neighonly) ipc_print_routes();
-+}
-+
-+/*
-+ * In a bigger mesh, there are probs with the fixed
-+ * bufsize. Because the Content-Length header is
-+ * optional, the sprintf() is changed to a more
-+ * scalable solution here.
-+ */
-+
-+static int
-+ipc_sendf(const char* format, ...)
-+{
-+ char txtnetbuf[TXT_IPC_BUFSIZE];
-+
-+ va_list arg;
-+ int rv;
-+#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __MacOSX__
-+ int flags = 0;
-+#else
-+ int flags = MSG_NOSIGNAL;
-+#endif
-+ va_start(arg, format);
-+ rv = vsnprintf(txtnetbuf, sizeof(txtnetbuf), format, arg);
-+ va_end(arg);
-+ if(ipc_socket_up) {
-+ if (0 > send(ipc_connection, txtnetbuf, rv, flags)) {
-+#ifndef NODEBUG
-+ olsr_printf(1, "(TXTINFO) Failed sending data to client!\n");
-+#endif
-+ close(ipc_connection);
-+ return - 1;
-+ }
-+ }
-+ return rv;
-+}
-diff -Nur olsrd-0.4.10.orig/lib/txtinfo/src/olsrd_txtinfo.h olsrd-0.4.10/lib/txtinfo/src/olsrd_txtinfo.h
---- olsrd-0.4.10.orig/lib/txtinfo/src/olsrd_txtinfo.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/txtinfo/src/olsrd_txtinfo.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,62 @@
-+/*
-+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
-+ * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+ * includes code by Bruno Randolf
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of olsr.org, olsrd nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * Visit http://www.olsr.org for more information.
-+ *
-+ * If you find this software useful feel free to make a donation
-+ * to the project. For more information see the website or contact
-+ * the copyright holders.
-+ *
-+ * $Id: olsrd-txtinfo.patch,v 1.5 2006/12/04 08:33:46 sven-ola Exp $
-+ */
-+
-+/*
-+ * Dynamic linked library for the olsr.org olsr daemon
-+ */
-+
-+#ifndef _OLSRD_DOT_DRAW
-+#define _OLSRD_DOT_DRAW
-+
-+
-+extern struct in_addr ipc_accept_ip;
-+extern int ipc_port;
-+extern int nompr;
-+
-+
-+int
-+olsrd_plugin_init(void);
-+
-+void
-+olsr_plugin_exit(void);
-+
-+#endif
-diff -Nur olsrd-0.4.10.orig/lib/txtinfo/version-script.txt olsrd-0.4.10/lib/txtinfo/version-script.txt
---- olsrd-0.4.10.orig/lib/txtinfo/version-script.txt 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/txtinfo/version-script.txt 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,10 @@
-+VERS_1.0
-+{
-+ global:
-+ olsrd_plugin_interface_version;
-+ olsrd_plugin_register_param;
-+ olsrd_plugin_init;
-+
-+ local:
-+ *;
-+};
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/quagga/ChangeLog olsrd-0.4.10/lib/quagga/ChangeLog
---- olsrd-0.4.10.orig/lib/quagga/ChangeLog 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/ChangeLog 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,17 @@
-+0.2.1: Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>:
-+ * now check (most of the) return-values of syscalls, improvement still
-+ possible...
-+ * added support for new zebra-protocoll-format (with
-+ ZEBRA_HEADER_MARKER and ZCLIENT_VERSION) if new
-+ quagga-headers are found)
-+ * Code Cleanup (removed lot of debug and test-stuff)
-+ * fixed return-bug in zebra_send_command
-+ * added copyright-stuff
-+ * removed memleak in zebra_add/delete_v4_route
-+
-+0.2.0: Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>:
-+ * Initial release, too :-)
-+ * Added support for route-export to the zebra/quagga
-+
-+0.1.0: Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>:
-+ * Initial release
-diff -Nur olsrd-0.4.10.orig/lib/quagga/Makefile olsrd-0.4.10/lib/quagga/Makefile
---- olsrd-0.4.10.orig/lib/quagga/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/Makefile 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,65 @@
-+# The olsr.org Optimized Link-State Routing daemon(olsrd)
-+# Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
-+# All rights reserved.
-+#
-+# Redistribution and use in source and binary forms, with or without
-+# modification, are permitted provided that the following conditions
-+# are met:
-+#
-+# * Redistributions of source code must retain the above copyright
-+# notice, this list of conditions and the following disclaimer.
-+# * Redistributions in binary form must reproduce the above copyright
-+# notice, this list of conditions and the following disclaimer in
-+# the documentation and/or other materials provided with the
-+# distribution.
-+# * Neither the name of olsr.org, olsrd nor the names of its
-+# contributors may be used to endorse or promote products derived
-+# from this software without specific prior written permission.
-+#
-+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+# POSSIBILITY OF SUCH DAMAGE.
-+#
-+# Visit http://www.olsr.org for more information.
-+#
-+# If you find this software useful feel free to make a donation
-+# to the project. For more information see the website or contact
-+# the copyright holders.
-+#
-+# $Id: Makefile,v 1.1 2005/05/26 16:09:25 br1 Exp $
-+
-+OLSRD_PLUGIN = true
-+PLUGIN_NAME = olsrd_quagga
-+PLUGIN_VER = 0.2.2
-+
-+#CFLAGS +=-DMY_DEBUG
-+CFLAGS += -g
-+CFLAGS +=-DUSE_UNIX_DOMAIN_SOCKET
-+
-+#uncomment the following line only if you are sure what you're doing, it will
-+#probably break things!
-+# CFLAGS +=-DZEBRA_HEADER_MARKER=255
-+
-+TOPDIR = ../..
-+include $(TOPDIR)/Makefile.inc
-+
-+default_target: $(PLUGIN_FULLNAME)
-+
-+$(PLUGIN_FULLNAME): $(OBJS)
-+ $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
-+
-+install: $(PLUGIN_FULLNAME)
-+ $(STRIP) $(PLUGIN_FULLNAME)
-+ $(INSTALL_LIB)
-+
-+clean:
-+ rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
-diff -Nur olsrd-0.4.10.orig/lib/quagga/quagga-0.98.6-olsr.diff olsrd-0.4.10/lib/quagga/quagga-0.98.6-olsr.diff
---- olsrd-0.4.10.orig/lib/quagga/quagga-0.98.6-olsr.diff 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/quagga-0.98.6-olsr.diff 2006-12-02 10:57:52.000000000 +0100
-@@ -0,0 +1,717 @@
-+diff -Nur quagga-0.98.6.orig/bgpd/bgp_vty.c quagga-0.98.6/bgpd/bgp_vty.c
-+--- quagga-0.98.6.orig/bgpd/bgp_vty.c 2006-03-30 18:12:25.000000000 +0200
-++++ quagga-0.98.6/bgpd/bgp_vty.c 2006-12-02 10:52:14.000000000 +0100
-+@@ -7793,7 +7793,9 @@
-+ return ZEBRA_ROUTE_STATIC;
-+ else if (strncmp (str, "r", 1) == 0)
-+ return ZEBRA_ROUTE_RIP;
-+- else if (strncmp (str, "o", 1) == 0)
-++ else if (strncmp (str, "ol", 2) == 0)
-++ return ZEBRA_ROUTE_OLSR;
-++ else if (strncmp (str, "os", 2) == 0)
-+ return ZEBRA_ROUTE_OSPF;
-+ }
-+ if (afi == AFI_IP6)
-+@@ -7806,20 +7808,23 @@
-+ return ZEBRA_ROUTE_STATIC;
-+ else if (strncmp (str, "r", 1) == 0)
-+ return ZEBRA_ROUTE_RIPNG;
-+- else if (strncmp (str, "o", 1) == 0)
-++ else if (strncmp (str, "os", 2) == 0)
-+ return ZEBRA_ROUTE_OSPF6;
-++ else if (strncmp (str, "ol", 2) == 0)
-++ return ZEBRA_ROUTE_OLSR;
-+ }
-+ return 0;
-+ }
-+
-+ DEFUN (bgp_redistribute_ipv4,
-+ bgp_redistribute_ipv4_cmd,
-+- "redistribute (connected|kernel|ospf|rip|static)",
-++ "redistribute (connected|kernel|ospf|rip|static|olsr)",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Static routes\n")
-+ {
-+ int type;
-+@@ -7835,13 +7840,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv4_rmap,
-+ bgp_redistribute_ipv4_rmap_cmd,
-+- "redistribute (connected|kernel|ospf|rip|static) route-map WORD",
-++ "redistribute (connected|kernel|ospf|rip|static|olsr) route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n")
-+ {
-+@@ -7860,13 +7866,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv4_metric,
-+ bgp_redistribute_ipv4_metric_cmd,
-+- "redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295>",
-++ "redistribute (connected|kernel|ospf|rip|static|olsr) metric <0-4294967295>",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n")
-+ {
-+@@ -7887,13 +7894,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv4_rmap_metric,
-+ bgp_redistribute_ipv4_rmap_metric_cmd,
-+- "redistribute (connected|kernel|ospf|rip|static) route-map WORD metric <0-4294967295>",
-++ "redistribute (connected|kernel|ospf|rip|static|olsr) route-map WORD metric <0-4294967295>",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n"
-+ "Metric for redistributed routes\n"
-+@@ -7917,13 +7925,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv4_metric_rmap,
-+ bgp_redistribute_ipv4_metric_rmap_cmd,
-+- "redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295> route-map WORD",
-++ "redistribute (connected|kernel|ospf|rip|static|olsr) metric <0-4294967295> route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n"
-+ "Route map reference\n"
-+@@ -7947,14 +7956,16 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv4,
-+ no_bgp_redistribute_ipv4_cmd,
-+- "no redistribute (connected|kernel|ospf|rip|static)",
-++ "no redistribute (connected|kernel|ospf|rip|static|olsr)",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+- "Static routes\n")
-++ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-++ )
-+ {
-+ int type;
-+
-+@@ -7970,7 +7981,7 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv4_rmap,
-+ no_bgp_redistribute_ipv4_rmap_cmd,
-+- "no redistribute (connected|kernel|ospf|rip|static) route-map WORD",
-++ "no redistribute (connected|kernel|ospf|rip|static|olsr) route-map WORD",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -7978,6 +7989,7 @@
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n")
-+ {
-+@@ -7996,7 +8008,7 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv4_metric,
-+ no_bgp_redistribute_ipv4_metric_cmd,
-+- "no redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295>",
-++ "no redistribute (connected|kernel|ospf|rip|static|olsr) metric <0-4294967295>",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -8004,6 +8016,7 @@
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n")
-+ {
-+@@ -8022,7 +8035,7 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv4_rmap_metric,
-+ no_bgp_redistribute_ipv4_rmap_metric_cmd,
-+- "no redistribute (connected|kernel|ospf|rip|static) route-map WORD metric <0-4294967295>",
-++ "no redistribute (connected|kernel|ospf|rip|static|olsr) route-map WORD metric <0-4294967295>",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -8030,6 +8043,7 @@
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n"
-+ "Metric for redistributed routes\n"
-+@@ -8051,7 +8065,7 @@
-+
-+ ALIAS (no_bgp_redistribute_ipv4_rmap_metric,
-+ no_bgp_redistribute_ipv4_metric_rmap_cmd,
-+- "no redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295> route-map WORD",
-++ "no redistribute (connected|kernel|ospf|rip|static|olsr) metric <0-4294967295> route-map WORD",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -8059,6 +8073,7 @@
-+ "Open Shurtest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n"
-+ "Route map reference\n"
-+@@ -8067,13 +8082,15 @@
-+ #ifdef HAVE_IPV6
-+ DEFUN (bgp_redistribute_ipv6,
-+ bgp_redistribute_ipv6_cmd,
-+- "redistribute (connected|kernel|ospf6|ripng|static)",
-++ "redistribute (connected|kernel|ospf6|ripng|static|olsr)",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+- "Static routes\n")
-++ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-++ )
-+ {
-+ int type;
-+
-+@@ -8089,13 +8106,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv6_rmap,
-+ bgp_redistribute_ipv6_rmap_cmd,
-+- "redistribute (connected|kernel|ospf6|ripng|static) route-map WORD",
-++ "redistribute (connected|kernel|ospf6|ripng|static|olsr) route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n")
-+ {
-+@@ -8114,13 +8132,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv6_metric,
-+ bgp_redistribute_ipv6_metric_cmd,
-+- "redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295>",
-++ "redistribute (connected|kernel|ospf6|ripng|static|olsr) metric <0-4294967295>",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n")
-+ {
-+@@ -8141,13 +8160,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv6_rmap_metric,
-+ bgp_redistribute_ipv6_rmap_metric_cmd,
-+- "redistribute (connected|kernel|ospf6|ripng|static) route-map WORD metric <0-4294967295>",
-++ "redistribute (connected|kernel|ospf6|ripng|static|ols) route-map WORD metric <0-4294967295>",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n"
-+ "Metric for redistributed routes\n"
-+@@ -8171,13 +8191,14 @@
-+
-+ DEFUN (bgp_redistribute_ipv6_metric_rmap,
-+ bgp_redistribute_ipv6_metric_rmap_cmd,
-+- "redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295> route-map WORD",
-++ "redistribute (connected|kernel|ospf6|ripng|static|olsr) metric <0-4294967295> route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n"
-+ "Route map reference\n"
-+@@ -8201,14 +8222,16 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv6,
-+ no_bgp_redistribute_ipv6_cmd,
-+- "no redistribute (connected|kernel|ospf6|ripng|static)",
-++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr)",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+ "Kernel routes\n"
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+- "Static routes\n")
-++ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-++ )
-+ {
-+ int type;
-+
-+@@ -8224,7 +8247,7 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv6_rmap,
-+ no_bgp_redistribute_ipv6_rmap_cmd,
-+- "no redistribute (connected|kernel|ospf6|ripng|static) route-map WORD",
-++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr) route-map WORD",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -8232,6 +8255,7 @@
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n")
-+ {
-+@@ -8250,7 +8274,7 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv6_metric,
-+ no_bgp_redistribute_ipv6_metric_cmd,
-+- "no redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295>",
-++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr) metric <0-4294967295>",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -8258,6 +8282,7 @@
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n")
-+ {
-+@@ -8276,7 +8301,7 @@
-+
-+ DEFUN (no_bgp_redistribute_ipv6_rmap_metric,
-+ no_bgp_redistribute_ipv6_rmap_metric_cmd,
-+- "no redistribute (connected|kernel|ospf6|ripng|static) route-map WORD metric <0-4294967295>",
-++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr) route-map WORD metric <0-4294967295>",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -8284,6 +8309,7 @@
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n"
-+ "Metric for redistributed routes\n"
-+@@ -8305,7 +8331,7 @@
-+
-+ ALIAS (no_bgp_redistribute_ipv6_rmap_metric,
-+ no_bgp_redistribute_ipv6_metric_rmap_cmd,
-+- "no redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295> route-map WORD",
-++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr) metric <0-4294967295> route-map WORD",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Connected\n"
-+@@ -8313,6 +8339,7 @@
-+ "Open Shurtest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-+ "Static routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "Default metric\n"
-+ "Route map reference\n"
-+@@ -8325,7 +8352,7 @@
-+ {
-+ int i;
-+ const char *str[] = { "system", "kernel", "connected", "static", "rip",
-+- "ripng", "ospf", "ospf6", "isis", "bgp"};
-++ "ripng", "ospf", "ospf6", "isis", "bgp", "hsls", "olsr"};
-+
-+ /* Unicast redistribution only. */
-+ if (safi != SAFI_UNICAST)
-+diff -Nur quagga-0.98.6.orig/lib/zebra.h quagga-0.98.6/lib/zebra.h
-+--- quagga-0.98.6.orig/lib/zebra.h 2005-06-15 13:54:18.000000000 +0200
-++++ quagga-0.98.6/lib/zebra.h 2006-12-02 10:48:51.000000000 +0100
-+@@ -378,7 +378,8 @@
-+ #define ZEBRA_ROUTE_ISIS 8
-+ #define ZEBRA_ROUTE_BGP 9
-+ #define ZEBRA_ROUTE_HSLS 10
-+-#define ZEBRA_ROUTE_MAX 11
-++#define ZEBRA_ROUTE_OLSR 11
-++#define ZEBRA_ROUTE_MAX 12
-+
-+ /* Zebra's family types. */
-+ #define ZEBRA_FAMILY_IPV4 1
-+diff -Nur quagga-0.98.6.orig/ospfd/ospf_vty.c quagga-0.98.6/ospfd/ospf_vty.c
-+--- quagga-0.98.6.orig/ospfd/ospf_vty.c 2006-03-30 17:41:20.000000000 +0200
-++++ quagga-0.98.6/ospfd/ospf_vty.c 2006-12-02 10:48:51.000000000 +0100
-+@@ -108,9 +108,11 @@
-+ *source = ZEBRA_ROUTE_RIP;
-+ else if (strncmp (str, "b", 1) == 0)
-+ *source = ZEBRA_ROUTE_BGP;
-++ else if (strncmp (str, "ol", 2) == 0)
-++ *source = ZEBRA_ROUTE_OLSR;
-+ else
-+ return 0;
-+-
-++
-+ return 1;
-+ }
-+
-+@@ -5302,13 +5304,14 @@
-+ \f
-+ DEFUN (ospf_redistribute_source_metric_type,
-+ ospf_redistribute_source_metric_type_routemap_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> metric-type (1|2) route-map WORD",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) metric <0-16777214> metric-type (1|2) route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "OSPF default metric\n"
-+ "OSPF exterior metric type for redistributed routes\n"
-+@@ -5346,13 +5349,14 @@
-+
-+ ALIAS (ospf_redistribute_source_metric_type,
-+ ospf_redistribute_source_metric_type_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> metric-type (1|2)",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) metric <0-16777214> metric-type (1|2)",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "OSPF default metric\n"
-+ "OSPF exterior metric type for redistributed routes\n"
-+@@ -5368,18 +5372,20 @@
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "OSPF default metric\n")
-+
-+ DEFUN (ospf_redistribute_source_type_metric,
-+ ospf_redistribute_source_type_metric_routemap_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric <0-16777214> route-map WORD",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) metric-type (1|2) metric <0-16777214> route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "OSPF exterior metric type for redistributed routes\n"
-+ "Set OSPF External Type 1 metrics\n"
-+ "Set OSPF External Type 2 metrics\n"
-+@@ -5417,13 +5423,14 @@
-+
-+ ALIAS (ospf_redistribute_source_type_metric,
-+ ospf_redistribute_source_type_metric_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric <0-16777214>",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) metric-type (1|2) metric <0-16777214>",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "OSPF exterior metric type for redistributed routes\n"
-+ "Set OSPF External Type 1 metrics\n"
-+ "Set OSPF External Type 2 metrics\n"
-+@@ -5432,7 +5439,7 @@
-+
-+ ALIAS (ospf_redistribute_source_type_metric,
-+ ospf_redistribute_source_type_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2)",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) metric-type (1|2)",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+@@ -5440,28 +5447,31 @@
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-+ "OSPF exterior metric type for redistributed routes\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Set OSPF External Type 1 metrics\n"
-+ "Set OSPF External Type 2 metrics\n")
-+
-+ ALIAS (ospf_redistribute_source_type_metric,
-+ ospf_redistribute_source_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp)",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr)",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+- "Border Gateway Protocol (BGP)\n")
-++ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n")
-+
-+ DEFUN (ospf_redistribute_source_metric_routemap,
-+ ospf_redistribute_source_metric_routemap_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> route-map WORD",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) metric <0-16777214> route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Metric for redistributed routes\n"
-+ "OSPF default metric\n"
-+ "Route map reference\n"
-+@@ -5490,13 +5500,14 @@
-+
-+ DEFUN (ospf_redistribute_source_type_routemap,
-+ ospf_redistribute_source_type_routemap_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) route-map WORD",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) metric-type (1|2) route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "OSPF exterior metric type for redistributed routes\n"
-+ "Set OSPF External Type 1 metrics\n"
-+ "Set OSPF External Type 2 metrics\n"
-+@@ -5526,13 +5537,14 @@
-+
-+ DEFUN (ospf_redistribute_source_routemap,
-+ ospf_redistribute_source_routemap_cmd,
-+- "redistribute (kernel|connected|static|rip|bgp) route-map WORD",
-++ "redistribute (kernel|connected|static|rip|bgp|olsr) route-map WORD",
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Route map reference\n"
-+ "Pointer to route-map entries\n")
-+ {
-+@@ -5553,14 +5565,16 @@
-+
-+ DEFUN (no_ospf_redistribute_source,
-+ no_ospf_redistribute_source_cmd,
-+- "no redistribute (kernel|connected|static|rip|bgp)",
-++ "no redistribute (kernel|connected|static|rip|bgp|olsr)",
-+ NO_STR
-+ "Redistribute information from another routing protocol\n"
-+ "Kernel routes\n"
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+- "Border Gateway Protocol (BGP)\n")
-++ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (olsr)\n"
-++ )
-+ {
-+ struct ospf *ospf = vty->index;
-+ int source;
-+@@ -5574,7 +5588,7 @@
-+
-+ DEFUN (ospf_distribute_list_out,
-+ ospf_distribute_list_out_cmd,
-+- "distribute-list WORD out (kernel|connected|static|rip|bgp)",
-++ "distribute-list WORD out (kernel|connected|static|rip|bgp|olsr)",
-+ "Filter networks in routing updates\n"
-+ "Access-list name\n"
-+ OUT_STR
-+@@ -5582,7 +5596,8 @@
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+- "Border Gateway Protocol (BGP)\n")
-++ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n")
-+ {
-+ struct ospf *ospf = vty->index;
-+ int source;
-+@@ -5596,7 +5611,7 @@
-+
-+ DEFUN (no_ospf_distribute_list_out,
-+ no_ospf_distribute_list_out_cmd,
-+- "no distribute-list WORD out (kernel|connected|static|rip|bgp)",
-++ "no distribute-list WORD out (kernel|connected|static|rip|bgp|olsr)",
-+ NO_STR
-+ "Filter networks in routing updates\n"
-+ "Access-list name\n"
-+@@ -5605,7 +5620,8 @@
-+ "Connected\n"
-+ "Static routes\n"
-+ "Routing Information Protocol (RIP)\n"
-+- "Border Gateway Protocol (BGP)\n")
-++ "Border Gateway Protocol (BGP)\n"
-++ "Optimized Link State Routing (OLSR)\n")
-+ {
-+ struct ospf *ospf = vty->index;
-+ int source;
-+@@ -7121,7 +7137,8 @@
-+
-+ \f
-+ const char *distribute_str[] = { "system", "kernel", "connected", "static",
-+- "rip", "ripng", "ospf", "ospf6", "isis", "bgp"};
-++ "rip", "ripng", "ospf", "ospf6", "isis", "bgp",
-++ "hsls","olsr"};
-+ int
-+ config_write_ospf_redistribute (struct vty *vty, struct ospf *ospf)
-+ {
-+diff -Nur quagga-0.98.6.orig/zebra/zebra_vty.c quagga-0.98.6/zebra/zebra_vty.c
-+--- quagga-0.98.6.orig/zebra/zebra_vty.c 2004-12-18 17:03:29.000000000 +0100
-++++ quagga-0.98.6/zebra/zebra_vty.c 2006-12-02 10:49:45.000000000 +0100
-+@@ -53,6 +53,8 @@
-+ return "isis";
-+ case ZEBRA_ROUTE_BGP:
-+ return "bgp";
-++ case ZEBRA_ROUTE_OLSR:
-++ return "olsr";
-+ default:
-+ return "unknown";
-+ }
-+@@ -84,6 +86,10 @@
-+ return 'I';
-+ case ZEBRA_ROUTE_BGP:
-+ return 'B';
-++ case ZEBRA_ROUTE_HSLS:
-++ return 'H';
-++ case ZEBRA_ROUTE_OLSR:
-++ return 'L';
-+ default:
-+ return '?';
-+ }
-+@@ -755,8 +761,8 @@
-+ }
-+
-+ #define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, " \
-+- "S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, " \
-+- "> - selected route, * - FIB route%s%s"
-++ "S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, H - HSLS, " \
-++ "L - OLSR, > - selected route, * - FIB route%s%s"
-+
-+ DEFUN (show_ip_route,
-+ show_ip_route_cmd,
-+@@ -874,7 +880,7 @@
-+
-+ DEFUN (show_ip_route_protocol,
-+ show_ip_route_protocol_cmd,
-+- "show ip route (bgp|connected|isis|kernel|ospf|rip|static)",
-++ "show ip route (bgp|connected|isis|kernel|ospf|rip|olsr|static)",
-+ SHOW_STR
-+ IP_STR
-+ "IP routing table\n"
-+@@ -884,6 +890,7 @@
-+ "Kernel\n"
-+ "Open Shortest Path First (OSPF)\n"
-+ "Routing Information Protocol (RIP)\n"
-++ "Optimized Link State Routing (OLSR)\n"
-+ "Static routes\n")
-+ {
-+ int type;
-+@@ -898,7 +905,7 @@
-+ type = ZEBRA_ROUTE_CONNECT;
-+ else if (strncmp (argv[0], "k", 1) ==0)
-+ type = ZEBRA_ROUTE_KERNEL;
-+- else if (strncmp (argv[0], "o", 1) == 0)
-++ else if (strncmp (argv[0], "os", 2) == 0)
-+ type = ZEBRA_ROUTE_OSPF;
-+ else if (strncmp (argv[0], "i", 1) == 0)
-+ type = ZEBRA_ROUTE_ISIS;
-+@@ -906,6 +913,8 @@
-+ type = ZEBRA_ROUTE_RIP;
-+ else if (strncmp (argv[0], "s", 1) == 0)
-+ type = ZEBRA_ROUTE_STATIC;
-++ else if (strncmp (argv[0], "ol", 2) == 0)
-++ type = ZEBRA_ROUTE_OLSR;
-+ else
-+ {
-+ vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
-+@@ -1732,7 +1741,7 @@
-+
-+ DEFUN (show_ipv6_route_protocol,
-+ show_ipv6_route_protocol_cmd,
-+- "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|static)",
-++ "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|olsr|static)",
-+ SHOW_STR
-+ IP_STR
-+ "IP routing table\n"
-+@@ -1742,6 +1751,7 @@
-+ "Kernel\n"
-+ "Open Shortest Path First (OSPFv3)\n"
-+ "Routing Information Protocol (RIPng)\n"
-++ "Optimized Link State Routing (olsr)\n"
-+ "Static routes\n")
-+ {
-+ int type;
-+@@ -1756,7 +1766,7 @@
-+ type = ZEBRA_ROUTE_CONNECT;
-+ else if (strncmp (argv[0], "k", 1) ==0)
-+ type = ZEBRA_ROUTE_KERNEL;
-+- else if (strncmp (argv[0], "o", 1) == 0)
-++ else if (strncmp (argv[0], "os", 2) == 0)
-+ type = ZEBRA_ROUTE_OSPF6;
-+ else if (strncmp (argv[0], "i", 1) == 0)
-+ type = ZEBRA_ROUTE_ISIS;
-+@@ -1764,7 +1774,9 @@
-+ type = ZEBRA_ROUTE_RIPNG;
-+ else if (strncmp (argv[0], "s", 1) == 0)
-+ type = ZEBRA_ROUTE_STATIC;
-+- else
-++ else if (strncmp (argv[0], "ol", 2) == 0)
-++ type = ZEBRA_ROUTE_OLSR;
-++ else
-+ {
-+ vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
-+ return CMD_WARNING;
-diff -Nur olsrd-0.4.10.orig/lib/quagga/README olsrd-0.4.10/lib/quagga/README
---- olsrd-0.4.10.orig/lib/quagga/README 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/README 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,58 @@
-+---------------------------------------------------------------------
-+QUAGGA PLUGIN FOR OLSRD
-+by Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
-+---------------------------------------------------------------------
-+
-+This is the Quagga Plugin for the OLSRD.
-+It allowes olsrd to redistribute from various quagga-protocols
-+as well as to export olsr-routes to quagga so that they can be
-+redistributed by the quagga-routing-daemons.
-+
-+Note Sven-Ola: You also need a source distribution of quagga-0.98.5
-+or quagga-0.98.6 (that is the current stable). The quagga source tree
-+needs to be patched with quagga-0.98.6-olsr.diff, compiled and installed
-+via 'make install'. Because many people will otherwise have compile
-+probs, I've added 2 include files in lib/quagga/src/quagga. If you
-+want to use another version of quagga, make sure to remove these
-+before you compile the olsrd_quagga plugin.
-+
-+---------------------------------------------------------------------
-+PLUGIN PARAMETERS (PlParam)
-+---------------------------------------------------------------------
-+
-+PlParam "redistribute" "<protocol>"
-+ where protocol is one of the following:
-+ system, kernel, connect, static, rip, ripng, ospf, ospf6,
-+ isis, bgp, hsls
-+ May be used more then once
-+
-+PlParam "ExportRoutes" "<only/both>"
-+ exportes olsr-routes to quagga or to both, quagga and kernel
-+ no routes are exportet if not set.
-+
-+PlParam "Localpref" "true"
-+ sets the zebra SELECTED-flag on the routes exported to zebra
-+ which means these routes are prefered in any case.
-+
-+PlParam "Distance" "0-255"
-+ allowes to set Administrative distance to routes exported
-+ to zebra.
-+
-+---------------------------------------------------------------------
-+SAMPLE CONFIG
-+---------------------------------------------------------------------
-+
-+add in /etc/olsrd.conf:
-+
-+LoadPlugin "olsrd_quagga.so.0.2.2"
-+{
-+ PlParam "redistribute" "ospf"
-+ PlParam "redistribute" "bgp"
-+ PlParam "ExportRoutes" "only"
-+ PlParam "Distance" "125"
-+ PlParam "Localpref" "false"
-+}
-+
-+
-+---------------------------------------------------------------------
-+EOF / 8.5.2006
-diff -Nur olsrd-0.4.10.orig/lib/quagga/src/olsrd_plugin.c olsrd-0.4.10/lib/quagga/src/olsrd_plugin.c
---- olsrd-0.4.10.orig/lib/quagga/src/olsrd_plugin.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/src/olsrd_plugin.c 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,107 @@
-+/***************************************************************************
-+ projekt : olsrd-quagga
-+ file : olsrd_plugin.c
-+ usage : olsrd-plugin-handler-stuff
-+ copyright : (C) 2006 by Immo 'FaUl' Wehrenberg
-+ e-mail : immo@chaostreff-dortmund.de
-+ ***************************************************************************/
-+
-+/***************************************************************************
-+ * *
-+ * This program is free software; you can redistribute it and/or modify *
-+ * it under the terms of the GNU General Public License version 2 as *
-+ * published by the Free Software Foundation. *
-+ * *
-+ ***************************************************************************/
-+
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include "olsrd_plugin.h"
-+#include "olsr.h"
-+#include "scheduler.h"
-+#include "defs.h"
-+#include "quagga.h"
-+#include "kernel_routes.h"
-+
-+#define PLUGIN_NAME "OLSRD quagga plugin"
-+#define PLUGIN_VERSION "0.2.2"
-+#define PLUGIN_AUTHOR "Immo 'FaUl' Wehrenberg"
-+#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION " by " PLUGIN_AUTHOR
-+
-+static void __attribute__ ((constructor)) my_init(void);
-+static void __attribute__ ((destructor)) my_fini(void);
-+static void redist_hna (void);
-+
-+
-+int olsrd_plugin_interface_version() {
-+ return OLSRD_PLUGIN_INTERFACE_VERSION;
-+}
-+
-+
-+int olsrd_plugin_register_param(char *key, char *value) {
-+ const char *zebra_route_types[] = {"system","kernel","connect","static",
-+ "rip","ripng","ospf","ospf6","isis",
-+ "bgp","hsls", NULL};
-+ unsigned char i = 0;
-+
-+ if(!strcmp(key, "redistribute")) {
-+ for (i = 0; zebra_route_types[i]; i++)
-+ if (!strcmp(value, zebra_route_types[i])) {
-+ zebra_redistribute(i);
-+ return 1;
-+ }
-+ }
-+ else if(!strcmp(key, "ExportRoutes")) {
-+ if (!strcmp(value, "only")) {
-+ if (!olsr_addroute_remove_function(&olsr_ioctl_add_route, AF_INET))
-+ puts ("AIII, could not remove the kernel route exporter");
-+ if (!olsr_delroute_remove_function(&olsr_ioctl_del_route, AF_INET))
-+ puts ("AIII, could not remove the kernel route deleter");
-+ olsr_addroute_add_function(&zebra_add_olsr_v4_route, AF_INET);
-+ olsr_delroute_add_function(&zebra_del_olsr_v4_route, AF_INET);
-+ return 1;
-+ }
-+ else if (!strcmp(value, "additional")) {
-+ olsr_addroute_add_function(&zebra_add_olsr_v4_route, AF_INET);
-+ olsr_delroute_add_function(&zebra_del_olsr_v4_route, AF_INET);
-+ return 1;
-+ }
-+ }
-+ else if (!strcmp(key, "Distance")) {
-+ unsigned int distance = atoi (key);
-+ if (distance < 255)
-+ zebra_olsr_distance(distance);
-+ return 1;
-+ }
-+
-+ else if (!strcmp(key, "LocalPref")) {
-+ if (!strcmp(key, "true"))
-+ zebra_olsr_localpref();
-+ else if (strcmp (key, "false"))
-+ return -1;
-+ return 1;
-+ }
-+ return -1;
-+}
-+
-+
-+int olsrd_plugin_init() {
-+ if(olsr_cnf->ip_version != AF_INET) {
-+ fputs("see the source - ipv4 so far not supportet\n" ,stderr);
-+ return 1;
-+ }
-+
-+ // olsr_register_timeout_function(&olsr_timeout);
-+ olsr_register_scheduler_event(&zebra_check, NULL, 1, 0, NULL);
-+ return 0;
-+}
-+
-+static void my_init(void) {
-+ init_zebra();
-+}
-+
-+static void my_fini(void) {
-+}
-+
-diff -Nur olsrd-0.4.10.orig/lib/quagga/src/quagga/zassert.h olsrd-0.4.10/lib/quagga/src/quagga/zassert.h
---- olsrd-0.4.10.orig/lib/quagga/src/quagga/zassert.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/src/quagga/zassert.h 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,27 @@
-+/*
-+ * $Id: zassert.h,v 1.2 2004/12/03 18:01:04 ajs Exp $
-+ */
-+
-+#ifndef _QUAGGA_ASSERT_H
-+#define _QUAGGA_ASSERT_H
-+
-+extern void _zlog_assert_failed (const char *assertion, const char *file,
-+ unsigned int line, const char *function)
-+ __attribute__ ((noreturn));
-+
-+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-+#define __ASSERT_FUNCTION __func__
-+#elif defined(__GNUC__)
-+#define __ASSERT_FUNCTION __FUNCTION__
-+#else
-+#define __ASSERT_FUNCTION NULL
-+#endif
-+
-+#define zassert(EX) ((void)((EX) ? 0 : \
-+ (_zlog_assert_failed(#EX, __FILE__, __LINE__, \
-+ __ASSERT_FUNCTION), 0)))
-+
-+#undef assert
-+#define assert(EX) zassert(EX)
-+
-+#endif /* _QUAGGA_ASSERT_H */
-diff -Nur olsrd-0.4.10.orig/lib/quagga/src/quagga/zebra.h olsrd-0.4.10/lib/quagga/src/quagga/zebra.h
---- olsrd-0.4.10.orig/lib/quagga/src/quagga/zebra.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/src/quagga/zebra.h 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,501 @@
-+/* Zebra common header.
-+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Kunihiro Ishiguro
-+
-+This file is part of GNU Zebra.
-+
-+GNU Zebra is free software; you can redistribute it and/or modify it
-+under the terms of the GNU General Public License as published by the
-+Free Software Foundation; either version 2, or (at your option) any
-+later version.
-+
-+GNU Zebra is distributed in the hope that it will be useful, but
-+WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GNU Zebra; see the file COPYING. If not, write to the Free
-+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA. */
-+
-+#ifndef _ZEBRA_H
-+#define _ZEBRA_H
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif /* HAVE_CONFIG_H */
-+
-+#ifdef SUNOS_5
-+#define _XPG4_2
-+#define __EXTENSIONS__
-+typedef unsigned int u_int32_t;
-+typedef unsigned short u_int16_t;
-+typedef unsigned char u_int8_t;
-+#endif /* SUNOS_5 */
-+
-+#ifndef HAVE_SOCKLEN_T
-+typedef int socklen_t;
-+#endif /* HAVE_SOCKLEN_T */
-+
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <ctype.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <signal.h>
-+#include <string.h>
-+#include <pwd.h>
-+#include <grp.h>
-+#ifdef HAVE_STROPTS_H
-+#include <stropts.h>
-+#endif /* HAVE_STROPTS_H */
-+#include <sys/fcntl.h>
-+#ifdef HAVE_SYS_SELECT_H
-+#include <sys/select.h>
-+#endif /* HAVE_SYS_SELECT_H */
-+#include <sys/stat.h>
-+#include <sys/time.h>
-+#include <sys/types.h>
-+#include <sys/param.h>
-+#ifdef HAVE_SYS_SYSCTL_H
-+#include <sys/sysctl.h>
-+#endif /* HAVE_SYS_SYSCTL_H */
-+#include <sys/ioctl.h>
-+#ifdef HAVE_SYS_CONF_H
-+#include <sys/conf.h>
-+#endif /* HAVE_SYS_CONF_H */
-+#ifdef HAVE_SYS_KSYM_H
-+#include <sys/ksym.h>
-+#endif /* HAVE_SYS_KSYM_H */
-+#include <syslog.h>
-+#include <time.h>
-+#include <sys/uio.h>
-+#include <sys/utsname.h>
-+#ifdef HAVE_RUSAGE
-+#include <sys/resource.h>
-+#endif /* HAVE_RUSAGE */
-+#ifdef HAVE_LIMITS_H
-+#include <limits.h>
-+#endif /* HAVE_LIMITS_H */
-+
-+/* machine dependent includes */
-+#ifdef SUNOS_5
-+#include <strings.h>
-+#endif /* SUNOS_5 */
-+
-+/* machine dependent includes */
-+#ifdef HAVE_LINUX_VERSION_H
-+#include <linux/version.h>
-+#endif /* HAVE_LINUX_VERSION_H */
-+
-+#ifdef HAVE_ASM_TYPES_H
-+#include <asm/types.h>
-+#endif /* HAVE_ASM_TYPES_H */
-+
-+/* misc include group */
-+#include <stdarg.h>
-+#if !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
-+/* Not C99; do we need to define va_copy? */
-+#ifndef va_copy
-+#ifdef __va_copy
-+#define va_copy(DST,SRC) __va_copy(DST,SRC)
-+#else
-+/* Now we are desperate; this should work on many typical platforms.
-+ But this is slightly dangerous, because the standard does not require
-+ va_copy to be a macro. */
-+#define va_copy(DST,SRC) memcpy(&(DST), &(SRC), sizeof(va_list))
-+#warning "Not C99 and no va_copy macro available, falling back to memcpy"
-+#endif /* __va_copy */
-+#endif /* !va_copy */
-+#endif /* !C99 */
-+
-+
-+#ifdef HAVE_LCAPS
-+#include <sys/capability.h>
-+#include <sys/prctl.h>
-+#endif /* HAVE_LCAPS */
-+
-+/* network include group */
-+
-+#include <sys/socket.h>
-+
-+#ifdef HAVE_SYS_SOCKIO_H
-+#include <sys/sockio.h>
-+#endif /* HAVE_SYS_SOCKIO_H */
-+
-+#ifdef HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif /* HAVE_NETINET_IN_H */
-+#include <netinet/in_systm.h>
-+#include <netinet/ip.h>
-+#include <netinet/tcp.h>
-+
-+#ifdef HAVE_NET_NETOPT_H
-+#include <net/netopt.h>
-+#endif /* HAVE_NET_NETOPT_H */
-+
-+#include <net/if.h>
-+
-+#ifdef HAVE_NET_IF_DL_H
-+#include <net/if_dl.h>
-+#endif /* HAVE_NET_IF_DL_H */
-+
-+#ifdef HAVE_NET_IF_VAR_H
-+#include <net/if_var.h>
-+#endif /* HAVE_NET_IF_VAR_H */
-+
-+#ifdef HAVE_NET_ROUTE_H
-+#include <net/route.h>
-+#endif /* HAVE_NET_ROUTE_H */
-+
-+#ifdef HAVE_NETLINK
-+#include <linux/netlink.h>
-+#include <linux/rtnetlink.h>
-+#else
-+#define RT_TABLE_MAIN 0
-+#endif /* HAVE_NETLINK */
-+
-+#ifdef HAVE_NETDB_H
-+#include <netdb.h>
-+#endif /* HAVE_NETDB_H */
-+
-+#include <arpa/inet.h>
-+#include <arpa/telnet.h>
-+
-+#ifdef HAVE_INET_ND_H
-+#include <inet/nd.h>
-+#endif /* HAVE_INET_ND_H */
-+
-+#ifdef HAVE_NETINET_IN_VAR_H
-+#include <netinet/in_var.h>
-+#endif /* HAVE_NETINET_IN_VAR_H */
-+
-+#ifdef HAVE_NETINET6_IN6_VAR_H
-+#include <netinet6/in6_var.h>
-+#endif /* HAVE_NETINET6_IN6_VAR_H */
-+
-+#ifdef HAVE_NETINET_IN6_VAR_H
-+#include <netinet/in6_var.h>
-+#endif /* HAVE_NETINET_IN6_VAR_H */
-+
-+#ifdef HAVE_NETINET6_IN_H
-+#include <netinet6/in.h>
-+#endif /* HAVE_NETINET6_IN_H */
-+
-+
-+#ifdef HAVE_NETINET6_IP6_H
-+#include <netinet6/ip6.h>
-+#endif /* HAVE_NETINET6_IP6_H */
-+
-+#ifdef HAVE_NETINET_ICMP6_H
-+#include <netinet/icmp6.h>
-+#endif /* HAVE_NETINET_ICMP6_H */
-+
-+#ifdef HAVE_NETINET6_ND6_H
-+#include <netinet6/nd6.h>
-+#endif /* HAVE_NETINET6_ND6_H */
-+
-+/* Some systems do not define UINT32_MAX */
-+#ifndef UINT32_MAX
-+#define UINT32_MAX 0xFFFFFFFFU
-+#endif /* UINT32_MAX */
-+
-+#ifdef HAVE_LIBUTIL_H
-+#include <libutil.h>
-+#endif /* HAVE_LIBUTIL_H */
-+
-+#ifdef HAVE_GLIBC_BACKTRACE
-+#include <execinfo.h>
-+#endif /* HAVE_GLIBC_BACKTRACE */
-+
-+#ifdef BSDI_NRL
-+
-+#ifdef HAVE_NETINET6_IN6_H
-+#include <netinet6/in6.h>
-+#endif /* HAVE_NETINET6_IN6_H */
-+
-+#ifdef NRL
-+#include <netinet6/in6.h>
-+#endif /* NRL */
-+
-+#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
-+
-+#endif /* BSDI_NRL */
-+
-+/* Local includes: */
-+#if !(defined(__GNUC__) || defined(VTYSH_EXTRACT_PL))
-+#define __attribute__(x)
-+#endif /* !__GNUC__ || VTYSH_EXTRACT_PL */
-+
-+#include "zassert.h"
-+
-+
-+#ifdef HAVE_BROKEN_CMSG_FIRSTHDR
-+/* This bug is present in Solaris 8 and pre-patch Solaris 9 <sys/socket.h>;
-+ please refer to http://bugzilla.quagga.net/show_bug.cgi?id=142 */
-+
-+/* Check that msg_controllen is large enough. */
-+#define ZCMSG_FIRSTHDR(mhdr) \
-+ (((size_t)((mhdr)->msg_controllen) >= sizeof(struct cmsghdr)) ? \
-+ CMSG_FIRSTHDR(mhdr) : (struct cmsghdr *)NULL)
-+
-+#warning "CMSG_FIRSTHDR is broken on this platform, using a workaround"
-+
-+#else /* HAVE_BROKEN_CMSG_FIRSTHDR */
-+#define ZCMSG_FIRSTHDR(M) CMSG_FIRSTHDR(M)
-+#endif /* HAVE_BROKEN_CMSG_FIRSTHDR */
-+
-+
-+
-+/*
-+ * RFC 3542 defines several macros for using struct cmsghdr.
-+ * Here, we define those that are not present
-+ */
-+
-+/*
-+ * Internal defines, for use only in this file.
-+ * These are likely wrong on other than ILP32 machines, so warn.
-+ */
-+#ifndef _CMSG_DATA_ALIGN
-+#define _CMSG_DATA_ALIGN(n) (((n) + 3) & ~3)
-+#endif /* _CMSG_DATA_ALIGN */
-+
-+#ifndef _CMSG_HDR_ALIGN
-+#define _CMSG_HDR_ALIGN(n) (((n) + 3) & ~3)
-+#endif /* _CMSG_HDR_ALIGN */
-+
-+/*
-+ * CMSG_SPACE and CMSG_LEN are required in RFC3542, but were new in that
-+ * version.
-+ */
-+#ifndef CMSG_SPACE
-+#define CMSG_SPACE(l) (_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)) + \
-+ _CMSG_HDR_ALIGN(l))
-+#warning "assuming 4-byte alignment for CMSG_SPACE"
-+#endif /* CMSG_SPACE */
-+
-+
-+#ifndef CMSG_LEN
-+#define CMSG_LEN(l) (_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)) + (l))
-+#warning "assuming 4-byte alignment for CMSG_LEN"
-+#endif /* CMSG_LEN */
-+
-+
-+/* The definition of struct in_pktinfo is missing in old version of
-+ GLIBC 2.1 (Redhat 6.1). */
-+#if defined (GNU_LINUX) && ! defined (HAVE_INPKTINFO)
-+struct in_pktinfo
-+{
-+ int ipi_ifindex;
-+ struct in_addr ipi_spec_dst;
-+ struct in_addr ipi_addr;
-+};
-+#endif
-+
-+/*
-+ * OSPF Fragmentation / fragmented writes
-+ *
-+ * ospfd can support writing fragmented packets, for cases where
-+ * kernel will not fragment IP_HDRINCL and/or multicast destined
-+ * packets (ie TTBOMK all kernels, BSD, SunOS, Linux). However,
-+ * SunOS, probably BSD too, clobber the user supplied IP ID and IP
-+ * flags fields, hence user-space fragmentation will not work.
-+ * Only Linux is known to leave IP header unmolested.
-+ * Further, fragmentation really should be done the kernel, which already
-+ * supports it, and which avoids nasty IP ID state problems.
-+ *
-+ * Fragmentation of OSPF packets can be required on networks with router
-+ * with many many interfaces active in one area, or on networks with links
-+ * with low MTUs.
-+ */
-+#ifdef GNU_LINUX
-+#define WANT_OSPF_WRITE_FRAGMENT
-+#endif
-+
-+/*
-+ * IP_HDRINCL / struct ip byte order
-+ *
-+ * Linux: network byte order
-+ * *BSD: network, except for length and offset. (cf Stevens)
-+ * SunOS: nominally as per BSD. but bug: network order on LE.
-+ * OpenBSD: network byte order, apart from older versions which are as per
-+ * *BSD
-+ */
-+#if defined(__NetBSD__) || defined(__FreeBSD__) \
-+ || (defined(__OpenBSD__) && (OpenBSD < 200311)) \
-+ || (defined(SUNOS_5) && defined(WORDS_BIGENDIAN))
-+#define HAVE_IP_HDRINCL_BSD_ORDER
-+#endif
-+
-+/* MAX / MIN are not commonly defined, but useful */
-+#ifndef MAX
-+#define MAX(a, b) ((a) > (b) ? (a) : (b))
-+#endif
-+#ifndef MIN
-+#define MIN(a, b) ((a) < (b) ? (a) : (b))
-+#endif
-+
-+/* For old definition. */
-+#ifndef IN6_ARE_ADDR_EQUAL
-+#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
-+#endif /* IN6_ARE_ADDR_EQUAL */
-+
-+/* Zebra message types. */
-+#define ZEBRA_INTERFACE_ADD 1
-+#define ZEBRA_INTERFACE_DELETE 2
-+#define ZEBRA_INTERFACE_ADDRESS_ADD 3
-+#define ZEBRA_INTERFACE_ADDRESS_DELETE 4
-+#define ZEBRA_INTERFACE_UP 5
-+#define ZEBRA_INTERFACE_DOWN 6
-+#define ZEBRA_IPV4_ROUTE_ADD 7
-+#define ZEBRA_IPV4_ROUTE_DELETE 8
-+#define ZEBRA_IPV6_ROUTE_ADD 9
-+#define ZEBRA_IPV6_ROUTE_DELETE 10
-+#define ZEBRA_REDISTRIBUTE_ADD 11
-+#define ZEBRA_REDISTRIBUTE_DELETE 12
-+#define ZEBRA_REDISTRIBUTE_DEFAULT_ADD 13
-+#define ZEBRA_REDISTRIBUTE_DEFAULT_DELETE 14
-+#define ZEBRA_IPV4_NEXTHOP_LOOKUP 15
-+#define ZEBRA_IPV6_NEXTHOP_LOOKUP 16
-+#define ZEBRA_IPV4_IMPORT_LOOKUP 17
-+#define ZEBRA_IPV6_IMPORT_LOOKUP 18
-+#define ZEBRA_INTERFACE_RENAME 19
-+#define ZEBRA_ROUTER_ID_ADD 20
-+#define ZEBRA_ROUTER_ID_DELETE 21
-+#define ZEBRA_ROUTER_ID_UPDATE 22
-+#define ZEBRA_MESSAGE_MAX 23
-+
-+/* Zebra route's types. */
-+#define ZEBRA_ROUTE_SYSTEM 0
-+#define ZEBRA_ROUTE_KERNEL 1
-+#define ZEBRA_ROUTE_CONNECT 2
-+#define ZEBRA_ROUTE_STATIC 3
-+#define ZEBRA_ROUTE_RIP 4
-+#define ZEBRA_ROUTE_RIPNG 5
-+#define ZEBRA_ROUTE_OSPF 6
-+#define ZEBRA_ROUTE_OSPF6 7
-+#define ZEBRA_ROUTE_ISIS 8
-+#define ZEBRA_ROUTE_BGP 9
-+#define ZEBRA_ROUTE_HSLS 10
-+#define ZEBRA_ROUTE_OLSR 11
-+#define ZEBRA_ROUTE_MAX 12
-+
-+/* Zebra's family types. */
-+#define ZEBRA_FAMILY_IPV4 1
-+#define ZEBRA_FAMILY_IPV6 2
-+#define ZEBRA_FAMILY_MAX 3
-+
-+/* Error codes of zebra. */
-+#define ZEBRA_ERR_RTEXIST -1
-+#define ZEBRA_ERR_RTUNREACH -2
-+#define ZEBRA_ERR_EPERM -3
-+#define ZEBRA_ERR_RTNOEXIST -4
-+
-+/* Zebra message flags */
-+#define ZEBRA_FLAG_INTERNAL 0x01
-+#define ZEBRA_FLAG_SELFROUTE 0x02
-+#define ZEBRA_FLAG_BLACKHOLE 0x04
-+#define ZEBRA_FLAG_IBGP 0x08
-+#define ZEBRA_FLAG_SELECTED 0x10
-+#define ZEBRA_FLAG_CHANGED 0x20
-+#define ZEBRA_FLAG_STATIC 0x40
-+#define ZEBRA_FLAG_REJECT 0x80
-+
-+/* Zebra nexthop flags. */
-+#define ZEBRA_NEXTHOP_IFINDEX 1
-+#define ZEBRA_NEXTHOP_IFNAME 2
-+#define ZEBRA_NEXTHOP_IPV4 3
-+#define ZEBRA_NEXTHOP_IPV4_IFINDEX 4
-+#define ZEBRA_NEXTHOP_IPV4_IFNAME 5
-+#define ZEBRA_NEXTHOP_IPV6 6
-+#define ZEBRA_NEXTHOP_IPV6_IFINDEX 7
-+#define ZEBRA_NEXTHOP_IPV6_IFNAME 8
-+#define ZEBRA_NEXTHOP_BLACKHOLE 9
-+
-+#ifndef INADDR_LOOPBACK
-+#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */
-+#endif
-+
-+/* Address family numbers from RFC1700. */
-+#define AFI_IP 1
-+#define AFI_IP6 2
-+#define AFI_MAX 3
-+
-+/* Subsequent Address Family Identifier. */
-+#define SAFI_UNICAST 1
-+#define SAFI_MULTICAST 2
-+#define SAFI_UNICAST_MULTICAST 3
-+#define SAFI_MPLS_VPN 4
-+#define SAFI_MAX 5
-+
-+/* Filter direction. */
-+#define FILTER_IN 0
-+#define FILTER_OUT 1
-+#define FILTER_MAX 2
-+
-+/* Default Administrative Distance of each protocol. */
-+#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
-+#define ZEBRA_CONNECT_DISTANCE_DEFAULT 0
-+#define ZEBRA_STATIC_DISTANCE_DEFAULT 1
-+#define ZEBRA_RIP_DISTANCE_DEFAULT 120
-+#define ZEBRA_RIPNG_DISTANCE_DEFAULT 120
-+#define ZEBRA_OSPF_DISTANCE_DEFAULT 110
-+#define ZEBRA_OSPF6_DISTANCE_DEFAULT 110
-+#define ZEBRA_ISIS_DISTANCE_DEFAULT 115
-+#define ZEBRA_IBGP_DISTANCE_DEFAULT 200
-+#define ZEBRA_EBGP_DISTANCE_DEFAULT 20
-+
-+/* Flag manipulation macros. */
-+#define CHECK_FLAG(V,F) ((V) & (F))
-+#define SET_FLAG(V,F) (V) = (V) | (F)
-+#define UNSET_FLAG(V,F) (V) = (V) & ~(F)
-+
-+/* AFI and SAFI type. */
-+typedef u_int16_t afi_t;
-+typedef u_int8_t safi_t;
-+
-+/* Zebra types. */
-+typedef u_int16_t zebra_size_t;
-+typedef u_int8_t zebra_command_t;
-+
-+/* FIFO -- first in first out structure and macros. */
-+struct fifo
-+{
-+ struct fifo *next;
-+ struct fifo *prev;
-+};
-+
-+#define FIFO_INIT(F) \
-+ do { \
-+ struct fifo *Xfifo = (struct fifo *)(F); \
-+ Xfifo->next = Xfifo->prev = Xfifo; \
-+ } while (0)
-+
-+#define FIFO_ADD(F,N) \
-+ do { \
-+ struct fifo *Xfifo = (struct fifo *)(F); \
-+ struct fifo *Xnode = (struct fifo *)(N); \
-+ Xnode->next = Xfifo; \
-+ Xnode->prev = Xfifo->prev; \
-+ Xfifo->prev = Xfifo->prev->next = Xnode; \
-+ } while (0)
-+
-+#define FIFO_DEL(N) \
-+ do { \
-+ struct fifo *Xnode = (struct fifo *)(N); \
-+ Xnode->prev->next = Xnode->next; \
-+ Xnode->next->prev = Xnode->prev; \
-+ } while (0)
-+
-+#define FIFO_HEAD(F) \
-+ ((((struct fifo *)(F))->next == (struct fifo *)(F)) \
-+ ? NULL : (F)->next)
-+
-+#define FIFO_EMPTY(F) \
-+ (((struct fifo *)(F))->next == (struct fifo *)(F))
-+
-+#define FIFO_TOP(F) \
-+ (FIFO_EMPTY(F) ? NULL : ((struct fifo *)(F))->next)
-+
-+#endif /* _ZEBRA_H */
-diff -Nur olsrd-0.4.10.orig/lib/quagga/src/quagga.c olsrd-0.4.10/lib/quagga/src/quagga.c
---- olsrd-0.4.10.orig/lib/quagga/src/quagga.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/src/quagga.c 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,870 @@
-+/***************************************************************************
-+ projekt : olsrd-quagga
-+ file : quagga.c
-+ usage : communication with the zebra-daemon
-+ copyright : (C) 2006 by Immo 'FaUl' Wehrenberg
-+ e-mail : immo@chaostreff-dortmund.de
-+ ***************************************************************************/
-+
-+/***************************************************************************
-+ * *
-+ * This program is free software; you can redistribute it and/or modify *
-+ * it under the terms of the GNU General Public License version 2 as *
-+ * published by the Free Software Foundation. *
-+ * *
-+ ***************************************************************************/
-+
-+
-+#ifdef MY_DEBUG
-+#include <stdio.h>
-+#endif
-+
-+#define HAVE_SOCKLEN_T
-+#include <quagga/zebra.h>
-+
-+#include <stdint.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include "quagga.h"
-+
-+#include "olsr.h"
-+#include "log.h"
-+#include "defs.h"
-+#include "local_hna_set.h"
-+
-+#ifdef USE_UNIX_DOMAIN_SOCKET
-+#include <sys/un.h>
-+#define ZEBRA_SOCKET "/var/run/quagga/zserv.api"
-+#endif
-+
-+#define ZAPI_MESSAGE_NEXTHOP 0x01
-+#define ZAPI_MESSAGE_IFINDEX 0x02
-+#define ZAPI_MESSAGE_DISTANCE 0x04
-+#define ZAPI_MESSAGE_METRIC 0x08
-+
-+#define BUFSIZE 1024
-+
-+#define STATUS_CONNECTED 1
-+
-+static struct {
-+ char status; // TODO: internal status
-+ int sock; // Socket to zebra...
-+ char redistribute[ZEBRA_ROUTE_MAX];
-+ char distance;
-+ char flags;
-+ struct ipv4_route *v4_rt; // routes currently exportet to zebra
-+} zebra;
-+
-+
-+/* prototypes intern */
-+static char *try_read (ssize_t *);
-+static char* zebra_route_packet (struct ipv4_route r, ssize_t *);
-+static int parse_interface_add (char *, size_t);
-+static int parse_interface_delete (char *, size_t);
-+static int parse_interface_up (char *, size_t);
-+static int parse_interface_down (char *, size_t);
-+static int parse_interface_address_add (char *, size_t);
-+static int parse_interface_address_delete (char *, size_t);
-+static int parse_ipv4_route (char *, size_t, struct ipv4_route *);
-+static int ipv4_route_add (char *, size_t);
-+static int ipv4_route_delete (char *, size_t);
-+static int parse_ipv6_route_add (char*, size_t);
-+static int zebra_reconnect (void);
-+static int zebra_connect (void);
-+static int add_v4_route_status (struct ipv4_route r);
-+static int del_v4_route_status (struct ipv4_route r);
-+static uint32_t prefixlentomask (uint8_t);
-+static void free_ipv4_route (struct ipv4_route);
-+static void update_olsr_zebra_routes (struct ipv4_route*, struct ipv4_route*);
-+static struct ipv4_route *zebra_create_ipv4_route_table_entry (uint32_t,
-+ uint32_t,
-+ uint32_t);
-+static struct ipv4_route *zebra_create_ipv4_route_table (void);
-+static void zebra_free_ipv4_route_table (struct ipv4_route*);
-+static uint8_t masktoprefixlen (uint32_t);
-+
-+
-+
-+#ifdef MY_DEBUG
-+static void dump_ipv4_route (struct ipv4_route r, char *c) {
-+ int i = 0, x = 0;
-+
-+ puts (c);
-+ printf("type: %d\n", r.type);
-+ puts("flags:");
-+ printf(" Internal: %s\n",r.flags&ZEBRA_FLAG_INTERNAL?"yes":"no");
-+ printf(" Selfroute %s\n",r.flags&ZEBRA_FLAG_SELFROUTE?"yes":"no");
-+ printf(" Blackhole %s\n",r.flags&ZEBRA_FLAG_BLACKHOLE?"yes":"no");
-+ printf(" IBGP: %s\n",r.flags&ZEBRA_FLAG_IBGP?"yes":"no");
-+ printf(" Selected: %s\n",r.flags&ZEBRA_FLAG_SELECTED?"yes":"no");
-+ printf(" Changed: %s\n",r.flags&ZEBRA_FLAG_CHANGED?"yes":"no");
-+ printf(" static: %s\n",r.flags&ZEBRA_FLAG_STATIC?"yes":"no");
-+ printf(" reject: %s\n",r.flags&ZEBRA_FLAG_REJECT?"yes":"no");
-+ puts("message:");
-+ printf(" nexthop: %s\n",r.message&ZAPI_MESSAGE_NEXTHOP?"yes":"no");
-+ printf(" ifindex: %s\n",r.message&ZAPI_MESSAGE_IFINDEX?"yes":"no");
-+ printf(" distance: %s\n",r.message&ZAPI_MESSAGE_DISTANCE?"yes":"no");
-+ printf(" metric: %s\n",r.message&ZAPI_MESSAGE_METRIC?"yes":"no");
-+ printf("Prefixlen: %d\n", r.prefixlen);
-+ printf("Prefix: %d", (unsigned char)r.prefix);
-+ c = (char*) &r.prefix;
-+ while (++i < (r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0)))
-+ printf(".%d",(unsigned char)*(c + i));
-+ while (i++ < 4)
-+ printf(".0");
-+ puts("");
-+ i=0;
-+ if (r.message&ZAPI_MESSAGE_NEXTHOP) {
-+ printf("nexthop-count: %d\n", r.nh_count);
-+ while (i++ < r.nh_count) {
-+ if (r.nexthops[i].type == ZEBRA_NEXTHOP_IPV4) {
-+ c = (unsigned char*) &r.nexthops[i].payload.v4;
-+ printf ("Nexthop %d: %d", i, (unsigned char) *c);
-+ while (++x < 4) {
-+ printf (".%d", (unsigned char) c[x]);
-+ }
-+ puts("");
-+ }
-+ }
-+ i=0;
-+ }
-+ if (r.message&ZAPI_MESSAGE_IFINDEX) {
-+
-+ printf("index-number: %d\n", r.ind_num);
-+ while (i++ < r.ind_num)
-+ printf("Index: %d: %d\n", i, r.index[i]);
-+ i=0;
-+ if (r.message&ZAPI_MESSAGE_DISTANCE)
-+ printf("Distance: %d\n",r.distance);
-+ if (r.message&ZAPI_MESSAGE_METRIC)
-+ printf("Metric: %d\n",r.metric);
-+ puts("\n");
-+ }
-+}
-+#endif
-+
-+void *my_realloc (void *buf, size_t s, const char *c) {
-+ buf = realloc (buf, s);
-+ if (!buf) {
-+ OLSR_PRINTF (1, "OUT OF MEMORY: %s\n", strerror(errno));
-+ olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n");
-+ olsr_exit(c, EXIT_FAILURE);
-+ }
-+ return buf;
-+}
-+
-+int init_zebra () {
-+ if (!zebra_connect()) {
-+ olsr_exit ("AIIIII, could not connect to zebra! is zebra running?",
-+ EXIT_FAILURE);
-+ }
-+}
-+
-+
-+static int zebra_reconnect (void) {
-+ struct ipv4_route *tmp;
-+ int i;
-+
-+ if (!zebra_connect())
-+ // log: zebra-reconnect failed
-+ ;
-+ for (i = 0; ZEBRA_ROUTE_MAX - 1; i++)
-+ if (zebra.redistribute[i]) zebra_redistribute(i + 1);
-+
-+ for (tmp = zebra.v4_rt; tmp; tmp = tmp->next)
-+ zebra_add_v4_route(*tmp);
-+}
-+
-+
-+static int add_v4_route_status (struct ipv4_route r) {
-+
-+ struct ipv4_route *tmp = olsr_malloc (sizeof r, "quagga_v4_route_status");
-+ memcpy (tmp, &r, sizeof r);
-+
-+ if (r.message & ZAPI_MESSAGE_NEXTHOP) {
-+ tmp->nexthops = olsr_malloc (r.nh_count * sizeof tmp->nexthops,
-+ "quagga_v4_route_status");
-+ memcpy (tmp->nexthops, &r.nexthops, sizeof *r.nexthops);
-+ }
-+
-+ if (r.message & ZAPI_MESSAGE_IFINDEX) {
-+ tmp->index = olsr_malloc (r.ind_num * sizeof *tmp->index,
-+ "quagga_v4_route_status");
-+ memcpy (tmp->index, &r.index, r.ind_num * sizeof *tmp->index);
-+ }
-+
-+ tmp->next = zebra.v4_rt;
-+ zebra.v4_rt = tmp;
-+
-+ return 0;
-+
-+}
-+
-+
-+static int cmp_v4_route (struct ipv4_route a, struct ipv4_route b) {
-+ if (a.type != b.type) return 1;
-+ if (a.flags != b.flags) return 1;
-+ if (a.message != b.message) return 1;
-+ if (a.prefixlen != b.prefixlen) return 1;
-+ if (a.message & ZAPI_MESSAGE_NEXTHOP) {
-+ if (a.nh_count != b.nh_count) return 1;
-+ if (memcmp (a.nexthops, b.nexthops, a.nh_count * sizeof *b.nexthops))
-+ return 1;
-+ }
-+ if (a.message & ZAPI_MESSAGE_IFINDEX) {
-+ if (a.ind_num != b.ind_num) return 1;
-+ if (memcpy (a.index, b.index, a.ind_num * sizeof *a.index)) return 1;
-+ }
-+ if (a.message & ZAPI_MESSAGE_DISTANCE)
-+ if (a.distance != b.distance) return 1;
-+ if (a.message & ZAPI_MESSAGE_METRIC)
-+ if (a.metric != b.metric) return 1;
-+ return 0;
-+}
-+
-+static int del_v4_route_status (struct ipv4_route r) {
-+
-+ struct ipv4_route *tmp, *prv = 0;
-+
-+ for (tmp = zebra.v4_rt; tmp; tmp = tmp->next) {
-+ if (!cmp_v4_route(*tmp, r)) {
-+ if (prv) prv->next = tmp->next;
-+
-+ free_ipv4_route(*tmp);
-+ free (tmp);
-+
-+ return 0;
-+
-+ }
-+ prv = tmp;
-+ }
-+
-+ return 1;
-+}
-+
-+
-+/* Connect to the zebra-daemon, returns a socket */
-+static int zebra_connect (void) {
-+
-+#ifndef USE_UNIX_DOMAIN_SOCKET
-+ struct sockaddr_in i;
-+ close (zebra.sock);
-+
-+ zebra.sock = socket (AF_INET,SOCK_STREAM, 0);
-+#else
-+ struct sockaddr_un i;
-+ close (zebra.sock);
-+
-+ zebra.sock = socket (AF_UNIX,SOCK_STREAM, 0);
-+#endif
-+
-+ int ret;
-+
-+ if (zebra.sock <0 )
-+ olsr_exit("could not create socket!", EXIT_FAILURE);
-+
-+ memset (&i, 0, sizeof i);
-+#ifndef USE_UNIX_DOMAIN_SOCKET
-+ i.sin_family = AF_INET;
-+ i.sin_port = htons (ZEBRA_PORT);
-+ i.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-+#else
-+ i.sun_family = AF_UNIX;
-+ strcpy (i.sun_path, ZEBRA_SOCKET);
-+#endif
-+
-+ ret = connect (zebra.sock, (struct sockaddr *)&i, sizeof i);
-+ if (ret < 0) {
-+ close (zebra.sock);
-+ }
-+ else zebra.status |= STATUS_CONNECTED;
-+ return zebra.sock;
-+}
-+
-+
-+/* Sends a command to zebra, command is
-+ the command defined in zebra.h, options is the packet-payload,
-+ optlen the length, of the payload */
-+char zebra_send_command (unsigned char command, char * options, int optlen) {
-+
-+#ifdef ZEBRA_HEADER_MARKER
-+ char *p = olsr_malloc (optlen + 6, "zebra_send_command");
-+ uint16_t length = optlen + 6; /* length of option + command + packet_length +
-+ marker + zserv-version */
-+ uint16_t cmd;
-+#else
-+ char *p = olsr_malloc (optlen + 3, "zebra_send_command");
-+ uint16_t length = optlen + 3; // length of option + command + packet_length
-+#endif
-+
-+ int ret;
-+
-+ uint16_t len = htons(length);
-+ memcpy (p, &len, 2);
-+
-+#ifdef ZEBRA_HEADER_MARKER
-+ p[2] = ZEBRA_HEADER_MARKER;
-+ p[3] = ZSERV_VERSION;
-+ cmd = htons (command);
-+ memcpy (p + 4, &cmd, 2);
-+ memcpy (p + 6, options, optlen);
-+#else
-+ p[2] = command;
-+ memcpy (p + 3, options, optlen);
-+#endif
-+
-+ errno = 0;
-+
-+ do {
-+ ret = write (zebra.sock, p, length);
-+ if (ret < 0) {
-+ if (errno == EINTR) {
-+ errno = 0;
-+ continue;
-+ }
-+ else {
-+ zebra.status &= ~STATUS_CONNECTED;
-+ return -1;
-+ }
-+ }
-+ p = p+ret;
-+ } while ((length -= ret));
-+
-+ return 0;
-+}
-+
-+
-+/* Creates a Route-Packet-Payload, needs address, netmask, nexthop,
-+ distance, and a pointer of an size_t */
-+static char* zebra_route_packet (struct ipv4_route r, ssize_t *optlen) {
-+
-+ int count;
-+
-+ char *cmdopt, *t;
-+ *optlen = 4; // first: type, flags, message, prefixlen
-+ *optlen += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0); // + prefix
-+ if (r.message & ZAPI_MESSAGE_NEXTHOP)
-+ if (r.nexthops->type == ZEBRA_NEXTHOP_IPV4
-+ || r.nexthops->type == ZEBRA_NEXTHOP_IPV4_IFINDEX){
-+ *optlen += (sizeof r.nexthops->payload.v4
-+ + sizeof r.nexthops->type) * r.nh_count + 1;
-+ }
-+ else if (r.nexthops->type == 0)
-+ *optlen += 5;
-+ if (r.message & ZAPI_MESSAGE_IFINDEX)
-+ *optlen += r.ind_num * sizeof *r.index + 1;
-+ if (r.message & ZAPI_MESSAGE_DISTANCE)
-+ *optlen++;
-+ if (r.message & ZAPI_MESSAGE_METRIC)
-+ *optlen += sizeof r.metric;
-+
-+ cmdopt = olsr_malloc (*optlen, "zebra add_v4_route");
-+
-+ t = cmdopt;
-+ *t++ = r.type;
-+ *t++ = r.flags;
-+ *t++ = r.message;
-+ *t++ = r.prefixlen;
-+ for (count = 0; count < r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0); count++) {
-+ *t++ = *((char*)&r.prefix + count); /* this is so sick!! */
-+ }
-+
-+ if (r.message & ZAPI_MESSAGE_NEXTHOP) {
-+ *t++ = r.nh_count;
-+ *t++ = r.nexthops->type;
-+ if (r.nexthops->type == ZEBRA_NEXTHOP_IPV4 ||
-+ r.nexthops->type == ZEBRA_NEXTHOP_IPV4_IFINDEX) {
-+ for (count = 0; count != r.nh_count; count++) {
-+ memcpy (t, &r.nexthops[count].payload.v4,
-+ sizeof r.nexthops->payload.v4);
-+ t += sizeof r.nexthops->payload.v4;
-+ }
-+ }
-+ else if (r.nexthops->type == 0) {
-+ *t++ = 0;
-+ *t++ = 0;
-+ *t++ = 0;
-+ }
-+ }
-+ if (r.message & ZAPI_MESSAGE_IFINDEX) {
-+ *t++ = r.ind_num;
-+ memcpy (t, r.index, sizeof *r.index * r.ind_num);
-+ t += sizeof r.index * r.ind_num;
-+ }
-+ if (r.message & ZAPI_MESSAGE_METRIC) {
-+ memcpy (t, &r.metric, sizeof r.metric);
-+ t += sizeof r.metric;
-+ }
-+ if (r.message & ZAPI_MESSAGE_DISTANCE)
-+ *t++ = r.distance;
-+ return cmdopt;
-+}
-+
-+
-+/* adds a route to zebra-daemon */
-+int zebra_add_v4_route (struct ipv4_route r) {
-+
-+ char *cmdopt;
-+ ssize_t optlen;
-+ int retval;
-+
-+ cmdopt = zebra_route_packet (r, &optlen);
-+
-+ retval = zebra_send_command (ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);
-+ free (cmdopt);
-+ return retval;
-+
-+}
-+
-+/* deletes a route from the zebra-daemon */
-+int zebra_delete_v4_route (struct ipv4_route r) {
-+
-+ char *cmdopt;
-+ ssize_t optlen;
-+ int retval;
-+
-+ cmdopt = zebra_route_packet (r, &optlen);
-+
-+ retval = zebra_send_command (ZEBRA_IPV4_ROUTE_DELETE, cmdopt, optlen);
-+ free (cmdopt);
-+
-+ return retval;
-+
-+}
-+
-+
-+/* Check wether there is data from zebra aviable */
-+void zebra_check (void* foo) {
-+ char *data, *f;
-+ ssize_t len, ret;
-+
-+ if (!(zebra.status & STATUS_CONNECTED)) {
-+ if (!zebra_reconnect()) return;
-+ }
-+ data = try_read (&len);
-+ if (data) {
-+ f = data;
-+ do {
-+ ret = zebra_parse_packet (f, len);
-+ if (!ret) {//something wired happened
-+ puts ("DEBUG: IIIIIIIIIIRGS");
-+ exit (EXIT_FAILURE);
-+ }
-+ f += ret;
-+ } while ((f - data) < len);
-+ free (data);
-+ }
-+}
-+
-+
-+// tries to read a packet from zebra_socket
-+// if there is something to read - make sure to read whole packages
-+static char *try_read (ssize_t *len) {
-+ char *buf = NULL;
-+ ssize_t ret = 0, bsize = 0;
-+ uint16_t length = 0, l = 0;
-+ int sockstate;
-+
-+ *len = 0;
-+
-+ sockstate = fcntl (zebra.sock, F_GETFL, 0);
-+ fcntl (zebra.sock, F_SETFL, sockstate|O_NONBLOCK);
-+
-+ do {
-+ if (*len == bsize) {
-+ bsize += BUFSIZE;
-+ buf = my_realloc (buf, bsize, "Zebra try_read");
-+ }
-+ ret = read (zebra.sock, buf + l, bsize - l);
-+ if (ret <= 0) {
-+ if (errno == EAGAIN) {
-+ errno = 0;
-+ }
-+ else {
-+ olsr_printf(1, "OOPS, something realy wired happened:"
-+ "read returned %s\n", strerror(errno));
-+ errno = 0;
-+ zebra.status &= ~STATUS_CONNECTED;
-+ return 0;
-+ }
-+ free (buf);
-+ return NULL;
-+ }
-+ *len += ret;
-+
-+ while ((*len - l) > length) {
-+ l += length;
-+ memcpy (&length, buf + l, 2);
-+ length = ntohs (length);
-+ }
-+ if (((*len) - l) == length) break; // GOT FULL PACKAGE!!
-+ if (*len < l) {
-+ fcntl (zebra.sock, F_SETFL, sockstate);
-+ continue;
-+ }
-+ } while (1);
-+
-+ fcntl (zebra.sock, F_SETFL, sockstate);
-+ return buf;
-+}
-+
-+
-+/* Parse a packet recived from zebra */
-+int zebra_parse_packet (char *packet, ssize_t maxlen) {
-+
-+ /* Array of functions */
-+ int (*foo[ZEBRA_MESSAGE_MAX]) (char *, size_t) = {
-+ parse_interface_add,
-+ parse_interface_delete,
-+ parse_interface_address_add,
-+ parse_interface_address_delete,
-+ parse_interface_up,
-+ parse_interface_down,
-+ ipv4_route_add,
-+ ipv4_route_delete,
-+ parse_ipv6_route_add
-+ };
-+
-+#ifdef MY_DEBUG
-+ puts ("DEBUG: zebra_parse_packet");
-+#endif
-+ uint16_t length;
-+
-+ int ret;
-+ memcpy (&length, packet, 2);
-+ length = ntohs (length);
-+
-+ if (maxlen < length) {
-+ puts("Error: programmer is an idiot");
-+ printf ("DEBUG: maxlen = %d, packet_length = %d\n", maxlen, length);
-+ return maxlen;
-+ }
-+
-+ if (packet[2] - 1 < ZEBRA_MESSAGE_MAX && foo[packet[2] - 1]) {
-+ if (!(ret = foo[packet[2] - 1] (packet + 3, length - 3)))
-+ return length;
-+ else printf ("DEBUG: Parse error: %d\n", ret);
-+ }
-+ else
-+ printf ("Unknown packet type: %d\n", packet[2]);
-+
-+ puts ("Quagga: RECIVED PACKET FROM ZEBRA THAT I CAN'T PARSE");
-+
-+ return length;
-+}
-+
-+
-+static int parse_interface_add (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+static int parse_interface_delete (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+static int parse_interface_address_add (char *opt, size_t len) {
-+
-+ //todo
-+ return 0;
-+}
-+
-+static int parse_interface_up (char *opt, size_t len) {
-+
-+ //todo
-+ return 0;
-+}
-+
-+static int parse_interface_down (char *opt, size_t len) {
-+
-+ //todo
-+ return 0;
-+}
-+
-+
-+static int parse_interface_address_delete (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+/* Parse an ipv4-route-packet recived from zebra
-+ */
-+static int parse_ipv4_route (char *opt, size_t len, struct ipv4_route *r) {
-+ int c;
-+
-+ if (len < 4) return -1;
-+
-+ r->type = *opt++;
-+ r->flags = *opt++;
-+ r->message = *opt++;
-+ r->prefixlen = *opt++;
-+ len -= 4;
-+ r->prefix = 0;
-+
-+ if ((int)len < r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0)) return -1;
-+
-+ memcpy (&r->prefix, opt, r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0));
-+ opt += r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0);
-+
-+ if (r->message & ZAPI_MESSAGE_NEXTHOP) {
-+ if (len < 1) return -1;
-+ r->nh_count = *opt++;
-+ len--;
-+ if (len < (sizeof (uint32_t) + 1) * r->nh_count) return -1;
-+ r->nexthops = olsr_malloc ((sizeof r->nexthops->type +
-+ sizeof r->nexthops->payload) * r->nh_count,
-+ "quagga: parse_ipv4_route_add");
-+ for (c = 0; c < r->nh_count; c++) {
-+ r->nexthops[c].type = *opt++;
-+ memcpy (&r->nexthops[c].payload.v4, opt, sizeof (uint32_t));
-+ opt += sizeof (uint32_t);
-+ len -= sizeof (uint32_t) + 1;
-+ }
-+ }
-+
-+ if (r->message & ZAPI_MESSAGE_IFINDEX) {
-+ if (len < 1) return -1;
-+ r->ind_num = *opt++;
-+ if (len < sizeof (uint32_t) * r->ind_num) return -1;
-+ r->index = olsr_malloc (sizeof (uint32_t) * r->ind_num,
-+ "quagga: parse_ipv4_route_add");
-+ memcpy (r->index, opt, r->ind_num * sizeof (uint32_t));
-+ opt += sizeof (uint32_t) * r->ind_num;
-+ len -= sizeof (uint32_t) * r->ind_num;
-+ }
-+
-+ if (r->message & ZAPI_MESSAGE_DISTANCE) {
-+ if (len < 1) return -1;
-+ r->distance = *opt++;
-+ len--;
-+ }
-+
-+ if (r->message & ZAPI_MESSAGE_METRIC) {
-+ if (len < sizeof (uint32_t)) return -1;
-+ memcpy (&r->metric, opt, sizeof (uint32_t));
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int ipv4_route_add (char *opt, size_t len) {
-+
-+ struct ipv4_route r;
-+ int f;
-+
-+ f = parse_ipv4_route (opt, len, &r);
-+ if (f < 0) {
-+ printf ("parse-error: %d\n",f);
-+ return f;
-+ }
-+
-+ add_hna4_route (r);
-+ return 0;
-+}
-+
-+static int ipv4_route_delete (char *opt, size_t len) {
-+ struct ipv4_route r;
-+ int f;
-+
-+ f = parse_ipv4_route (opt, len, &r);
-+ if (f < 0) return f;
-+
-+ return delete_hna4_route (r);
-+
-+}
-+
-+static int parse_ipv6_route_add (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+/* start redistribution FROM zebra */
-+int zebra_redistribute (unsigned char type) {
-+
-+ if (type > ZEBRA_ROUTE_MAX) return -1;
-+ zebra.redistribute[type - 1] = 1;
-+
-+ return zebra_send_command (ZEBRA_REDISTRIBUTE_ADD, &type, 1);
-+
-+
-+}
-+
-+
-+/* end redistribution FROM zebra */
-+int zebra_disable_redistribute (unsigned char type) {
-+
-+ if (type > ZEBRA_ROUTE_MAX) return -1;
-+ zebra.redistribute[type - 1] = 0;
-+
-+ return zebra_send_command (ZEBRA_REDISTRIBUTE_DELETE, &type, 1);
-+
-+}
-+
-+static uint32_t prefixlentomask (uint8_t prefix) {
-+ uint32_t mask = 0;
-+
-+ if (prefix) {
-+ mask = 0xffffffff<<(32-prefix);
-+ mask = ntohl(mask);
-+ }
-+
-+ return mask;
-+}
-+
-+int add_hna4_route (struct ipv4_route r) {
-+ union olsr_ip_addr net, mask;
-+
-+#ifdef MY_DEBUG
-+ dump_ipv4_route(r, "add_hna4_route");
-+#endif
-+
-+ mask.v4 = prefixlentomask(r.prefixlen);
-+ net.v4 = r.prefix;
-+
-+ add_local_hna4_entry(&net, &mask);
-+ free_ipv4_route(r);
-+ return 0;
-+}
-+
-+int delete_hna4_route (struct ipv4_route r) {
-+
-+ union olsr_ip_addr net, mask;
-+
-+#ifdef MY_DEBUG
-+ dump_ipv4_route(r, "delete_hna4_route");
-+#endif
-+
-+ mask.v4 = prefixlentomask(r.prefixlen);
-+ net.v4 = r.prefix;
-+
-+ remove_local_hna4_entry(&net, &mask) ? 0 : -1;
-+ free_ipv4_route(r);
-+ return 0;
-+
-+}
-+
-+static void free_ipv4_route (struct ipv4_route r) {
-+
-+ if(r.message&ZAPI_MESSAGE_IFINDEX && r.ind_num) free(r.index);
-+ if(r.message&ZAPI_MESSAGE_NEXTHOP && r.nh_count) free(r.nexthops);
-+
-+}
-+
-+static uint8_t masktoprefixlen (uint32_t mask) {
-+
-+ uint8_t prefixlen = 0;
-+
-+ mask = htonl (mask);
-+
-+ if (mask) while (mask << ++prefixlen && prefixlen < 32);
-+
-+ return prefixlen;
-+
-+}
-+
-+int zebra_add_olsr_v4_route (struct rt_entry *r) {
-+
-+ struct ipv4_route route;
-+ int retval;
-+
-+ route.type = ZEBRA_ROUTE_OLSR; // OLSR
-+ route.message = ZAPI_MESSAGE_METRIC;
-+ route.flags = zebra.flags;
-+ route.prefixlen = masktoprefixlen (r->rt_mask.v4);
-+ route.prefix = r->rt_dst.v4;
-+ if ((r->rt_router.v4 == r->rt_dst.v4 && route.prefixlen == 32)){
-+ route.message |= ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_NEXTHOP;
-+ route.ind_num = 1;
-+ route.index = olsr_malloc (sizeof *route.index,
-+ "zebra_add_olsr_v4_route");
-+ *route.index = htonl(r->rt_if->if_index);
-+ route.nexthops = olsr_malloc (sizeof route.nexthops->type +
-+ sizeof route.nexthops->payload,
-+ "zebra_add_olsr_v4_route");
-+ route.nh_count = 1;
-+ route.nexthops->type = 0;
-+ }
-+ else {
-+ route.message |= ZAPI_MESSAGE_NEXTHOP;
-+ route.nh_count = 1;
-+ route.nexthops = olsr_malloc (route.nh_count *
-+ (sizeof route.nexthops->type +
-+ sizeof route.nexthops->payload),
-+ "zebra_add_olsr_v4_route");
-+ route.nexthops->type = ZEBRA_NEXTHOP_IPV4;
-+ route.nexthops->payload.v4 = r->rt_router.v4;
-+ }
-+
-+ route.metric = r->rt_metric;
-+ route.metric = htonl(route.metric);
-+
-+ if (zebra.distance) {
-+ route.message |= ZAPI_MESSAGE_DISTANCE;
-+ route.distance = zebra.distance;
-+ }
-+
-+ add_v4_route_status (route);
-+ retval = zebra_add_v4_route(route);
-+ free_ipv4_route (route);
-+ return retval;
-+}
-+
-+int zebra_del_olsr_v4_route (struct rt_entry *r) {
-+
-+ struct ipv4_route route;
-+ int retval;
-+ route.type = ZEBRA_ROUTE_OLSR; // OLSR
-+ route.message = ZAPI_MESSAGE_METRIC;
-+ route.flags = zebra.flags;
-+ route.prefixlen = masktoprefixlen (r->rt_mask.v4);
-+ route.prefix = r->rt_dst.v4;
-+ if ((r->rt_router.v4 == r->rt_dst.v4 && route.prefixlen == 32)){
-+ route.message |= ZAPI_MESSAGE_IFINDEX;
-+ route.ind_num = 1;
-+ route.index = olsr_malloc (sizeof *route.index,
-+ "zebra_add_olsr_v4_route");
-+ *route.index = htonl (r->rt_if->if_index);
-+ route.nexthops = olsr_malloc (sizeof route.nexthops->type +
-+ sizeof route.nexthops->payload,
-+ "zebra_add_olsr_v4_route");
-+ route.nh_count = 1;
-+ route.nexthops->type = 0;
-+ }
-+ else {
-+ route.message |= ZAPI_MESSAGE_NEXTHOP;
-+ route.nh_count = 1;
-+ route.nexthops = olsr_malloc (route.nh_count *
-+ (sizeof route.nexthops->type +
-+ sizeof route.nexthops->payload),
-+ "zebra_add_olsr_v4_route");
-+ route.nexthops->type = ZEBRA_NEXTHOP_IPV4;
-+ route.nexthops->payload.v4 = r->rt_router.v4;
-+ }
-+ route.metric = r->rt_metric;
-+ route.metric = htonl (route.metric);
-+
-+ if (zebra.distance) {
-+ route.message |= ZAPI_MESSAGE_DISTANCE;
-+ route.distance = zebra.distance;
-+ }
-+
-+ retval = zebra_delete_v4_route(route);
-+ del_v4_route_status(route);
-+ free_ipv4_route (route);
-+ return retval;
-+}
-+
-+void zebra_olsr_distance (char dist) {
-+ zebra.distance = dist;
-+}
-+
-+void zebra_olsr_localpref (void) {
-+ zebra.flags &= ZEBRA_FLAG_SELECTED;
-+}
-diff -Nur olsrd-0.4.10.orig/lib/quagga/src/quagga.h olsrd-0.4.10/lib/quagga/src/quagga.h
---- olsrd-0.4.10.orig/lib/quagga/src/quagga.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/src/quagga.h 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,68 @@
-+/***************************************************************************
-+ projekt : olsrd-quagga
-+ file : quagga.h
-+ usage : header for quagga.c
-+ copyright : (C) 2006 by Immo 'FaUl' Wehrenberg
-+ e-mail : immo@chaostreff-dortmund.de
-+ ***************************************************************************/
-+
-+/***************************************************************************
-+ * *
-+ * This program is free software; you can redistribute it and/or modify *
-+ * it under the terms of the GNU General Public License version 2 as *
-+ * published by the Free Software Foundation. *
-+ * *
-+ ***************************************************************************/
-+
-+#include <stdint.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include "routing_table.h"
-+#define HAVE_SOCKLEN_T
-+#include <quagga/zebra.h>
-+
-+#ifndef ZEBRA_PORT
-+#define ZEBRA_PORT 2600
-+#endif
-+
-+#ifdef ZEBRA_HEADER_MARKER
-+#ifndef ZSERV_VERSION
-+#define ZSERV_VERSION 1
-+#endif
-+#endif
-+
-+struct ipv4_route {
-+ uint8_t type;
-+ uint8_t flags;
-+ uint8_t message;
-+ uint8_t prefixlen;
-+ uint32_t prefix;
-+ uint8_t nh_count;
-+ struct {
-+ uint8_t type;
-+ union {
-+ uint32_t v4;
-+ } payload;
-+ } *nexthops;
-+ uint8_t ind_num;
-+ uint32_t *index;
-+ uint32_t metric;
-+ uint32_t distance;
-+ struct ipv4_route *next;
-+};
-+
-+int init_zebra (void);
-+char zebra_send_command (unsigned char, char *, int );
-+int zebra_add_v4_route (struct ipv4_route r);
-+int zebra_delete_v4_route (struct ipv4_route r);
-+void zebra_check (void*);
-+int zebra_parse_packet (char*, ssize_t);
-+int zebra_redistribute (unsigned char);
-+int zebra_disable_redistribute (unsigned char);
-+int add_hna4_route (struct ipv4_route);
-+int delete_hna4_route (struct ipv4_route);
-+void *my_realloc (void *, size_t, const char*);
-+int zebra_add_olsr_v4_route (struct rt_entry*);
-+int zebra_del_olsr_v4_route (struct rt_entry*);
-+void zebra_olsr_localpref(void);
-+void zebra_olsr_distance(char);
-diff -Nur olsrd-0.4.10.orig/lib/quagga/test/foo.c olsrd-0.4.10/lib/quagga/test/foo.c
---- olsrd-0.4.10.orig/lib/quagga/test/foo.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/test/foo.c 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,10 @@
-+#include "quagga.h"
-+
-+int main (void) {
-+
-+ init_zebra();
-+ zebra_redistribute (2);
-+ // zebra_redistribute (1);
-+ while (!sleep (1)) zebra_check();
-+ return 0;
-+}
-diff -Nur olsrd-0.4.10.orig/lib/quagga/test/foo.pl olsrd-0.4.10/lib/quagga/test/foo.pl
---- olsrd-0.4.10.orig/lib/quagga/test/foo.pl 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/test/foo.pl 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,19 @@
-+#!/usr/bin/perl
-+
-+use IO::Socket;
-+
-+$command = 11; # 11 = redistribute_add , 13 = redistribute_default_add
-+
-+$proto = 2; # connected
-+
-+$remote = IO::Socket::INET->new (Proto => "tcp",
-+ PeerAddr => "127.0.0.1",
-+ PeerPort => "2600",
-+ );
-+$remote->autoflush (1);
-+#print $remote pack ("nc", 3, 13);
-+print $remote pack ("nc",3,1);
-+print $remote pack ("ncc", 4,$command,2);
-+print $remote pack ("ncccccNcNcNN", 25, 7, 10, 16, 11, 25, 0xc0a80206, 0, 0, 1, 5, 1);
-+print <$remote>;
-+close $remote
-diff -Nur olsrd-0.4.10.orig/lib/quagga/test/quagga.try1.c olsrd-0.4.10/lib/quagga/test/quagga.try1.c
---- olsrd-0.4.10.orig/lib/quagga/test/quagga.try1.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/test/quagga.try1.c 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,710 @@
-+/*
-+ * (C) 2006 by Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
-+ *
-+ * This code is covered by the GPLv2
-+ *
-+ */
-+
-+#include <stdint.h>
-+#ifdef MY_DEBUG
-+#include <stdio.h>
-+#endif
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#define HAVE_SOCKLEN_T
-+#include <quagga/zebra.h>
-+#include "quagga.h"
-+
-+#ifdef OLSR_PLUGIN
-+#include "olsr.h"
-+#include "log.h"
-+#include "defs.h"
-+#include "local_hna_set.h"
-+#endif
-+
-+#define ZAPI_MESSAGE_NEXTHOP 0x01
-+#define ZAPI_MESSAGE_IFINDEX 0x02
-+#define ZAPI_MESSAGE_DISTANCE 0x04
-+#define ZAPI_MESSAGE_METRIC 0x08
-+
-+
-+#define STATUS_CONNECTED 1
-+#define BUFSIZE 1024
-+static char status = 0;
-+
-+static int zsock; // Socket to zebra...
-+struct ipv4_route *quagga_routes = 0; // routes currently exportet to zebra
-+
-+
-+/* prototypes ntern */
-+static char *try_read (ssize_t *);
-+static char* zebra_route_packet (struct ipv4_route r, ssize_t *);
-+static int parse_interface_add (char *, size_t);
-+static int parse_interface_delete (char *, size_t);
-+static int parse_interface_up (char *, size_t);
-+static int parse_interface_down (char *, size_t);
-+static int parse_interface_address_add (char *, size_t);
-+static int parse_interface_address_delete (char *, size_t);
-+static int parse_ipv4_route (char *, size_t, struct ipv4_route *);
-+static int ipv4_route_add (char *, size_t);
-+static int ipv4_route_delete (char *, size_t);
-+static int parse_ipv6_route_add (char*, size_t);
-+static uint32_t prefixlentomask (uint8_t);
-+static void free_ipv4_route (struct ipv4_route);
-+static void update_olsr_zebra_routes (struct ipv4_route*, struct ipv4_route*);
-+static struct ipv4_route *zebra_create_ipv4_route_table_entry (uint32_t,
-+ uint32_t,
-+ uint32_t);
-+static struct ipv4_route *zebra_create_ipv4_route_table (void);
-+static void zebra_free_ipv4_route_table (struct ipv4_route*);
-+static uint8_t masktoprefixlen (uint32_t);
-+
-+
-+
-+#ifdef MY_DEBUG
-+static void dump_ipv4_route (struct ipv4_route r, char *c) {
-+ int i = 0, x = 0;
-+
-+ puts (c);
-+ printf("type: %d\n", r.type);
-+ puts("flags:");
-+ printf(" Internal: %s\n",r.flags&ZEBRA_FLAG_INTERNAL?"yes":"no");
-+ printf(" Selfroute %s\n",r.flags&ZEBRA_FLAG_SELFROUTE?"yes":"no");
-+ printf(" Blackhole %s\n",r.flags&ZEBRA_FLAG_BLACKHOLE?"yes":"no");
-+ printf(" IBGP: %s\n",r.flags&ZEBRA_FLAG_IBGP?"yes":"no");
-+ printf(" Selected: %s\n",r.flags&ZEBRA_FLAG_SELECTED?"yes":"no");
-+ printf(" Changed: %s\n",r.flags&ZEBRA_FLAG_CHANGED?"yes":"no");
-+ printf(" static: %s\n",r.flags&ZEBRA_FLAG_STATIC?"yes":"no");
-+ printf(" reject: %s\n",r.flags&ZEBRA_FLAG_REJECT?"yes":"no");
-+ puts("message:");
-+ printf(" nexthop: %s\n",r.message&ZAPI_MESSAGE_NEXTHOP?"yes":"no");
-+ printf(" ifindex: %s\n",r.message&ZAPI_MESSAGE_IFINDEX?"yes":"no");
-+ printf(" distance: %s\n",r.message&ZAPI_MESSAGE_DISTANCE?"yes":"no");
-+ printf(" metric: %s\n",r.message&ZAPI_MESSAGE_METRIC?"yes":"no");
-+ printf("Prefixlen: %d\n", r.prefixlen);
-+ printf("Prefix: %d", (unsigned char)r.prefix);
-+ c = (char*) &r.prefix;
-+ while (++i < (r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0)))
-+ printf(".%d",(unsigned char)*(c + i));
-+ while (i++ < 4)
-+ printf(".0");
-+ puts("");
-+ i=0;
-+ if (r.message&ZAPI_MESSAGE_NEXTHOP) {
-+
-+ printf("nexthop-count: %d\n", r.nh_count);
-+ while (i++ < r.nh_count) {
-+ c = (unsigned char*) &r.nexthops[i];
-+ printf ("Nexthop %d: %d", i, (unsigned char) *c);
-+ while (++x < 4) {
-+ printf (".%d", (unsigned char) c[x]);
-+ }
-+ puts("");
-+ }
-+ i=0;
-+ }
-+ if (r.message&ZAPI_MESSAGE_IFINDEX) {
-+
-+ printf("index-number: %d\n", r.ind_num);
-+ while (i++ < r.ind_num)
-+ printf("Index: %d: %d\n", i, r.index[i]);
-+ i=0;
-+ if (r.message&ZAPI_MESSAGE_DISTANCE)
-+ printf("Distance: %d\n",r.distance);
-+ if (r.message&ZAPI_MESSAGE_METRIC)
-+ printf("Metric: %d\n",r.metric);
-+ puts("\n");
-+ }
-+}
-+#endif
-+
-+void *my_realloc (void *buf, size_t s, const char *c) {
-+ buf = realloc (buf, s);
-+ if (!buf) {
-+#ifdef OLSR_PLUGIN
-+ OLSR_PRINTF (1, "OUT OF MEMORY: %s\n", strerror(errno));
-+ olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n");
-+ olsr_exit(c, EXIT_FAILURE);
-+#else
-+ exit (EXIT_FAILURE);
-+#endif
-+ }
-+ return buf;
-+}
-+
-+
-+#ifndef OLSR_PLUGIN
-+void *olsr_malloc (size_t f, const char *c) {
-+ void* v = malloc (f);
-+ return v;
-+}
-+#endif
-+
-+/* Connect to the zebra-daemon, returns a socket */
-+int init_zebra () {
-+ struct sockaddr_in i;
-+ int ret;
-+
-+ zsock = socket (AF_INET,SOCK_STREAM, 0);
-+ if (zsock <0 ) // TODO: Could not create socket
-+ return -1;
-+ memset (&i, 0, sizeof i);
-+ i.sin_family = AF_INET;
-+ i.sin_port = htons (ZEBRA_PORT);
-+ // i.sin_len = sizeof i;
-+ i.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-+
-+ ret = connect (zsock, (struct sockaddr *)&i, sizeof i);
-+ if (ret < 0) {
-+ close (zsock);
-+ return -1;
-+ }
-+ status |= STATUS_CONNECTED;
-+ return zsock;
-+}
-+
-+
-+/* Sends a command to zebra, command is
-+ the command defined in zebra.h, options is the packet-payload,
-+ optlen the length, of the payload */
-+char zebra_send_command (unsigned char command, char * options, int optlen) {
-+
-+ char *p = olsr_malloc (optlen+3, "zebra send_command");
-+ uint16_t length = optlen + 3; // length of option + command + packet_length
-+
-+ int ret;
-+
-+ uint16_t len = htons(length);
-+ memcpy (p, &len, 2);
-+ p[2] = command;
-+ memcpy (p + 3, options, optlen);
-+
-+ do {
-+ ret = write (zsock, p, length);
-+ if (ret < 0) {
-+ if (errno == EINTR) continue;
-+ }
-+ else return -1;
-+ p = p+ret;
-+ } while ((length =- ret));
-+
-+ return 0;
-+}
-+
-+
-+/* Creates a Route-Packet-Payload, needs address, netmask, nexthop,
-+ distance, and a pointer of an size_t */
-+static char* zebra_route_packet (struct ipv4_route r, ssize_t *optlen) {
-+
-+ char *cmdopt, *t;
-+ *optlen = 9; // first: type, flags, message, prefixlen, nexthop number, nexthop)
-+ *optlen += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0);
-+
-+ cmdopt = olsr_malloc (*optlen, "zebra add_v4_route");
-+ t = cmdopt;
-+ *t++ = 10; // Type: olsr
-+ *t++ = r.flags; // flags
-+ *t++ = r.message; // message: contains nexthop
-+ *t++ = r.prefixlen;
-+ memcpy (t, &r.prefix, r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0));
-+ *t += r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0);
-+ *t++ = r.nh_count;
-+ memcpy (t, r.nexthops, r.nh_count * sizeof *r.nexthops);
-+ return cmdopt;
-+}
-+
-+
-+/* adds a route to zebra-daemon (needs socket from zebra,
-+ address = prefix of the route
-+ mask = netmask of the route
-+ nexthop = nexthop of the route
-+ distance = distance-value of the route
-+*/
-+int zebra_add_v4_route (struct ipv4_route r) {
-+
-+ char *cmdopt;
-+ ssize_t optlen;
-+
-+ cmdopt = zebra_route_packet (r, &optlen);
-+
-+ puts ("DEBUG: zebra_route_packet returned");
-+
-+
-+
-+ return zebra_send_command (ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);
-+
-+}
-+
-+/* deletes a route from the zebra-daemon (
-+ needs socket from zebra,
-+ address = prefix of the route
-+ mask = netmask of the route
-+ nexthop = nexthop of the route
-+ distance = distance-value of the route
-+*/
-+int zebra_delete_v4_route (struct ipv4_route r) {
-+
-+ char *cmdopt;
-+ ssize_t optlen;
-+
-+ cmdopt = zebra_route_packet (r, &optlen);
-+
-+ return zebra_send_command (ZEBRA_IPV4_ROUTE_DELETE, cmdopt, optlen);
-+
-+}
-+
-+
-+/* Check wether there is data from zebra aviable */
-+void zebra_check (void* foo) {
-+ char *data, *f;
-+ ssize_t len, ret;
-+
-+ if (!status & STATUS_CONNECTED) {
-+ }
-+ data = try_read (&len);
-+ if (data) {
-+ f = data;
-+ do {
-+ ret = zebra_parse_packet (f, len);
-+ if (!ret) {//something wired happened
-+ puts ("DEBUG: IIIIIIIIIIRGS");
-+ exit (EXIT_FAILURE);
-+ }
-+ f += ret;
-+ } while ((f - data) < len);
-+ free (data);
-+ }
-+}
-+
-+
-+// tries to read a packet from zebra_socket
-+// if there is something to read - make sure to read whole packages
-+static char *try_read (ssize_t *len) {
-+ char *buf = NULL;
-+ ssize_t ret = 0, bsize = 0;
-+ uint16_t length = 0, l = 0;
-+ int sockstate;
-+
-+ *len = 0;
-+
-+ sockstate = fcntl (zsock, F_GETFL, 0);
-+ fcntl (zsock, F_SETFL, sockstate|O_NONBLOCK);
-+
-+ do {
-+ if (*len == bsize) {
-+ bsize += BUFSIZE;
-+ buf = my_realloc (buf, bsize, "Zebra try_read");
-+ }
-+ ret = read (zsock, buf + l, bsize - l);
-+ if (ret <= 0) {
-+ if (errno == EAGAIN) {
-+ errno = 0;
-+ }
-+ else {
-+ // TODO: errorhandling
-+ ;
-+ }
-+ free (buf);
-+ return NULL;
-+ }
-+ *len += ret;
-+
-+ while ((*len - l) > length) {
-+ // printf ("DEBUG: *len -l > length - %d - %d > %d\n", *len, l, length);
-+ l += length;
-+ memcpy (&length, buf + l, 2);
-+ length = ntohs (length);
-+ }
-+ // printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);
-+ if (((*len) - l) == length) break; // GOT FULL PACKAGE!!
-+ if (*len < l) {
-+ // printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);
-+ fcntl (zsock, F_SETFL, sockstate);
-+ continue;
-+ }
-+ } while (1);
-+
-+ fcntl (zsock, F_SETFL, sockstate);
-+ return buf;
-+}
-+
-+
-+/* Parse a packet recived from zebra */
-+int zebra_parse_packet (char *packet, ssize_t maxlen) {
-+
-+ /* Array of functions */
-+ int (*foo[ZEBRA_MESSAGE_MAX]) (char *, size_t) = {
-+ parse_interface_add,
-+ parse_interface_delete,
-+ parse_interface_address_add,
-+ parse_interface_address_delete,
-+ parse_interface_up,
-+ parse_interface_down,
-+ ipv4_route_add,
-+ ipv4_route_delete,
-+ parse_ipv6_route_add
-+ };
-+
-+ puts ("DEBUG: zebra_parse_packet");
-+ uint16_t length;
-+
-+ int ret;
-+ memcpy (&length, packet, 2);
-+ length = ntohs (length);
-+
-+ if (maxlen < length) {
-+ puts("Error: programmer is an idiot");
-+ printf ("DEBUG: maxlen = %d, packet_length = %d\n", maxlen, length);
-+ return maxlen;
-+ }
-+
-+ if (packet[2] - 1 < ZEBRA_MESSAGE_MAX && foo[packet[2] - 1]) {
-+ if (!(ret = foo[packet[2] - 1] (packet + 3, length - 3)))
-+ return length;
-+ else printf ("DEBUG: Parse error: %d\n", ret);
-+ }
-+ else
-+ printf ("Unknown packet type: %d\n", packet[2]);
-+
-+ puts ("Quagga: RECIVED PACKET FROM ZEBRA THAT I CAN'T PARSE");
-+
-+ return length;
-+}
-+
-+
-+static int parse_interface_add (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+static int parse_interface_delete (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+static int parse_interface_address_add (char *opt, size_t len) {
-+
-+ //todo
-+ return 0;
-+}
-+
-+static int parse_interface_up (char *opt, size_t len) {
-+
-+ //todo
-+ return 0;
-+}
-+
-+static int parse_interface_down (char *opt, size_t len) {
-+
-+ //todo
-+ return 0;
-+}
-+
-+
-+static int parse_interface_address_delete (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+/* Parse an ipv4-route-packet recived from zebra
-+ */
-+static int parse_ipv4_route (char *opt, size_t len, struct ipv4_route *r) {
-+ // puts ("DEBUG: parse_ipv4_route");
-+ if (len < 4) return -1;
-+
-+ r->type = *opt++;
-+ r->flags = *opt++;
-+ r->message = *opt++;
-+ r->prefixlen = *opt++;
-+ len -= 4;
-+ r->prefix = 0;
-+
-+ if ((int)len < r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0)) return -1;
-+
-+ memcpy (&r->prefix, opt, r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0));
-+ opt += r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0);
-+
-+ if (r->message & ZAPI_MESSAGE_NEXTHOP) {
-+ if (len < 1) return -1;
-+ r->nh_count = *opt++;
-+ if (len < sizeof (uint32_t) * r->nh_count) return -1;
-+ r->nexthops = olsr_malloc (sizeof (uint32_t) * r->nh_count,
-+ "quagga: parse_ipv4_route_add");
-+ memcpy (r->nexthops, opt, sizeof (uint32_t) * r->nh_count);
-+ opt += sizeof (uint32_t) * r->nh_count;
-+ len -= sizeof (uint32_t) * r->nh_count + 1;
-+ }
-+
-+ if (r->message & ZAPI_MESSAGE_IFINDEX) {
-+ if (len < 1) return -2;
-+ r->ind_num = *opt++;
-+ if (len < sizeof (uint32_t) * r->ind_num) return -3;
-+ r->index = olsr_malloc (sizeof (uint32_t) * r->ind_num,
-+ "quagga: parse_ipv4_route_add");
-+ memcpy (r->index, opt, r->ind_num * sizeof (uint32_t));
-+ opt += sizeof (uint32_t) * r->ind_num;
-+ len -= sizeof (uint32_t) * r->ind_num;
-+ }
-+
-+ if (r->message & ZAPI_MESSAGE_DISTANCE)
-+ // todo
-+ ;
-+
-+ if (r->message & ZAPI_MESSAGE_METRIC) {
-+ if (len < sizeof (uint32_t)) return -4;
-+ memcpy (&r->metric, opt, sizeof (uint32_t));
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int ipv4_route_add (char *opt, size_t len) {
-+
-+ struct ipv4_route r;
-+ int f;
-+
-+ // puts ("DEBUG: ipv4_route_add");
-+
-+ f = parse_ipv4_route (opt, len, &r);
-+ if (f < 0) {
-+ printf ("parse-error: %d\n",f);
-+ return f;
-+ }
-+
-+ add_hna4_route (r);
-+ return 0;
-+}
-+
-+static int ipv4_route_delete (char *opt, size_t len) {
-+ struct ipv4_route r;
-+ int f;
-+
-+ f = parse_ipv4_route (opt, len, &r);
-+ if (f < 0) return f;
-+
-+ return delete_hna4_route (r);
-+ // OK, now delete that foo
-+
-+}
-+
-+static int parse_ipv6_route_add (char *opt, size_t len) {
-+ //todo
-+ return 0;
-+}
-+
-+
-+/* start redistribution FROM zebra */
-+int zebra_redistribute (unsigned char type) {
-+
-+ return zebra_send_command (ZEBRA_REDISTRIBUTE_ADD, &type, 1);
-+
-+
-+}
-+
-+
-+/* end redistribution FROM zebra */
-+int zebra_disable_redistribute (unsigned char type) {
-+
-+ return zebra_send_command (ZEBRA_REDISTRIBUTE_DELETE, &type, 1);
-+
-+}
-+
-+static uint32_t prefixlentomask (uint8_t prefix) {
-+ uint32_t mask;
-+ mask = 0xffffffff<<(32-prefix);
-+ mask = ntohl(mask);
-+ return mask;
-+}
-+
-+int add_hna4_route (struct ipv4_route r) {
-+ union olsr_ip_addr net, mask;
-+
-+#ifdef MY_DEBUG
-+ dump_ipv4_route(r, "add_hna4_route");
-+#endif
-+
-+ mask.v4 = prefixlentomask(r.prefixlen);
-+ net.v4 = r.prefix;
-+
-+
-+#ifdef OLSR_PLUGIN
-+ add_local_hna4_entry(&net, &mask);
-+#endif
-+ free_ipv4_route(r);
-+ return 0;
-+}
-+
-+int delete_hna4_route (struct ipv4_route r) {
-+
-+ union olsr_ip_addr net, mask;
-+
-+#ifdef MY_DEBUG
-+ dump_ipv4_route(r, "delete_hna4_route");
-+#endif
-+
-+ mask.v4 = prefixlentomask(r.prefixlen);
-+ net.v4 = r.prefix;
-+
-+#ifdef OLSR_PLUGIN
-+ return remove_local_hna4_entry(&net, &mask) ? 0 : -1;
-+#endif
-+
-+ free_ipv4_route(r);
-+ return 0;
-+
-+}
-+
-+static void free_ipv4_route (struct ipv4_route r) {
-+
-+ if(r.message&ZAPI_MESSAGE_IFINDEX && r.ind_num) free(r.index);
-+ if(r.message&ZAPI_MESSAGE_NEXTHOP && r.nh_count) free(r.nexthops);
-+
-+}
-+
-+void zebra_clear_routes(void) {
-+
-+ struct ipv4_route *t;
-+
-+ t = quagga_routes;
-+ while (t) {
-+ zebra_delete_v4_route(*t);
-+ t=t->next;
-+ }
-+ zebra_free_ipv4_route_table(quagga_routes);
-+
-+ quagga_routes = NULL;
-+}
-+
-+
-+void zebra_update_hna (void* f) {
-+
-+ struct ipv4_route *a = zebra_create_ipv4_route_table();
-+ update_olsr_zebra_routes(a, quagga_routes);
-+ zebra_free_ipv4_route_table(quagga_routes);
-+
-+ quagga_routes = a;
-+
-+}
-+
-+static struct ipv4_route *zebra_create_ipv4_route_table (void) {
-+
-+ struct ipv4_route *r = 0, *t = 0 /* make compiler happy */;
-+ int i;
-+ struct hna_entry *e;
-+ struct hna_net *n;
-+
-+ for (i = 0; i < HASHSIZE; i++) {
-+ e = hna_set[i].next;
-+ for(;e != &hna_set[i];e = e->next) {
-+ n = e->networks.next;
-+ for(;n != &e->networks; n = n->next) {
-+ if (!r) {
-+ r = zebra_create_ipv4_route_table_entry(n->A_network_addr.v4,
-+ n->A_netmask.v4,
-+ e->A_gateway_addr.v4);
-+ t = r;
-+ }
-+ else {
-+ t->next = zebra_create_ipv4_route_table_entry(n->A_network_addr.v4,
-+ n->A_netmask.v4,
-+ e->A_gateway_addr.v4);
-+ t = t->next;
-+ }
-+ }
-+ }
-+ }
-+
-+ return r;
-+
-+}
-+
-+
-+static struct ipv4_route *zebra_create_ipv4_route_table_entry (uint32_t addr,
-+ uint32_t mask,
-+ uint32_t gw) {
-+
-+ struct ipv4_route *r;
-+
-+
-+ r = olsr_malloc (sizeof *r,"zebra_create_ipv4_route_table_entry");
-+ memset (r, 0, sizeof *r);
-+ r->prefix = addr;
-+ r->prefixlen = masktoprefixlen (mask);
-+ r->message |= ZAPI_MESSAGE_NEXTHOP;
-+ r->nh_count = 1;
-+ r->nexthops = olsr_malloc (sizeof (uint32_t), "zebra_create_ipv4_route_table_entry");
-+ *r->nexthops = gw;
-+ r->next = NULL;
-+
-+ return r;
-+}
-+
-+static uint8_t masktoprefixlen (uint32_t mask) {
-+
-+
-+ uint8_t prefixlen = 0;
-+ while (mask & (1 << ++prefixlen && prefixlen < 32);
-+ return prefixlen;
-+
-+}
-+
-+static void update_olsr_zebra_routes (struct ipv4_route *a,
-+ struct ipv4_route *r) {
-+
-+ struct ipv4_route *t;
-+
-+ if (!r) {
-+ puts("no quagga_routing_table aviable");
-+ for (;a;a = a->next) {
-+ dump_ipv4_route (*a, "adding this route");
-+ // zebra_add_v4_route(*r);
-+ }
-+ return;
-+ }
-+
-+ while (a) {
-+ for (t = r; t; t = t->next) {
-+ if (a->prefix == t->prefix)
-+ if (a->prefixlen == t->prefixlen)
-+ if (*a->nexthops == *t->nexthops) {
-+ goto foo;
-+ }
-+ }
-+ dump_ipv4_route (*a, "adding this route");
-+ //zebra_add_v4_route(*a);
-+ foo:
-+ a = a->next;
-+ }
-+
-+ while (r) {
-+ for (t = a; t; t = t->next) {
-+ if (r->prefix == t->prefix)
-+ if (r->prefixlen == t->prefixlen)
-+ if (*r->nexthops == *t->nexthops) {
-+ goto bar;
-+ }
-+ }
-+ dump_ipv4_route (*r, "deleting this route");
-+ //zebra_delete_v4_route(*r);
-+ bar:
-+ r = r->next;
-+ }
-+
-+}
-+
-+
-+static void zebra_free_ipv4_route_table (struct ipv4_route *r) {
-+ struct ipv4_route *n;
-+ if (!r) return;
-+ while ((n = r->next)) {
-+ if (r->message & ZAPI_MESSAGE_NEXTHOP) free (r->nexthops);
-+ if (r->message & ZAPI_MESSAGE_IFINDEX) free (r->index);
-+ free(r);
-+ r = n;
-+ }
-+}
-diff -Nur olsrd-0.4.10.orig/lib/quagga/version-script.txt olsrd-0.4.10/lib/quagga/version-script.txt
---- olsrd-0.4.10.orig/lib/quagga/version-script.txt 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/quagga/version-script.txt 2006-12-02 10:56:37.000000000 +0100
-@@ -0,0 +1,10 @@
-+VERS_1.0
-+{
-+ global:
-+ olsrd_plugin_interface_version;
-+ olsrd_plugin_register_param;
-+ olsrd_plugin_init;
-+
-+ local:
-+ *;
-+};
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/src/main.c olsrd-0.4.10/src/main.c
---- olsrd-0.4.10.orig/src/main.c 2005-09-29 07:53:34.000000000 +0200
-+++ olsrd-0.4.10/src/main.c 2006-12-01 09:10:15.000000000 +0100
-@@ -280,6 +280,9 @@
- /* Initialize parser */
- olsr_init_parser();
-
-+ /* Initialize route-exporter */
-+ olsr_init_export_route();
-+
- /* Initialize message sequencnumber */
- init_msg_seqno();
-
-diff -Nur olsrd-0.4.10.orig/src/process_routes.c olsrd-0.4.10/src/process_routes.c
---- olsrd-0.4.10.orig/src/process_routes.c 2005-05-30 15:13:38.000000000 +0200
-+++ olsrd-0.4.10/src/process_routes.c 2006-12-01 09:10:15.000000000 +0100
-@@ -3,6 +3,9 @@
- * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
- * All rights reserved.
- *
-+ * export_route_entry interface added by Immo 'FaUl Wehrenberg
-+ * <immo@chaostreff-dortmund.de>
-+ *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
-@@ -39,7 +42,6 @@
- * $Id: process_routes.c,v 1.27 2005/05/30 13:13:38 kattemat Exp $
- */
-
--
- #include "defs.h"
- #include "olsr.h"
- #include "log.h"
-@@ -51,10 +53,162 @@
- #define strerror(x) StrError(x)
- #endif
-
-+struct export_route_entry
-+{
-+ olsr_u8_t type; /* AF_INET/AF_INET6 */
-+ int (*function)(struct rt_entry*);
-+ struct export_route_entry *next;
-+};
-+
-+
-+static struct export_route_entry *add_routes;
-+static struct export_route_entry *del_routes;
-+
-
- struct rt_entry old_routes[HASHSIZE];
- struct rt_entry old_hna[HASHSIZE];
-
-+void
-+olsr_addroute_add_function(int (*function)(struct rt_entry*), olsr_u8_t type)
-+{
-+ struct export_route_entry *tmp;
-+ tmp = olsr_malloc(sizeof *tmp, "olsr_addroute_add_function");
-+ tmp->type = type;
-+ tmp->function = function;
-+ tmp->next = add_routes;
-+ add_routes = tmp;
-+}
-+
-+void
-+olsr_delroute_add_function(int (*function) (struct rt_entry*), olsr_u8_t type)
-+{
-+ struct export_route_entry *tmp;
-+ tmp = olsr_malloc(sizeof *tmp, "olsr_delroute_add_function");
-+ tmp->type = type;
-+ tmp->function = function;
-+ tmp->next = del_routes;
-+ del_routes = tmp;
-+}
-+
-+
-+int
-+olsr_addroute_remove_function(int (*function) (struct rt_entry*), olsr_u8_t type)
-+{
-+ struct export_route_entry *tmp, *prev = NULL /* Make compiler happy */;
-+ tmp = add_routes;
-+ while (tmp)
-+ {
-+ if (function == tmp->function && type == tmp->type)
-+ {
-+ if (tmp == add_routes)
-+ {
-+ add_routes = add_routes->next;
-+ free (tmp);
-+ return 1;
-+ }
-+ else
-+ {
-+ prev->next = tmp->next;
-+ free (tmp);
-+ return 1;
-+ }
-+ }
-+ prev = tmp;
-+ tmp = tmp->next;
-+ }
-+ return 0;
-+}
-+
-+int
-+olsr_delroute_remove_function(int (*function) (struct rt_entry*), olsr_u8_t type)
-+{
-+ struct export_route_entry *tmp, *prev = NULL /* Make compiler happy */;
-+ tmp = del_routes;
-+ while (tmp)
-+ {
-+ if (function == tmp->function && type == tmp->type)
-+ {
-+ if (tmp == del_routes)
-+ {
-+ del_routes = del_routes->next;
-+ free (tmp);
-+ return 1;
-+ }
-+ else
-+ {
-+ prev->next = tmp->next;
-+ free (tmp);
-+ return 1;
-+ }
-+ }
-+ prev = tmp;
-+ tmp = tmp->next;
-+ }
-+ return 0;
-+}
-+
-+void
-+olsr_init_export_route()
-+{
-+ olsr_addroute_add_function(&olsr_ioctl_add_route, AF_INET);
-+ olsr_addroute_add_function(&olsr_ioctl_add_route6, AF_INET6);
-+ olsr_delroute_add_function(&olsr_ioctl_del_route, AF_INET);
-+ olsr_delroute_add_function(&olsr_ioctl_del_route6, AF_INET6);
-+}
-+
-+int
-+olsr_export_add_route (struct rt_entry *e)
-+{
-+ int retval = 0;
-+ struct export_route_entry *tmp;
-+ for (tmp = add_routes; tmp; tmp = tmp->next)
-+ {
-+ if (tmp->type == AF_INET)
-+ retval = tmp->function(e);
-+ }
-+ return retval;
-+}
-+
-+int
-+olsr_export_add_route6 (struct rt_entry *e)
-+{
-+ int retval = 0;
-+ struct export_route_entry *tmp;
-+ for (tmp = add_routes; tmp; tmp = tmp->next)
-+ {
-+ if (tmp->type == AF_INET6)
-+ retval = tmp->function(e);
-+ }
-+ return retval;
-+}
-+
-+int
-+olsr_export_del_route (struct rt_entry *e)
-+{
-+ int retval = 0;
-+ struct export_route_entry *tmp;
-+ for (tmp = del_routes; tmp; tmp = tmp->next)
-+ {
-+ if (tmp->type == AF_INET)
-+ retval = tmp->function(e);
-+ }
-+ return retval;
-+}
-+
-+int
-+olsr_export_del_route6 (struct rt_entry *e)
-+{
-+ int retval = 0;
-+ struct export_route_entry *tmp;
-+ for (tmp = del_routes; tmp; tmp = tmp->next)
-+ {
-+ if (tmp->type == AF_INET6)
-+ retval = tmp->function(e);
-+ }
-+ return retval;
-+}
-+
-+
-
- int
- olsr_init_old_table()
-@@ -348,9 +502,9 @@
- if(!olsr_cnf->host_emul)
- {
- if(olsr_cnf->ip_version == AF_INET)
-- error = olsr_ioctl_del_route(destination_ptr->destination);
-+ error = olsr_export_del_route(destination_ptr->destination);
- else
-- error = olsr_ioctl_del_route6(destination_ptr->destination);
-+ error = olsr_export_del_route6(destination_ptr->destination);
-
- if(error < 0)
- {
-@@ -436,9 +590,9 @@
- if(!olsr_cnf->host_emul)
- {
- if(olsr_cnf->ip_version == AF_INET)
-- error=olsr_ioctl_add_route(destination_kernel->destination);
-+ error=olsr_export_add_route(destination_kernel->destination);
- else
-- error=olsr_ioctl_add_route6(destination_kernel->destination);
-+ error=olsr_export_add_route6(destination_kernel->destination);
-
- if(error < 0)
- {
-diff -Nur olsrd-0.4.10.orig/src/process_routes.h olsrd-0.4.10/src/process_routes.h
---- olsrd-0.4.10.orig/src/process_routes.h 2005-05-29 14:47:45.000000000 +0200
-+++ olsrd-0.4.10/src/process_routes.h 2006-12-01 09:10:15.000000000 +0100
-@@ -50,6 +50,34 @@
- extern struct rt_entry old_routes[HASHSIZE];
- extern struct rt_entry old_hna[HASHSIZE];
-
-+void
-+olsr_init_export_route(void);
-+
-+void
-+olsr_addroute_add_function(int (*)(struct rt_entry*), olsr_u8_t);
-+
-+int
-+olsr_addroute_remove_function(int (*)(struct rt_entry*), olsr_u8_t);
-+
-+void
-+olsr_delroute_add_function(int (*)(struct rt_entry*), olsr_u8_t);
-+
-+int
-+olsr_delroute_remove_function(int (*)(struct rt_entry*), olsr_u8_t);
-+
-+int
-+olsr_export_add_route (struct rt_entry*);
-+
-+int
-+olsr_export_del_route (struct rt_entry*);
-+
-+int
-+olsr_export_add_route6 (struct rt_entry*);
-+
-+int
-+olsr_export_del_route6 (struct rt_entry*);
-+
-+
- int
- olsr_init_old_table(void);
-
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/bmf/Makefile olsrd-0.4.10/lib/bmf/Makefile
---- olsrd-0.4.10.orig/lib/bmf/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/Makefile 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,64 @@
-+#
-+# OLSR Basic Multicast Forwarding (BMF) plugin.
-+# Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+# Written by Erik Tromp.
-+# All rights reserved.
-+#
-+# Redistribution and use in source and binary forms, with or without
-+# modification, are permitted provided that the following conditions
-+# are met:
-+#
-+# * Redistributions of source code must retain the above copyright
-+# notice, this list of conditions and the following disclaimer.
-+# * Redistributions in binary form must reproduce the above copyright
-+# notice, this list of conditions and the following disclaimer in
-+# the documentation and/or other materials provided with the
-+# distribution.
-+# * Neither the name of Thales, BMF nor the names of its
-+# contributors may be used to endorse or promote products derived
-+# from this software without specific prior written permission.
-+#
-+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+# POSSIBILITY OF SUCH DAMAGE.
-+#
-+# $Id: Makefile,v 1.10 2005/05/25 13:50:22 br1 Exp $
-+
-+OLSRD_PLUGIN = true
-+PLUGIN_NAME = olsrd_bmf
-+PLUGIN_VER = 1.1
-+
-+TOPDIR = ../..
-+include $(TOPDIR)/Makefile.inc
-+
-+LIBS += -lpthread
-+
-+ifneq ($(OS),linux)
-+
-+default_target install clean:
-+ @echo "*** BMF Plugin only supported on Linux, sorry!"
-+
-+else
-+
-+default_target: $(PLUGIN_FULLNAME)
-+
-+$(PLUGIN_FULLNAME): $(OBJS)
-+ $(CC) $(LDFLAGS) -o $(PLUGIN_FULLNAME) $(OBJS) $(LIBS)
-+
-+install: $(PLUGIN_FULLNAME)
-+ $(STRIP) $(PLUGIN_FULLNAME)
-+ $(INSTALL_LIB)
-+
-+clean:
-+ rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
-+
-+endif
-\ Kein Zeilenumbruch am Dateiende.
-diff -Nur olsrd-0.4.10.orig/lib/bmf/PluginBmf.prj olsrd-0.4.10/lib/bmf/PluginBmf.prj
---- olsrd-0.4.10.orig/lib/bmf/PluginBmf.prj 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/PluginBmf.prj 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,83 @@
-+#DO NOT EDIT THIS FILE!!!
-+[APPTYPE@DEBUG]
-+APPTYPE = 0
-+[APPTYPE@RELEASE]
-+APPTYPE = 0
-+[COMPILE@DEBUG]
-+COMPILEOPTION = -c -g
-+[COMPILE@RELEASE]
-+COMPILEOPTION = -c
-+[CVS]
-+INITDIR = $CVSROOT
-+REMOTELOGIN = 0
-+[DEBUG@DEBUG]
-+EXEPOS = PluginSmf2
-+WORKDIR =
-+[DEBUG@RELEASE]
-+EXEPOS = PluginSmf2
-+WORKDIR =
-+[DEPENDENCY]
-+FILENAME = README_BMF.txt
-+FILENAME = ../../olsrd.conf
-+FILENAME = README_BMF
-+FILENAME = version-script.txt
-+FILENAME = README_SMF
-+FILENAME = Makefile
-+[GDBSERVER]
-+ISGDBSERVER = 0
-+[HEADER]
-+FILENAME = src/Bmf.h
-+FILENAME = src/PacketHistory.h
-+FILENAME = src/Packet.h
-+FILENAME = src/Address.h
-+FILENAME = src/NetworkInterfaces.h
-+FILENAME = src/DropList.h
-+[LANTYPE@DEBUG]
-+LANTYPE = 0
-+[LANTYPE@RELEASE]
-+LANTYPE = 0
-+[LINK@DEBUG]
-+LINKOPTION = -g -o PluginSmf2
-+OUTPUT = PluginSmf2
-+[LINK@RELEASE]
-+LINKOPTION = -o PluginSmf2
-+OUTPUT = PluginSmf2
-+[MAIN]
-+CONFIG = RELEASE,DEBUG
-+DEFAULTCONFIG = DEBUG
-+DEVTYPE = 0
-+ONLINE = 1
-+VERSION = 3.0
-+WATCH =
-+[MAKE@DEBUG]
-+CUSTOMMAKE = Makefile
-+CUSTOMMAKEBUILDPARAM =
-+CUSTOMMAKECLEANPARAM = clean
-+CUSTOMMAKEDIR =
-+CUSTOMSHELL =
-+MAKEFILE = Makefile_DEBUG.mk
-+MANUALDEFAULT = 1
-+REGENMAKEFILE = 1
-+[MAKE@RELEASE]
-+CUSTOMMAKE = Makefile
-+CUSTOMMAKEBUILDPARAM =
-+CUSTOMMAKECLEANPARAM = clean
-+CUSTOMMAKEDIR =
-+CUSTOMSHELL =
-+MAKEFILE = Makefile_DEBUG.mk
-+MANUALDEFAULT = 1
-+REGENMAKEFILE = 1
-+[PRECOMPILE@DEBUG]
-+ESQL_OPTION = -g
-+PROC_OPTION = DEFINE=_PROC_ MODE=ORACLE LINES=true
-+[PRECOMPILE@RELEASE]
-+ESQL_OPTION =
-+PROC_OPTION = DEFINE=_PROC_ MODE=ORACLE
-+[SOURCE]
-+FILENAME = src/Bmf.c
-+FILENAME = src/Packet.c
-+FILENAME = src/PacketHistory.c
-+FILENAME = src/DropList.c
-+FILENAME = src/olsrd_plugin.c
-+FILENAME = src/Address.c
-+FILENAME = src/NetworkInterfaces.c
-diff -Nur olsrd-0.4.10.orig/lib/bmf/README_BMF.txt olsrd-0.4.10/lib/bmf/README_BMF.txt
---- olsrd-0.4.10.orig/lib/bmf/README_BMF.txt 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/README_BMF.txt 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,233 @@
-+BASIC MULTICAST FORWARDING PLUGIN FOR OLSRD
-+by Erik Tromp (erik.tromp@nl.thalesgroup.com)
-+
-+12 Jul 2006: Version 1.1
-+* Major updates in code forwarding from and to non-OLSR enabled
-+ network interfaces.
-+* Debug level 9 gives a better indication of what happens to each
-+ handled multicast/broadcast packet.
-+* Can now deal with network interface removal ("ifdown eth1") and
-+ addition ("ifup eth1").
-+* CRC-calculation for duplicate detection is done over first 256
-+ bytes in packet instead of over full packet length.
-+* CRC calculated only on captured packets, and is subsequently
-+ passed on in a special OLSR-BMF encapsulation header.
-+* Deals correctly with fragmented packets
-+
-+27 Apr 2006: Version 1.0.1
-+* First release.
-+
-+1. Introduction
-+---------------
-+
-+The Basic Multicast Forwarding Plugin floods IP-multicast and
-+IP-local-broadcast traffic over an OLSRD network. It uses the
-+Multi-Point Relays (MPRs) as identified by the OLSR protocol
-+to optimize the flooding of multicast and local broadcast packets
-+to all the nodes in the network. To prevent broadcast storms, a
-+history of packets is kept; only packets that have not been seen
-+in the past 3-6 seconds are forwarded.
-+
-+In the IP header there is room for only two IP-addresses:
-+* the destination IP address (in our case either a multicast
-+ IP-address 224.0.0.0...239.255.255.255, or a local broadcast
-+ address e.g. 192.168.1.255), and
-+* the source IP address (the originator).
-+
-+For optimized flooding, however, we need more information. Let's
-+assume we are the BMF process on one node. We will need to know which
-+node forwarded the IP packet to us. Since OLSR keeps track of which
-+nodes select our node as MPR (see the olsr_lookup_mprs_set function),
-+we can determine if the node that forwarded the packet, has selected us as
-+MPR. If so, we must also forward the packet, changing the 'forwarded-by'
-+IP-address to that of us.
-+
-+Because we need more information than fits in a normal IP-header, the
-+original packets are encapsulated into a new IP packet. Encapsulated
-+packets are transported in UDP, port 50505. The source address of the
-+encapsulation packet is set to the address of the forwarder instead of
-+the originator. Of course, the payload of the encapsulation packet is
-+the original IP packet.
-+
-+For local reception, each received encapsulated packets is unpacked
-+and passed into a tuntap interface which is specially created for
-+this purpose.
-+
-+Here is in short how the flooding works (see also the
-+BmfEncapsulatedPacketReceived(...) function; details with respect to
-+the forwarding towards non-OLSR enabled nodes are omitted):
-+
-+ On all OLSR-enabled interfaces, setup reception of packets
-+ on UDP port 50505.
-+ Upon reception of such a packet:
-+ If the received packet was sent by myself, drop it.
-+ If the packet was recently seen, drop it.
-+ Unpack the encapsulated packet and send a copy to myself via the
-+ TunTap device.
-+ If I am an MPR for the node that forwarded the packet to me,
-+ forward the packet to all OLSR-enabled interfaces *including*
-+ the interface on which it was received.
-+
-+As with all good things in life, it's so simple you could have
-+thought of it yourself.
-+
-+
-+2. How to build and install
-+---------------------------
-+
-+Follow the instructions in the base directory README file under
-+section II. - BUILDING AND RUNNING OLSRD. To be sure to install
-+the BMF plugin, cd to the base directory and issue the follwing
-+command at the shell prompt:
-+
-+ make install_all
-+
-+Next, turn on the possibility to create a tuntap device (see also
-+/usr/src/linux/Documentation/networking/tuntap.txt)
-+
-+ mkdir /dev/net # if it doesn't exist already
-+ mknod /dev/net/tun c 10 200
-+
-+Set permissions, e.g.:
-+ chmod 0700 /dev/net/tun
-+
-+Edit the file /etc/olsrd.conf to load the BMF plugin. For example:
-+
-+ LoadPlugin "olsrd_bmf.so.1.1"
-+ {
-+ # No PlParam entries required for basic operation
-+ }
-+
-+
-+3. How to run
-+-------------
-+
-+After building and installing OLSRD with the BMF plugin, run the
-+olsrd deamon by entering at the shell prompt:
-+ olsrd
-+
-+Look at the output; it should list the BMF plugin, e.g.:
-+
-+ ---------- Plugin loader ----------
-+ Library: olsrd_bmf.so.1.1
-+ OLSRD Basic Multicast Forwarding plugin 1.1 (Jul 12 2006 04:12:42)
-+ (C) Thales Communications Huizen, Netherlands
-+ Erik Tromp (erik.tromp@nl.thalesgroup.com)
-+ Checking plugin interface version... 4 - OK
-+ Trying to fetch plugin init function... OK
-+ Trying to fetch param function... OK
-+ Sending parameters...
-+ "NonOlsrIf"/"eth0"... OK
-+ Running plugin_init function...
-+ OLSRD Basic Multicast Forwarding plugin: opened 6 sockets
-+ ---------- LIBRARY LOADED ----------
-+
-+
-+4. How to check if it works
-+---------------------------
-+
-+To check that BMF is working, enter the following command on the
-+command prompt:
-+
-+ ping -I eth1 224.0.0.1
-+
-+Replace eth1 with the name of any OLSR-enabled network interface.
-+
-+All OLSR-BMF nodes in the MANET should respond. For example:
-+
-+root@IsdbServer:~# ping -I eth1 224.0.0.1
-+PING 224.0.0.1 (224.0.0.1) from 192.168.151.50 eth1: 56(84) bytes of data.
-+64 bytes from 192.168.151.50: icmp_seq=1 ttl=64 time=0.511 ms
-+64 bytes from 192.168.151.53: icmp_seq=1 ttl=64 time=4.67 ms (DUP!)
-+64 bytes from 192.168.151.55: icmp_seq=1 ttl=63 time=10.7 ms (DUP!)
-+64 bytes from 192.168.151.50: icmp_seq=2 ttl=64 time=0.076 ms
-+64 bytes from 192.168.151.53: icmp_seq=2 ttl=64 time=1.23 ms (DUP!)
-+64 bytes from 192.168.151.55: icmp_seq=2 ttl=63 time=1.23 ms (DUP!)
-+64 bytes from 192.168.151.50: icmp_seq=3 ttl=64 time=0.059 ms
-+64 bytes from 192.168.151.53: icmp_seq=3 ttl=64 time=2.94 ms (DUP!)
-+64 bytes from 192.168.151.55: icmp_seq=3 ttl=63 time=5.62 ms (DUP!)
-+64 bytes from 192.168.151.50: icmp_seq=4 ttl=64 time=0.158 ms
-+64 bytes from 192.168.151.53: icmp_seq=4 ttl=64 time=1.14 ms (DUP!)
-+64 bytes from 192.168.151.55: icmp_seq=4 ttl=63 time=1.16 ms (DUP!)
-+
-+
-+5. Adding non-OLSR interfaces to the multicast flooding
-+-------------------------------------------------------
-+
-+As a special feature, it is possible to have multicast and local-broadcast
-+IP packets forwarded also on non-OLSR interfaces.
-+
-+If you have network interfaces on which OLSR is *not* running, but you *do*
-+want to forward multicast and local-broadcast IP packets, specify these
-+interfaces one by one as "NonOlsrIf" parameters in the BMF plugin section
-+of /etc/olsrd.conf. For example:
-+
-+ LoadPlugin "olsrd_bmf.so.1.1"
-+ {
-+ # Non-OLSR interfaces to participate in the multicast flooding
-+ PlParam "NonOlsrIf" "eth2"
-+ PlParam "NonOlsrIf" "eth3"
-+ }
-+
-+If an interface is listed both as NonOlsrIf for BMF, and in the
-+Interfaces { ... } section of olsrd.conf, it will be seen by BMF
-+as an OLSR-enabled interface.
-+
-+Note that when BMF receives or sends a packet via a non-OLSR interface,
-+the TTL is decremented. TTL is NOT decremented on packets traveling
-+within the OLSR-BMF MANET, since that is considered to be one (repaired)
-+broadcast domain.
-+
-+Packets are not forwarded from one non-OLSR interface to another non-OLSR
-+interface, only from non-OLSR interfaces to OLSR interfaces and vice versa.
-+Packet forwarding between non-OLSR interfaces should be the result of
-+other multicast routing protocols.
-+
-+
-+6. Testing in a lab environment
-+-------------------------------
-+
-+Setup IP-tables to drop packets from nodes which are not
-+direct (1-hop) neigbors. For example, to drop all packets from
-+a host with MAC address 00:0C:29:28:0E:CC, enter at the shell prompt:
-+
-+ iptables -A INPUT -m mac --mac-source 00:0C:29:28:0E:CC -j DROP
-+
-+Edit the file /etc/olsrd.conf, and specify the MAC addresses of the nodes
-+we do not want to see; even though packets from these nodes are dropped
-+by iptables, they are still received on network interfaces which are in
-+promiscuous mode. For example:
-+
-+ LoadPlugin "olsrd_bmf.so.1.1"
-+ {
-+ # Drop all packets received from the following MAC sources
-+ PlParam "DropMac" "00:0C:29:C6:E2:61" # RemoteClient1
-+ PlParam "DropMac" "00:0C:29:61:34:B7" # SimpleClient1
-+ PlParam "DropMac" "00:0C:29:28:0E:CC" # SimpleClient2
-+ }
-+
-+
-+
-+7. Common problems, FAQ
-+-----------------------
-+
-+Question:
-+On which platforms does BMF currently compile?
-+
-+Answer:
-+Only on Linux. No compilation on Windows (yet). The oldest Linux
-+kernel on which the BMF plugin was tested was version 2.4.18.
-+
-+
-+Question:
-+When starting OLSRD with the BMF plugin, I can see the following
-+error message:
-+
-+OLSRD Basic Multicast Forwarding plugin: error opening /dev/net/tun: No such file or directory
-+
-+Wat to do?
-+
-+Answer:
-+Turn on the possibility to create a tuntap device; see section 2 of this
-+file.
-+
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Address.c olsrd-0.4.10/lib/bmf/src/Address.c
---- olsrd-0.4.10.orig/lib/bmf/src/Address.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Address.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,194 @@
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : Address.c
-+ * Description: IP packet characterization functions
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+#include "Address.h"
-+
-+/* System includes */
-+#include <assert.h> /* assert() */
-+#include <netinet/ip.h> /* struct ip */
-+#include <netinet/udp.h> /* struct udphdr */
-+
-+/* OLSRD includes */
-+#include "defs.h" /* COMP_IP */
-+
-+/* Plugin includes */
-+#include "Bmf.h" /* BMF_ENCAP_PORT */
-+#include "NetworkInterfaces.h" /* TBmfInterface */
-+
-+/* -------------------------------------------------------------------------
-+ * Function : IsMulticast
-+ * Description: Check if an IP address is a multicast address
-+ * Input : ipAddress
-+ * Output : none
-+ * Return : true (1) or false (0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int IsMulticast(union olsr_ip_addr* ipAddress)
-+{
-+ assert(ipAddress != NULL);
-+
-+ return (ntohl(ipAddress->v4) & 0xF0000000) == 0xE0000000;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : IsLocalBroadcast
-+ * Description: Check if an IP address is a local broadcast address for a
-+ * given network interface
-+ * Input : destIp, ifFrom
-+ * Output : none
-+ * Return : true (1) or false (0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int IsLocalBroadcast(union olsr_ip_addr* destIp, struct TBmfInterface* ifFrom)
-+{
-+ struct sockaddr_in* sin;
-+
-+ assert(destIp != NULL && ifFrom != NULL);
-+
-+ /* Cast down to correct sockaddr subtype */
-+ sin = (struct sockaddr_in*)&(ifFrom->broadAddr);
-+
-+ return COMP_IP(&(sin->sin_addr.s_addr), destIp);
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : IsOlsrOrBmfPacket
-+ * Description: Check if an ethernet packet is an OLSR packet or a BMF packet
-+ * Input : intf, ethPkt, len
-+ * Output : none
-+ * Return : true (1) or false (0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int IsOlsrOrBmfPacket(struct TBmfInterface* intf, unsigned char* ethPkt, size_t len)
-+{
-+ struct ip* ipData;
-+ unsigned int ipHeaderLen;
-+
-+ assert(ethPkt != NULL);
-+
-+ /* Consider OLSR and BMF packets not to be local broadcast
-+ * OLSR packets are UDP - port 698
-+ * OLSR-BMF packets are UDP - port 50698
-+ * OLSR-Autodetect probe packets are UDP - port 51698
-+ * Fragments of the above packets are also not local broadcast */
-+
-+ ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
-+ ipHeaderLen = ipData->ip_hl << 2;
-+ if (len < IP_HDR_OFFSET + ipHeaderLen)
-+ {
-+ return 0;
-+ }
-+
-+ if (ipData->ip_p != SOL_UDP)
-+ {
-+ return 0;
-+ }
-+
-+ /* Check if the packet is a fragment */
-+ if ((ntohs(ipData->ip_off) & IP_OFFMASK) != 0)
-+ {
-+ int i;
-+ for (i = 0; i < FRAGMENT_HISTORY_SIZE; i++)
-+ {
-+ /* Quick-access pointer */
-+ struct TFragmentHistory* entry = &intf->fragmentHistory[i];
-+
-+ /* Match */
-+ if (entry->ipId == ntohs(ipData->ip_id) &&
-+ entry->ipProto == ipData->ip_p &&
-+ entry->ipSrc.s_addr == ntohl(ipData->ip_src.s_addr) &&
-+ entry->ipDst.s_addr == ntohl(ipData->ip_dst.s_addr))
-+ {
-+ /* Found matching history entry, so packet is assumed to be a fragment
-+ * of an earlier OLSR/OLSR-BMF/OLSR-Autodetect packet */
-+
-+ /* More fragments? If not, invalidate entry */
-+ if (((ntohs(ipData->ip_off) & IP_MF) == 0))
-+ {
-+ memset(entry, 0, sizeof(struct TFragmentHistory));
-+ }
-+
-+ return 1;
-+ }
-+ }
-+
-+ /* Matching history entry not found, so packet is not assumed to be a fragment
-+ * of an earlier OLSR/OLSR-BMF/OLSR-Autodetect packet */
-+ return 0;
-+ }
-+
-+ /* The packet is the first (or only) fragment */
-+
-+ /* Check length first */
-+ if (len < IP_HDR_OFFSET + ipHeaderLen + sizeof(struct udphdr ))
-+ {
-+ return 0;
-+ }
-+
-+ /* Go into the UDP header and check port number */
-+ struct udphdr* udpData = (struct udphdr*) (ethPkt + IP_HDR_OFFSET + ipHeaderLen);
-+ u_int16_t port = ntohs(udpData->source);
-+
-+ if (port == OLSRPORT || port == BMF_ENCAP_PORT || port == 51698)
-+ /* TODO define for 51698 */
-+ {
-+ /* If more fragments are expected, keep a record in the fragment history */
-+ if ((ntohs(ipData->ip_off) & IP_MF) != 0)
-+ {
-+ /* Quick-access pointer */
-+ struct TFragmentHistory* entry = &intf->fragmentHistory[intf->nextFragmentHistoryEntry];
-+
-+ /* Store in fragment history */
-+ entry->ipId = ntohs(ipData->ip_id);
-+ entry->ipProto = ipData->ip_p;
-+ entry->ipSrc.s_addr = ntohl(ipData->ip_src.s_addr);
-+ entry->ipDst.s_addr = ntohl(ipData->ip_dst.s_addr);
-+
-+ /* Advance to next entry */
-+ intf->nextFragmentHistoryEntry++;
-+ intf->nextFragmentHistoryEntry %= FRAGMENT_HISTORY_SIZE;
-+ }
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Address.h olsrd-0.4.10/lib/bmf/src/Address.h
---- olsrd-0.4.10.orig/lib/bmf/src/Address.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Address.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,55 @@
-+#ifndef _BMF_ADDRESS_H
-+#define _BMF_ADDRESS_H
-+
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : Address.h
-+ * Description: IP packet characterization functions
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+#include "olsr_types.h" /* olsr_ip_addr */
-+#include "interfaces.h" /* struct interface */
-+
-+struct TBmfInterface;
-+
-+int IsMulticast(union olsr_ip_addr* ipAddress);
-+int IsLocalBroadcast(union olsr_ip_addr* destIp, struct TBmfInterface* ifFrom);
-+int IsOlsrOrBmfPacket(struct TBmfInterface* intf, unsigned char* ethPkt, size_t len);
-+
-+#endif /* _BMF_ADDRESS_H */
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Bmf.c olsrd-0.4.10/lib/bmf/src/Bmf.c
---- olsrd-0.4.10.orig/lib/bmf/src/Bmf.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Bmf.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,935 @@
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : Bmf.c
-+ * Description: Multicast forwarding functions
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+#define _MULTI_THREADED
-+
-+#include "Bmf.h"
-+
-+/* System includes */
-+#include <stdio.h> /* NULL */
-+#include <sys/types.h> /* ssize_t */
-+#include <string.h> /* strerror() */
-+#include <errno.h> /* errno */
-+#include <assert.h> /* assert() */
-+#include <linux/if_packet.h> /* struct sockaddr_ll, PACKET_MULTICAST */
-+#include <pthread.h> /* pthread_t, pthread_create() */
-+#include <signal.h> /* sigset_t, sigfillset(), sigdelset(), SIGINT */
-+#include <netinet/ip.h> /* struct ip */
-+
-+/* OLSRD includes */
-+#include "defs.h" /* olsr_cnf */
-+#include "olsr.h" /* olsr_printf */
-+#include "scheduler.h" /* olsr_register_scheduler_event */
-+#include "mid_set.h" /* mid_lookup_main_addr() */
-+#include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
-+#include "link_set.h" /* get_best_link_to_neighbor() */
-+
-+/* Plugin includes */
-+#include "NetworkInterfaces.h" /* TBmfInterface, CreateBmfNetworkInterfaces(), CloseBmfNetworkInterfaces() */
-+#include "Address.h" /* IsMulticast(), IsLocalBroadcast() */
-+#include "Packet.h" /* ETH_TYPE_OFFSET, IFHWADDRLEN etc. */
-+#include "PacketHistory.h" /* InitPacketHistory() */
-+#include "DropList.h" /* DropMac() */
-+
-+static pthread_t BmfThread;
-+static int BmfThreadRunning = 0;
-+
-+
-+/* -------------------------------------------------------------------------
-+ * Function : BmfPacketCaptured
-+ * Description: Handle a captured raw IP packet
-+ * Input : intf - the network interface on which the packet was captured
-+ * buffer - space for the encapsulation header, followed by
-+ * the captured packet
-+ * len - the number of octets in the encapsulation header plus
-+ * captured packet
-+ * Output : none
-+ * Return : none
-+ * Data Used : BmfInterfaces
-+ * Notes : The packet is assumed to be captured on a socket of family
-+ * PF_PACKET and type SOCK_RAW.
-+ * ------------------------------------------------------------------------- */
-+static void BmfPacketCaptured(struct TBmfInterface* intf, unsigned char* buffer, ssize_t len)
-+{
-+ unsigned char* srcMac;
-+ union olsr_ip_addr srcIp;
-+ union olsr_ip_addr destIp;
-+ union olsr_ip_addr* origIp;
-+ struct sockaddr_in encapDest;
-+ struct TBmfInterface* nextFwIntf;
-+ int isFromOlsrIntf; /* Boolean indicating if packet captured on OLSR-enabled interface */
-+ int iAmNotMpr;
-+ unsigned char* ethPkt = buffer + ENCAP_HDR_LEN;
-+ ssize_t ethPktLen = len - ENCAP_HDR_LEN;
-+ struct ip* ipData;
-+
-+ /* Only forward IPv4 packets */
-+ u_int16_t type;
-+ memcpy(&type, ethPkt + ETH_TYPE_OFFSET, 2);
-+ if (ntohs(type) != IPV4_TYPE)
-+ {
-+ return;
-+ }
-+
-+ ipData = (struct ip*)(ethPkt + IP_HDR_OFFSET);
-+
-+ /* Only forward multicast or local broadcast packets */
-+ COPY_IP(&destIp, &ipData->ip_dst);
-+ if (! IsMulticast(&destIp) && ! IsLocalBroadcast(&destIp, intf))
-+ {
-+ return;
-+ }
-+
-+ /* Discard OLSR packets (UDP port 698) and BMF encapsulated packets */
-+ if (IsOlsrOrBmfPacket(intf, ethPkt, ethPktLen))
-+ {
-+ return;
-+ }
-+
-+ COPY_IP(&srcIp, &ipData->ip_src);
-+ olsr_printf(
-+ 9,
-+ "%s: pkt of %d bytes incoming on \"%s\": %s->%s\n",
-+ PLUGIN_NAME_SHORT,
-+ ethPktLen,
-+ intf->ifName,
-+ olsr_ip_to_string(&srcIp),
-+ olsr_ip_to_string(&destIp));
-+
-+ /* Apply drop list for testing purposes. */
-+ srcMac = ethPkt + IFHWADDRLEN;
-+ if (IsInDropList(srcMac))
-+ {
-+ olsr_printf(
-+ 9,
-+ "%s: --> discarding: source MAC (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) found in drop list\n",
-+ PLUGIN_NAME_SHORT,
-+ srcMac, srcMac + 1, srcMac + 2, srcMac + 3, srcMac + 4, srcMac + 5);
-+ return;
-+ }
-+
-+ /* Lookup main address of source in the MID table of OLSR */
-+ origIp = mid_lookup_main_addr(&srcIp);
-+ if (origIp == NULL)
-+ {
-+ origIp = &srcIp;
-+ }
-+
-+ /* Check if this packet is received on an OLSR-enabled interface */
-+ isFromOlsrIntf = (intf->olsrIntf != NULL);
-+
-+ /* If this packet is captured on a non-OLSR interface, it will be forwarded
-+ * only to OLSR interfaces, thereby crossing the boundary between the external
-+ * network and the OLSR network. So decrease the TTL and re-calculate the IP header
-+ * checksum. */
-+ if (! isFromOlsrIntf)
-+ {
-+ DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
-+ }
-+
-+ /* If the resulting TTL is <= 0, this packet life has ended, so do not forward it */
-+ if (GetIpTtl(ethPkt) <= 0)
-+ {
-+ olsr_printf(
-+ 9,
-+ "%s: --> discarding: TTL=0\n",
-+ PLUGIN_NAME_SHORT);
-+ return;
-+ }
-+
-+ /* Check if this packet was seen recently */
-+ u_int32_t crc32 = PacketCrc32(ethPkt, ethPktLen);
-+ if (CheckAndMarkRecentPacket(Hash16(crc32)))
-+ {
-+ olsr_printf(
-+ 9,
-+ "%s: --> discarding: packet is duplicate\n",
-+ PLUGIN_NAME_SHORT);
-+ return;
-+ }
-+
-+ /* Compose encapsulation header */
-+ struct TEncapHeader* encapHdr = (struct TEncapHeader*) buffer;
-+ memset (encapHdr, 0, ENCAP_HDR_LEN);
-+ encapHdr->crc32 = htonl(crc32);
-+
-+ /* If this packet is captured on an OLSR interface from an OLSR neighbor,
-+ * check with OLSR if I am MPR for that neighbor */
-+ iAmNotMpr =
-+ (isFromOlsrIntf /* captured on an OLSR interface */
-+ && get_best_link_to_neighbor(origIp) != NULL /* from an OLSR neighbor */
-+ && olsr_lookup_mprs_set(origIp) == NULL); /* but not selected as MPR */
-+
-+ memset(&encapDest, 0, sizeof(encapDest));
-+ encapDest.sin_family = AF_INET;
-+ encapDest.sin_port = htons(BMF_ENCAP_PORT);
-+
-+ /* Check with each interface what needs to be done on it */
-+ nextFwIntf = BmfInterfaces;
-+ while (nextFwIntf != NULL)
-+ {
-+ int isToOlsrIntf; /* Boolean indicating if forwarding interface is OLSR-enabled */
-+
-+ struct TBmfInterface* fwIntf = nextFwIntf;
-+ nextFwIntf = fwIntf->next;
-+
-+ isToOlsrIntf = (fwIntf->olsrIntf != NULL);
-+
-+ /* The following if-else statement seems very complicated. Let's
-+ * draw a Karnaugh-diagram of it for some clarification.
-+ *
-+ * ------- isFromOlsrIntf
-+ * -------- isToOlsrIntf
-+ * +---+---+---+---+
-+ * | 3 | 2 | 2 | 1 |
-+ * +---+---+---+---+
-+ * | | X | X | 4 | 1 |
-+ * +---+---+---+---+
-+ * iAmNotMpr
-+ *
-+ * X = does not occur (iAmNotMpr = isFromOlsrIntf && ...)
-+ * 1 = handled in first if-clause: if (isFromOlsrIntf && !isToOlsrIntf)...
-+ * 2 = handled in second if-clause: if (isToOlsrIntf && !iAmNotMpr)...
-+ * 3 = handled in third if-clause: if (!isFromOlsrIntf && !isToOlsrIntf)...
-+ * 4 = handled in else-clause.
-+ */
-+
-+ /* Forward from OLSR-interface to non-OLSR interface */
-+ if (isFromOlsrIntf && !isToOlsrIntf)
-+ {
-+ struct TSaveTtl sttl;
-+
-+ /* Save IP header checksum and the TTL-value of the packet */
-+ SaveTtlAndChecksum(ethPkt, &sttl);
-+
-+ /* Save IP header checksum and the TTL-value of the packet, then
-+ * decrease the TTL by 1 before writing */
-+ DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
-+
-+ /* If the TTL is <= 0, do not forward this packet */
-+ if (GetIpTtl(ethPkt) <= 0)
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> not forwarding on \"%s\": TTL=0\n",
-+ PLUGIN_NAME_SHORT,
-+ fwIntf->ifName);
-+ }
-+ else
-+ {
-+ /* Change source MAC address to that of sending interface */
-+ memcpy(ethPkt + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
-+
-+ int nBytesWritten = write(fwIntf->capturingSkfd, ethPkt, ethPktLen);
-+ if (nBytesWritten != ethPktLen)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: write() error forwarding pkt for %s to \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ olsr_ip_to_string(&destIp),
-+ fwIntf->ifName,
-+ strerror(errno));
-+ }
-+ else
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> forwarded to \"%s\"\n",
-+ PLUGIN_NAME_SHORT,
-+ fwIntf->ifName);
-+ }
-+ }
-+
-+ /* Restore the IP header checksum and the TTL-value of the packet */
-+ RestoreTtlAndChecksum(ethPkt, &sttl);
-+
-+ } /* if (isFromOlsrIntf && !isToOlsrIntf) */
-+
-+ /* Forward from any interface to OLSR interface. Packets from non-OLSR interfaces
-+ * already had their TTL decreased. */
-+ else /* !isFromOlsrIntf || isToOlsrIntf */
-+ if (isToOlsrIntf && !iAmNotMpr)
-+ {
-+ int nBytesWritten;
-+
-+ /* Change encapsulated source MAC address to that of sending interface */
-+ memcpy(ethPkt + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
-+
-+ /* Destination address is local broadcast */
-+ encapDest.sin_addr.s_addr = ((struct sockaddr_in*)&fwIntf->olsrIntf->int_broadaddr)->sin_addr.s_addr;
-+
-+ nBytesWritten = sendto(
-+ fwIntf->encapsulatingSkfd,
-+ buffer,
-+ len,
-+ MSG_DONTROUTE,
-+ (struct sockaddr*) &encapDest,
-+ sizeof(encapDest));
-+
-+ if (nBytesWritten != len)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: sendto() error forwarding pkt for %s to \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ olsr_ip_to_string(&destIp),
-+ fwIntf->ifName,
-+ strerror(errno));
-+ }
-+ else
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> encapsulated and forwarded to \"%s\"\n",
-+ PLUGIN_NAME_SHORT,
-+ fwIntf->ifName);
-+ } /* if (nBytesWritten != len) */
-+ } /* else if (isToOlsrIntf && !iAmNotMpr) */
-+
-+ else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) */
-+ if (!isFromOlsrIntf && !isToOlsrIntf)
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> not forwarding from \"%s\" to \"%s\": both non-OLSR interfaces\n",
-+ PLUGIN_NAME_SHORT,
-+ intf->ifName,
-+ fwIntf->ifName);
-+ }
-+
-+ else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) && (isFromOlsrIntf || isToOlsrIntf) */
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> not forwarding from \"%s\" to \"%s\": I am not selected as MPR by %s\n",
-+ PLUGIN_NAME_SHORT,
-+ intf->ifName,
-+ fwIntf->ifName,
-+ olsr_ip_to_string(&srcIp));
-+ }
-+ } /* while (nextFwIntf != NULL) */
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : BmfEncapsulatedPacketReceived
-+ * Description: Handle a received BMF-encapsulated IP packet
-+ * Input : intf - the network interface on which the packet was received
-+ * fromIp - the IP node that forwarded the packet to us
-+ * buffer - the received encapsulated packet
-+ * len - the number of octets in the received encapsulated packet
-+ * Output : none
-+ * Return : none
-+ * Data Used : BmfInterfaces
-+ * Notes : The packet is assumed to be received on a socket of family
-+ * PF_INET and type SOCK_DGRAM (UDP).
-+ * ------------------------------------------------------------------------- */
-+static void BmfEncapsulatedPacketReceived(
-+ struct TBmfInterface* intf,
-+ union olsr_ip_addr* fromIp,
-+ unsigned char* buffer,
-+ ssize_t len)
-+{
-+ union olsr_ip_addr* forwarder;
-+ int nBytesToWrite;
-+ unsigned char* bufferToWrite;
-+ int nBytesWritten;
-+ int iAmMpr;
-+ struct sockaddr_in encapDest;
-+ struct TBmfInterface* nextFwIntf;
-+ struct ip* ipData;
-+ unsigned char* ethPkt;
-+ ssize_t ethPktLen;
-+
-+ /* Are we talking to ourselves? */
-+ if (if_ifwithaddr(fromIp) != NULL)
-+ {
-+ return;
-+ }
-+
-+ /* Encapsulated packet received on non-OLSR interface? Then discard */
-+ if (intf->olsrIntf == NULL)
-+ {
-+ return;
-+ }
-+
-+ /* Apply drop list? No, not needed: encapsulated packets are routed,
-+ * so filtering should be done by adding a rule to the iptables FORWARD
-+ * chain, e.g.:
-+ * iptables -A FORWARD -m mac --mac-source 00:0C:29:28:0E:CC -j DROP */
-+
-+ ethPkt = buffer + ENCAP_HDR_LEN;
-+ ethPktLen = len - ENCAP_HDR_LEN;
-+
-+ ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
-+
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: encapsulated pkt of %d bytes incoming on \"%s\": %s->",
-+ PLUGIN_NAME_SHORT,
-+ ethPktLen,
-+ intf->ifName,
-+ inet_ntoa(ipData->ip_src));
-+ OLSR_PRINTF(
-+ 9,
-+ "%s, forwarded by %s\n",
-+ inet_ntoa(ipData->ip_dst), /* not possible to call inet_ntoa twice in same printf */
-+ olsr_ip_to_string(fromIp));
-+
-+ /* Get encapsulation header */
-+ struct TEncapHeader* encapHdr = (struct TEncapHeader*) buffer;
-+
-+ /* Check if this packet was seen recently */
-+ if (CheckAndMarkRecentPacket(Hash16(ntohl(encapHdr->crc32))))
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> discarding: packet is duplicate\n",
-+ PLUGIN_NAME_SHORT);
-+ return;
-+ }
-+
-+ /* Unpack encapsulated packet and send a copy to myself via the EtherTunTap device */
-+ bufferToWrite = ethPkt;
-+ nBytesToWrite = ethPktLen;
-+ if (TunOrTap == TT_TUN)
-+ {
-+ bufferToWrite += IP_HDR_OFFSET;
-+ nBytesToWrite -= IP_HDR_OFFSET;
-+ }
-+ nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite);
-+ if (nBytesWritten != nBytesToWrite)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: write() error forwarding encapsulated pkt to \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ EtherTunTapIfName,
-+ strerror(errno));
-+ }
-+ else
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> unpacked and forwarded to \"%s\"\n",
-+ PLUGIN_NAME_SHORT,
-+ EtherTunTapIfName);
-+ }
-+
-+ /* Lookup main address of forwarding node */
-+ forwarder = mid_lookup_main_addr(fromIp);
-+ if (forwarder == NULL)
-+ {
-+ forwarder = fromIp;
-+ }
-+
-+ /* Check if I am MPR for the forwarder */
-+ iAmMpr = (olsr_lookup_mprs_set(forwarder) != NULL);
-+
-+ memset(&encapDest, 0, sizeof(encapDest));
-+ encapDest.sin_family = AF_INET;
-+ encapDest.sin_port = htons(BMF_ENCAP_PORT);
-+
-+ nextFwIntf = BmfInterfaces;
-+ while (nextFwIntf != NULL)
-+ {
-+ struct TBmfInterface* fwIntf = nextFwIntf;
-+ nextFwIntf = fwIntf->next;
-+
-+ /* Forward from OLSR interface to non-OLSR interface: unpack encapsulated
-+ * packet, decrease TTL and forward */
-+ if (fwIntf->olsrIntf == NULL)
-+ {
-+ struct TSaveTtl sttl;
-+
-+ /* Save IP header checksum and the TTL-value of the packet, then
-+ * decrease the TTL by 1 before writing */
-+ SaveTtlAndChecksum(ethPkt, &sttl);
-+ DecreaseTtlAndUpdateHeaderChecksum(ethPkt);
-+
-+ /* If the TTL is <= 0, do not forward this packet */
-+ if (GetIpTtl(ethPkt) <= 0)
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> not forwarding on \"%s\": TTL=0\n",
-+ PLUGIN_NAME_SHORT,
-+ fwIntf->ifName);
-+ }
-+ else
-+ {
-+ nBytesWritten = write(fwIntf->capturingSkfd, ethPkt, ethPktLen);
-+ if (nBytesWritten != ethPktLen)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: write() error forwarding unpacked encapsulated MC pkt to \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ fwIntf->ifName,
-+ strerror(errno));
-+ }
-+ else
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> unpacked and forwarded to \"%s\"\n",
-+ PLUGIN_NAME_SHORT,
-+ fwIntf->ifName);
-+ }
-+ }
-+
-+ /* Restore the IP header checksum and the TTL-value of the packet */
-+ RestoreTtlAndChecksum(ethPkt, &sttl);
-+
-+ } /* if (fwIntf->olsrIntf == NULL) */
-+
-+ /* Forward from OLSR interface to OLSR interface: forward the packet if this
-+ * node is selected as MPR by the forwarding node */
-+ else if (iAmMpr)
-+ {
-+ /* Change source MAC address to that of sending interface */
-+ memcpy(buffer + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
-+
-+ /* Destination address is local broadcast */
-+ encapDest.sin_addr.s_addr = ((struct sockaddr_in*)&fwIntf->olsrIntf->int_broadaddr)->sin_addr.s_addr;
-+
-+ nBytesWritten = sendto(
-+ fwIntf->encapsulatingSkfd,
-+ buffer,
-+ len,
-+ MSG_DONTROUTE,
-+ (struct sockaddr*) &encapDest,
-+ sizeof(encapDest));
-+
-+ if (nBytesWritten != len)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: sendto() error forwarding encapsulated pkt via \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ fwIntf->ifName,
-+ strerror(errno));
-+ }
-+ else
-+ {
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> forwarded to \"%s\"\n",
-+ PLUGIN_NAME_SHORT,
-+ fwIntf->ifName);
-+ }
-+ } /* else if (iAmMpr) */
-+ else /* fwIntf->olsrIntf != NULL && !iAmMpr */
-+ {
-+ /* fwIntf is an OLSR interface and I am not selected as MPR */
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: --> not forwarding to \"%s\": I am not selected as MPR by %s\n",
-+ PLUGIN_NAME_SHORT,
-+ fwIntf->ifName,
-+ olsr_ip_to_string(fromIp));
-+ }
-+ } /* while (nextFwIntf != NULL) */
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : DoBmf
-+ * Description: Wait (blocking) for IP packets, then call the handler for each
-+ * received packet
-+ * Input : none
-+ * Output : none
-+ * Return : none
-+ * Data Used : BmfInterfaces
-+ * ------------------------------------------------------------------------- */
-+static void DoBmf(void)
-+{
-+#define BUFFER_MAX 2048
-+ struct TBmfInterface* currIf;
-+ int nFdBitsSet;
-+
-+ /* Compose set of socket file descriptors.
-+ * Keep the highest descriptor seen. */
-+ int highestSkfd = -1;
-+ fd_set input_set;
-+ FD_ZERO(&input_set);
-+
-+ currIf = BmfInterfaces;
-+ while (currIf != NULL)
-+ {
-+ FD_SET(currIf->capturingSkfd, &input_set);
-+ if (currIf->capturingSkfd > highestSkfd)
-+ {
-+ highestSkfd = currIf->capturingSkfd;
-+ }
-+
-+ if (currIf->encapsulatingSkfd >= 0)
-+ {
-+ FD_SET(currIf->encapsulatingSkfd, &input_set);
-+ if (currIf->encapsulatingSkfd > highestSkfd)
-+ {
-+ highestSkfd = currIf->encapsulatingSkfd;
-+ }
-+ }
-+
-+ currIf = currIf->next;
-+ }
-+
-+ assert(highestSkfd >= 0);
-+
-+ /* Wait (blocking) for packets received on any of the sockets.
-+ * NOTE: don't use a timeout (last parameter). It causes a high system CPU load! */
-+ nFdBitsSet = select(highestSkfd + 1, &input_set, NULL, NULL, NULL);
-+ if (nFdBitsSet < 0)
-+ {
-+ if (errno != EINTR)
-+ {
-+ olsr_printf(1, "%s: select() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ }
-+ return;
-+ }
-+
-+ if (nFdBitsSet == 0)
-+ {
-+ /* No packets waiting. This is unexpected; normally we would excpect select(...)
-+ * to return only if at least one packet was received (so nFdBitsSet > 0), or
-+ * if this thread received a signal (so nFdBitsSet < 0). */
-+ return;
-+ }
-+
-+ while (nFdBitsSet > 0)
-+ {
-+ struct TBmfInterface* nextIf = BmfInterfaces;
-+ while (nextIf != NULL)
-+ {
-+ int skfd;
-+ currIf = nextIf;
-+ nextIf = currIf->next;
-+
-+ skfd = currIf->capturingSkfd;
-+ if (FD_ISSET(skfd, &input_set))
-+ {
-+ unsigned char buffer[BUFFER_MAX];
-+ struct sockaddr_ll pktAddr;
-+ socklen_t addrLen;
-+ int nBytes;
-+ unsigned char* ethPkt = buffer + ENCAP_HDR_LEN;
-+ struct ip* ipData;
-+
-+ /* A packet was captured. */
-+
-+ nFdBitsSet--;
-+
-+ memset(&pktAddr, 0, sizeof(struct sockaddr_ll));
-+ addrLen = sizeof(pktAddr);
-+
-+ /* Receive the packet, leaving space for the BMF encap header */
-+ nBytes = recvfrom(
-+ skfd,
-+ ethPkt,
-+ BUFFER_MAX - ENCAP_HDR_LEN,
-+ 0,
-+ (struct sockaddr*)&pktAddr,
-+ &addrLen);
-+ if (nBytes < 0)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: recvfrom() error on \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ currIf->ifName,
-+ strerror(errno));
-+ }
-+ else
-+ {
-+ /* Don't let BMF crash by sending too short packets */
-+ int ipHeaderLen;
-+ ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
-+ ipHeaderLen = ipData->ip_hl << 2;
-+ if (nBytes >= IP_HDR_OFFSET + ipHeaderLen)
-+ {
-+ if (pktAddr.sll_pkttype == PACKET_OUTGOING)
-+ {
-+ union olsr_ip_addr destIp;
-+ COPY_IP(&destIp, &ipData->ip_dst);
-+ if (IsMulticast(&destIp) || IsLocalBroadcast(&destIp, currIf))
-+ {
-+ if (! IsOlsrOrBmfPacket(currIf, ethPkt, nBytes))
-+ {
-+ /* For outbound packets, just record the fact that the packet was
-+ * seen recently */
-+ u_int32_t crc32 = PacketCrc32(ethPkt, nBytes);
-+ MarkRecentPacket(Hash16(crc32));
-+ }
-+ }
-+ }
-+ else if (pktAddr.sll_pkttype == PACKET_MULTICAST ||
-+ pktAddr.sll_pkttype == PACKET_BROADCAST)
-+ {
-+ /* An inbound multicast or broadcast packet was captured */
-+ BmfPacketCaptured(currIf, buffer, nBytes + ENCAP_HDR_LEN);
-+ }
-+ } /* if (nBytes >= IP_HDR_OFFSET + ipHeaderLen) */
-+ } /* if (nBytes < 0) */
-+ } /* if (FD_ISSET...) */
-+
-+ skfd = currIf->encapsulatingSkfd;
-+ if (skfd >= 0 && (FD_ISSET(skfd, &input_set)))
-+ {
-+ unsigned char buffer[BUFFER_MAX];
-+ struct sockaddr_in from;
-+ socklen_t fromLen = sizeof(from);
-+ int nBytes;
-+ struct ip* ipData;
-+
-+ /* An encapsulated packet was received */
-+
-+ nFdBitsSet--;
-+
-+ nBytes = recvfrom(skfd, buffer, BUFFER_MAX, 0, (struct sockaddr*)&from, &fromLen);
-+ if (nBytes < 0)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: recvfrom() error on \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ currIf->ifName,
-+ strerror(errno));
-+ }
-+ else
-+ {
-+ /* Don't let BMF crash by sending too short packets. */
-+ int ipHeaderLen;
-+ ipData = (struct ip *) (buffer + IP_HDR_OFFSET);
-+ ipHeaderLen = ipData->ip_hl << 2;
-+ if (nBytes >= IP_HDR_OFFSET + ipHeaderLen)
-+ {
-+ union olsr_ip_addr srcIp;
-+ COPY_IP(&srcIp, &from.sin_addr.s_addr);
-+ BmfEncapsulatedPacketReceived(currIf, &srcIp, buffer, nBytes);
-+ }
-+ else
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: encapsulated packet too short (%d bytes) from %s on \"%s\"\n",
-+ PLUGIN_NAME,
-+ nBytes,
-+ inet_ntoa(from.sin_addr),
-+ currIf->ifName);
-+ }
-+ } /* if (nBytes < 0) */
-+ } /* if (skfd >= 0 && (FD_ISSET...) */
-+ } /* while (intf != NULL) */
-+ } /* while (nFdBitsSet > 0) */
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : BmfSignalHandler
-+ * Description: Dummy signal handler function
-+ * Input : signo - signal being handled
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+static void BmfSignalHandler(int signo)
-+{
-+ /* Dummy handler function */
-+ return;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : BmfRun
-+ * Description: Receiver thread function
-+ * Input : useless - not used
-+ * Output : none
-+ * Return : not used
-+ * Data Used : BmfThreadRunning
-+ * Notes : Another thread can gracefully stop this thread by writing a
-+ * '0' into global variable 'BmfThreadRunning' followed by sending
-+ * a SIGALRM signal.
-+ * ------------------------------------------------------------------------- */
-+static void* BmfRun(void* useless)
-+{
-+ /* Mask all signals except SIGALRM */
-+ sigset_t blockedSigs;
-+ sigfillset(&blockedSigs);
-+ sigdelset(&blockedSigs, SIGALRM);
-+ if (pthread_sigmask(SIG_BLOCK, &blockedSigs, NULL) < 0)
-+ {
-+ olsr_printf(1, "%s: pthread_sigmask() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ }
-+
-+ /* Set up the signal handler for the process: use SIGALRM to terminate
-+ * the BMF thread. Only if a signal handler is specified, does a blocking
-+ * system call return with errno set to EINTR; if a signal hander is not
-+ * specified, any system call in which the thread may be waiting will not
-+ * return. Note that the BMF thread is usually blocked in the select()
-+ * function (see DoBmf()). */
-+ if (signal(SIGALRM, BmfSignalHandler) == SIG_ERR)
-+ {
-+ olsr_printf(1, "%s: signal() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ }
-+
-+ /* Call the thread function until flagged to exit */
-+ while (BmfThreadRunning != 0)
-+ {
-+ DoBmf();
-+ }
-+
-+ return NULL;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : InterfaceChange
-+ * Description: Callback function passed to OLSRD for it to call whenever a
-+ * network interface has been added, removed or updated
-+ * Input : interf - the network interface to deal with
-+ * action - indicates if the specified network interface was
-+ * added, removed or updated.
-+ * Output : none
-+ * Return : always 0
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int InterfaceChange(struct interface* interf, int action)
-+{
-+ switch (action)
-+ {
-+ case (IFCHG_IF_ADD):
-+ AddInterface(interf);
-+ olsr_printf(1, "%s: interface %s added\n", PLUGIN_NAME, interf->int_name);
-+ break;
-+
-+ case (IFCHG_IF_REMOVE):
-+ CloseBmf();
-+ InitBmf(interf);
-+ olsr_printf(1, "%s: interface %s removed\n", PLUGIN_NAME, interf->int_name);
-+ break;
-+
-+ case (IFCHG_IF_UPDATE):
-+ olsr_printf(1, "%s: interface %s updated\n", PLUGIN_NAME, interf->int_name);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : InitBmf
-+ * Description: Initialize the BMF plugin
-+ * Input : skipThisIntf - specifies which network interface should not
-+ * be enabled for BMF. Pass NULL to indicate all.
-+ * Output : none
-+ * Return : fail (0) or success (1)
-+ * Data Used : BmfThreadRunning, BmfThread
-+ * ------------------------------------------------------------------------- */
-+int InitBmf(struct interface* skipThisIntf)
-+{
-+ if (CreateBmfNetworkInterfaces(skipThisIntf) < 0)
-+ {
-+ olsr_printf(1, "%s: Could not initialize any network interface!\n", PLUGIN_NAME);
-+ /* Continue anyway; maybe an interface will be added later */
-+ }
-+
-+ /* Start running the multicast packet processing thread */
-+ BmfThreadRunning = 1;
-+ if (pthread_create(&BmfThread, NULL, BmfRun, NULL) == 0)
-+ {
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CloseBmf
-+ * Description: Close the BMF plugin and clean up
-+ * Input : none
-+ * Output : none
-+ * Return : none
-+ * Data Used : BmfThreadRunning, BmfThread
-+ * ------------------------------------------------------------------------- */
-+void CloseBmf()
-+{
-+ /* Signal BmfThread to exit */
-+ BmfThreadRunning = 0;
-+ if (pthread_kill(BmfThread, SIGALRM) < 0)
-+ /* Strangely enough, all running threads receive the SIGALRM signal. But only the
-+ * BMF thread is affected by this signal, having specified a handler for this
-+ * signal in its thread entry function BmfRun(...). */
-+ {
-+ olsr_printf(1, "%s: pthread_kill() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ }
-+
-+ /* Wait for BmfThread to acknowledge */
-+ if (pthread_join(BmfThread, NULL) < 0)
-+ {
-+ olsr_printf(1, "%s: pthread_join() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ }
-+
-+ /* Time to clean up */
-+ CloseBmfNetworkInterfaces();
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : RegisterBmfParameter
-+ * Description: Register a configuration parameter with the BMF process
-+ * Input : key - the parameter name: "DropMac" or "NonOlsrIf"
-+ * value - the parameter value
-+ * Output : none
-+ * Return : fatal error (<0), minor error (0) or success (>0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int RegisterBmfParameter(char* key, char* value)
-+{
-+ if (strcmp(key, "DropMac") == 0)
-+ {
-+ return DropMac(value);
-+ }
-+ else if (strcmp(key, "NonOlsrIf") == 0)
-+ {
-+ return AddNonOlsrBmfIf(value);
-+ }
-+
-+ /* Key not recognized */
-+ return 0;
-+}
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Bmf.h olsrd-0.4.10/lib/bmf/src/Bmf.h
---- olsrd-0.4.10.orig/lib/bmf/src/Bmf.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Bmf.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,64 @@
-+#ifndef _BMF_BMF_H
-+#define _BMF_BMF_H
-+
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : Bmf.h
-+ * Description: Multicast forwarding functions
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+/* BMF plugin data */
-+#define PLUGIN_NAME "OLSRD Basic Multicast Forwarding plugin"
-+#define PLUGIN_NAME_SHORT "OLSRD BMF"
-+#define PLUGIN_VERSION "1.1 (" __DATE__ " " __TIME__ ")"
-+#define PLUGIN_COPYRIGHT " (C) Thales Communications Huizen, Netherlands"
-+#define PLUGIN_AUTHOR " Erik Tromp (erik.tromp@nl.thalesgroup.com)"
-+#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION "\n" PLUGIN_COPYRIGHT "\n" PLUGIN_AUTHOR
-+
-+/* UDP-Port on which multicast packets are encapsulated */
-+#define BMF_ENCAP_PORT 50698
-+
-+struct interface;
-+
-+int InterfaceChange(struct interface* interf, int action);
-+int InitBmf(struct interface* skipThisIntf);
-+void CloseBmf(void);
-+int RegisterBmfParameter(char* key, char* value);
-+
-+#endif /* _BMF_BMF_H */
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/DropList.c olsrd-0.4.10/lib/bmf/src/DropList.c
---- olsrd-0.4.10.orig/lib/bmf/src/DropList.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/DropList.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,129 @@
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : DropList.c
-+ * Description: List of MAC addresses of hosts from which all packets are dropped.
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+
-+#include "DropList.h"
-+
-+/* System includes */
-+#include <assert.h> /* assert() */
-+#include <stdio.h> /* NULL */
-+#include <stdlib.h> /* malloc */
-+#include <string.h> /* memcmp */
-+
-+/* OLSRD includes */
-+#include "olsr.h" /* olsr_printf */
-+
-+/* Plugin includes */
-+#include "Bmf.h" /* PLUGIN_NAME */
-+#include "Packet.h" /* IFHWADDRLEN */
-+
-+static struct TMacAddress* DroppedMacAddresses = NULL;
-+
-+/* Register a MAC address in the drop list.
-+ */
-+/* -------------------------------------------------------------------------
-+ * Function : DropMac
-+ * Description: Register a MAC address in the drop list
-+ * Input : macStr - MAC address as string
-+ * Output : none
-+ * Return : success (1) or fail (0)
-+ * Data Used : DroppedMacAddresses
-+ * Notes : The registered MAC address will be matched to the source MAC
-+ * address of incoming multicast packets. If matched, the multicast
-+ * packet will be silently dropped.
-+ * The drop list is needed only in lab environments, where hidden
-+ * nodes are simulated by using iptables with the
-+ * -m mac helper and --mac-source option (as in:
-+ * "iptables -A INPUT -m mac --mac-source 00:0C:29:EE:C9:D0 -j DROP")
-+ * The drop list is needed because network interfaces in promiscuous
-+ * mode will still capture packets even if they are specified to
-+ * be dropped by iptables.
-+ * ------------------------------------------------------------------------- */
-+int DropMac(const char* macStr)
-+{
-+ unsigned int mac[6];
-+ int n;
-+ struct TMacAddress* newMacAddress;
-+ int i;
-+
-+ assert(macStr != NULL);
-+
-+ n = sscanf(macStr, "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
-+ if (n != 6)
-+ {
-+ olsr_printf(1, "%s: Invalid Ethernet address '%s'\n", PLUGIN_NAME, macStr);
-+ return 0;
-+ }
-+
-+ newMacAddress = malloc(sizeof(struct TMacAddress));
-+ for (i = 0; i < 6; i++)
-+ {
-+ newMacAddress->addr[i] = (unsigned char) mac[i];
-+ }
-+ newMacAddress->next = DroppedMacAddresses;
-+ DroppedMacAddresses = newMacAddress;
-+
-+ return 1;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : IsInDropList
-+ * Description: Check if a MAC address is in the drop list
-+ * Input : macAddress
-+ * Output : none
-+ * Return : true (1) or false (0)
-+ * Data Used : DroppedMacAddresses
-+ * ------------------------------------------------------------------------- */
-+int IsInDropList(const unsigned char* macAddress)
-+{
-+ struct TMacAddress* ma = DroppedMacAddresses;
-+
-+ assert(macAddress != NULL);
-+
-+ while (ma != NULL)
-+ {
-+ if (memcmp(ma->addr, macAddress, IFHWADDRLEN) == 0) return 1;
-+ ma = ma->next;
-+ }
-+ return 0;
-+}
-+
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/DropList.h olsrd-0.4.10/lib/bmf/src/DropList.h
---- olsrd-0.4.10.orig/lib/bmf/src/DropList.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/DropList.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,55 @@
-+#ifndef _BMF_DROPLIST_H
-+#define _BMF_DROPLIST_H
-+
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : DropList.h
-+ * Description: List of MAC addresses of hosts from which all packets are dropped.
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+struct TMacAddress
-+{
-+ unsigned char addr[6];
-+ struct TMacAddress* next;
-+};
-+
-+int DropMac(const char* macStr);
-+int IsInDropList(const unsigned char* macAddress);
-+
-+#endif /* _BMF_DROPLIST_H */
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c
---- olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,818 @@
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : NetworkInterfaces.c
-+ * Description: Functions to open and close sockets
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+#include "NetworkInterfaces.h"
-+
-+/* System includes */
-+#include <syslog.h> /* syslog() */
-+#include <string.h> /* strerror() */
-+#include <errno.h> /* errno */
-+#include <unistd.h> /* close() */
-+#include <sys/ioctl.h> /* ioctl() */
-+#include <fcntl.h> /* fcntl() */
-+#include <assert.h> /* assert() */
-+#include <net/if.h> /* socket(), ifreq, if_indextoname(), if_nametoindex() */
-+#include <netinet/in.h> /* htons() */
-+#include <linux/if_ether.h> /* ETH_P_ALL */
-+#include <linux/if_packet.h> /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
-+#include <linux/if_tun.h> /* IFF_TAP */
-+
-+/* OLSRD includes */
-+#include "olsr.h" /* olsr_printf() */
-+#include "defs.h" /* olsr_cnf */
-+
-+/* Plugin includes */
-+#include "Packet.h" /* IFHWADDRLEN */
-+#include "Bmf.h" /* PLUGIN_NAME */
-+
-+/* List of network interfaces used by BMF plugin */
-+struct TBmfInterface* BmfInterfaces = NULL;
-+
-+/* File descriptor of EtherTunTap device */
-+int EtherTunTapFd = -1;
-+
-+/* Network interface name of EtherTunTap device. If the name starts with "tun", an
-+ * IP tunnel interface will be used. Otherwise, an EtherTap device will be used. */
-+const char* EtherTunTapIfName = "tun0"; /* "tap0"; */
-+
-+/* If the network interface name starts with "tun", an IP tunnel interface will be
-+ * used, and this variable will be set to TUN. Otherwise, an EtherTap device will
-+ * be used, and this variable will be set to TAP. */
-+enum TTunOrTap TunOrTap;
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CreateCaptureSocket
-+ * Description: Create socket for promiscuously capturing multicast IP traffic
-+ * Input : ifname - network interface (e.g. "eth0")
-+ * Output : none
-+ * Return : the socket descriptor ( >= 0), or -1 if an error occurred
-+ * Data Used : none
-+ * Notes : The socket is a raw packet socket, bound to the specified
-+ * network interface
-+ * ------------------------------------------------------------------------- */
-+static int CreateCaptureSocket(const char* ifName)
-+{
-+ int ifIndex = if_nametoindex(ifName);
-+ struct packet_mreq mreq;
-+ struct ifreq req;
-+ struct sockaddr_ll bindTo;
-+
-+ /* Open raw packet socket */
-+ int skfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
-+ if (skfd < 0)
-+ {
-+ olsr_printf(1, "%s: socket(PF_PACKET) error: %s\n", PLUGIN_NAME, strerror(errno));
-+ return -1;
-+ }
-+
-+ /* Set interface to promiscuous mode */
-+ memset(&mreq, 0, sizeof(struct packet_mreq));
-+ mreq.mr_ifindex = ifIndex;
-+ mreq.mr_type = PACKET_MR_PROMISC;
-+ if (setsockopt(skfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
-+ {
-+ olsr_printf(1, "%s: setsockopt(PACKET_MR_PROMISC) error: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ /* Get hardware (MAC) address */
-+ memset(&req, 0, sizeof(struct ifreq));
-+ strncpy(req.ifr_name, ifName, IFNAMSIZ);
-+ if (ioctl(skfd, SIOCGIFHWADDR, &req) < 0)
-+ {
-+ olsr_printf(1, "%s: error retrieving MAC address: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ /* Bind the socket to the specified interface */
-+ memset(&bindTo, 0, sizeof(bindTo));
-+ bindTo.sll_protocol = htons(ETH_P_ALL);
-+ bindTo.sll_ifindex = ifIndex;
-+ bindTo.sll_family = AF_PACKET;
-+ memcpy(bindTo.sll_addr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
-+ bindTo.sll_halen = IFHWADDRLEN;
-+
-+ if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
-+ {
-+ olsr_printf(1, "%s: bind() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ /* Set socket to blocking operation */
-+ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
-+ {
-+ olsr_printf(1, "%s: fcntl() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ return skfd;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CreateEncapsulateSocket
-+ * Description: Create a socket for sending and receiving encapsulated
-+ * multicast packets
-+ * Input : ifname - network interface (e.g. "eth0")
-+ * Output : none
-+ * Return : the socket descriptor ( >= 0), or -1 if an error occurred
-+ * Data Used : none
-+ * Notes : The socket is an UDP (datagram) over IP socket, bound to the
-+ * specified network interface
-+ * ------------------------------------------------------------------------- */
-+static int CreateEncapsulateSocket(const char* ifName)
-+{
-+ int on = 1;
-+ struct sockaddr_in bindTo;
-+
-+ /* Open UDP-IP socket */
-+ int skfd = socket(PF_INET, SOCK_DGRAM, 0);
-+ if (skfd < 0)
-+ {
-+ olsr_printf(1, "%s: socket(PF_INET) error: %s\n", PLUGIN_NAME, strerror(errno));
-+ return -1;
-+ }
-+
-+ /* Enable sending to broadcast addresses */
-+ if (setsockopt(skfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
-+ {
-+ olsr_printf(1, "%s: setsockopt() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ /* Bind to the specific network interfaces indicated by ifName. */
-+ /* When using Kernel 2.6 this must happer prior to the port binding! */
-+ if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, strlen(ifName) + 1) < 0)
-+ {
-+ olsr_printf(1, "%s: setsockopt() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ /* Bind to port */
-+ memset(&bindTo, 0, sizeof(bindTo));
-+ bindTo.sin_family = AF_INET;
-+ bindTo.sin_port = htons(BMF_ENCAP_PORT);
-+ bindTo.sin_addr.s_addr = htonl(INADDR_ANY);
-+
-+ if (bind(skfd, (struct sockaddr*)&bindTo, sizeof(bindTo)) < 0)
-+ {
-+ olsr_printf(1, "%s: bind() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ /* Set socket to blocking operation */
-+ if (fcntl(skfd, F_SETFL, fcntl(skfd, F_GETFL, 0) & ~O_NONBLOCK) < 0)
-+ {
-+ olsr_printf(1, "%s: fcntl() error: %s\n", PLUGIN_NAME, strerror(errno));
-+ close(skfd);
-+ return -1;
-+ }
-+
-+ return skfd;
-+}
-+
-+/* To save the state of the IP spoof filter for the EtherTunTap device */
-+static char EthTapSpoofState = '1';
-+
-+/* -------------------------------------------------------------------------
-+ * Function : DeactivateSpoofFilter
-+ * Description: Deactivates the Linux anti-spoofing filter for the tuntap
-+ * interface
-+ * Input : tunTapName - name used for the tuntap interface (e.g. "tun0" or "tap1")
-+ * Output : none
-+ * Return : success (1) or fail (0)
-+ * Data Used : EthTapSpoofState
-+ * Notes : Saves the current filter state for later restoring
-+ * ------------------------------------------------------------------------- */
-+static int DeactivateSpoofFilter(const char* tunTapName)
-+{
-+ FILE* procSpoof;
-+ char procFile[FILENAME_MAX];
-+
-+ assert(tunTapName != NULL);
-+
-+ /* Generate the procfile name */
-+ sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", tunTapName);
-+
-+ procSpoof = fopen(procFile, "r");
-+ if (procSpoof == NULL)
-+ {
-+ fprintf(
-+ stderr,
-+ "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
-+ "Are you using the procfile filesystem?\n"
-+ "Does your system support IPv4?\n"
-+ "I will continue (in 3 sec) - but you should manually ensure that IP spoof\n"
-+ "filtering is disabled!\n\n",
-+ procFile);
-+
-+ sleep(3);
-+ return 0;
-+ }
-+
-+ EthTapSpoofState = fgetc(procSpoof);
-+ fclose(procSpoof);
-+
-+ procSpoof = fopen(procFile, "w");
-+ if (procSpoof == NULL)
-+ {
-+ fprintf(stderr, "Could not open %s for writing!\n", procFile);
-+ fprintf(
-+ stderr,
-+ "I will continue (in 3 sec) - but you should manually ensure that IP"
-+ " spoof filtering is disabled!\n\n");
-+ sleep(3);
-+ return 0;
-+ }
-+
-+ syslog(LOG_INFO, "Writing \"0\" to %s", procFile);
-+ fputs("0", procSpoof);
-+
-+ fclose(procSpoof);
-+
-+ return 1;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : RestoreSpoofFilter
-+ * Description: Restores the Linux anti-spoofing filter setting for the tuntap
-+ * interface
-+ * Input : tunTapName - name used for the tuntap interface (e.g. "tun0" or "tap1")
-+ * Output : none
-+ * Return : none
-+ * Data Used : EthTapSpoofState
-+ * ------------------------------------------------------------------------- */
-+static void RestoreSpoofFilter(const char* tunTapName)
-+{
-+ FILE* procSpoof;
-+ char procFile[FILENAME_MAX];
-+
-+ assert(tunTapName != NULL);
-+
-+ /* Generate the procfile name */
-+ sprintf(procFile, "/proc/sys/net/ipv4/conf/%s/rp_filter", tunTapName);
-+
-+ procSpoof = fopen(procFile, "w");
-+ if (procSpoof == NULL)
-+ {
-+ fprintf(stderr, "Could not open %s for writing!\nSettings not restored!\n", procFile);
-+ }
-+ else
-+ {
-+ syslog(LOG_INFO, "Resetting %s to %c\n", procFile, EthTapSpoofState);
-+
-+ fputc(EthTapSpoofState, procSpoof);
-+ fclose(procSpoof);
-+ }
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CreateLocalEtherTunTap
-+ * Description: Creates and brings up an EtherTunTap device
-+ * Input : none
-+ * Output : none
-+ * Return : success (0) or fail (<0)
-+ * Data Used : EtherTunTapIfName - name used for the tuntap interface (e.g.
-+ * "tun0" or "tap1")
-+ * ------------------------------------------------------------------------- */
-+static int CreateLocalEtherTunTap(void)
-+{
-+ static char* deviceName = "/dev/net/tun";
-+ struct ifreq ifreq;
-+ int etfd = open(deviceName, O_RDWR);
-+ int skfd;
-+ int ioctlres = 0;
-+
-+ if (etfd < 0)
-+ {
-+ olsr_printf(1, "%s: error opening %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
-+ return -1;
-+ }
-+
-+ memset(&ifreq, 0, sizeof(ifreq));
-+
-+ /* Specify either the IFF_TAP flag for Ethernet frames, or the IFF_TUN flag for IP.
-+ * Specify IFF_NO_PI for not receiving extra meta packet information. */
-+ if (strncmp(EtherTunTapIfName, "tun", 3) == 0)
-+ {
-+ ifreq.ifr_flags = IFF_TUN;
-+ TunOrTap = TT_TUN;
-+ }
-+ else
-+ {
-+ ifreq.ifr_flags = IFF_TAP;
-+ TunOrTap = TT_TAP;
-+ }
-+ ifreq.ifr_flags |= IFF_NO_PI;
-+
-+ strcpy(ifreq.ifr_name, EtherTunTapIfName);
-+ if (ioctl(etfd, TUNSETIFF, (void *)&ifreq) < 0)
-+ {
-+ olsr_printf(1, "%s: ioctl(TUNSETIFF) error on %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
-+ close(etfd);
-+ return -1;
-+ }
-+
-+ memset(&ifreq, 0, sizeof(ifreq));
-+ strcpy(ifreq.ifr_name, EtherTunTapIfName);
-+ ifreq.ifr_addr.sa_family = AF_INET;
-+ skfd = socket(PF_INET, SOCK_DGRAM, 0);
-+ if (skfd < 0)
-+ {
-+ olsr_printf(1, "%s: socket(PF_INET) error on %s: %s\n", PLUGIN_NAME, deviceName, strerror(errno));
-+ close(etfd);
-+ return -1;
-+ }
-+
-+ if (ioctl(skfd, SIOCGIFADDR, &ifreq) < 0)
-+ {
-+ /* EtherTunTap interface does not yet have an IP address.
-+ * Give it a dummy IP address "1.2.3.4". */
-+ struct sockaddr_in *inaddr = (struct sockaddr_in *)&ifreq.ifr_addr;
-+ inet_aton("1.2.3.4", &inaddr->sin_addr);
-+ ioctlres = ioctl(skfd, SIOCSIFADDR, &ifreq);
-+ if (ioctlres >= 0)
-+ {
-+ /* Bring EtherTunTap interface up (if not already) */
-+ ioctlres = ioctl(skfd, SIOCGIFFLAGS, &ifreq);
-+ if (ioctlres >= 0)
-+ {
-+ ifreq.ifr_flags |= (IFF_UP | IFF_RUNNING);
-+ ioctlres = ioctl(skfd, SIOCSIFFLAGS, &ifreq);
-+ }
-+ }
-+
-+ if (ioctlres < 0)
-+ {
-+ /* Any of the three above ioctl() calls failed */
-+ olsr_printf(
-+ 1,
-+ "%s: error bringing up EtherTunTap interface \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ EtherTunTapIfName,
-+ strerror(errno));
-+
-+ close(etfd);
-+ close(skfd);
-+ return -1;
-+ } /* if (ioctlres < 0) */
-+ } /* if (ioctl...) */
-+
-+ /* Set the multicast flag on the interface. TODO: Maybe also set
-+ * IFF_ALLMULTI. */
-+ memset(&ifreq, 0, sizeof(ifreq));
-+ strcpy(ifreq.ifr_name, EtherTunTapIfName);
-+ ioctlres = ioctl(skfd, SIOCGIFFLAGS, &ifreq);
-+ if (ioctlres >= 0)
-+ {
-+ ifreq.ifr_flags |= IFF_MULTICAST;
-+ ioctlres = ioctl(skfd, SIOCSIFFLAGS, &ifreq);
-+ }
-+ if (ioctlres < 0)
-+ {
-+ /* Any of the two above ioctl() calls failed */
-+ olsr_printf(
-+ 1,
-+ "%s: error setting multicast flag on EtherTunTap interface \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ EtherTunTapIfName,
-+ strerror(errno));
-+ /* Continue anyway */
-+ }
-+ close(skfd);
-+
-+ /* Deactivate IP spoof filter for EtherTunTap device */
-+ DeactivateSpoofFilter(ifreq.ifr_name);
-+
-+ olsr_printf(9, "%s: opened \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
-+
-+ return etfd;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : IsNullMacAddress
-+ * Description: Checks if a MAC address is all-zeroes
-+ * Input : mac - address to check
-+ * Output : none
-+ * Return : true (1) or false (0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+static int IsNullMacAddress(char* mac)
-+{
-+ int i;
-+
-+ assert(mac != NULL);
-+
-+ for (i = 0; i < IFHWADDRLEN; i++)
-+ {
-+ if (mac[i] != 0) return 0;
-+ }
-+ return 1;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CreateInterface
-+ * Description: Create a new TBmfInterface object and adds it to the global
-+ * BmfInterfaces list
-+ * Input : ifName - name of the network interface (e.g. "eth0")
-+ * Output : none
-+ * Return : the number of opened sockets
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+static int CreateInterface(
-+ const char* ifName,
-+ struct interface* olsrIntf)
-+{
-+ int capturingSkfd;
-+ int encapsulatingSkfd = -1;
-+ struct ifreq ifr;
-+ int nOpened = 0;
-+ struct TBmfInterface* newIf = malloc(sizeof(struct TBmfInterface));
-+
-+ assert(ifName != NULL);
-+
-+ if (newIf == NULL)
-+ {
-+ return 0;
-+ }
-+
-+ if (olsrIntf != NULL)
-+ {
-+ /* On OLSR interfaces, create socket for encapsulating and forwarding
-+ * multicast packets */
-+ encapsulatingSkfd = CreateEncapsulateSocket(ifName);
-+ if (encapsulatingSkfd < 0)
-+ {
-+ free(newIf);
-+ return 0;
-+ }
-+ nOpened++;
-+ }
-+
-+ /* On all interfaces, create socket for capturing and sending multicast packets */
-+ capturingSkfd = CreateCaptureSocket(ifName);
-+ if (capturingSkfd < 0)
-+ {
-+ close(encapsulatingSkfd);
-+ free(newIf);
-+ return 0;
-+ }
-+ nOpened++;
-+
-+ /* Retrieve the MAC address */
-+ memset(&ifr, 0, sizeof(struct ifreq));
-+ strncpy(ifr.ifr_name, ifName, IFNAMSIZ);
-+ if (ioctl(capturingSkfd, SIOCGIFHWADDR, &ifr) < 0)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: ioctl(SIOCGIFHWADDR) error for device \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ ifName,
-+ strerror(errno));
-+ close(capturingSkfd);
-+ close(encapsulatingSkfd);
-+ free(newIf);
-+ return 0;
-+ }
-+
-+ /* If null-interface, cancel the whole creation and return NULL */
-+ if (IsNullMacAddress(ifr.ifr_hwaddr.sa_data))
-+ {
-+ close(capturingSkfd);
-+ close(encapsulatingSkfd);
-+ free(newIf);
-+ return 0;
-+ }
-+
-+ newIf->capturingSkfd = capturingSkfd;
-+ newIf->encapsulatingSkfd = encapsulatingSkfd;
-+ memcpy(newIf->macAddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
-+ memcpy(newIf->ifName, ifName, IFNAMSIZ);
-+ newIf->olsrIntf = olsrIntf;
-+ if (olsrIntf != NULL)
-+ {
-+ /* Copy broadcast address from OLSR interface */
-+ newIf->broadAddr = olsrIntf->int_broadaddr;
-+ }
-+ else
-+ {
-+ /* Non-OLSR interface: retrieve the IP broadcast address */
-+ memset(&ifr, 0, sizeof(struct ifreq));
-+ strncpy(ifr.ifr_name, ifName, IFNAMSIZ);
-+ if (ioctl(capturingSkfd, SIOCGIFBRDADDR, &ifr) < 0)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: ioctl(SIOCGIFBRDADDR) error for device \"%s\": %s\n",
-+ PLUGIN_NAME,
-+ ifName,
-+ strerror(errno));
-+
-+ ((struct sockaddr_in*)&newIf->broadAddr)->sin_addr.s_addr = inet_addr("0.0.0.0");
-+ }
-+ else
-+ {
-+ newIf->broadAddr = ifr.ifr_broadaddr;
-+ }
-+ }
-+
-+ memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
-+ newIf->nextFragmentHistoryEntry = 0;
-+
-+ newIf->next = BmfInterfaces;
-+ BmfInterfaces = newIf;
-+
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: opened %s interface \"%s\"\n",
-+ PLUGIN_NAME_SHORT,
-+ olsrIntf != NULL ? "OLSR" : "non-OLSR",
-+ ifName);
-+
-+ return nOpened;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CreateBmfNetworkInterfaces
-+ * Description: Create a list of TBmfInterface objects, one for each network
-+ * interface on which BMF runs
-+ * Input : skipThisIntf - network interface to skip, if seen
-+ * Output : none
-+ * Return : success (0) or fail (<0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
-+{
-+ int skfd;
-+ struct ifconf ifc;
-+ int numreqs = 30;
-+ struct ifreq* ifr;
-+ int n;
-+ int nOpened = 0;
-+
-+ EtherTunTapFd = CreateLocalEtherTunTap();
-+ if (EtherTunTapFd >=0)
-+ {
-+ nOpened++;
-+ }
-+
-+ skfd = socket(PF_INET, SOCK_DGRAM, 0);
-+ if (skfd < 0)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: no inet socket available to retrieve interface list: %s\n",
-+ PLUGIN_NAME,
-+ strerror(errno));
-+ return -1;
-+ }
-+
-+ /* Retrieve the network interface configuration list */
-+ ifc.ifc_buf = NULL;
-+ for (;;)
-+ {
-+ ifc.ifc_len = sizeof(struct ifreq) * numreqs;
-+ ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
-+
-+ if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
-+ {
-+ olsr_printf(1, "%s: ioctl(SIOCGIFCONF) error: %s\n", PLUGIN_NAME, strerror(errno));
-+
-+ close(skfd);
-+ free(ifc.ifc_buf);
-+ return -1;
-+ }
-+ if ((unsigned)ifc.ifc_len == sizeof(struct ifreq) * numreqs)
-+ {
-+ /* Assume it overflowed; double the space and try again */
-+ numreqs *= 2;
-+ assert(numreqs < 1024);
-+ continue; /* for (;;) */
-+ }
-+ break; /* for (;;) */
-+ } /* for (;;) */
-+
-+ close(skfd);
-+
-+ /* For each item in the interface configuration list... */
-+ ifr = ifc.ifc_req;
-+ for (n = ifc.ifc_len / sizeof(struct ifreq); --n >= 0; ifr++)
-+ {
-+ struct interface* olsrIntf;
-+
-+ /* ...find the OLSR interface structure, if any */
-+ union olsr_ip_addr ipAddr;
-+ COPY_IP(&ipAddr, &((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr.s_addr);
-+ olsrIntf = if_ifwithaddr(&ipAddr);
-+
-+ if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
-+ {
-+ continue; /* for (n = ...) */
-+ }
-+
-+ if (olsrIntf == NULL && ! IsNonOlsrBmfIf(ifr->ifr_name))
-+ {
-+ /* Interface is neither OLSR interface, nor specified as non-OLSR BMF
-+ * interface in the BMF plugin parameter list */
-+ continue; /* for (n = ...) */
-+ }
-+
-+ nOpened += CreateInterface(ifr->ifr_name, olsrIntf);
-+
-+ } /* for (n = ...) */
-+
-+ free(ifc.ifc_buf);
-+
-+ if (BmfInterfaces == NULL)
-+ {
-+ olsr_printf(1, "%s: could not initialize any network interface\n", PLUGIN_NAME);
-+ return -1;
-+ }
-+
-+ olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
-+
-+ return 0;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : AddInterface
-+ * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
-+ * network interfaces
-+ * Input : newIntf - network interface to add
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+void AddInterface(struct interface* newIntf)
-+{
-+ int nOpened;
-+
-+ assert(newIntf != NULL);
-+
-+ nOpened = CreateInterface(newIntf->int_name, newIntf);
-+
-+ olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CloseBmfNetworkInterfaces
-+ * Description: Closes every socket on each network interface used by BMF
-+ * Input : newIntf - network interface to add
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * Notes : Closes
-+ * - the local EtherTunTap interface (e.g. "tun0" or "tap0")
-+ * - for each BMF-enabled interface, the socket used for
-+ * capturing multicast packets
-+ * - for each OLSR-enabled interface, the socket used for
-+ * encapsulating packets
-+ * Also restores the network state to the situation before BMF
-+ * was started.
-+ * ------------------------------------------------------------------------- */
-+void CloseBmfNetworkInterfaces()
-+{
-+ int nClosed = 0;
-+
-+ /* Close all opened sockets */
-+ struct TBmfInterface* nextBmfIf = BmfInterfaces;
-+ while (nextBmfIf != NULL)
-+ {
-+ struct TBmfInterface* bmfIf = nextBmfIf;
-+ nextBmfIf = bmfIf->next;
-+
-+ if (bmfIf->capturingSkfd >= 0)
-+ {
-+ close(bmfIf->capturingSkfd);
-+ nClosed++;
-+ }
-+ if (bmfIf->encapsulatingSkfd >= 0)
-+ {
-+ close(bmfIf->encapsulatingSkfd);
-+ nClosed++;
-+ }
-+
-+ OLSR_PRINTF(
-+ 9,
-+ "%s: closed %s interface \"%s\"\n",
-+ PLUGIN_NAME_SHORT,
-+ bmfIf->olsrIntf != NULL ? "OLSR" : "non-OLSR",
-+ bmfIf->ifName);
-+
-+ free(bmfIf);
-+ }
-+
-+ if (EtherTunTapFd >= 0)
-+ {
-+ /* Restore IP spoof filter for EtherTunTap device */
-+ RestoreSpoofFilter(EtherTunTapIfName);
-+
-+ close(EtherTunTapFd);
-+ nClosed++;
-+
-+ OLSR_PRINTF(9, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
-+ }
-+
-+ BmfInterfaces = NULL;
-+
-+ olsr_printf(1, "%s: closed %d sockets\n", PLUGIN_NAME, nClosed);
-+}
-+
-+#define MAX_NON_OLSR_IFS 10
-+static char NonOlsrIfNames[MAX_NON_OLSR_IFS][IFNAMSIZ];
-+static int nNonOlsrIfs = 0;
-+
-+/* -------------------------------------------------------------------------
-+ * Function : AddNonOlsrBmfIf
-+ * Description: Add an non-OLSR enabled network interface to the list of BMF-enabled
-+ * network interfaces
-+ * Input : ifName - network interface (e.g. "eth0")
-+ * Output : none
-+ * Return : success (1) or fail (0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int AddNonOlsrBmfIf(const char* ifName)
-+{
-+ assert(ifName != NULL);
-+
-+ if (nNonOlsrIfs >= MAX_NON_OLSR_IFS)
-+ {
-+ olsr_printf(
-+ 1,
-+ "%s: too many non-OLSR interfaces specified, maximum is %d\n",
-+ PLUGIN_NAME,
-+ MAX_NON_OLSR_IFS);
-+ return 0;
-+ }
-+
-+ strncpy(NonOlsrIfNames[nNonOlsrIfs], ifName, IFNAMSIZ);
-+ nNonOlsrIfs++;
-+ return 1;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : IsNonOlsrBmfIf
-+ * Description: Checks if a network interface is OLSR-enabled
-+ * Input : ifName - network interface (e.g. "eth0")
-+ * Output : none
-+ * Return : true (1) or false (0)
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int IsNonOlsrBmfIf(const char* ifName)
-+{
-+ int i;
-+
-+ assert(ifName != NULL);
-+
-+ for (i = 0; i < nNonOlsrIfs; i++)
-+ {
-+ if (strncmp(NonOlsrIfNames[i], ifName, IFNAMSIZ) == 0) return 1;
-+ }
-+ return 0;
-+}
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.h olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.h
---- olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,106 @@
-+#ifndef _BMF_NETWORKINTERFACES_H
-+#define _BMF_NETWORKINTERFACES_H
-+
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : NetworkInterfaces.h
-+ * Description: Functions to open and close sockets
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+/* System includes */
-+#include <netinet/in.h> /* struct in_addr */
-+
-+/* Plugin includes */
-+#include "Packet.h" /* IFHWADDRLEN */
-+
-+
-+struct TBmfInterface
-+{
-+ /* File descriptor of raw packet socket, used for capturing multicast packets */
-+ int capturingSkfd;
-+
-+ /* File descriptor of UDP (datagram) socket for encapsulated multicast packets.
-+ * Only used for OLSR-enabled interfaces; set to -1 if interface is not OLSR-enabled. */
-+ int encapsulatingSkfd;
-+
-+ unsigned char macAddr[IFHWADDRLEN];
-+
-+ char ifName[IFNAMSIZ];
-+
-+ /* OLSRs idea of this network interface. NULL if this interface is not
-+ * OLSR-enabled. */
-+ struct interface* olsrIntf;
-+
-+ /* Kernels index of this network interface */
-+ int ifIndex;
-+
-+ /* Broadcast address of this network interface */
-+ struct sockaddr broadAddr;
-+
-+ #define FRAGMENT_HISTORY_SIZE 10
-+ struct TFragmentHistory
-+ {
-+ u_int16_t ipId;
-+ u_int8_t ipProto;
-+ struct in_addr ipSrc;
-+ struct in_addr ipDst;
-+ } fragmentHistory [FRAGMENT_HISTORY_SIZE];
-+
-+ int nextFragmentHistoryEntry;
-+
-+ /* Next element in list */
-+ struct TBmfInterface* next;
-+};
-+
-+extern struct TBmfInterface* BmfInterfaces;
-+
-+extern int EtherTunTapFd;
-+
-+extern const char* EtherTunTapIfName;
-+
-+enum TTunOrTap { TT_TUN = 0, TT_TAP };
-+extern enum TTunOrTap TunOrTap;
-+
-+int CreateBmfNetworkInterfaces(struct interface* skipThisIntf);
-+void AddInterface(struct interface* newIntf);
-+void CloseBmfNetworkInterfaces(void);
-+int AddNonOlsrBmfIf(const char* ifName);
-+int IsNonOlsrBmfIf(const char* ifName);
-+
-+#endif /* _BMF_NETWORKINTERFACES_H */
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/olsrd_plugin.c olsrd-0.4.10/lib/bmf/src/olsrd_plugin.c
---- olsrd-0.4.10.orig/lib/bmf/src/olsrd_plugin.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/olsrd_plugin.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,166 @@
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : olsrd_plugin.c
-+ * Description: Interface to the OLSRD plugin system
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+/* System includes */
-+#include <assert.h> /* assert() */
-+#include <stdio.h>
-+
-+/* OLSRD includes */
-+#include "olsrd_plugin.h"
-+#include "defs.h" /* olsr_u8_t, olsr_cnf */
-+#include "scheduler.h" /* olsr_register_scheduler_event */
-+
-+/* BMF includes */
-+#include "Bmf.h" /* InitBmf(), CloseBmf(), RegisterBmfParameter() */
-+#include "PacketHistory.h" /* InitPacketHistory() */
-+
-+static void __attribute__ ((constructor)) my_init(void);
-+static void __attribute__ ((destructor)) my_fini(void);
-+
-+void olsr_plugin_exit(void);
-+
-+/* -------------------------------------------------------------------------
-+ * Function : olsrd_plugin_interface_version
-+ * Description: Plugin interface version
-+ * Input : none
-+ * Output : none
-+ * Return : BMF plugin interface version number
-+ * Data Used : none
-+ * Notes : Called by main OLSRD (olsr_load_dl) to check plugin interface
-+ * version
-+ * ------------------------------------------------------------------------- */
-+int olsrd_plugin_interface_version()
-+{
-+ return OLSRD_PLUGIN_INTERFACE_VERSION;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : olsrd_plugin_init
-+ * Description: Plugin initialisation
-+ * Input : none
-+ * Output : none
-+ * Return : fail (0) or success (1)
-+ * Data Used : olsr_cnf
-+ * Notes : Called by main OLSRD (init_olsr_plugin) to initialize plugin
-+ * ------------------------------------------------------------------------- */
-+int olsrd_plugin_init()
-+{
-+ /* Check validity */
-+ if (olsr_cnf->ip_version != AF_INET)
-+ {
-+ fprintf(stderr, PLUGIN_NAME ": This plugin only supports IPv4!\n");
-+ return 0;
-+ }
-+
-+ /* Clear the packet history */
-+ InitPacketHistory();
-+
-+ /* Register ifchange function */
-+ add_ifchgf(&InterfaceChange);
-+
-+ /* Register the duplicate registration pruning process */
-+ olsr_register_scheduler_event(&PrunePacketHistory, NULL, 3.0, 2.0, NULL);
-+
-+ return InitBmf(NULL);
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : olsr_plugin_exit
-+ * Description: Plugin cleanup
-+ * Input : none
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * Notes : Called by my_fini() at unload of shared object
-+ * ------------------------------------------------------------------------- */
-+void olsr_plugin_exit()
-+{
-+ CloseBmf();
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : olsrd_plugin_register_param
-+ * Description: Register parameters from config file
-+ * Input : key - the parameter name
-+ * value - the parameter value
-+ * Output : none
-+ * Return : fatal error (<0), minor error (0) or success (>0)
-+ * Data Used : none
-+ * Notes : Called by main OLSR (init_olsr_plugin) for all plugin parameters
-+ * ------------------------------------------------------------------------- */
-+int olsrd_plugin_register_param(char* key, char* value)
-+{
-+ assert(key != NULL && value != NULL);
-+
-+ return RegisterBmfParameter(key, value);
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : my_init
-+ * Description: Plugin constructor
-+ * Input : none
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * Notes : Called at load of shared object
-+ * ------------------------------------------------------------------------- */
-+static void my_init()
-+{
-+ /* Print plugin info to stdout */
-+ printf("%s\n", MOD_DESC);
-+
-+ return;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : my_fini
-+ * Description: Plugin destructor
-+ * Input : none
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * Notes : Called at unload of shared object
-+ * ------------------------------------------------------------------------- */
-+static void my_fini()
-+{
-+ olsr_plugin_exit();
-+}
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.c olsrd-0.4.10/lib/bmf/src/Packet.c
---- olsrd-0.4.10.orig/lib/bmf/src/Packet.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Packet.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,133 @@
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : Packet.c
-+ * Description: BMF and IP packet processing functions
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+#include "Packet.h"
-+
-+/* System includes */
-+#include <assert.h> /* assert() */
-+#include <sys/types.h> /* u_int32_t */
-+#include <netinet/in.h> /* ntohs(), htons() */
-+#include <linux/ip.h>
-+
-+/* -------------------------------------------------------------------------
-+ * Function : GetIpTtl
-+ * Description: Retrieve the TTL (Time To Live) value from the IP header of
-+ * the passed ethernet-IP packet
-+ * Input : buffer - the ethernet-IP packet
-+ * Output : none
-+ * Return : TTL value
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+int GetIpTtl(unsigned char* buffer)
-+{
-+ struct iphdr* iph;
-+
-+ assert(buffer != NULL);
-+
-+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
-+ return iph->ttl;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : SaveTtlAndChecksum
-+ * Description: Save the TTL (Time To Live) value and IP checksum as found in
-+ * the IP header of the passed ethernet-IP packet
-+ * Input : buffer - the ethernet-IP packet
-+ * Output : sttl - the TTL and checksum values
-+ * Return : none
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+void SaveTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl)
-+{
-+ struct iphdr* iph;
-+
-+ assert(buffer != NULL && sttl != NULL);
-+
-+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
-+ sttl->ttl = iph->ttl;
-+ sttl->check = ntohs(iph->check);
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : RestoreTtlAndChecksum
-+ * Description: Restore the TTL (Time To Live) value and IP checksum in
-+ * the IP header of the passed ethernet-IP packet
-+ * Input : buffer - the ethernet-IP packet
-+ * sttl - the TTL and checksum values
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+void RestoreTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl)
-+{
-+ struct iphdr* iph;
-+
-+ assert(buffer != NULL && sttl != NULL);
-+
-+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
-+ iph->ttl = sttl->ttl;
-+ iph->check = htons(sttl->check);
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : DecreaseTtlAndUpdateHeaderChecksum
-+ * Description: For an IP packet, decrement the TTL value and update the IP header
-+ * checksum accordingly.
-+ * Input : buffer - the ethernet-IP packet
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * Notes : See also RFC1141
-+ * ------------------------------------------------------------------------- */
-+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* buffer)
-+{
-+ struct iphdr* iph;
-+ u_int32_t sum;
-+
-+ assert(buffer != NULL);
-+
-+ iph = (struct iphdr*) (buffer + IP_HDR_OFFSET);
-+
-+ iph->ttl--; /* decrement ttl */
-+ sum = ntohs(iph->check) + 0x100; /* increment checksum high byte */
-+ iph->check = htons(sum + (sum>>16)); /* add carry */
-+}
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.h olsrd-0.4.10/lib/bmf/src/Packet.h
---- olsrd-0.4.10.orig/lib/bmf/src/Packet.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Packet.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,85 @@
-+#ifndef _BMF_PACKET_H
-+#define _BMF_PACKET_H
-+
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : Packet.h
-+ * Description: BMF and IP packet processing functions
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+/* System includes */
-+#include <net/if.h> /* IFNAMSIZ, IFHWADDRLEN */
-+#include <sys/types.h> /* u_int8_t, u_int16_t */
-+
-+/* Offsets and sizes into IP-ethernet packets */
-+#define IPV4_ADDR_SIZE 4
-+#define ETH_TYPE_OFFSET (2*IFHWADDRLEN)
-+#define ETH_TYPE_LEN 2
-+#define IP_HDR_OFFSET (ETH_TYPE_OFFSET + ETH_TYPE_LEN)
-+#define IPV4_OFFSET_SRCIP 12
-+#define IPV4_OFFSET_DSTIP (IPV4_OFFSET_SRCIP + IPV4_ADDR_SIZE)
-+
-+#define IPV4_TYPE 0x0800
-+
-+/* BMF-encapsulated packets are Ethernet-IP-UDP packets, which start
-+ * with a 16-bytes BMF header (struct TEncapHeader), followed by the
-+ * encapsulated Ethernet-IP packet itself */
-+
-+struct TEncapHeader
-+{
-+ u_int32_t crc32;
-+ u_int32_t futureExpansion1;
-+ u_int32_t futureExpansion2;
-+ u_int32_t futureExpansion3;
-+} __attribute__((__packed__));
-+
-+#define ENCAP_HDR_LEN sizeof(struct TEncapHeader)
-+
-+struct TSaveTtl
-+{
-+ u_int8_t ttl;
-+ u_int16_t check;
-+} __attribute__((__packed__));
-+
-+int GetIpTtl(unsigned char* buffer);
-+void SaveTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl);
-+void RestoreTtlAndChecksum(unsigned char* buffer, struct TSaveTtl* sttl);
-+void DecreaseTtlAndUpdateHeaderChecksum(unsigned char* buffer);
-+
-+#endif /* _BMF_PACKET_H */
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.c olsrd-0.4.10/lib/bmf/src/PacketHistory.c
---- olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.c 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/PacketHistory.c 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,293 @@
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : PacketHistory.c
-+ * Description: Functions for keeping and accessing the history of processed
-+ * multicast IP packets.
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+#include "PacketHistory.h"
-+
-+/* System includes */
-+#include <assert.h> /* assert() */
-+#include <sys/types.h> /* u_int16_t, u_int32_t */
-+#include <string.h> /* memset */
-+
-+/* OLSRD includes */
-+#include "olsr.h" /* olsr_printf */
-+
-+/* Plugin includes */
-+#include "Packet.h"
-+
-+static u_int32_t PacketHistory[HISTORY_TABLE_SIZE];
-+
-+#define CRC_UPTO_NBYTES 256
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CalcCrcCcitt
-+ * Description: Calculate 16-bits CRC according to CRC-CCITT specification
-+ * Input : buffer - the bytes to calculate the CRC value over
-+ * len - the number of bytes to calculate the CRC value over
-+ * Output : none
-+ * Return : CRC-16 value
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+static u_int16_t CalcCrcCcitt(unsigned char* buffer, ssize_t len)
-+{
-+ /* Initial value of 0xFFFF should be 0x1D0F according to
-+ * www.joegeluso.com/software/articles/ccitt.htm */
-+ u_int16_t crc = 0xFFFF;
-+ int i;
-+
-+ assert(buffer != NULL);
-+
-+ for (i = 0; i < len; i++)
-+ {
-+ crc = (unsigned char)(crc >> 8) | (crc << 8);
-+ crc ^= buffer[i];
-+ crc ^= (unsigned char)(crc & 0xff) >> 4;
-+ crc ^= (crc << 8) << 4;
-+ crc ^= ((crc & 0xff) << 4) << 1;
-+ }
-+ return crc;
-+}
-+
-+
-+/* -------------------------------------------------------------------------
-+ * Function : GenerateCrc32Table
-+ * Description: Generate the table of CRC remainders for all possible bytes,
-+ * according to CRC-32-IEEE 802.3
-+ * Input : none
-+ * Output : none
-+ * Return : none
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+#define CRC32_POLYNOMIAL 0xedb88320UL /* bit-inverse of 0x04c11db7UL */
-+
-+static unsigned long CrcTable[256];
-+
-+static void GenerateCrc32Table(void)
-+{
-+ int i, j;
-+ u_int32_t crc;
-+ for (i = 0; i < 256; i++)
-+ {
-+ crc = (u_int32_t) i;
-+ for (j = 0; j < 8; j++)
-+ {
-+ if (crc & 1)
-+ {
-+ crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
-+ }
-+ else
-+ {
-+ crc = (crc >> 1);
-+ }
-+ }
-+ CrcTable[i] = crc;
-+ }
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CalcCrc32
-+ * Description: Calculate CRC-32 according to CRC-32-IEEE 802.3
-+ * Input : buffer - the bytes to calculate the CRC value over
-+ * len - the number of bytes to calculate the CRC value over
-+ * Output : none
-+ * Return : CRC-32 value
-+ * Data Used : none
-+ * ------------------------------------------------------------------------- */
-+static u_int32_t CalcCrc32(unsigned char* buffer, ssize_t len)
-+{
-+ int i, j;
-+ u_int32_t crc = 0xffffffffUL;
-+ for (i = 0; i < len; i++)
-+ {
-+ /* Skip IP header checksum; we want to avoid as much as possible
-+ * calculating a checksum over data containing a checksum */
-+ // if (i >= 12 && i < 14) continue;
-+
-+ j = ((int) (crc & 0xFF) ^ *buffer++);
-+ crc = (crc >> 8) ^ CrcTable[j];
-+ }
-+ return crc ^ 0xffffffffUL;
-+}
-+
-+/* */
-+/* -------------------------------------------------------------------------
-+ * Function : PacketCrc32
-+ * Description: Calculates the CRC-32 value for an Ethernet packet
-+ * Input : ethPkt - the Ethernet packet
-+ * len - the number of octets in the Ethernet packet
-+ * Output : none
-+ * Return : 32-bits hash value
-+ * Data Used : none
-+ * Notes : The source and destination MAC address are not taken into account
-+ * in the CRC calculation.
-+ * ------------------------------------------------------------------------- */
-+u_int32_t PacketCrc32(unsigned char* ethPkt, ssize_t len)
-+{
-+ assert(ethPkt != NULL);
-+ assert(len > ETH_TYPE_OFFSET);
-+
-+ /* Start CRC calculation at ethertype; skip source and destination MAC
-+ * addresses. Clip number of bytes over which CRC is calculated to prevent
-+ * long packets from possibly claiming too much CPU resources. */
-+ ssize_t nCrcBytes = len - ETH_TYPE_OFFSET;
-+ if (nCrcBytes > CRC_UPTO_NBYTES)
-+ {
-+ nCrcBytes = CRC_UPTO_NBYTES;
-+ }
-+ return CalcCrc32(ethPkt + ETH_TYPE_OFFSET, nCrcBytes);
-+}
-+
-+/* Calculates a 16-bit hash value from a 32-bit hash value */
-+u_int16_t Hash16(u_int32_t hash32)
-+{
-+ return ((hash32 >> 16) + hash32) & 0xFFFFU;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : InitPacketHistory
-+ * Description: Initialize the packet history table and CRC-32 table
-+ * Input : none
-+ * Output : none
-+ * Return : none
-+ * Data Used : PacketHistory
-+ * ------------------------------------------------------------------------- */
-+void InitPacketHistory()
-+{
-+ memset(PacketHistory, 0, sizeof(PacketHistory));
-+ GenerateCrc32Table();
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : MarkRecentPacket
-+ * Description: Record the fact that this packet was seen recently
-+ * Input : hash16
-+ * Output : none
-+ * Return : none
-+ * Data Used : PacketHistory
-+ * ------------------------------------------------------------------------- */
-+void MarkRecentPacket(u_int16_t hash16)
-+{
-+ u_int32_t index;
-+ uint offset;
-+
-+ index = hash16 / NPACKETS_PER_ENTRY;
-+ assert(index < HISTORY_TABLE_SIZE);
-+
-+ offset = (hash16 % NPACKETS_PER_ENTRY) * NBITS_PER_PACKET;
-+ assert(offset <= NBITS_IN_UINT32 - NBITS_PER_PACKET);
-+
-+ /* Mark as "seen recently" */
-+ PacketHistory[index] = PacketHistory[index] | (0x3u << offset);
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : CheckAndMarkRecentPacket
-+ * Description: Check if this packet was seen recently, then record the fact
-+ * that this packet was seen recently.
-+ * Input : hash16
-+ * Output : none
-+ * Return : not recently seen (0), recently seen (1)
-+ * Data Used : PacketHistory
-+ * ------------------------------------------------------------------------- */
-+int CheckAndMarkRecentPacket(u_int16_t hash16)
-+{
-+ u_int32_t index;
-+ uint offset;
-+ u_int32_t bitMask;
-+ int result;
-+
-+ index = hash16 / NPACKETS_PER_ENTRY;
-+ assert(index < HISTORY_TABLE_SIZE);
-+
-+ offset = (hash16 % NPACKETS_PER_ENTRY) * NBITS_PER_PACKET;
-+ assert(offset <= NBITS_IN_UINT32 - NBITS_PER_PACKET);
-+
-+ bitMask = 0x1u << offset;
-+ result = ((PacketHistory[index] & bitMask) == bitMask);
-+
-+ /* Always mark as "seen recently" */
-+ PacketHistory[index] = PacketHistory[index] | (0x3u << offset);
-+
-+ return result;
-+}
-+
-+/* -------------------------------------------------------------------------
-+ * Function : PrunePacketHistory
-+ * Description: Prune the packet history table.
-+ * Input : useless - not used
-+ * Output : none
-+ * Return : none
-+ * Data Used : PacketHistory
-+ * ------------------------------------------------------------------------- */
-+void PrunePacketHistory(void* useless)
-+{
-+ uint i;
-+ for (i = 0; i < HISTORY_TABLE_SIZE; i++)
-+ {
-+ if (PacketHistory[i] > 0)
-+ {
-+ uint j;
-+ for (j = 0; j < NPACKETS_PER_ENTRY; j++)
-+ {
-+ uint offset = j * NBITS_PER_PACKET;
-+
-+ u_int32_t bitMask = 0x3u << offset;
-+ u_int32_t bitsSeenRecenty = 0x3u << offset;
-+ u_int32_t bitsTimingOut = 0x1u << offset;
-+
-+ /* 10 should never occur */
-+ assert ((PacketHistory[i] & bitMask) != (0x2u << offset));
-+
-+ if ((PacketHistory[i] & bitMask) == bitsSeenRecenty)
-+ {
-+ /* 11 -> 01 */
-+ PacketHistory[i] &= ~bitMask | bitsTimingOut;
-+ }
-+ else if ((PacketHistory[i] & bitMask) == bitsTimingOut)
-+ {
-+ /* 01 -> 00 */
-+ PacketHistory[i] &= ~bitMask;
-+ }
-+ } /* for (j = ...) */
-+ } /* if (PacketHistory[i] > 0) */
-+ } /* for (i = ...) */
-+}
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.h olsrd-0.4.10/lib/bmf/src/PacketHistory.h
---- olsrd-0.4.10.orig/lib/bmf/src/PacketHistory.h 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/PacketHistory.h 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,67 @@
-+#ifndef _BMF_PACKETHISTORY_H
-+#define _BMF_PACKETHISTORY_H
-+
-+/*
-+ * OLSR Basic Multicast Forwarding (BMF) plugin.
-+ * Copyright (c) 2005, 2006, Thales Communications, Huizen, The Netherlands.
-+ * Written by Erik Tromp.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ * * Neither the name of Thales, BMF nor the names of its
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* -------------------------------------------------------------------------
-+ * File : PacketHistory.h
-+ * Description: Functions for keeping and accessing the history of processed
-+ * multicast IP packets.
-+ * Created : 29 Jun 2006
-+ *
-+ * $Id$
-+ *
-+ * $Log$
-+ * ------------------------------------------------------------------------- */
-+
-+#include <sys/types.h> /* ssize_t */
-+
-+/* 2 bits per seen packet:
-+ * 11 = "seen recently",
-+ * 01 = "timing out"
-+ * 00 = "not seen recently"
-+ * Note that 10 is unused */
-+#define NBITS_PER_PACKET 2
-+#define NBITS_IN_UINT16 (sizeof(u_int16_t) * 8)
-+#define NBITS_IN_UINT32 (sizeof(u_int32_t) * 8)
-+#define NPACKETS_PER_ENTRY (NBITS_IN_UINT32 / NBITS_PER_PACKET)
-+#define HISTORY_TABLE_SIZE ((1 << NBITS_IN_UINT16) / NPACKETS_PER_ENTRY)
-+
-+void InitPacketHistory(void);
-+u_int32_t PacketCrc32(unsigned char* ethPkt, ssize_t len);
-+u_int16_t Hash16(u_int32_t hash32);
-+void MarkRecentPacket(u_int16_t hash16);
-+int CheckAndMarkRecentPacket(u_int16_t hash16);
-+void PrunePacketHistory(void*);
-+
-+#endif /* _BMF_PACKETHISTORY_H */
-diff -Nur olsrd-0.4.10.orig/lib/bmf/version-script.txt olsrd-0.4.10/lib/bmf/version-script.txt
---- olsrd-0.4.10.orig/lib/bmf/version-script.txt 1970-01-01 01:00:00.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/version-script.txt 2006-12-01 08:26:58.000000000 +0100
-@@ -0,0 +1,10 @@
-+VERS_1.0
-+{
-+ global:
-+ olsrd_plugin_interface_version;
-+ olsrd_plugin_register_param;
-+ olsrd_plugin_init;
-+
-+ local:
-+ *;
-+};
-diff -Nur olsrd-0.4.10.orig/Makefile olsrd-0.4.10/Makefile
---- olsrd-0.4.10.orig/Makefile 2006-12-01 08:26:58.000000000 +0100
-+++ olsrd-0.4.10/Makefile 2006-12-01 08:26:58.000000000 +0100
-@@ -164,5 +164,10 @@
- $(MAKE) -C lib/pgraph
- $(MAKE) -C lib/pgraph install
-
-+bmf:
-+ $(MAKE) -C lib/bmf clean
-+ $(MAKE) -C lib/bmf
-+ $(MAKE) -C lib/bmf install
-+
- build_all: cfgparser olsrd libs
- install_all: install install_libs
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Bmf.c olsrd-0.4.10/lib/bmf/src/Bmf.c
---- olsrd-0.4.10.orig/lib/bmf/src/Bmf.c 2006-11-29 12:45:19.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Bmf.c 2006-11-29 12:47:49.000000000 +0100
-@@ -114,7 +114,15 @@
-
- /* Only forward multicast or local broadcast packets */
- COPY_IP(&destIp, &ipData->ip_dst);
-- if (! IsMulticast(&destIp) && ! IsLocalBroadcast(&destIp, intf))
-+ if (! IsMulticast(&destIp)
-+#ifdef SVEN_OLA_DISABLED
-+ /*
-+ * Sven-Ola@gmx.de: In a bigger mesh, there are a lot of
-+ * accidential bcast sources. Disabled to save bandwidth
-+ */
-+ && ! IsLocalBroadcast(&destIp, intf)
-+#endif
-+ )
- {
- return;
- }
-@@ -128,9 +136,10 @@
- COPY_IP(&srcIp, &ipData->ip_src);
- olsr_printf(
- 9,
-- "%s: pkt of %d bytes incoming on \"%s\": %s->%s\n",
-+ "%s: pkt of %d bytes ttl=%d incoming on \"%s\": %s->%s\n",
- PLUGIN_NAME_SHORT,
- ethPktLen,
-+ GetIpTtl(ethPkt),
- intf->ifName,
- olsr_ip_to_string(&srcIp),
- olsr_ip_to_string(&destIp));
-@@ -191,6 +200,7 @@
- struct TEncapHeader* encapHdr = (struct TEncapHeader*) buffer;
- memset (encapHdr, 0, ENCAP_HDR_LEN);
- encapHdr->crc32 = htonl(crc32);
-+ encapHdr->encapttl = GetIpTtl(ethPkt);
-
- /* If this packet is captured on an OLSR interface from an OLSR neighbor,
- * check with OLSR if I am MPR for that neighbor */
-@@ -248,7 +258,7 @@
- /* If the TTL is <= 0, do not forward this packet */
- if (GetIpTtl(ethPkt) <= 0)
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: --> not forwarding on \"%s\": TTL=0\n",
- PLUGIN_NAME_SHORT,
-@@ -272,10 +282,11 @@
- }
- else
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
-- "%s: --> forwarded to \"%s\"\n",
-+ "%s: --> forwarded(capt) ttl=%d to \"%s\"\n",
- PLUGIN_NAME_SHORT,
-+ GetIpTtl(ethPkt),
- fwIntf->ifName);
- }
- }
-@@ -291,6 +302,7 @@
- if (isToOlsrIntf && !iAmNotMpr)
- {
- int nBytesWritten;
-+ unsigned char ttl;
-
- /* Change encapsulated source MAC address to that of sending interface */
- memcpy(ethPkt + IFHWADDRLEN, fwIntf->macAddr, IFHWADDRLEN);
-@@ -298,6 +310,10 @@
- /* Destination address is local broadcast */
- encapDest.sin_addr.s_addr = ((struct sockaddr_in*)&fwIntf->olsrIntf->int_broadaddr)->sin_addr.s_addr;
-
-+ /* SVEN_OLA: Normal TTL of this socket will be 64 if unset */
-+ ttl = GetIpTtl(ethPkt);
-+ if (0 <= (nBytesWritten = setsockopt(fwIntf->encapsulatingSkfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))))
-+
- nBytesWritten = sendto(
- fwIntf->encapsulatingSkfd,
- buffer,
-@@ -306,6 +322,18 @@
- (struct sockaddr*) &encapDest,
- sizeof(encapDest));
-
-+ /*
-+ * Sven-Ola@gmx.de: Very primitive testing of forward error correction
-+ */
-+ if (nBytesWritten == len)
-+ nBytesWritten = sendto(
-+ fwIntf->encapsulatingSkfd,
-+ buffer,
-+ len,
-+ MSG_DONTROUTE,
-+ (struct sockaddr*) &encapDest,
-+ sizeof(encapDest));
-+
- if (nBytesWritten != len)
- {
- olsr_printf(
-@@ -318,10 +346,11 @@
- }
- else
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
-- "%s: --> encapsulated and forwarded to \"%s\"\n",
-+ "%s: --> encapsulated and forwarded ttl=%d to \"%s\"\n",
- PLUGIN_NAME_SHORT,
-+ GetIpTtl(ethPkt),
- fwIntf->ifName);
- } /* if (nBytesWritten != len) */
- } /* else if (isToOlsrIntf && !iAmNotMpr) */
-@@ -329,7 +358,7 @@
- else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) */
- if (!isFromOlsrIntf && !isToOlsrIntf)
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: --> not forwarding from \"%s\" to \"%s\": both non-OLSR interfaces\n",
- PLUGIN_NAME_SHORT,
-@@ -339,7 +368,7 @@
-
- else /* (!isFromOlsrIntf || isToOlsrIntf) && (!isToOlsrIntf || iAmNotMpr) && (isFromOlsrIntf || isToOlsrIntf) */
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: --> not forwarding from \"%s\" to \"%s\": I am not selected as MPR by %s\n",
- PLUGIN_NAME_SHORT,
-@@ -402,17 +431,21 @@
-
- ipData = (struct ip*) (ethPkt + IP_HDR_OFFSET);
-
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
-- "%s: encapsulated pkt of %d bytes incoming on \"%s\": %s->",
-+ "%s: encapsulated pkt of %d bytes ttl=%d incoming on \"%s\": %s->",
- PLUGIN_NAME_SHORT,
- ethPktLen,
-+ GetIpTtl(ethPkt),
- intf->ifName,
- inet_ntoa(ipData->ip_src));
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
-- "%s, forwarded by %s\n",
-- inet_ntoa(ipData->ip_dst), /* not possible to call inet_ntoa twice in same printf */
-+ "%s, ",
-+ inet_ntoa(ipData->ip_dst)); /* not possible to call inet_ntoa twice in same printf */
-+ olsr_printf(
-+ 9,
-+ "forwarded by %s\n",
- olsr_ip_to_string(fromIp));
-
- /* Get encapsulation header */
-@@ -421,7 +454,7 @@
- /* Check if this packet was seen recently */
- if (CheckAndMarkRecentPacket(Hash16(ntohl(encapHdr->crc32))))
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: --> discarding: packet is duplicate\n",
- PLUGIN_NAME_SHORT);
-@@ -448,12 +481,28 @@
- }
- else
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
-- "%s: --> unpacked and forwarded to \"%s\"\n",
-+ "%s: --> unpacked and forwarded ttl=%d to \"%s\"\n",
- PLUGIN_NAME_SHORT,
-+ GetIpTtl(ethPkt),
- EtherTunTapIfName);
- }
-+
-+ /*
-+ * Sven-Ola@gmx.de: The original implemenation make a wave
-+ * through the complete mesh for every packet. Packets are
-+ * discarded if any device has seen it (most bad case). We
-+ * Want some "local" distribution mode, so I've added some
-+ * hopcounter here - derived from the original ttl
-+ */
-+ if (0 == encapHdr->encapttl || 0 == --encapHdr->encapttl) {
-+ olsr_printf(
-+ 9,
-+ "%s: --> dicarding encapsulated: TTL=0\n",
-+ PLUGIN_NAME_SHORT);
-+ return;
-+ }
-
- /* Lookup main address of forwarding node */
- forwarder = mid_lookup_main_addr(fromIp);
-@@ -489,7 +538,7 @@
- /* If the TTL is <= 0, do not forward this packet */
- if (GetIpTtl(ethPkt) <= 0)
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: --> not forwarding on \"%s\": TTL=0\n",
- PLUGIN_NAME_SHORT,
-@@ -509,10 +558,12 @@
- }
- else
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
-- "%s: --> unpacked and forwarded to \"%s\"\n",
-+ "%s: --> unpacked and forwarded ttl=%d, sttl=%d to \"%s\"\n",
- PLUGIN_NAME_SHORT,
-+ GetIpTtl(ethPkt),
-+ sttl.ttl,
- fwIntf->ifName);
- }
- }
-@@ -551,17 +602,18 @@
- }
- else
- {
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
-- "%s: --> forwarded to \"%s\"\n",
-+ "%s: --> forwarded(encrec) ttl=%d to \"%s\"\n",
- PLUGIN_NAME_SHORT,
-+ GetIpTtl(ethPkt),
- fwIntf->ifName);
- }
- } /* else if (iAmMpr) */
- else /* fwIntf->olsrIntf != NULL && !iAmMpr */
- {
- /* fwIntf is an OLSR interface and I am not selected as MPR */
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: --> not forwarding to \"%s\": I am not selected as MPR by %s\n",
- PLUGIN_NAME_SHORT,
-@@ -690,7 +742,15 @@
- {
- union olsr_ip_addr destIp;
- COPY_IP(&destIp, &ipData->ip_dst);
-- if (IsMulticast(&destIp) || IsLocalBroadcast(&destIp, currIf))
-+ if (IsMulticast(&destIp)
-+#ifdef SVEN_OLA_DISABLED
-+ /*
-+ * Sven-Ola@gmx.de: In a bigger mesh, there are a lot of
-+ * accidential bcast sources. Disabled to save bandwidth
-+ */
-+ || IsLocalBroadcast(&destIp, currIf)
-+#endif
-+ )
- {
- if (! IsOlsrOrBmfPacket(currIf, ethPkt, nBytes))
- {
-@@ -701,8 +761,15 @@
- }
- }
- }
-- else if (pktAddr.sll_pkttype == PACKET_MULTICAST ||
-- pktAddr.sll_pkttype == PACKET_BROADCAST)
-+ else if (pktAddr.sll_pkttype == PACKET_MULTICAST
-+#ifdef SVEN_OLA_DISABLED
-+ /*
-+ * Sven-Ola@gmx.de: In a bigger mesh, there are a lot of
-+ * accidential bcast sources. Disabled to save bandwidth
-+ */
-+ || pktAddr.sll_pkttype == PACKET_BROADCAST
-+#endif
-+ )
- {
- /* An inbound multicast or broadcast packet was captured */
- BmfPacketCaptured(currIf, buffer, nBytes + ENCAP_HDR_LEN);
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c
---- olsrd-0.4.10.orig/lib/bmf/src/NetworkInterfaces.c 2006-11-29 12:45:19.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/NetworkInterfaces.c 2006-11-29 12:47:49.000000000 +0100
-@@ -568,7 +568,7 @@
- newIf->next = BmfInterfaces;
- BmfInterfaces = newIf;
-
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: opened %s interface \"%s\"\n",
- PLUGIN_NAME_SHORT,
-@@ -738,7 +738,7 @@
- nClosed++;
- }
-
-- OLSR_PRINTF(
-+ olsr_printf(
- 9,
- "%s: closed %s interface \"%s\"\n",
- PLUGIN_NAME_SHORT,
-@@ -756,7 +756,7 @@
- close(EtherTunTapFd);
- nClosed++;
-
-- OLSR_PRINTF(9, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
-+ olsr_printf(9, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
- }
-
- BmfInterfaces = NULL;
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.c olsrd-0.4.10/lib/bmf/src/Packet.c
---- olsrd-0.4.10.orig/lib/bmf/src/Packet.c 2006-11-29 12:45:19.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Packet.c 2006-11-29 12:50:35.000000000 +0100
-@@ -46,6 +46,8 @@
- #include <assert.h> /* assert() */
- #include <sys/types.h> /* u_int32_t */
- #include <netinet/in.h> /* ntohs(), htons() */
-+/* Fixes (k)ubuntu linux-kernel-headers package */
-+#include <asm/byteorder.h>
- #include <linux/ip.h>
-
- /* -------------------------------------------------------------------------
-diff -Nur olsrd-0.4.10.orig/lib/bmf/src/Packet.h olsrd-0.4.10/lib/bmf/src/Packet.h
---- olsrd-0.4.10.orig/lib/bmf/src/Packet.h 2006-11-29 12:45:19.000000000 +0100
-+++ olsrd-0.4.10/lib/bmf/src/Packet.h 2006-11-29 12:47:49.000000000 +0100
-@@ -66,7 +66,8 @@
- u_int32_t crc32;
- u_int32_t futureExpansion1;
- u_int32_t futureExpansion2;
-- u_int32_t futureExpansion3;
-+ u_int8_t futureExpansion3[3];
-+ u_int8_t encapttl;
- } __attribute__((__packed__));
-
- #define ENCAP_HDR_LEN sizeof(struct TEncapHeader)
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/src/duplicate_set.c olsrd-0.4.10/src/duplicate_set.c
---- olsrd-0.4.10.orig/src/duplicate_set.c 2005-02-27 19:39:43.000000000 +0100
-+++ olsrd-0.4.10/src/duplicate_set.c 2006-11-12 09:33:49.000000000 +0100
-@@ -93,7 +93,7 @@
-
-
- /* Hash the senders address */
-- hash = olsr_hashing(originator);
-+ hash = HASHMASK & seqno;
-
- new_dup_entry = olsr_malloc(sizeof(struct dup_entry), "New dup entry");
-
-@@ -131,7 +131,7 @@
- struct dup_entry *tmp_dup_table;
-
- /* Hash the senders address */
-- hash = olsr_hashing(originator);
-+ hash = HASHMASK & seqno;
-
- /* Check for entry */
- for(tmp_dup_table = dup_set[hash].next;
-@@ -163,7 +163,7 @@
- struct dup_entry *tmp_dup_table;
-
- /* Hash the senders address */
-- hash = olsr_hashing(originator);
-+ hash = HASHMASK & seqno;
-
- /* Check for entry */
- for(tmp_dup_table = dup_set[hash].next;
-@@ -268,7 +268,7 @@
- struct dup_iface *new_iface;
-
- /* Hash the senders address */
-- hash = olsr_hashing(originator);
-+ hash = HASHMASK & seqno;
-
-
- /* Check for entry */
-@@ -313,7 +313,7 @@
- struct dup_entry *tmp_dup_table;
-
- /* Hash the senders address */
-- hash = olsr_hashing(originator);
-+ hash = HASHMASK & seqno;
-
- /* Check for entry */
- for(tmp_dup_table = dup_set[hash].next;
-diff -Nur olsrd-0.4.10.orig/src/hashing.c olsrd-0.4.10/src/hashing.c
---- olsrd-0.4.10.orig/src/hashing.c 2005-02-20 19:52:18.000000000 +0100
-+++ olsrd-0.4.10/src/hashing.c 2006-11-12 09:33:49.000000000 +0100
-@@ -58,7 +58,7 @@
-
- if(olsr_cnf->ip_version == AF_INET)
- /* IPv4 */
-- hash = (ntohl(address->v4));
-+ hash = address->v4x[0] ^ address->v4x[1] ^ address->v4x[2] ^ address->v4x[3];
- else
- {
- /* IPv6 */
-diff -Nur olsrd-0.4.10.orig/src/hashing.h olsrd-0.4.10/src/hashing.h
---- olsrd-0.4.10.orig/src/hashing.h 2005-02-20 19:52:18.000000000 +0100
-+++ olsrd-0.4.10/src/hashing.h 2006-11-12 09:33:49.000000000 +0100
-@@ -43,7 +43,7 @@
- #ifndef _OLSR_HASHING
- #define _OLSR_HASHING
-
--#define HASHSIZE 32
-+#define HASHSIZE 128
- #define HASHMASK (HASHSIZE - 1)
-
- #include "olsr_types.h"
-diff -Nur olsrd-0.4.10.orig/src/lq_avl.c olsrd-0.4.10/src/lq_avl.c
---- olsrd-0.4.10.orig/src/lq_avl.c 2005-01-22 15:30:57.000000000 +0100
-+++ olsrd-0.4.10/src/lq_avl.c 2006-11-12 09:33:49.000000000 +0100
-@@ -40,6 +40,9 @@
- */
-
- #include <stddef.h>
-+#ifndef DISABLE_SVEN_OLA
-+#include <time.h>
-+#endif
-
- #include "lq_avl.h"
-
-@@ -52,11 +55,33 @@
- tree->comp = comp;
- }
-
-+#ifndef DISABLE_SVEN_OLA
-+static struct avl_node *avl_find_rec_ipv4(struct avl_node *node, void *key)
-+{
-+ if (*(unsigned int *)key < *(unsigned int *)node->key) {
-+ if (node->left != NULL) {
-+ return avl_find_rec_ipv4(node->left, key);
-+ }
-+ }
-+ else if (*(unsigned int *)key > *(unsigned int *)node->key) {
-+ if (node->right != NULL) {
-+ return avl_find_rec_ipv4(node->right, key);
-+ }
-+ }
-+ return node;
-+}
-+#endif
-+
- static struct avl_node *avl_find_rec(struct avl_node *node, void *key,
- int (*comp)(void *, void *))
- {
- int diff;
-
-+#ifndef DISABLE_SVEN_OLA
-+ if (0 == comp) {
-+ return avl_find_rec_ipv4(node, key);
-+ }
-+#endif
- diff = (*comp)(key, node->key);
-
- if (diff < 0)
-@@ -87,6 +112,13 @@
-
- node = avl_find_rec(tree->root, key, tree->comp);
-
-+#ifndef DISABLE_SVEN_OLA
-+ if (0 == tree->comp) {
-+ if (0 != svenola_avl_comp_ipv4(node->key, key))
-+ return NULL;
-+ }
-+ else
-+#endif
- if ((*tree->comp)(node->key, key) != 0)
- return NULL;
-
-@@ -228,6 +260,12 @@
-
- node = avl_find_rec(tree->root, new->key, tree->comp);
-
-+#ifndef DISABLE_SVEN_OLA
-+ if (0 == tree->comp) {
-+ diff = svenola_avl_comp_ipv4(new->key, node->key);
-+ }
-+ else
-+#endif
- diff = (*tree->comp)(new->key, node->key);
-
- if (diff == 0)
-diff -Nur olsrd-0.4.10.orig/src/lq_avl.h olsrd-0.4.10/src/lq_avl.h
---- olsrd-0.4.10.orig/src/lq_avl.h 2005-02-20 19:52:18.000000000 +0100
-+++ olsrd-0.4.10/src/lq_avl.h 2006-11-12 09:33:49.000000000 +0100
-@@ -62,4 +62,9 @@
- struct avl_node *avl_find(struct avl_tree *, void *);
- int avl_insert(struct avl_tree *, struct avl_node *);
-
-+#ifndef DISABLE_SVEN_OLA
-+#define svenola_avl_comp_ipv4(ip1, ip2) \
-+ (*(unsigned int *)ip1 == *(unsigned int *)ip2 ? 0 : \
-+ *(unsigned int *)ip1 < *(unsigned int *)ip2 ? -1 : +1)
-+#endif
- #endif
-diff -Nur olsrd-0.4.10.orig/src/lq_list.c olsrd-0.4.10/src/lq_list.c
---- olsrd-0.4.10.orig/src/lq_list.c 2004-12-04 18:06:57.000000000 +0100
-+++ olsrd-0.4.10/src/lq_list.c 2006-11-12 09:33:49.000000000 +0100
-@@ -48,6 +48,7 @@
- list->tail = NULL;
- }
-
-+#ifdef DISABLE_SVEN_OLA
- struct list_node *list_get_head(struct list *list)
- {
- return list->head;
-@@ -67,6 +68,7 @@
- {
- return node->prev;
- }
-+#endif
-
- void list_add_head(struct list *list, struct list_node *node)
- {
-diff -Nur olsrd-0.4.10.orig/src/lq_list.h olsrd-0.4.10/src/lq_list.h
---- olsrd-0.4.10.orig/src/lq_list.h 2005-02-20 19:52:18.000000000 +0100
-+++ olsrd-0.4.10/src/lq_list.h 2006-11-12 09:33:49.000000000 +0100
-@@ -58,11 +58,18 @@
-
- void list_init(struct list *list);
-
-+#ifndef DISABLE_SVEN_OLA
-+#define list_get_head(node) (node)->head
-+#define list_get_tail(node) (node)->tail
-+#define list_get_next(node) (node)->next
-+#define list_get_prev(node) (node)->prev
-+#else
- struct list_node *list_get_head(struct list *list);
- struct list_node *list_get_tail(struct list *list);
-
- struct list_node *list_get_next(struct list_node *node);
- struct list_node *list_get_prev(struct list_node *node);
-+#endif
-
- void list_add_head(struct list *list, struct list_node *node);
- void list_add_tail(struct list *list, struct list_node *node);
-diff -Nur olsrd-0.4.10.orig/src/lq_route.c olsrd-0.4.10/src/lq_route.c
---- olsrd-0.4.10.orig/src/lq_route.c 2005-11-29 19:37:58.000000000 +0100
-+++ olsrd-0.4.10/src/lq_route.c 2006-11-12 09:34:46.000000000 +0100
-@@ -205,6 +205,16 @@
-
- // add the vertex to the list, if it's not us
-
-+#ifndef DISABLE_SVEN_OLA
-+ if (0 == comp) {
-+ if (svenola_avl_comp_ipv4(&main_addr, node->key) != 0)
-+ {
-+ vert->node.data = vert;
-+ list_add_tail(vertex_list, &vert->node);
-+ }
-+ }
-+ else
-+#endif
- if ((*comp)(&main_addr, node->key) != 0)
- {
- vert->node.data = vert;
-@@ -266,6 +276,154 @@
- }
-
- // XXX - bad complexity
-+#define SVEN_OPT
-+#undef SVEN_OPT_DBG
-+
-+/*
-+ * The function extract_best() is most expensive (>50% CPU in profiling).
-+ * It is called in two modes: while doing Dijkstra route calculation and
-+ * while searching for a direct route/hna. The latter can be optimized
-+ * because the stored verices do not change from call to call and it is
-+ * more sufficient to have them sorted/popped from a list rather than
-+ * searching the complete list by every call. Sven-Ola@gmx.de, 11/2006
-+ */
-+
-+#ifdef SVEN_OPT
-+static struct dijk_vertex **etx_cache = 0;
-+static int etx_cache_count;
-+static int etx_cache_get;
-+static int etx_cache_saved = 0;
-+
-+static int etx_cache_compare(const void *a, const void *b)
-+{
-+ // Oh jeah. I love this macro assembler :)
-+
-+ if ((*(struct dijk_vertex **)a)->path_etx > (*(struct dijk_vertex **)b)->path_etx) return 1;
-+ if ((*(struct dijk_vertex **)a)->path_etx < (*(struct dijk_vertex **)b)->path_etx) return -1;
-+
-+ // This is for debugging only: etx==etx then compare pointers
-+ // to make it possible to compare to the original search algo.
-+ if (*(struct dijk_vertex **)a > *(struct dijk_vertex **)b) return 1;
-+ if (*(struct dijk_vertex **)a < *(struct dijk_vertex **)b) return -1;
-+
-+ return 0;
-+}
-+
-+static struct dijk_vertex *extract_best_route(struct list *vertex_list)
-+{
-+#ifdef SVEN_OPT_DBG
-+ float best_etx = INFINITE_ETX + 1.0;
-+#endif
-+ struct list_node *node;
-+ struct dijk_vertex *vert;
-+ struct dijk_vertex *res = NULL;
-+
-+#ifdef SVEN_OPT_DBG
-+ node = list_get_head(vertex_list);
-+
-+ // loop through all vertices
-+
-+ while (node != NULL)
-+ {
-+ vert = node->data;
-+
-+ // see whether the current vertex is better than what we have
-+
-+ if (!vert->done && vert->path_etx < best_etx)
-+ {
-+ best_etx = vert->path_etx;
-+ res = vert;
-+ }
-+ else if (!vert->done && vert->path_etx == best_etx && vert < res)
-+ {
-+ // Otherwise order is undefined if etx==etx and debug will complain
-+ best_etx = vert->path_etx;
-+ res = vert;
-+ }
-+
-+ node = list_get_next(node);
-+ }
-+#endif
-+ if (NULL == etx_cache)
-+ {
-+ int count = 0;
-+ node = list_get_head(vertex_list);
-+ while (node != NULL)
-+ {
-+ vert = node->data;
-+ if (!vert->done && vert->path_etx < INFINITE_ETX) count++;
-+ node = list_get_next(node);
-+ }
-+ if (0 < count)
-+ {
-+ etx_cache = olsr_malloc(sizeof(etx_cache[0]) * count, "ETX Cache");
-+#ifdef SVEN_OPT_DBG
-+ printf("count=%d, Malloc(%d)=%p\n", count, sizeof(etx_cache[0]) * count, etx_cache);
-+#endif
-+ node = list_get_head(vertex_list);
-+ etx_cache_count = 0;
-+ etx_cache_get = 0;
-+ while (node != NULL)
-+ {
-+ vert = node->data;
-+ if (!vert->done && vert->path_etx < INFINITE_ETX)
-+ {
-+ etx_cache[etx_cache_count] = vert;
-+ etx_cache_count++;
-+ }
-+ node = list_get_next(node);
-+ }
-+#ifdef SVEN_OPT_DBG
-+ printf("qsort(etx_cache_count=%d)\n", etx_cache_count);
-+#endif
-+ qsort(etx_cache, etx_cache_count, sizeof(etx_cache[0]), etx_cache_compare);
-+#ifdef SVEN_OPT_DBG
-+ if (0 < etx_cache_count)
-+ {
-+ int i = 0;
-+ while(i < etx_cache_count && i < 10)
-+ {
-+ printf("%d: %p=%f\n", i, etx_cache[i], etx_cache[i]->path_etx);
-+ i++;
-+ }
-+ }
-+#endif
-+ }
-+ }
-+
-+#ifdef SVEN_OPT_DBG
-+ if (NULL != etx_cache)
-+ {
-+ struct dijk_vertex *rescache = NULL;
-+ if (etx_cache_get < etx_cache_count)
-+ {
-+ rescache = etx_cache[etx_cache_get++];
-+ }
-+ if (res != rescache)
-+ {
-+ printf("miss: etx_cache_get=%d, res=%p,%f != rescache=%p,%f\n",
-+ etx_cache_get, res, (NULL != res ? res->path_etx : -1), rescache, (NULL != rescache ? rescache->path_etx : -1));
-+ }
-+ else
-+ {
-+ etx_cache_saved++;
-+ }
-+ }
-+#else
-+ if (NULL != etx_cache && etx_cache_get < etx_cache_count)
-+ {
-+ res = etx_cache[etx_cache_get++];
-+ }
-+#endif
-+
-+ // if we've found a vertex, remove it from the set
-+
-+ if (res != NULL)
-+ res->done = OLSR_TRUE;
-+
-+ return res;
-+}
-+#endif // SVEN_OPT
-
- static struct dijk_vertex *extract_best(struct list *vertex_list)
- {
-@@ -371,7 +529,11 @@
- struct interface *inter;
-
- if (ipsize == 4)
-+#ifndef DISABLE_SVEN_OLA
-+ avl_comp = 0;
-+#else
- avl_comp = avl_comp_ipv4;
-+#endif
-
- else
- avl_comp = avl_comp_ipv6;
-@@ -614,13 +776,27 @@
-
- // add HNA routes - the set of unprocessed network nodes contains
- // all reachable network nodes
-+#ifdef SVEN_OPT
-+#ifdef SVEN_OPT_DBG
-+ printf("free etx_cache, saved compares=%d, etx_cache=%p\n", etx_cache_saved, etx_cache);
-+ etx_cache_saved = 0;
-+#endif
-+ if (NULL != etx_cache) {
-+ free(etx_cache);
-+ etx_cache = NULL;
-+ }
-+#endif
-
- for (;;)
- {
- // extract the network node with the best ETX and remove it
- // from the set of unprocessed network nodes
-
-+#ifdef SVEN_OPT
-+ vert = extract_best_route(&vertex_list);
-+#else
- vert = extract_best(&vertex_list);
-+#endif
-
- // no more nodes left
-
-diff -Nur olsrd-0.4.10.orig/src/olsr_types.h olsrd-0.4.10/src/olsr_types.h
---- olsrd-0.4.10.orig/src/olsr_types.h 2005-05-15 14:57:24.000000000 +0200
-+++ olsrd-0.4.10/src/olsr_types.h 2006-11-12 09:33:49.000000000 +0100
-@@ -93,6 +93,7 @@
- union olsr_ip_addr
- {
- olsr_u32_t v4;
-+ olsr_u8_t v4x[4];
- struct in6_addr v6;
- };
-
+++ /dev/null
-diff -Naur olsrd-0.4.10/files/olsrd.conf.default.lq olsrd-0.4.10-patched/files/olsrd.conf.default.lq
---- olsrd-0.4.10/files/olsrd.conf.default.lq 2005-03-31 20:35:23.000000000 +0200
-+++ olsrd-0.4.10-patched/files/olsrd.conf.default.lq 2006-11-16 13:22:26.000000000 +0100
-@@ -259,6 +259,7 @@
- # HNA validity time
- HnaValidityTime 30.0
-
-+
- # When multiple links exist between hosts
- # the weight of interface is used to determine
- # the link to use. Normally the weight is
-@@ -266,9 +267,29 @@
- # on the characteristics of the interface,
- # but here you can specify a fixed value.
- # Olsrd will choose links with the lowest value.
--
-+ # Note:
-+ # Interface weight is used only when LinkQualityLevel is 0.
-+ # For any other value of LinkQualityLevel, the interface ETX
-+ # value is used instead.
- # Weight 0
-
-
-+ # If a certain route should be preferred
-+ # or ignored by the mesh, the Link Quality
-+ # value of a node can be multiplied with a factor
-+ # entered here. In the example the route
-+ # using 192.168.0.1 would rather be ignored.
-+ # A multiplier of 0.5 will result in a small
-+ # (bad) LinkQuality value and a high (bad)
-+ # ETX value.
-+ # Note:
-+ # Link quality multiplier is used only when
-+ # LinkQualityLevel is > 0.
-+
-+ # LinkQualityMult 192.168.0.1 0.5
-+
-+ # This multiplier applies to all other nodes
-+ # LinkQualityMult default 0.8
-+
- }
-
-diff -Naur olsrd-0.4.10/files/olsrd.conf.default.lq-fisheye olsrd-0.4.10-patched/files/olsrd.conf.default.lq-fisheye
---- olsrd-0.4.10/files/olsrd.conf.default.lq-fisheye 2005-12-17 08:30:34.000000000 +0100
-+++ olsrd-0.4.10-patched/files/olsrd.conf.default.lq-fisheye 2006-11-16 13:24:18.000000000 +0100
-@@ -267,6 +267,7 @@
- # HNA validity time
- HnaValidityTime 100.0
-
-+
- # When multiple links exist between hosts
- # the weight of interface is used to determine
- # the link to use. Normally the weight is
-@@ -274,7 +275,10 @@
- # on the characteristics of the interface,
- # but here you can specify a fixed value.
- # Olsrd will choose links with the lowest value.
--
-+ # Note:
-+ # Interface weight is used only when LinkQualityLevel is set to 0.
-+ # For any other value of LinkQualityLevel, the interface ETX
-+ # value is used instead.
- # Weight 0
-
-
-@@ -286,13 +290,14 @@
- # A multiplier of 0.5 will result in a small
- # (bad) LinkQuality value and a high (bad)
- # ETX value.
-+ # Note:
-+ # Link quality multiplier is used only when
-+ # LinkQualityLevel is > 0.
-
- # LinkQualityMult 192.168.0.1 0.5
-
- # This multiplier applies to all other nodes
- # LinkQualityMult default 0.8
--
--
-
- }
-
-diff -Naur olsrd-0.4.10/files/olsrd.conf.default.rfc olsrd-0.4.10-patched/files/olsrd.conf.default.rfc
---- olsrd-0.4.10/files/olsrd.conf.default.rfc 2005-06-04 17:34:05.000000000 +0200
-+++ olsrd-0.4.10-patched/files/olsrd.conf.default.rfc 2006-11-16 13:23:02.000000000 +0100
-@@ -254,6 +254,7 @@
- # HNA validity time
- # HnaValidityTime 15.0
-
-+
- # When multiple links exist between hosts
- # the weight of interface is used to determine
- # the link to use. Normally the weight is
-@@ -261,9 +262,29 @@
- # on the characteristics of the interface,
- # but here you can specify a fixed value.
- # Olsrd will choose links with the lowest value.
--
-+ # Note:
-+ # Interface weight is used only when LinkQualityLevel is set to 0.
-+ # For any other value of LinkQualityLevel, the interface ETX
-+ # value is used instead.
- # Weight 0
-
-
-+ # If a certain route should be preferred
-+ # or ignored by the mesh, the Link Quality
-+ # value of a node can be multiplied with a factor
-+ # entered here. In the example the route
-+ # using 192.168.0.1 would rather be ignored.
-+ # A multiplier of 0.5 will result in a small
-+ # (bad) LinkQuality value and a high (bad)
-+ # ETX value.
-+ # Note:
-+ # Link quality multiplier is used only when
-+ # LinkQualityLevel is > 0.
-+
-+ # LinkQualityMult 192.168.0.1 0.5
-+
-+ # This multiplier applies to all other nodes
-+ # LinkQualityMult default 0.8
-+
- }
-
-diff -Naur olsrd-0.4.10/lib/httpinfo/src/html.h olsrd-0.4.10-patched/lib/httpinfo/src/html.h
---- olsrd-0.4.10/lib/httpinfo/src/html.h 2005-03-14 22:28:15.000000000 +0100
-+++ olsrd-0.4.10-patched/lib/httpinfo/src/html.h 2006-09-14 13:11:02.000000000 +0200
-@@ -48,7 +48,7 @@
-
- static const char *httpinfo_css[] =
- {
-- "A {text-decoration: none}\n",
-+ "#A {text-decoration: none}\n",
- "TH{text-align: left}\n",
- "H1, H3, TD, TH {font-family: Helvetica; font-size: 80%%}\n",
- "h2\n {\nfont-family: Helvetica;\n font-size: 14px;text-align: center;\n",
-diff -Naur olsrd-0.4.10/lib/httpinfo/src/olsrd_httpinfo.c olsrd-0.4.10-patched/lib/httpinfo/src/olsrd_httpinfo.c
---- olsrd-0.4.10/lib/httpinfo/src/olsrd_httpinfo.c 2005-12-22 16:06:52.000000000 +0100
-+++ olsrd-0.4.10-patched/lib/httpinfo/src/olsrd_httpinfo.c 2006-11-24 12:53:25.000000000 +0100
-@@ -713,7 +713,10 @@
-
- size += sprintf(&buf[size], "<h2>OLSR routes in kernel</h2>\n");
-
-- size += sprintf(&buf[size], "<table width=\"100%%\" BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=center><tr><th>Destination</th><th>Gateway</th><th>Metric</th><th>ETX</th><th>Interface</th><th>Type</th></tr>\n");
-+ size += sprintf(&buf[size], "<table width=\"100%%\" BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=center><tr><th>Destination</th><th>Gateway</th><th>Metric</th>");
-+ if (olsr_cnf->lq_level > 0)
-+ size += sprintf(&buf[size], "<th>ETX</th>");
-+ size += sprintf(&buf[size], "<th>Interface</th><th>Type</th></tr>\n");
-
- /* Neighbors */
- for(index = 0;index < HASHSIZE;index++)
-@@ -722,12 +725,23 @@
- routes != &routingtable[index];
- routes = routes->next)
- {
-- size += sprintf(&buf[size], "<tr><td>%s</td><td>%s</td><td>%d</td><td>%.2f</td><td>%s</td><td>HOST</td></tr>\n",
-- olsr_ip_to_string(&routes->rt_dst),
-- olsr_ip_to_string(&routes->rt_router),
-- routes->rt_metric,
-- routes->rt_etx,
-- routes->rt_if->int_name);
-+ size += sprintf(&buf[size],
-+ "<tr><td><a href=\"http://%s:%d/all\">%s</a></td>"
-+ "<td><a href=\"http://%s:%d/all\">%s</a></td>"
-+ "<td>%d</td>",
-+ olsr_ip_to_string(&routes->rt_dst),
-+ http_port,
-+ olsr_ip_to_string(&routes->rt_dst),
-+ olsr_ip_to_string(&routes->rt_router),
-+ http_port,
-+ olsr_ip_to_string(&routes->rt_router),
-+ routes->rt_metric);
-+ if (olsr_cnf->lq_level > 0)
-+ size += sprintf(&buf[size], "<td>%.2f</td>", routes->rt_etx);
-+ size += sprintf(&buf[size],
-+ "<td>%s</td>"
-+ "<td>HOST</td></tr>\n",
-+ routes->rt_if->int_name);
- }
- }
-
-@@ -738,11 +752,21 @@
- routes != &hna_routes[index];
- routes = routes->next)
- {
-- size += sprintf(&buf[size], "<tr><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>HNA</td></tr>\n",
-- olsr_ip_to_string(&routes->rt_dst),
-- olsr_ip_to_string(&routes->rt_router),
-- routes->rt_metric,
-- routes->rt_if->int_name);
-+ size += sprintf(&buf[size],
-+ "<tr><td>%s</td>"
-+ "<td><a href=\"http://%s:%d/all\">%s</a></td>"
-+ "<td>%d</td>",
-+ olsr_ip_to_string(&routes->rt_dst),
-+ olsr_ip_to_string(&routes->rt_router),
-+ http_port,
-+ olsr_ip_to_string(&routes->rt_router),
-+ routes->rt_metric);
-+ if (olsr_cnf->lq_level > 0)
-+ size += sprintf(&buf[size], "<td>%.2f</td>", routes->rt_etx);
-+ size += sprintf(&buf[size],
-+ "<td>%s</td>"
-+ "<td>HNA</td></tr>\n",
-+ routes->rt_if->int_name);
- }
- }
-
-@@ -816,17 +840,24 @@
-
- size += sprintf(&buf[size], "</tr>\n<tr>\n");
-
-- size += sprintf(&buf[size], "<td>Hysteresis: %s</td>\n", olsr_cnf->use_hysteresis ? "Enabled" : "Disabled");
--
-- size += sprintf(&buf[size], "<td>Hyst scaling: %0.2f</td>\n", olsr_cnf->hysteresis_param.scaling);
-- size += sprintf(&buf[size], "<td>Hyst lower/upper: %0.2f/%0.2f</td>\n", olsr_cnf->hysteresis_param.thr_low, olsr_cnf->hysteresis_param.thr_high);
-+ if (olsr_cnf->lq_level == 0)
-+ {
-+ size += sprintf(&buf[size], "<td>Hysteresis: %s</td>\n", olsr_cnf->use_hysteresis ? "Enabled" : "Disabled");
-+ if (olsr_cnf->use_hysteresis)
-+ {
-+ size += sprintf(&buf[size], "<td>Hyst scaling: %0.2f</td>\n", olsr_cnf->hysteresis_param.scaling);
-+ size += sprintf(&buf[size], "<td>Hyst lower/upper: %0.2f/%0.2f</td>\n", olsr_cnf->hysteresis_param.thr_low, olsr_cnf->hysteresis_param.thr_high);
-+ }
-+ }
-
- size += sprintf(&buf[size], "</tr>\n<tr>\n");
-
-- size += sprintf(&buf[size], "<td>LQ extention: %s</td>\n", olsr_cnf->lq_level ? "Enabled" : "Disabled");
-- size += sprintf(&buf[size], "<td>LQ level: %d</td>\n", olsr_cnf->lq_level);
-- size += sprintf(&buf[size], "<td>LQ winsize: %d</td>\n", olsr_cnf->lq_wsize);
-- size += sprintf(&buf[size], "<td></td>\n");
-+ size += sprintf(&buf[size], "<td>LQ extension: %s</td>\n", olsr_cnf->lq_level ? "Enabled" : "Disabled");
-+ if (olsr_cnf->lq_level)
-+ {
-+ size += sprintf(&buf[size], "<td>LQ level: %d</td>\n", olsr_cnf->lq_level);
-+ size += sprintf(&buf[size], "<td>LQ winsize: %d</td>\n", olsr_cnf->lq_wsize);
-+ }
-
- size += sprintf(&buf[size], "</tr></table>\n");
-
-@@ -868,7 +899,6 @@
- size += sprintf(&buf[size], "<td>WLAN: %s</td>\n", rifs->is_wireless ? "Yes" : "No");
- size += sprintf(&buf[size], "<td>STATUS: UP</td></tr>\n");
- }
--
- }
-
- size += sprintf(&buf[size], "</table>\n");
-@@ -950,21 +980,39 @@
- int size = 0, index, thop_cnt;
-
- size += sprintf(&buf[size], "<h2>Links</h2>\n");
-- size += sprintf(&buf[size], "<table width=\"100%%\" BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=center><tr><th>Local IP</th><th>remote IP</th><th>Hysteresis</th><th>LinkQuality</th><th>lost</th><th>total</th><th>NLQ</th><th>ETX</th></tr>\n");
-+ size += sprintf(&buf[size], "<table width=\"100%%\" BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=center><tr><th>Local IP</th><th>remote IP</th><th>Hysteresis</th>\n");
-+ if (olsr_cnf->lq_level > 0)
-+ size += sprintf(&buf[size], "<th>LinkQuality</th><th>lost</th><th>total</th><th>NLQ</th><th>ETX</th>\n");
-+ size += sprintf(&buf[size], "</tr>\n");
-
- /* Link set */
- link = link_set;
- while(link)
- {
-- size += sprintf(&buf[size], "<tr><td>%s</td><td>%s</td><td>%0.2f</td><td>%0.2f</td><td>%d</td><td>%d</td><td>%0.2f</td><td>%0.2f</td></tr>\n",
-- olsr_ip_to_string(&link->local_iface_addr),
-- olsr_ip_to_string(&link->neighbor_iface_addr),
-- link->L_link_quality,
-- link->loss_link_quality,
-- link->lost_packets,
-- link->total_packets,
-- link->neigh_link_quality,
-- (link->loss_link_quality * link->neigh_link_quality) ? 1.0 / (link->loss_link_quality * link->neigh_link_quality) : 0.0);
-+ size += sprintf(&buf[size],
-+ "<tr><td>%s</td>"
-+ "<td><a href=\"http://%s:%d/all\">%s</a></td>"
-+ "<td>%0.2f</td>",
-+ olsr_ip_to_string(&link->local_iface_addr),
-+ olsr_ip_to_string(&link->neighbor_iface_addr),
-+ http_port,
-+ olsr_ip_to_string(&link->neighbor_iface_addr),
-+ link->L_link_quality);
-+ if (olsr_cnf->lq_level > 0)
-+ {
-+ size += sprintf(&buf[size],
-+ "<td>%0.2f</td>"
-+ "<td>%d</td>"
-+ "<td>%d</td>"
-+ "<td>%0.2f</td>"
-+ "<td>%0.2f</td></tr>\n",
-+ link->loss_link_quality,
-+ link->lost_packets,
-+ link->total_packets,
-+ link->neigh_link_quality,
-+ (link->loss_link_quality * link->neigh_link_quality) ? 1.0 / (link->loss_link_quality * link->neigh_link_quality) : 0.0);
-+ }
-+ size += sprintf(&buf[size], "</tr>\n");
-
- link = link->next;
- }
-@@ -981,7 +1029,13 @@
- neigh = neigh->next)
- {
- size += sprintf(&buf[size],
-- "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td>",
-+ "<tr><td><a href=\"http://%s:%d/all\">%s</a></td>"
-+ "<td>%s</td>"
-+ "<td>%s</td>"
-+ "<td>%s</td>"
-+ "<td>%d</td>",
-+ olsr_ip_to_string(&neigh->neighbor_main_addr),
-+ http_port,
- olsr_ip_to_string(&neigh->neighbor_main_addr),
- (neigh->status == SYM) ? "YES" : "NO",
- neigh->is_mpr ? "YES" : "NO",
-@@ -1021,7 +1075,10 @@
- struct topo_dst *dst_entry;
-
-
-- size += sprintf(&buf[size], "<h2>Topology entries</h2>\n<table width=\"100%%\" BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=center><tr><th>Destination IP</th><th>Last hop IP</th><th>LQ</th><th>ILQ</th><th>ETX</th></tr>\n");
-+ size += sprintf(&buf[size], "<h2>Topology entries</h2>\n<table width=\"100%%\" BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=center><tr><th>Destination IP</th><th>Last hop IP</th>");
-+ if (olsr_cnf->lq_level > 0)
-+ size += sprintf(&buf[size], "<th>LQ</th><th>ILQ</th><th>ETX</th>");
-+ size += sprintf(&buf[size], "</tr>\n");
-
-
- /* Topology */
-@@ -1035,12 +1092,26 @@
- dst_entry = entry->destinations.next;
- while(dst_entry != &entry->destinations)
- {
-- size += sprintf(&buf[size], "<tr><td>%s</td><td>%s</td><td>%0.2f</td><td>%0.2f</td><td>%0.2f</td></tr>\n",
-- olsr_ip_to_string(&dst_entry->T_dest_addr),
-- olsr_ip_to_string(&entry->T_last_addr),
-- dst_entry->link_quality,
-- dst_entry->inverse_link_quality,
-- (dst_entry->link_quality * dst_entry->inverse_link_quality) ? 1.0 / (dst_entry->link_quality * dst_entry->inverse_link_quality) : 0.0);
-+ size += sprintf(&buf[size],
-+ "<tr><td><a href=\"http://%s:%d/all\">%s</a></td>"
-+ "<td><a href=\"http://%s:%d/all\">%s</a></td>",
-+ olsr_ip_to_string(&dst_entry->T_dest_addr),
-+ http_port,
-+ olsr_ip_to_string(&dst_entry->T_dest_addr),
-+ olsr_ip_to_string(&entry->T_last_addr),
-+ http_port,
-+ olsr_ip_to_string(&entry->T_last_addr));
-+ if (olsr_cnf->lq_level > 0)
-+ {
-+ size += sprintf(&buf[size],
-+ "<td>%0.2f</td>"
-+ "<td>%0.2f</td>"
-+ "<td>%0.2f</td>\n",
-+ dst_entry->link_quality,
-+ dst_entry->inverse_link_quality,
-+ (dst_entry->link_quality * dst_entry->inverse_link_quality) ? 1.0 / (dst_entry->link_quality * dst_entry->inverse_link_quality) : 0.0);
-+ }
-+ size += sprintf(&buf[size], "</tr>\n");
-
- dst_entry = dst_entry->next;
- }
-@@ -1083,7 +1154,9 @@
- olsr_ip_to_string(&tmp_net->A_network_addr));
- size += sprintf(&buf[size], "<td>%s</td>",
- olsr_netmask_to_string(&tmp_net->A_netmask));
-- size += sprintf(&buf[size], "<td>%s</td></tr>\n",
-+ size += sprintf(&buf[size], "<td><a href=\"http://%s:%d/all\">%s</a></td></tr>\n",
-+ olsr_ip_to_string(&tmp_hna->A_gateway_addr),
-+ http_port,
- olsr_ip_to_string(&tmp_hna->A_gateway_addr));
- tmp_net = tmp_net->next;
- }
-@@ -1101,7 +1174,7 @@
- int
- build_mid_body(char *buf, olsr_u32_t bufsize)
- {
-- int size = 0;
-+ int size = 0, mid_cnt;
- olsr_u8_t index;
- struct mid_entry *entry;
- struct mid_address *alias;
-@@ -1114,18 +1187,21 @@
- entry = mid_set[index].next;
- while(entry != &mid_set[index])
- {
-- size += sprintf(&buf[size], "<tr><td>%s</td>\n", olsr_ip_to_string(&entry->main_addr));
-+ size += sprintf(&buf[size], "<tr><td><a href=\"http://%s:%d/all\">%s</a></td>\n",
-+ olsr_ip_to_string(&entry->main_addr),
-+ http_port,
-+ olsr_ip_to_string(&entry->main_addr));
- size += sprintf(&buf[size], "<td><select>\n<option>IP ADDRESS</option>\n");
-
- alias = entry->aliases;
-+ mid_cnt = 0;
- while(alias)
- {
- size += sprintf(&buf[size], "<option>%s</option>\n", olsr_ip_to_string(&alias->alias));
-+ mid_cnt ++;
- alias = alias->next_alias;
- }
-- size += sprintf(&buf[size], "</select>\n");
--
-- size += sprintf(&buf[size], "</tr>\n");
-+ size += sprintf(&buf[size], "</select> (%d)</td></tr>\n", mid_cnt);
- entry = entry->next;
- }
- }
-diff -Naur olsrd-0.4.10/lib/httpinfo/src/olsrd_plugin.c olsrd-0.4.10-patched/lib/httpinfo/src/olsrd_plugin.c
---- olsrd-0.4.10/lib/httpinfo/src/olsrd_plugin.c 2005-05-29 14:47:41.000000000 +0200
-+++ olsrd-0.4.10-patched/lib/httpinfo/src/olsrd_plugin.c 2006-09-18 03:03:50.000000000 +0200
-@@ -51,6 +51,8 @@
- #include <stdlib.h>
- #include "olsrd_httpinfo.h"
-
-+int http_port = 0;
-+
- static void __attribute__ ((constructor))
- my_init(void);
-
-diff -Naur olsrd-0.4.10/lib/httpinfo/src/olsrd_plugin.h olsrd-0.4.10-patched/lib/httpinfo/src/olsrd_plugin.h
---- olsrd-0.4.10/lib/httpinfo/src/olsrd_plugin.h 2005-05-29 14:47:41.000000000 +0200
-+++ olsrd-0.4.10-patched/lib/httpinfo/src/olsrd_plugin.h 2006-09-18 03:03:38.000000000 +0200
-@@ -71,7 +71,7 @@
- #define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION " by " PLUGIN_AUTHOR
- #define PLUGIN_INTERFACE_VERSION 4
-
--int http_port;
-+extern int http_port;
-
- /* Allowed hosts stuff */
-
-diff -Naur olsrd-0.4.10/src/cfgparser/cfgfile_gen.c olsrd-0.4.10-patched/src/cfgparser/cfgfile_gen.c
---- olsrd-0.4.10/src/cfgparser/cfgfile_gen.c 2005-12-30 03:24:00.000000000 +0100
-+++ olsrd-0.4.10-patched/src/cfgparser/cfgfile_gen.c 2006-11-16 13:54:04.000000000 +0100
-@@ -311,7 +311,17 @@
- }
- }
-
-- fprintf(fd, " # When multiple links exist between hosts\n # the weight of interface is used to determine\n # the link to use. Normally the weight is\n # automatically calculated by olsrd based\n # on the characteristics of the interface,\n # but here you can specify a fixed value.\n # Olsrd will choose links with the lowest value.\n");
-+ fprintf(fd, " # When multiple links exist between hosts\n");
-+ fprintf(fd, " # the weight of interface is used to determine\n");
-+ fprintf(fd, " # the link to use. Normally the weight is\n");
-+ fprintf(fd, " # automatically calculated by olsrd based\n");
-+ fprintf(fd, " # on the characteristics of the interface,\n");
-+ fprintf(fd, " # but here you can specify a fixed value.\n");
-+ fprintf(fd, " # Olsrd will choose links with the lowest value.\n");
-+ fprintf(fd, " # Note:\n");
-+ fprintf(fd, " # Interface weight is used only when LinkQualityLevel is 0.\n");
-+ fprintf(fd, " # For any other value of LinkQualityLevel, the interface ETX\n");
-+ fprintf(fd, " # value is used instead.\n\n");
- if(in->cnf->weight.fixed)
- {
- fprintf(fd, " Weight\t %d\n\n", in->cnf->weight.value);
-@@ -615,9 +625,19 @@
- }
-
- if(first)
-- WRITE_TO_BUF(" # When multiple links exist between hosts\n # the weight of interface is used to determine\n # the link to use. Normally the weight is\n")
-- if(first)
-- WRITE_TO_BUF(" # automatically calculated by olsrd based\n # on the characteristics of the interface,\n # but here you can specify a fixed value.\n # Olsrd will choose links with the lowest value.\n")
-+ {
-+ WRITE_TO_BUF(" # When multiple links exist between hosts\n");
-+ WRITE_TO_BUF(" # the weight of interface is used to determine\n");
-+ WRITE_TO_BUF(" # the link to use. Normally the weight is\n")
-+ WRITE_TO_BUF(" # automatically calculated by olsrd based\n");
-+ WRITE_TO_BUF(" # on the characteristics of the interface,\n");
-+ WRITE_TO_BUF(" # but here you can specify a fixed value.\n");
-+ WRITE_TO_BUF(" # Olsrd will choose links with the lowest value.\n")
-+ WRITE_TO_BUF(" # Note:\n");
-+ WRITE_TO_BUF(" # Interface weight is used only when LinkQualityLevel is 0.\n");
-+ WRITE_TO_BUF(" # For any other value of LinkQualityLevel, the interface ETX\n");
-+ WRITE_TO_BUF(" # value is used instead.\n\n");
-+ }
- if(in->cnf->weight.fixed)
- {
- WRITE_TO_BUF(" Weight\t %d\n\n", in->cnf->weight.value)
-diff -Naur olsrd-0.4.10/src/defs.h olsrd-0.4.10-patched/src/defs.h
---- olsrd-0.4.10/src/defs.h 2006-01-01 16:59:02.000000000 +0100
-+++ olsrd-0.4.10-patched/src/defs.h 2006-09-13 15:24:48.000000000 +0200
-@@ -72,7 +72,7 @@
- #define MAXMESSAGESIZE 1500 /* max broadcast size */
- #define UDP_IPV4_HDRSIZE 28
- #define UDP_IPV6_HDRSIZE 48
--#define MAX_IFS 16
-+#define MAX_IFS 32
-
- /* Debug helper macro */
- #ifdef DEBUG
-diff -Naur olsrd-0.4.10/src/link_set.c olsrd-0.4.10-patched/src/link_set.c
---- olsrd-0.4.10/src/link_set.c 2005-11-17 05:25:44.000000000 +0100
-+++ olsrd-0.4.10-patched/src/link_set.c 2006-11-16 13:49:17.000000000 +0100
-@@ -263,7 +263,7 @@
- if (!COMP_IP(&walker->neighbor->neighbor_main_addr, main_addr))
- continue;
-
-- // handle the non-LQ case
-+ // handle the non-LQ, RFC-compliant case
-
- if (olsr_cnf->lq_level == 0)
- {
-@@ -297,7 +297,7 @@
- }
- }
-
-- // handle the LQ case
-+ // handle the LQ, non-RFC compliant case
-
- else
- {
-@@ -402,7 +402,8 @@
- while(tmp_link_set)
- {
- if(COMP_IP(remote, &tmp_link_set->neighbor_iface_addr) &&
-- COMP_IP(local, &tmp_link_set->local_iface_addr))
-+ COMP_IP(local, &tmp_link_set->local_iface_addr) &&
-+ COMP_IP(remote_main, &tmp_link_set->neighbor->neighbor_main_addr))
- return tmp_link_set;
- tmp_link_set = tmp_link_set->next;
- }
-@@ -501,7 +502,12 @@
-
- /* Copy the main address - make sure this is done every time
- * as neighbors might change main address */
-- COPY_IP(&neighbor->neighbor_main_addr, remote_main);
-+ /* Erik Tromp - OOPS! Don't do this! Neighbor entries are hashed through their
-+ * neighbor_main_addr field, and when that field is changed, their position
-+ * in the hash table is no longer correct, so that the function
-+ * olsr_lookup_neighbor_table() can no longer find the neighbor
-+ * entry. */
-+ /*COPY_IP(&neighbor->neighbor_main_addr, remote_main);*/
-
- neighbor->linkcount++;
-
-@@ -516,9 +522,14 @@
- * We'll go for one that is hopefully long
- * enough in most cases. 10 seconds
- */
-- OLSR_PRINTF(1, "Adding MID alias main %s ", olsr_ip_to_string(remote_main))
-- OLSR_PRINTF(1, "-> %s based on HELLO\n\n", olsr_ip_to_string(remote))
-- insert_mid_alias(remote_main, remote, MID_ALIAS_HACK_VTIME);
-+ /* Erik Tromp - commented out. It is not RFC-compliant. Also, MID aliases
-+ * that are not explicitly declared by a node will be removed as soon as
-+ * the olsr_prune_aliases(...) function is called.
-+ *
-+ * OLSR_PRINTF(1, "Adding MID alias main %s ", olsr_ip_to_string(remote_main))
-+ * OLSR_PRINTF(1, "-> %s based on HELLO\n\n", olsr_ip_to_string(remote))
-+ * insert_mid_alias(remote_main, remote, MID_ALIAS_HACK_VTIME);
-+ */
- }
-
- return link_set;
-diff -Naur olsrd-0.4.10/src/linux/net.h olsrd-0.4.10-patched/src/linux/net.h
---- olsrd-0.4.10/src/linux/net.h 2005-08-28 21:30:30.000000000 +0200
-+++ olsrd-0.4.10-patched/src/linux/net.h 2006-09-18 01:09:50.000000000 +0200
-@@ -55,8 +55,7 @@
- #include <syslog.h>
- #include <netinet/in.h>
- #include "../olsr_protocol.h"
--
--#define MAXIFS 8 /* Maximum number of network interfaces */
-+#include "../defs.h" /* MAX_IFS */
-
- /* Redirect proc entry */
- #define REDIRECT_PROC "/proc/sys/net/ipv4/conf/%s/send_redirects"
-@@ -77,7 +76,7 @@
- struct nic_state *next;
- };
-
--struct nic_state nic_states[MAXIFS];
-+struct nic_state nic_states[MAX_IFS];
-
-
- extern int
-diff -Naur olsrd-0.4.10/src/local_hna_set.c olsrd-0.4.10-patched/src/local_hna_set.c
---- olsrd-0.4.10/src/local_hna_set.c 2005-02-27 19:39:43.000000000 +0100
-+++ olsrd-0.4.10-patched/src/local_hna_set.c 2006-09-20 09:55:20.000000000 +0200
-@@ -129,6 +129,45 @@
- return 0;
- }
-
-+struct hna4_entry *
-+find_local_hna4_entry(union olsr_ip_addr *net, olsr_u32_t mask)
-+{
-+ struct hna4_entry *h4 = olsr_cnf->hna4_entries;
-+
-+ while(h4)
-+ {
-+ if((net->v4 == h4->net.v4) &&
-+ (mask == h4->netmask.v4))
-+ {
-+ return h4;
-+ }
-+ h4 = h4->next;
-+ }
-+
-+ return NULL;
-+}
-+
-+
-+
-+struct hna6_entry *
-+find_local_hna6_entry(union olsr_ip_addr *net, olsr_u16_t prefix_len)
-+{
-+ struct hna6_entry *h6 = olsr_cnf->hna6_entries;
-+
-+ while(h6)
-+ {
-+ if((memcmp(net, &h6->net, ipsize) == 0) &&
-+ (prefix_len == h6->prefix_len))
-+ {
-+ return h6;
-+ }
-+ h6 = h6->next;
-+ }
-+
-+ return NULL;
-+}
-+
-+
-
-
- int
-diff -Naur olsrd-0.4.10/src/local_hna_set.h olsrd-0.4.10-patched/src/local_hna_set.h
---- olsrd-0.4.10/src/local_hna_set.h 2005-02-20 19:52:18.000000000 +0100
-+++ olsrd-0.4.10-patched/src/local_hna_set.h 2006-09-20 09:55:42.000000000 +0200
-@@ -58,6 +58,12 @@
- int
- remove_local_hna6_entry(union olsr_ip_addr *, olsr_u16_t);
-
-+struct hna4_entry *
-+find_local_hna4_entry(union olsr_ip_addr *net, olsr_u32_t mask);
-+
-+struct hna6_entry *
-+find_local_hna6_entry(union olsr_ip_addr *net, olsr_u16_t prefix_len);
-+
- int
- check_inet_gw(void);
-
-diff -Naur olsrd-0.4.10/src/lq_mpr.c olsrd-0.4.10-patched/src/lq_mpr.c
---- olsrd-0.4.10/src/lq_mpr.c 2005-11-29 19:37:58.000000000 +0100
-+++ olsrd-0.4.10-patched/src/lq_mpr.c 2006-11-16 15:18:33.000000000 +0100
-@@ -51,7 +51,7 @@
- struct neighbor_list_entry *walker;
- int i, k;
- struct neighbor_entry *neigh;
-- double best;
-+ double best, best_1hop;
- olsr_bool mpr_changes = OLSR_FALSE;
- struct link_entry *link;
-
-@@ -90,6 +90,8 @@
- neigh2 != &two_hop_neighbortable[i];
- neigh2 = neigh2->next)
- {
-+ best_1hop = -1.0;
-+
- // check whether this 2-hop neighbour is also a neighbour
-
- neigh = olsr_lookup_neighbor_table(&neigh2->neighbor_2_addr);
-@@ -110,14 +112,14 @@
- if(!link)
- continue;
-
-- best = link->loss_link_quality * link->neigh_link_quality;
-+ best_1hop = link->loss_link_quality * link->neigh_link_quality;
-
- // see wether we find a better route via an MPR
-
- for (walker = neigh2->neighbor_2_nblist.next;
- walker != &neigh2->neighbor_2_nblist;
- walker = walker->next)
-- if (walker->path_link_quality > best)
-+ if (walker->path_link_quality > best_1hop)
- break;
-
- // we've reached the end of the list, so we haven't found
-@@ -157,7 +159,10 @@
- best = walker->path_link_quality;
- }
-
-- if (neigh != NULL)
-+ // Found a 1-hop neighbor that we haven't previously selected.
-+ // Use it as MPR only when the 2-hop path through it is better than
-+ // any existing 1-hop path.
-+ if ((neigh != NULL) && (best > best_1hop))
- {
- neigh->is_mpr = OLSR_TRUE;
- neigh->skip = OLSR_TRUE;
-diff -Naur olsrd-0.4.10/src/mid_set.c olsrd-0.4.10-patched/src/mid_set.c
---- olsrd-0.4.10/src/mid_set.c 2005-05-29 14:47:45.000000000 +0200
-+++ olsrd-0.4.10-patched/src/mid_set.c 2006-11-13 14:29:14.000000000 +0100
-@@ -46,6 +46,7 @@
- #include "scheduler.h"
- #include "neighbor_table.h"
- #include "link_set.h"
-+#include "packet.h" /* struct mid_alias */
-
-
- struct mid_entry mid_set[HASHSIZE];
-@@ -99,6 +100,7 @@
- struct mid_entry *tmp;
- struct mid_address *tmp_adr;
- olsr_u32_t hash, alias_hash;
-+ union olsr_ip_addr *registered_m_addr;
-
- hash = olsr_hashing(m_addr);
- alias_hash = olsr_hashing(&alias->alias);
-@@ -110,8 +112,16 @@
- {
- if(COMP_IP(&tmp->main_addr, m_addr))
- break;
-+ }
-+
-+ /* Check if alias is already registered with m_addr */
-+ registered_m_addr = mid_lookup_main_addr(&alias->alias);
-+ if (registered_m_addr != NULL && COMP_IP(registered_m_addr, m_addr))
-+ {
-+ /* Alias is already registered with main address. Nothing to do here. */
-+ return;
- }
--
-+
- /*If the address was registered*/
- if(tmp != &mid_set[hash])
- {
-@@ -312,7 +322,7 @@
- /*find match*/
- if(COMP_IP(&tmp_list->main_addr, adr))
- {
-- //printf("Updating timer for node %s\n",ip_to_string(&tmp_list->main_addr));
-+ // printf("MID: Updating timer for node %s\n", olsr_ip_to_string(&tmp_list->main_addr));
- tmp_list->ass_timer = GET_TIMESTAMP(vtime*1000);
-
- return 1;
-@@ -322,6 +332,91 @@
- }
-
-
-+/**
-+ *Remove aliases from 'entry' which are not listed in 'declared_aliases'.
-+ *
-+ *@param entry the MID entry
-+ *@param declared_aliases the list of declared aliases for the MID entry
-+ *
-+ *@return nada
-+ */
-+void
-+olsr_prune_aliases(union olsr_ip_addr *m_addr, struct mid_alias *declared_aliases)
-+{
-+ struct mid_entry *entry;
-+ olsr_u32_t hash;
-+ struct mid_address *registered_aliases;
-+ struct mid_address *previous_alias;
-+ struct mid_alias *save_declared_aliases = declared_aliases;
-+
-+ hash = olsr_hashing(m_addr);
-+
-+ /* Check for registered entry */
-+ for(entry = mid_set[hash].next;
-+ entry != &mid_set[hash];
-+ entry = entry->next)
-+ {
-+ if(COMP_IP(&entry->main_addr, m_addr))
-+ break;
-+ }
-+ if(entry == &mid_set[hash])
-+ {
-+ /* MID entry not found, nothing to prune here */
-+ return;
-+ }
-+
-+ registered_aliases = entry->aliases;
-+ previous_alias = NULL;
-+
-+ while(registered_aliases != 0)
-+ {
-+ struct mid_address *current_alias = registered_aliases;
-+ registered_aliases = registered_aliases->next_alias;
-+
-+ declared_aliases = save_declared_aliases;
-+
-+ /* Go through the list of declared aliases to find the matching current alias */
-+ while(declared_aliases != 0 &&
-+ ! COMP_IP(¤t_alias->alias, &declared_aliases->alias_addr))
-+ {
-+ declared_aliases = declared_aliases->next;
-+ }
-+
-+ if (declared_aliases == 0)
-+ {
-+ /* Current alias not found in list of declared aliases: free current alias */
-+ OLSR_PRINTF(1, "MID remove: (%s, ", olsr_ip_to_string(&entry->main_addr))
-+ OLSR_PRINTF(1, "%s)\n", olsr_ip_to_string(¤t_alias->alias))
-+
-+ /* Update linked list as seen by 'entry' */
-+ if (previous_alias != NULL)
-+ {
-+ previous_alias->next_alias = current_alias->next_alias;
-+ }
-+ else
-+ {
-+ entry->aliases = current_alias->next_alias;
-+ }
-+
-+ /* Remove from hash table */
-+ DEQUEUE_ELEM(current_alias);
-+
-+ free(current_alias);
-+
-+ /*
-+ *Recalculate topology
-+ */
-+ changes_neighborhood = OLSR_TRUE;
-+ changes_topology = OLSR_TRUE;
-+ }
-+ else
-+ {
-+ previous_alias = current_alias;
-+ }
-+ }
-+}
-+
-+
-
- /**
- *Find timed out entries and delete them
-diff -Naur olsrd-0.4.10/src/mid_set.h olsrd-0.4.10-patched/src/mid_set.h
---- olsrd-0.4.10/src/mid_set.h 2005-05-29 14:47:45.000000000 +0200
-+++ olsrd-0.4.10-patched/src/mid_set.h 2006-11-08 13:35:44.000000000 +0100
-@@ -73,6 +73,7 @@
- extern struct mid_entry mid_set[HASHSIZE];
- extern struct mid_address reverse_mid_set[HASHSIZE];
-
-+struct mid_alias;
-
- int
- olsr_init_mid_set(void);
-@@ -95,6 +96,9 @@
- void
- olsr_time_out_mid_set(void *);
-
-+void
-+olsr_prune_aliases(union olsr_ip_addr *m_addr, struct mid_alias *declared_aliases);
-+
- int
- olsr_update_mid_table(union olsr_ip_addr *, float);
-
-diff -Naur olsrd-0.4.10/src/olsr.c olsrd-0.4.10-patched/src/olsr.c
---- olsrd-0.4.10/src/olsr.c 2005-11-17 05:25:44.000000000 +0100
-+++ olsrd-0.4.10-patched/src/olsr.c 2006-11-09 14:12:24.000000000 +0100
-@@ -217,13 +217,17 @@
-
- if (olsr_cnf->debug_level > 3)
- {
-- olsr_print_duplicate_table();
-+ if (olsr_cnf->debug_level > 8)
-+ {
-+ olsr_print_duplicate_table();
-+ }
- olsr_print_hna_set();
- }
- }
-
- olsr_print_link_set();
- olsr_print_neighbor_table();
-+ olsr_print_two_hop_neighbor_table();
- olsr_print_tc_table();
- }
-
-diff -Naur olsrd-0.4.10/src/process_package.c olsrd-0.4.10-patched/src/process_package.c
---- olsrd-0.4.10/src/process_package.c 2005-11-29 19:38:40.000000000 +0100
-+++ olsrd-0.4.10-patched/src/process_package.c 2006-11-24 12:19:33.000000000 +0100
-@@ -52,6 +52,7 @@
- #include "parser.h"
- #include "duplicate_set.h"
- #include "rebuild_packet.h"
-+#include "local_hna_set.h"
-
-
- /**
-@@ -406,6 +407,8 @@
- tmp_adr = tmp_adr->next;
- }
-
-+ olsr_prune_aliases(&message.mid_origaddr, message.mid_addr);
-+
- forward:
- olsr_forward_message(m,
- &message.mid_origaddr,
-@@ -470,8 +473,13 @@
-
- while(hna_tmp)
- {
-- olsr_update_hna_entry(&message.originator, &hna_tmp->net, &hna_tmp->netmask, (float)message.vtime);
--
-+ /* Don't add an HNA entry that we are advertising ourselves. */
-+ if (!find_local_hna4_entry(&hna_tmp->net, hna_tmp->netmask.v4) &&
-+ !find_local_hna6_entry(&hna_tmp->net, hna_tmp->netmask.v6))
-+ {
-+ olsr_update_hna_entry(&message.originator, &hna_tmp->net, &hna_tmp->netmask, (float)message.vtime);
-+ }
-+
- hna_tmp = hna_tmp->next;
- }
-
-@@ -494,7 +502,7 @@
-
- /**
- *Processes an list of neighbors from an incoming HELLO message.
-- *@param neighbor the neighbor who sendt the message.
-+ *@param neighbor the neighbor who sent the message.
- *@param message the HELLO message
- *@return nada
- */
-@@ -539,6 +547,31 @@
- /* Updating the holding time for this neighbor */
- two_hop_neighbor_yet->neighbor_2_timer = GET_TIMESTAMP(message->vtime*1000);
- two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
-+
-+ // For link quality OLSR, reset the path link quality here.
-+ // The path link quality will be calculated in the second pass, below.
-+ // Keep the saved_path_link_quality for reference.
-+
-+ if (olsr_cnf->lq_level > 0)
-+ {
-+ // loop through the one-hop neighbors that see this
-+ // 'two_hop_neighbor'
-+
-+ struct neighbor_list_entry *walker;
-+
-+ for (walker = two_hop_neighbor->neighbor_2_nblist.next;
-+ walker != &two_hop_neighbor->neighbor_2_nblist;
-+ walker = walker->next)
-+ {
-+ // have we found the one-hop neighbor that sent the
-+ // HELLO message that we're current processing?
-+
-+ if (walker->neighbor == neighbor)
-+ {
-+ walker->path_link_quality = 0.0;
-+ }
-+ }
-+ }
- }
- else
- {
-@@ -586,19 +619,48 @@
- (float)message->vtime);
- }
- }
-+ }
-+ }
-
-- if (olsr_cnf->lq_level > 0)
-+ // Separate, second and third pass for link quality OLSR
-+
-+ if (olsr_cnf->lq_level > 0)
-+ {
-+ struct link_entry *link =
-+ get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
-+
-+ if(!link)
-+ return;
-+
-+ // Second pass for link quality OLSR: calculate the best 2-hop
-+ // path costs to all the 2-hop neighbors indicated in the
-+ // HELLO message. Since the same 2-hop neighbor may be listed
-+ // more than once in the same HELLO message (each at a possibly
-+ // different quality) we want to select only the best one, not just
-+ // the last one listed in the HELLO message.
-+
-+ for(message_neighbors = message->neighbors;
-+ message_neighbors != NULL;
-+ message_neighbors = message_neighbors->next)
-+ {
-+ if(if_ifwithaddr(&message_neighbors->address) != NULL)
-+ continue;
-+
-+ if(((message_neighbors->status == SYM_NEIGH) ||
-+ (message_neighbors->status == MPR_NEIGH)))
- {
-- struct neighbor_list_entry *walker;
-- struct link_entry *link;
-+ struct neighbor_list_entry *walker;
-+ struct neighbor_2_entry *two_hop_neighbor;
-+ struct neighbor_2_list_entry *two_hop_neighbor_yet =
-+ olsr_lookup_my_neighbors(neighbor, &message_neighbors->address);
-
-- link = get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
-+ if(!two_hop_neighbor_yet)
-+ continue;
-
-- if(!link)
-- continue;
-+ two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
-
- // loop through the one-hop neighbors that see this
-- // two hop neighbour
-+ // 'two_hop_neighbor'
-
- for (walker = two_hop_neighbor->neighbor_2_nblist.next;
- walker != &two_hop_neighbor->neighbor_2_nblist;
-@@ -609,14 +671,7 @@
-
- if (walker->neighbor == neighbor)
- {
-- double saved_lq, rel_lq;
--
-- // saved previous total link quality
--
-- saved_lq = walker->saved_path_link_quality;
--
-- if (saved_lq == 0.0)
-- saved_lq = -1.0;
-+ double new_second_hop_link_quality, new_path_link_quality;
-
- // path link quality = link quality between us
- // and our one-hop neighbor x link quality between
-@@ -633,18 +688,75 @@
- // the link quality between the 1-hop neighbour and the
- // 2-hop neighbour
-
-- walker->second_hop_link_quality =
-+ new_second_hop_link_quality =
- message_neighbors->link_quality *
- message_neighbors->neigh_link_quality;
-
- // the total quality for the route
- // "us --- 1-hop --- 2-hop"
-
-- walker->path_link_quality =
-- walker->second_hop_link_quality *
-+ new_path_link_quality =
-+ new_second_hop_link_quality *
- link->loss_link_quality * link->neigh_link_quality;
-
-- // if the link quality has changed by more than 10
-+ // Only copy the link quality if it is better than what we have
-+ // for this 2-hop neighbor
-+ if (new_path_link_quality > walker->path_link_quality)
-+ {
-+ walker->second_hop_link_quality = new_second_hop_link_quality;
-+ walker->path_link_quality = new_path_link_quality;
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ // Third pass for link quality OLSR: check if the 2-hop path qualities have
-+ // actually changed. If so, signal this through the 'changes_neighborhood'
-+ // and 'changes_topology' booleans. Keep a 'saved_path_link_quality' for
-+ // later reference.
-+ for(message_neighbors = message->neighbors;
-+ message_neighbors != NULL;
-+ message_neighbors = message_neighbors->next)
-+ {
-+ if(if_ifwithaddr(&message_neighbors->address) != NULL)
-+ continue;
-+
-+ if(((message_neighbors->status == SYM_NEIGH) ||
-+ (message_neighbors->status == MPR_NEIGH)))
-+ {
-+ struct neighbor_list_entry *walker;
-+ struct neighbor_2_entry *two_hop_neighbor;
-+ struct neighbor_2_list_entry *two_hop_neighbor_yet =
-+ olsr_lookup_my_neighbors(neighbor, &message_neighbors->address);
-+
-+ if(!two_hop_neighbor_yet)
-+ continue;
-+
-+ two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
-+
-+ // loop through the one-hop neighbors that see this
-+ // 'two_hop_neighbor'
-+
-+ for (walker = two_hop_neighbor->neighbor_2_nblist.next;
-+ walker != &two_hop_neighbor->neighbor_2_nblist;
-+ walker = walker->next)
-+ {
-+ // have we found the one-hop neighbor that sent the
-+ // HELLO message that we're current processing?
-+
-+ if (walker->neighbor == neighbor)
-+ {
-+ double saved_lq, rel_lq;
-+
-+ // saved previous total link quality
-+
-+ saved_lq = walker->saved_path_link_quality;
-+
-+ if (saved_lq == 0.0)
-+ saved_lq = -1.0;
-+
-+ // if the link cost has changed by more than 10
- // percent, signal
-
- rel_lq = walker->path_link_quality / saved_lq;
-diff -Naur olsrd-0.4.10/src/routing_table.c olsrd-0.4.10-patched/src/routing_table.c
---- olsrd-0.4.10/src/routing_table.c 2005-11-17 00:55:54.000000000 +0100
-+++ olsrd-0.4.10-patched/src/routing_table.c 2006-11-26 12:08:12.004604584 +0100
-@@ -65,10 +65,10 @@
- olsr_fill_routing_table_with_two_hop_neighbors(void);
-
- static struct rt_entry *
--olsr_check_for_higher_hopcount(struct rt_entry *, struct hna_net *, olsr_u16_t);
-+olsr_check_for_higher_quality(struct rt_entry *, struct hna_net *, float);
-
- struct rt_entry *
--olsr_check_for_lower_hopcount(struct rt_entry *, struct hna_net *, olsr_u16_t);
-+olsr_check_for_lower_quality(struct rt_entry *, struct hna_net *, float);
-
- static olsr_bool
- two_hop_neighbor_reachable(struct neighbor_2_list_entry *);
-@@ -212,7 +212,12 @@
- new_route_entry->rt_if = iface;
-
- new_route_entry->rt_metric = metric;
-- new_route_entry->rt_etx = etx;
-+ if (etx< 0.0)
-+ /* non-LQ case */
-+ new_route_entry->rt_etx = (float)metric;
-+ else
-+ /* LQ case */
-+ new_route_entry->rt_etx = etx;
-
- if(COMP_IP(dst, router))
- /* Not GW */
-@@ -289,7 +294,7 @@
- &link->neighbor_iface_addr,
- iface,
- 1,
-- 0);
-+ -1.0);
- }
- }
-
-@@ -404,7 +409,7 @@
- &link->neighbor_iface_addr,
- iface,
- 2,
-- 0);
-+ -1.0);
-
- if(new_route_entry != NULL)
- {
-@@ -501,7 +506,7 @@
- &list_destination_n->destination->rt_router,
- list_destination_n->destination->rt_if,
- list_destination_n->destination->rt_metric+1,
-- 0);
-+ -1.0);
- if(destination_n_1->destination != NULL)
- {
- destination_n_1->next=list_destination_n_1;
-@@ -549,17 +554,17 @@
-
-
- /**
-- *Check for a entry with a higher hopcount than
-+ *Check for an entry with a higher quality (lower etx) than
- *a given value in a routing table
- *
- *@param routes the routingtable to look in
- *@param net the network entry to look for
-- *@param metric the metric to check for
-+ *@param etx the metric to check for
- *
-- *@return the localted entry if found. NULL if not
-+ *@return the located entry if found. NULL if not
- */
- static struct rt_entry *
--olsr_check_for_higher_hopcount(struct rt_entry *routes, struct hna_net *net, olsr_u16_t metric)
-+olsr_check_for_higher_quality(struct rt_entry *routes, struct hna_net *net, float etx)
- {
- int index;
-
-@@ -574,8 +579,8 @@
- if(COMP_IP(&tmp_routes->rt_dst, &net->A_network_addr) &&
- (memcmp(&tmp_routes->rt_mask, &net->A_netmask, netmask_size) == 0))
- {
-- /* Found a entry */
-- if(tmp_routes->rt_metric > metric)
-+ /* Found an entry */
-+ if(tmp_routes->rt_etx < etx)
- return tmp_routes;
- else
- return NULL;
-@@ -589,17 +594,17 @@
-
-
- /**
-- *Check for a entry with a lower or equal hopcount than
-+ *Check for an entry with a lower or equal quality (higher or equal etx) than
- *a given value in a routing table
- *
- *@param routes the routingtable to look in
- *@param net the network entry to look for
-- *@param metric the metric to check for
-+ *@param etx the metric to check for
- *
-- *@return the localted entry if found. NULL if not
-+ *@return the located entry if found. NULL if not
- */
- struct rt_entry *
--olsr_check_for_lower_hopcount(struct rt_entry *routes, struct hna_net *net, olsr_u16_t metric)
-+olsr_check_for_lower_quality(struct rt_entry *routes, struct hna_net *net, float etx)
- {
- int index;
-
-@@ -614,8 +619,8 @@
- if(COMP_IP(&tmp_routes->rt_dst, &net->A_network_addr) &&
- (memcmp(&tmp_routes->rt_mask, &net->A_netmask, netmask_size) == 0))
- {
-- /* Found a entry */
-- if(tmp_routes->rt_metric <= metric)
-+ /* Found an entry */
-+ if(tmp_routes->rt_etx >= etx)
- return tmp_routes;
- else
- return NULL;
-@@ -672,13 +677,13 @@
- }
-
- /* If there exists a better or equal entry - skip */
-- if(olsr_check_for_lower_hopcount(hna_routes, tmp_net, tmp_rt->rt_metric) != NULL)
-+ if(olsr_check_for_higher_quality(hna_routes, tmp_net, tmp_rt->rt_etx) != NULL)
- {
- continue;
- }
-
-- /* If we find an entry with higher hopcount we just edit it */
-- if((new_rt = olsr_check_for_higher_hopcount(hna_routes, tmp_net, tmp_rt->rt_metric)) != NULL)
-+ /* If we find an entry with lower quality we just edit it */
-+ if((new_rt = olsr_check_for_lower_quality(hna_routes, tmp_net, tmp_rt->rt_etx)) != NULL)
- {
- /* Fill struct */
- /* Net */
-@@ -687,6 +692,7 @@
- /* Gateway */
- COPY_IP(&new_rt->rt_router, &tmp_rt->rt_router);
- /* Metric */
-+ new_rt->rt_etx = tmp_rt->rt_etx;
- new_rt->rt_metric = tmp_rt->rt_metric;
- /* Flags */
- new_rt->rt_flags = RTF_UP | RTF_GATEWAY;
-@@ -707,6 +713,7 @@
- /* Gateway */
- COPY_IP(&new_rt->rt_router, &tmp_rt->rt_router);
- /* Metric */
-+ new_rt->rt_etx = tmp_rt->rt_etx;
- new_rt->rt_metric = tmp_rt->rt_metric;
- /* Flags */
- new_rt->rt_flags = RTF_UP | RTF_GATEWAY;
-diff -Naur olsrd-0.4.10/src/unix/ifnet.c olsrd-0.4.10-patched/src/unix/ifnet.c
---- olsrd-0.4.10/src/unix/ifnet.c 2005-12-29 19:37:16.000000000 +0100
-+++ olsrd-0.4.10-patched/src/unix/ifnet.c 2006-11-16 13:14:42.000000000 +0100
-@@ -308,9 +308,11 @@
- OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name)
- OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_addr))
- OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_addr))
-+
-+ ifp->int_addr = ifr.ifr_addr;
-
- if(memcmp(&main_addr,
-- &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
-+ &ifp->ip_addr,
- ipsize) == 0)
- {
- OLSR_PRINTF(1, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr))
-@@ -320,7 +322,6 @@
- ipsize);
- }
-
-- ifp->int_addr = ifr.ifr_addr;
- memcpy(&ifp->ip_addr,
- &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr,
- ipsize);
-@@ -845,7 +846,6 @@
- ifs.if_index = if_nametoindex(ifr.ifr_name);
-
- /* Set interface metric */
-- /* Set interface metric */
- if(iface->cnf->weight.fixed)
- ifs.int_metric = iface->cnf->weight.value;
- else
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/src/defs.h olsrd-0.4.10/src/defs.h
---- olsrd-0.4.10.orig/src/defs.h 2006-11-28 21:17:27.000000000 +0100
-+++ olsrd-0.4.10/src/defs.h 2006-11-28 21:18:46.000000000 +0100
-@@ -68,10 +68,10 @@
- #define OLSRD_GLOBAL_CONF_FILE "/etc/" OLSRD_CONF_FILE_NAME
- #endif
-
--#define HOPCNT_MAX 32 /* maximum hops number */
-+#define HOPCNT_MAX 64 /* maximum hops number */
- #define MAXMESSAGESIZE 1500 /* max broadcast size */
- #define UDP_IPV4_HDRSIZE 28
--#define UDP_IPV6_HDRSIZE 48
-+#define UDP_IPV6_HDRSIZE 62
- #define MAX_IFS 32
-
- /* Debug helper macro */
-diff -Nur olsrd-0.4.10.orig/src/interfaces.h olsrd-0.4.10/src/interfaces.h
---- olsrd-0.4.10.orig/src/interfaces.h 2005-06-03 10:00:55.000000000 +0200
-+++ olsrd-0.4.10/src/interfaces.h 2006-11-28 21:18:01.000000000 +0100
-@@ -136,6 +136,8 @@
- struct vtimes valtimes;
-
- struct if_gen_property *gen_properties;/* Generic interface properties */
-+
-+ int ttl_index; /* index in TTL array for fish-eye */
-
- struct interface *int_next;
- };
-diff -Nur olsrd-0.4.10.orig/src/link_set.c olsrd-0.4.10/src/link_set.c
---- olsrd-0.4.10.orig/src/link_set.c 2006-11-28 21:17:27.000000000 +0100
-+++ olsrd-0.4.10/src/link_set.c 2006-11-28 21:18:01.000000000 +0100
-@@ -963,8 +963,9 @@
-
- entry->loss_link_quality =
- (float)(entry->total_packets - entry->lost_packets) /
-- (float)(entry->loss_window_size);
--
-+ (float)(entry->loss_window_size < (2 * 4) ? entry->loss_window_size:
-+ 4 * ((entry->loss_window_size / 4 - 1) * entry->total_packets + entry->loss_window_size) / entry->loss_window_size);
-+
- // multiply the calculated link quality with the user-specified multiplier
-
- entry->loss_link_quality *= entry->loss_link_multiplier;
-diff -Nur olsrd-0.4.10.orig/src/lq_packet.c olsrd-0.4.10/src/lq_packet.c
---- olsrd-0.4.10.orig/src/lq_packet.c 2005-11-17 02:58:51.000000000 +0100
-+++ olsrd-0.4.10/src/lq_packet.c 2006-11-28 21:18:01.000000000 +0100
-@@ -149,9 +149,8 @@
- int i;
- struct neighbor_entry *walker;
- struct link_entry *link;
-- static int ttl_list[] = { MAX_TTL, 3, 2, 1, 2, 1, 1, 3, 2, 1, 2, 1, 1, 0 };
-- static int ttl_index = 0;
--
-+ static int ttl_list[] = { 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1, MAX_TTL-1, 0};
-+
- // remember that we have generated an LQ TC message; this is
- // checked in net_output()
-
-@@ -167,10 +166,13 @@
-
- if (olsr_cnf->lq_fish > 0)
- {
-- if (ttl_list[ttl_index] == 0)
-- ttl_index = 0;
-+ // SVEN_OLA: Too lazy to find the different iface inits. This will do it too.
-+ if (outif->ttl_index >= sizeof(ttl_list) / sizeof(ttl_list[0])) outif->ttl_index = 0;
-+
-+ if (ttl_list[outif->ttl_index] == 0)
-+ outif->ttl_index = 0;
-
-- lq_tc->comm.ttl = ttl_list[ttl_index++];
-+ lq_tc->comm.ttl = ttl_list[outif->ttl_index++];
-
- OLSR_PRINTF(3, "Creating LQ TC with TTL %d.\n", lq_tc->comm.ttl);
- }
-diff -Nur olsrd-0.4.10.orig/src/olsr.c olsrd-0.4.10/src/olsr.c
---- olsrd-0.4.10.orig/src/olsr.c 2006-11-28 21:17:27.000000000 +0100
-+++ olsrd-0.4.10/src/olsr.c 2006-11-28 21:18:01.000000000 +0100
-@@ -68,6 +68,7 @@
- olsr_bool changes_topology;
- olsr_bool changes_neighborhood;
- olsr_bool changes_hna;
-+olsr_bool changes_force;
-
- /**
- * Process changes functions
-@@ -142,6 +143,11 @@
- OLSR_PRINTF(3, "CHANGES IN HNA\n")
- #endif
-
-+ if(!changes_force &&
-+ 2 <= olsr_cnf->lq_level &&
-+ 0 >= olsr_cnf->lq_dlimit)
-+ return;
-+
- if(!changes_neighborhood &&
- !changes_topology &&
- !changes_hna)
-@@ -171,11 +177,6 @@
- olsr_calculate_routing_table();
- olsr_calculate_hna_routes();
- }
--
-- else
-- {
-- olsr_calculate_lq_routing_table();
-- }
- }
-
- else if (changes_topology)
-@@ -187,11 +188,6 @@
- olsr_calculate_routing_table();
- olsr_calculate_hna_routes();
- }
--
-- else
-- {
-- olsr_calculate_lq_routing_table();
-- }
- }
-
- else if (changes_hna)
-@@ -202,11 +198,11 @@
- {
- olsr_calculate_hna_routes();
- }
--
-- else
-- {
-- olsr_calculate_lq_routing_table();
-- }
-+ }
-+
-+ if (olsr_cnf->lq_level >= 2)
-+ {
-+ olsr_calculate_lq_routing_table();
- }
-
- if (olsr_cnf->debug_level > 0)
-@@ -243,6 +239,7 @@
- changes_neighborhood = OLSR_FALSE;
- changes_topology = OLSR_FALSE;
- changes_hna = OLSR_FALSE;
-+ changes_force = OLSR_FALSE;
-
-
- return;
-diff -Nur olsrd-0.4.10.orig/src/olsr.h olsrd-0.4.10/src/olsr.h
---- olsrd-0.4.10.orig/src/olsr.h 2005-05-29 14:47:45.000000000 +0200
-+++ olsrd-0.4.10/src/olsr.h 2006-11-28 21:18:01.000000000 +0100
-@@ -49,6 +49,7 @@
- extern olsr_bool changes_topology;
- extern olsr_bool changes_neighborhood;
- extern olsr_bool changes_hna;
-+extern olsr_bool changes_force;
-
- void
- register_pcf(int (*)(int, int, int));
-diff -Nur olsrd-0.4.10.orig/src/scheduler.c olsrd-0.4.10/src/scheduler.c
---- olsrd-0.4.10.orig/src/scheduler.c 2005-12-29 23:34:37.000000000 +0100
-+++ olsrd-0.4.10/src/scheduler.c 2006-11-28 21:18:01.000000000 +0100
-@@ -70,6 +70,7 @@
-
- changes_neighborhood = OLSR_TRUE;
- changes_topology = OLSR_TRUE;
-+ changes_force = OLSR_TRUE;
- }
-
- /**
-diff -Nur olsrd-0.4.10.orig/src/unix/ifnet.c olsrd-0.4.10/src/unix/ifnet.c
---- olsrd-0.4.10.orig/src/unix/ifnet.c 2006-11-28 21:17:27.000000000 +0100
-+++ olsrd-0.4.10/src/unix/ifnet.c 2006-11-28 21:18:01.000000000 +0100
-@@ -690,6 +690,17 @@
- return 1;
- }
-
-+static char basename[32];
-+char* if_basename(char* name);
-+char* if_basename(char* name)
-+{
-+ char *p = strchr(name, ':');
-+ if (0 == p || p - name >= (int)(sizeof(basename) / sizeof(basename[0]) - 1)) return name;
-+ memcpy(basename, name, p - name);
-+ basename[p - name] = 0;
-+ return basename;
-+}
-+
- /**
- * Initializes a interface described by iface,
- * if it is set up and is of the correct type.
-@@ -833,10 +844,10 @@
- }
-
- /* Deactivate IP spoof filter */
-- deactivate_spoof(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
-+ deactivate_spoof(if_basename(ifr.ifr_name), iface->index, olsr_cnf->ip_version);
-
- /* Disable ICMP redirects */
-- disable_redirects(ifr.ifr_name, iface->index, olsr_cnf->ip_version);
-+ disable_redirects(if_basename(ifr.ifr_name), iface->index, olsr_cnf->ip_version);
-
- }
-
-@@ -894,7 +905,7 @@
- ifp->gen_properties = NULL;
- ifp->int_name = olsr_malloc(strlen(ifr.ifr_name) + 1, "Interface update 3");
-
-- strcpy(ifp->int_name, ifr.ifr_name);
-+ strcpy(ifp->int_name, if_basename(ifr.ifr_name));
- /* Segfaults if using strncpy(IFNAMSIZ) why oh why?? */
- ifp->int_next = ifnet;
- ifnet = ifp;
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/src/bsd/kernel_routes.c olsrd-0.4.10/src/bsd/kernel_routes.c
---- olsrd-0.4.10.orig/src/bsd/kernel_routes.c 2005-02-27 11:43:38.000000000 +0100
-+++ olsrd-0.4.10/src/bsd/kernel_routes.c 2006-12-12 08:59:26.000000000 +0100
-@@ -170,12 +170,103 @@
- return add_del_route(dest, 0);
- }
-
--int olsr_ioctl_add_route6(struct rt_entry *dest)
-+static int add_del_route6(struct rt_entry *dest, int add)
- {
-+ struct rt_msghdr *rtm;
-+ unsigned char buff[512];
-+ unsigned char *walker;
-+ struct sockaddr_in6 sin6;
-+ struct sockaddr_dl sdl;
-+ int step, step_dl;
-+ int len;
-+ char Str1[40], Str2[40];
-+
-+ inet_ntop(AF_INET6, &dest->rt_dst.v6, Str1, 40);
-+ inet_ntop(AF_INET6, &dest->rt_router.v6, Str2, 40);
-+
-+ OLSR_PRINTF(1, "%s IPv6 route to %s/%d via %s.\n",
-+ (add != 0) ? "Adding" : "Removing", Str1, dest->rt_mask.v6, Str2)
-+
-+ memset(buff, 0, sizeof (buff));
-+ memset(&sin6, 0, sizeof (sin6));
-+ memset(&sdl, 0, sizeof (sdl));
-+
-+ sin6.sin6_len = sizeof (sin6);
-+ sin6.sin6_family = AF_INET6;
-+ sdl.sdl_len = sizeof (sdl);
-+ sdl.sdl_family = AF_LINK;
-+
-+ step = 1 + ((sizeof (struct sockaddr_in6) - 1) | 3);
-+ step_dl = 1 + ((sizeof (struct sockaddr_dl) - 1) | 3);
-+
-+ rtm = (struct rt_msghdr *)buff;
-+ rtm->rtm_version = RTM_VERSION;
-+ rtm->rtm_type = (add != 0) ? RTM_ADD : RTM_DELETE;
-+ rtm->rtm_index = 0;
-+ rtm->rtm_flags = dest->rt_flags;
-+ rtm->rtm_addrs = RTA_DST | RTA_GATEWAY;
-+ rtm->rtm_seq = ++seq;
-+
-+ walker = buff + sizeof (struct rt_msghdr);
-+
-+ memcpy(&sin6.sin6_addr.s6_addr, &dest->rt_dst.v6, sizeof(struct in6_addr));
-+
-+ memcpy(walker, &sin6, sizeof (sin6));
-+ walker += step;
-+
-+ if ((rtm->rtm_flags & RTF_GATEWAY) != 0)
-+ {
-+ memcpy(&sin6.sin6_addr.s6_addr, &dest->rt_router.v6, sizeof(struct in6_addr));
-+
-+ memcpy(walker, &sin6, sizeof (sin6));
-+ walker += step;
-+ }
-+
-+ // the host is directly reachable, so add the output interface's address
-+
-+ else
-+ {
-+ memcpy(&sin6.sin6_addr.s6_addr, &dest->rt_if->int6_addr.sin6_addr.s6_addr,
-+ sizeof(struct in6_addr));
-+
-+ memcpy(walker, &sin6, sizeof (sin6));
-+ walker += step;
-+ rtm->rtm_flags |= RTF_LLINFO;
-+ }
-+
-+ if ((rtm->rtm_flags & RTF_HOST) == 0)
-+ {
-+ olsr_prefix_to_netmask((union olsr_ip_addr *)&sin6.sin6_addr, dest->rt_mask.v6);
-+ memcpy(walker, &sin6, sizeof (sin6));
-+ walker += step;
-+ rtm->rtm_addrs |= RTA_NETMASK;
-+ }
-+
-+ if ((rtm->rtm_flags & RTF_GATEWAY) != 0)
-+ {
-+ strcpy(&sdl.sdl_data[0], dest->rt_if->int_name);
-+ sdl.sdl_nlen = (u_char)strlen(dest->rt_if->int_name);
-+ memcpy(walker, &sdl, sizeof (sdl));
-+ walker += step_dl;
-+ rtm->rtm_addrs |= RTA_IFP;
-+ }
-+
-+ rtm->rtm_msglen = (unsigned short)(walker - buff);
-+
-+ len = write(rts, buff, rtm->rtm_msglen);
-+
-+ if (len < rtm->rtm_msglen)
-+ fprintf(stderr, "cannot write to routing socket: %s\n", strerror(errno));
-+
- return 0;
- }
-
-+int olsr_ioctl_add_route6(struct rt_entry *dest)
-+{
-+ return add_del_route6(dest, 1);
-+}
-+
- int olsr_ioctl_del_route6(struct rt_entry *dest)
- {
-- return 0;
-+ return add_del_route6(dest, 0);
- }
-diff -Nur olsrd-0.4.10.orig/src/bsd/net.c olsrd-0.4.10/src/bsd/net.c
---- olsrd-0.4.10.orig/src/bsd/net.c 2005-08-28 21:30:29.000000000 +0200
-+++ olsrd-0.4.10/src/bsd/net.c 2006-12-12 08:59:30.000000000 +0100
-@@ -61,8 +61,10 @@
- #endif
-
- #ifdef __FreeBSD__
-+#include <ifaddrs.h>
- #include <net/if_var.h>
- #include <net/ethernet.h>
-+#include <netinet/in_var.h>
- #ifndef FBSD_NO_80211
- #include <net80211/ieee80211.h>
- #include <net80211/ieee80211_ioctl.h>
-@@ -71,8 +73,8 @@
- #endif
- #endif
-
--#ifdef SPOOF
- #include <net/if_dl.h>
-+#ifdef SPOOF
- #include <libnet.h>
- #endif /* SPOOF */
-
-@@ -172,6 +174,17 @@
- name = "net.inet6.icmp6.rediraccept";
-
- ignore_redir = set_sysctl_int(name, 0);
-+#elif defined __FreeBSD__
-+ if (olsr_cnf->ip_version == AF_INET)
-+ {
-+ name = "net.inet.icmp.drop_redirect";
-+ ignore_redir = set_sysctl_int(name, 1);
-+ }
-+ else
-+ {
-+ name = "net.inet6.icmp6.rediraccept";
-+ ignore_redir = set_sysctl_int(name, 0);
-+ }
- #else
- if (olsr_cnf->ip_version == AF_INET)
- name = "net.inet.icmp.drop_redirect";
-@@ -243,6 +256,12 @@
- else
- name = "net.inet6.icmp6.rediraccept";
-
-+#elif defined __FreeBSD__
-+ if (olsr_cnf->ip_version == AF_INET)
-+ name = "net.inet.icmp.drop_redirect";
-+
-+ else
-+ name = "net.inet6.icmp6.rediraccept";
- #else
- if (olsr_cnf->ip_version == AF_INET)
- name = "net.inet.icmp.drop_redirect";
-@@ -335,7 +354,6 @@
- return (-1);
- }
-
--#ifdef SPOOF
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEPORT failed");
-@@ -347,7 +365,6 @@
- perror("IP_RECVIF failed");
- return (-1);
- }
--#endif /* SPOOF */
-
- for (on = bufspace; ; on -= 1024)
- {
-@@ -406,6 +423,18 @@
- return (-1);
- }
-
-+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
-+ {
-+ perror("SO_REUSEPORT failed");
-+ return (-1);
-+ }
-+
-+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0)
-+ {
-+ perror("IPV6_RECVPKTINFO failed");
-+ return (-1);
-+ }
-+
- if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0)
- {
- perror("bind");
-@@ -425,31 +454,16 @@
- int
- join_mcast(struct interface *ifs, int sock)
- {
-- /* See linux/in6.h */
-+ /* See netinet6/in6.h */
-
- struct ipv6_mreq mcastreq;
-
- COPY_IP(&mcastreq.ipv6mr_multiaddr, &ifs->int6_multaddr.sin6_addr);
- mcastreq.ipv6mr_interface = ifs->if_index;
-
--#if 0
- OLSR_PRINTF(3, "Interface %s joining multicast %s...", ifs->int_name, olsr_ip_to_string((union olsr_ip_addr *)&ifs->int6_multaddr.sin6_addr))
-- /* Send multicast */
-- if(setsockopt(sock,
-- IPPROTO_IPV6,
-- IPV6_ADD_MEMBERSHIP,
-- (char *)&mcastreq,
-- sizeof(struct ipv6_mreq))
-- < 0)
-- {
-- perror("Join multicast");
-- return -1;
-- }
--#else
--#warning implement IPV6_ADD_MEMBERSHIP
--#endif
-
-- /* Old libc fix */
-+ /* rfc 3493 */
- #ifdef IPV6_JOIN_GROUP
- /* Join reciever group */
- if(setsockopt(sock,
-@@ -458,8 +472,8 @@
- (char *)&mcastreq,
- sizeof(struct ipv6_mreq))
- < 0)
--#else
-- /* Join reciever group */
-+#else /* rfc 2133, obsoleted */
-+ /* Join receiver group */
- if(setsockopt(sock,
- IPPROTO_IPV6,
- IPV6_ADD_MEMBERSHIP,
-@@ -494,6 +508,70 @@
-
- int get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
- {
-+ struct ifaddrs *ifap, *ifa;
-+ const struct sockaddr_in6 *sin6 = NULL;
-+ struct in6_ifreq ifr6;
-+ int found = 0;
-+ int s6;
-+ u_int32_t flags6;
-+
-+ if (getifaddrs(&ifap) != 0)
-+ {
-+ OLSR_PRINTF(3, "get_ipv6_address: getifaddrs() failed.\n")
-+ return 0;
-+ }
-+
-+ for (ifa = ifap; ifa; ifa = ifa->ifa_next)
-+ {
-+ if (ifa->ifa_addr->sa_family == AF_INET6 &&
-+ strcmp(ifa->ifa_name, ifname) == 0)
-+ {
-+ sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
-+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
-+ continue;
-+ strncpy(ifr6.ifr_name, ifname, sizeof(ifname));
-+ if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
-+ {
-+ OLSR_PRINTF(3, "socket(AF_INET6,SOCK_DGRAM)");
-+ break;
-+ }
-+ ifr6.ifr_addr = *sin6;
-+ if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0)
-+ {
-+ OLSR_PRINTF(3, "ioctl(SIOCGIFAFLAG_IN6)");
-+ close(s6);
-+ break;
-+ }
-+ close(s6);
-+ flags6 = ifr6.ifr_ifru.ifru_flags6;
-+ if ((flags6 & IN6_IFF_ANYCAST) != 0)
-+ continue;
-+ if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
-+ {
-+ if (scope_in)
-+ {
-+ memcpy(&saddr6->sin6_addr, &sin6->sin6_addr,
-+ sizeof(struct in6_addr));
-+ found = 1;
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ if (scope_in == 0)
-+ {
-+ memcpy(&saddr6->sin6_addr, &sin6->sin6_addr,
-+ sizeof(struct in6_addr));
-+ found = 1;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ freeifaddrs(ifap);
-+ if (found)
-+ return 1;
-+
- return 0;
- }
-
-@@ -621,16 +699,19 @@
- struct sockaddr *from,
- socklen_t *fromlen)
- {
--#if SPOOF
- struct msghdr mhdr;
- struct iovec iov;
- struct cmsghdr *cm;
- struct sockaddr_dl *sdl;
- struct sockaddr_in *sin = (struct sockaddr_in *) from; //XXX
-+ struct sockaddr_in6 *sin6;
-+ struct in6_addr *iaddr6;
-+ struct in6_pktinfo *pkti;
-+ struct interface *ifc;
-+ char addrstr[INET6_ADDRSTRLEN];
-+ char iname[IFNAMSIZ];
- unsigned char chdr[4096];
- int count;
-- struct interface *ifc;
-- char iname[32];
-
- bzero(&mhdr, sizeof(mhdr));
- bzero(&iov, sizeof(iov));
-@@ -653,35 +734,45 @@
-
- /* this needs to get communicated back to caller */
- *fromlen = mhdr.msg_namelen;
--
-- cm = (struct cmsghdr *) chdr;
-- sdl = (struct sockaddr_dl *) CMSG_DATA (cm);
-- bzero (iname, sizeof (iname));
-- memcpy (iname, sdl->sdl_data, sdl->sdl_nlen);
-+ if (olsr_cnf->ip_version == AF_INET6)
-+ {
-+ for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&mhdr); cm;
-+ cm = (struct cmsghdr *)CMSG_NXTHDR(&mhdr, cm))
-+ {
-+ if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO)
-+ {
-+ pkti = (struct in6_pktinfo *) CMSG_DATA(cm);
-+ iaddr6 = &pkti->ipi6_addr;
-+ if_indextoname(pkti->ipi6_ifindex, iname);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ cm = (struct cmsghdr *) chdr;
-+ sdl = (struct sockaddr_dl *) CMSG_DATA (cm);
-+ bzero (iname, sizeof (iname));
-+ memcpy (iname, sdl->sdl_data, sdl->sdl_nlen);
-+ }
-
- ifc = if_ifwithsock (s);
-
-+ sin6 = (struct sockaddr_in6 *)from;
-+ OLSR_PRINTF (4, "%d bytes from %s, socket associated %s really received on %s\n",
-+ count,
-+ (olsr_cnf->ip_version == AF_INET6) ?
-+ inet_ntop(AF_INET6, (char *)&sin6->sin6_addr, addrstr,
-+ INET6_ADDRSTRLEN):
-+ inet_ntoa (sin->sin_addr),
-+ ifc->int_name,
-+ iname);
-+
- if (strcmp (ifc->int_name, iname) != 0)
- {
- return (0);
- }
-
-- OLSR_PRINTF (2, "%d bytes from %s, socket associated %s really received on %s\n",
-- count,
-- inet_ntoa (sin->sin_addr),
-- ifc->int_name,
-- iname);
--
- return (count);
--
--#else /* SPOOF */
-- return recvfrom(s,
-- buf,
-- len,
-- 0,
-- from,
-- fromlen);
--#endif /* SPOOF */
- }
-
- /**
-diff -Nur olsrd-0.4.10.orig/src/net_olsr.c olsrd-0.4.10/src/net_olsr.c
---- olsrd-0.4.10.orig/src/net_olsr.c 2005-12-29 19:37:16.000000000 +0100
-+++ olsrd-0.4.10/src/net_olsr.c 2006-12-12 08:59:35.000000000 +0100
-@@ -526,7 +526,7 @@
-
- for(;p > 0; p -= 8)
- {
-- adr->v6.s6_addr[i] = (p < 8) ? 0xff ^ (0xff << p) : 0xff;
-+ adr->v6.s6_addr[i] = (p < 8) ? 0xff ^ (0xff >> p) : 0xff;
- i++;
- }
-
-@@ -564,7 +564,7 @@
- {
- for(tmp = adr->v6.s6_addr[i];
- tmp > 0;
-- tmp = tmp >> 1)
-+ tmp = (tmp << 1) & 0xff)
- prefix++;
- }
- }
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/dot_draw/src/olsrd_dot_draw.c olsrd-0.4.10/lib/dot_draw/src/olsrd_dot_draw.c
---- olsrd-0.4.10.orig/lib/dot_draw/src/olsrd_dot_draw.c 2005-12-30 03:23:59.000000000 +0100
-+++ olsrd-0.4.10/lib/dot_draw/src/olsrd_dot_draw.c 2006-12-01 20:23:37.000000000 +0100
-@@ -136,6 +136,8 @@
- /* Register the "ProcessChanges" function */
- register_pcf(&pcf_event);
-
-+ plugin_ipc_init();
-+
- return 1;
- }
-
-@@ -237,6 +239,7 @@
-
-
- /* Register with olsrd */
-+ printf("Adding socket with olsrd\n");
- add_olsr_socket(ipc_socket, &ipc_action);
- ipc_socket_up = 1;
- }
-diff -Nur olsrd-0.4.10.orig/lib/httpinfo/src/olsrd_httpinfo.c olsrd-0.4.10/lib/httpinfo/src/olsrd_httpinfo.c
---- olsrd-0.4.10.orig/lib/httpinfo/src/olsrd_httpinfo.c 2006-12-01 20:20:31.000000000 +0100
-+++ olsrd-0.4.10/lib/httpinfo/src/olsrd_httpinfo.c 2006-12-01 20:23:37.000000000 +0100
-@@ -297,6 +297,7 @@
- if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == -1)
- {
- olsr_printf(1, "(HTTPINFO) bind failed %s\n", strerror(errno));
-+ close(s);
- return -1;
- }
-
-@@ -304,6 +305,7 @@
- if (listen(s, 1) == -1)
- {
- olsr_printf(1, "(HTTPINFO) listen failed %s\n", strerror(errno));
-+ close(s);
- return -1;
- }
-
-diff -Nur olsrd-0.4.10.orig/lib/secure/src/olsrd_secure.c olsrd-0.4.10/lib/secure/src/olsrd_secure.c
---- olsrd-0.4.10.orig/lib/secure/src/olsrd_secure.c 2005-11-19 09:37:23.000000000 +0100
-+++ olsrd-0.4.10/lib/secure/src/olsrd_secure.c 2006-12-01 20:23:37.000000000 +0100
-@@ -952,7 +952,7 @@
- else
- {
- /* Check configuration timeout */
-- if(!TIMED_OUT(&entry->conftime))
-+ if(!TIMED_OUT(entry->conftime))
- {
- /* If registered - do not accept! */
- olsr_printf(1, "[ENC]Challenge from registered node...dropping!\n");
-@@ -1205,7 +1205,7 @@
- while(tmp_list != ×tamps[index])
- {
- /*Check if the entry is timed out*/
-- if((TIMED_OUT(&tmp_list->valtime)) && (TIMED_OUT(&tmp_list->conftime)))
-+ if((TIMED_OUT(tmp_list->valtime)) && (TIMED_OUT(tmp_list->conftime)))
- {
- entry_to_delete = tmp_list;
- tmp_list = tmp_list->next;
-diff -Nur olsrd-0.4.10.orig/make/Makefile.linux olsrd-0.4.10/make/Makefile.linux
---- olsrd-0.4.10.orig/make/Makefile.linux 2005-11-19 09:43:51.000000000 +0100
-+++ olsrd-0.4.10/make/Makefile.linux 2006-12-01 20:23:37.000000000 +0100
-@@ -3,7 +3,11 @@
- #
-
- INSTALL_PREFIX ?=
-+ifeq ($(shell arch),x86_64)
-+LIBDIR = $(INSTALL_PREFIX)/usr/lib64
-+else
- LIBDIR = $(INSTALL_PREFIX)/usr/lib
-+endif
-
- SRCS += $(wildcard src/linux/*.c) $(wildcard src/unix/*.c)
- HDRS += $(wildcard src/linux/*.h) $(wildcard src/unix/*.h)
-diff -Nur olsrd-0.4.10.orig/make/Makefile.osx olsrd-0.4.10/make/Makefile.osx
---- olsrd-0.4.10.orig/make/Makefile.osx 2005-12-29 20:48:43.000000000 +0100
-+++ olsrd-0.4.10/make/Makefile.osx 2006-12-01 20:23:37.000000000 +0100
-@@ -2,6 +2,10 @@
- # MAC OSX SPECIFIC CONFIGURATION
- #
-
-+# don't strip executables and bundles for now until we figure out the proper way
-+# to do it (flags).
-+STRIP = \#
-+
- INSTALL_PREFIX ?=
- LIBDIR = $(INSTALL_PREFIX)/usr/lib
-
-@@ -12,12 +16,10 @@
- LIBS =
-
- PLUGIN_FULLNAME ?= $(PLUGIN_NAME).so.$(PLUGIN_VER)
--INSTALL_LIB = install -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); \
-- /sbin/ldconfig
-+INSTALL_LIB = install -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME)
-
- ifdef OLSRD_PLUGIN
--CFLAGS += -fPIC
--LDFLAGS = -fPIC -dynamiclib -single_module -flat_namespace -undefined suppress
-+LDFLAGS = -bundle -flat_namespace -undefined suppress
- else
- LDFLAGS = -dynamic
- endif
-diff -Nur olsrd-0.4.10.orig/Makefile olsrd-0.4.10/Makefile
---- olsrd-0.4.10.orig/Makefile 2006-12-01 20:20:31.000000000 +0100
-+++ olsrd-0.4.10/Makefile 2006-12-01 20:23:37.000000000 +0100
-@@ -171,3 +171,4 @@
-
- build_all: cfgparser olsrd libs
- install_all: install install_libs
-+clean_all: uberclean clean_libs
-diff -Nur olsrd-0.4.10.orig/src/bsd/net.c olsrd-0.4.10/src/bsd/net.c
---- olsrd-0.4.10.orig/src/bsd/net.c 2005-08-28 21:30:29.000000000 +0200
-+++ olsrd-0.4.10/src/bsd/net.c 2006-12-01 20:23:37.000000000 +0100
-@@ -290,6 +290,7 @@
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEADDR failed");
-+ close(sock);
- return (-1);
- }
- /* connect to PORT on HOST */
-@@ -298,6 +299,7 @@
- printf("FAILED\n");
- fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
- printf("connection refused\n");
-+ close(sock);
- return (-1);
- }
-
-@@ -332,6 +334,7 @@
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEADDR failed");
-+ close(sock);
- return (-1);
- }
-
-@@ -339,12 +342,14 @@
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEPORT failed");
-+ close(sock);
- return (-1);
- }
-
- if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)
- {
- perror("IP_RECVIF failed");
-+ close(sock);
- return (-1);
- }
- #endif /* SPOOF */
-@@ -403,6 +408,7 @@
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEADDR failed");
-+ close(sock);
- return (-1);
- }
-
-diff -Nur olsrd-0.4.10.orig/src/linux/net.c olsrd-0.4.10/src/linux/net.c
---- olsrd-0.4.10.orig/src/linux/net.c 2005-09-17 22:48:50.000000000 +0200
-+++ olsrd-0.4.10/src/linux/net.c 2006-12-01 20:23:37.000000000 +0100
-@@ -434,6 +434,7 @@
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEADDR failed");
-+ close(sock);
- return (-1);
- }
- /* connect to PORT on HOST */
-@@ -442,6 +443,7 @@
- printf("FAILED\n");
- fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
- printf("connection refused\n");
-+ close(sock);
- return (-1);
- }
-
-@@ -487,6 +489,7 @@
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEADDR failed");
-+ close(sock);
- return (-1);
- }
-
-@@ -520,6 +523,7 @@
- {
- fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
- syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
-+ close(sock);
- return -1;
- }
-
-@@ -606,6 +610,7 @@
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEADDR failed");
-+ close(sock);
- return (-1);
- }
-
-@@ -619,6 +624,7 @@
- {
- fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
- syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
-+ close(sock);
- return -1;
- }
-
-diff -Nur olsrd-0.4.10.orig/src/main.c olsrd-0.4.10/src/main.c
---- olsrd-0.4.10.orig/src/main.c 2006-12-01 20:20:31.000000000 +0100
-+++ olsrd-0.4.10/src/main.c 2006-12-01 20:23:54.000000000 +0100
-@@ -118,7 +118,7 @@
- system_tick_divider = 1000/sysconf(_SC_CLK_TCK);
-
- /* Check if user is root */
-- if(getuid() || getgid())
-+ if(geteuid())
- {
- fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n");
- exit(EXIT_FAILURE);
-@@ -395,6 +395,7 @@
- signal(SIGHUP, olsr_reconfigure);
- signal(SIGINT, olsr_shutdown);
- signal(SIGTERM, olsr_shutdown);
-+ signal(SIGPIPE, SIG_IGN);
- #endif
-
- /* Register socket poll event */
-@@ -535,6 +536,7 @@
- fprintf(stderr, " [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n");
- fprintf(stderr, " [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n");
- fprintf(stderr, " [-T <Polling Rate (secs)>] [-nofork] [-hemu <ip_address>] \n");
-+ fprintf(stderr, " [-lql <LQ level>] [-lqw <LQ winsize>]\n");
-
- }
-
-@@ -635,6 +637,42 @@
- memcpy(&ifcnf->ipv4_broadcast.v4, &in.s_addr, sizeof(olsr_u32_t));
- continue;
- }
-+
-+ /*
-+ * Set LQ level
-+ */
-+ if (strcmp(*argv, "-lql") == 0)
-+ {
-+ int tmp_lq_level;
-+ NEXT_ARG;
-+ CHECK_ARGC;
-+
-+ /* Sanity checking is done later */
-+ sscanf(*argv, "%d", &tmp_lq_level);
-+ olsr_cnf->lq_level = tmp_lq_level;
-+ continue;
-+ }
-+
-+ /*
-+ * Set LQ winsize
-+ */
-+ if (strcmp(*argv, "-lqw") == 0)
-+ {
-+ int tmp_lq_wsize;
-+ NEXT_ARG;
-+ CHECK_ARGC;
-+
-+ sscanf(*argv, "%d", &tmp_lq_wsize);
-+
-+ if(tmp_lq_wsize < MIN_LQ_WSIZE || tmp_lq_wsize > MAX_LQ_WSIZE)
-+ {
-+ printf("LQ winsize %d not allowed. Range [%d-%d]\n",
-+ tmp_lq_wsize, MIN_LQ_WSIZE, MAX_LQ_WSIZE);
-+ olsr_exit(__func__, EXIT_FAILURE);
-+ }
-+ olsr_cnf->lq_wsize = tmp_lq_wsize;
-+ continue;
-+ }
-
- /*
- * Enable additional debugging information to be logged.
-diff -Nur olsrd-0.4.10.orig/src/scheduler.c olsrd-0.4.10/src/scheduler.c
---- olsrd-0.4.10.orig/src/scheduler.c 2006-12-01 20:20:31.000000000 +0100
-+++ olsrd-0.4.10/src/scheduler.c 2006-12-01 20:23:37.000000000 +0100
-@@ -330,6 +330,7 @@
- {
- prev->next = entry->next;
- }
-+ free(entry);
- return 1;
- }
-
-diff -Nur olsrd-0.4.10.orig/src/win32/net.c olsrd-0.4.10/src/win32/net.c
---- olsrd-0.4.10.orig/src/win32/net.c 2005-05-30 15:50:27.000000000 +0200
-+++ olsrd-0.4.10/src/win32/net.c 2006-12-01 20:23:37.000000000 +0100
-@@ -87,6 +87,7 @@
- printf("FAILED\n");
- fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
- printf("connection refused\n");
-+ closesocket(sock);
- return (-1);
- }
-
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/src/link_set.c olsrd-0.4.10/src/link_set.c
---- olsrd-0.4.10.orig/src/link_set.c 2006-12-01 09:04:56.000000000 +0100
-+++ olsrd-0.4.10/src/link_set.c 2006-12-01 09:06:22.000000000 +0100
-@@ -381,6 +381,69 @@
- }
-
- /**
-+ *Delete all interface link entries
-+ *
-+ *@param interface ip address
-+ */
-+
-+void
-+del_if_link_entries(union olsr_ip_addr *int_addr)
-+{
-+ struct link_entry *tmp_link_set, *last_link_entry;
-+
-+ if(link_set == NULL)
-+ return;
-+
-+ tmp_link_set = link_set;
-+ last_link_entry = NULL;
-+
-+ while(tmp_link_set)
-+ {
-+
-+ if(COMP_IP(int_addr, &tmp_link_set->local_iface_addr))
-+ {
-+ if(last_link_entry != NULL)
-+ {
-+ last_link_entry->next = tmp_link_set->next;
-+
-+ /* Delete neighbor entry */
-+ if(tmp_link_set->neighbor->linkcount == 1)
-+ olsr_delete_neighbor_table(&tmp_link_set->neighbor->neighbor_main_addr);
-+ else
-+ tmp_link_set->neighbor->linkcount--;
-+
-+ //olsr_delete_neighbor_if_no_link(&tmp_link_set->neighbor->neighbor_main_addr);
-+ changes_neighborhood = OLSR_TRUE;
-+
-+ free(tmp_link_set);
-+ tmp_link_set = last_link_entry;
-+ }
-+ else
-+ {
-+ link_set = tmp_link_set->next; /* CHANGED */
-+
-+ /* Delete neighbor entry */
-+ if(tmp_link_set->neighbor->linkcount == 1)
-+ olsr_delete_neighbor_table(&tmp_link_set->neighbor->neighbor_main_addr);
-+ else
-+ tmp_link_set->neighbor->linkcount--;
-+
-+ changes_neighborhood = OLSR_TRUE;
-+
-+ free(tmp_link_set);
-+ tmp_link_set = link_set;
-+ continue;
-+ }
-+ }
-+
-+ last_link_entry = tmp_link_set;
-+ tmp_link_set = tmp_link_set->next;
-+ }
-+
-+ return;
-+}
-+
-+/**
- *Nothing mysterious here.
- *Adding a new link entry to the link set.
- *
-diff -Nur olsrd-0.4.10.orig/src/link_set.h olsrd-0.4.10/src/link_set.h
---- olsrd-0.4.10.orig/src/link_set.h 2005-10-23 22:58:14.000000000 +0200
-+++ olsrd-0.4.10/src/link_set.h 2006-12-01 09:06:22.000000000 +0100
-@@ -116,6 +116,9 @@
- void
- olsr_init_link_set(void);
-
-+void
-+del_if_link_entries(union olsr_ip_addr *);
-+
- struct link_entry *
- get_best_link_to_neighbor(union olsr_ip_addr *);
-
-diff -Nur olsrd-0.4.10.orig/src/linux/kernel_routes.c olsrd-0.4.10/src/linux/kernel_routes.c
---- olsrd-0.4.10.orig/src/linux/kernel_routes.c 2005-02-27 19:39:43.000000000 +0100
-+++ olsrd-0.4.10/src/linux/kernel_routes.c 2006-12-01 09:06:22.000000000 +0100
-@@ -244,9 +244,8 @@
- inet_ntop(AF_INET, &destination->rt_mask.v4, mask_str, 16);
- inet_ntop(AF_INET, &destination->rt_router.v4, router_str, 16);
-
-- OLSR_PRINTF(1, "(ioctl)Deleting route with metric %d to %s/%s via %s/%s.\n",
-- destination->rt_metric, dst_str, mask_str, router_str,
-- destination->rt_if->int_name)
-+ OLSR_PRINTF(1, "(ioctl)Deleting route with metric %d to %s/%s via %s.\n",
-+ destination->rt_metric, dst_str, mask_str, router_str)
-
- memset(&kernel_route,0,sizeof(struct rtentry));
-
-diff -Nur olsrd-0.4.10.orig/src/lq_packet.c olsrd-0.4.10/src/lq_packet.c
---- olsrd-0.4.10.orig/src/lq_packet.c 2006-12-01 09:04:56.000000000 +0100
-+++ olsrd-0.4.10/src/lq_packet.c 2006-12-01 09:06:22.000000000 +0100
-@@ -225,8 +225,10 @@
-
- link = get_best_link_to_neighbor(&neigh->main);
-
-- neigh->link_quality = link->loss_link_quality;
-- neigh->neigh_link_quality = link->neigh_link_quality;
-+ if (link) {
-+ neigh->link_quality = link->loss_link_quality;
-+ neigh->neigh_link_quality = link->neigh_link_quality;
-+ }
-
- // queue the neighbour entry
-
-diff -Nur olsrd-0.4.10.orig/src/unix/ifnet.c olsrd-0.4.10/src/unix/ifnet.c
---- olsrd-0.4.10.orig/src/unix/ifnet.c 2006-12-01 09:04:56.000000000 +0100
-+++ olsrd-0.4.10/src/unix/ifnet.c 2006-12-01 09:06:22.000000000 +0100
-@@ -56,6 +56,7 @@
- #include "mantissa.h"
- #include "lq_packet.h"
- #include "log.h"
-+#include "link_set.h"
- #include <signal.h>
- #include <sys/types.h>
- #include <net/if.h>
-@@ -393,6 +394,8 @@
- OLSR_PRINTF(1, "Removing interface %s\n", iface->name)
- olsr_syslog(OLSR_LOG_INFO, "Removing interface %s\n", iface->name);
-
-+ del_if_link_entries(&ifp->ip_addr);
-+
- /*
- *Call possible ifchange functions registered by plugins
- */
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/src/parser.c olsrd-0.4.10/src/parser.c
---- olsrd-0.4.10.orig/src/parser.c 2005-11-19 09:49:44.000000000 +0100
-+++ olsrd-0.4.10/src/parser.c 2006-12-04 09:12:40.000000000 +0100
-@@ -61,6 +61,14 @@
- #define strerror(x) StrError(x)
- #endif
-
-+/* Sven-Ola: On very slow devices used in huge networks
-+ * the amount of lq_tc messages is so high, that the
-+ * recv() loop never ends. This is a small hack to end
-+ * the loop in this cases
-+ */
-+
-+unsigned int cpu_overload_exit = 0;
-+
- struct parse_function_entry *parse_functions;
-
- static char inbuf[MAXMESSAGESIZE+1];
-@@ -347,9 +355,16 @@
- int cc;
- struct interface *olsr_in_if;
- union olsr_ip_addr from_addr;
--
-+ cpu_overload_exit = 0;
-+
- for (;;)
- {
-+ if (32 < ++cpu_overload_exit)
-+ {
-+ OLSR_PRINTF(1, "CPU overload detected, ending olsr_input() loop\n")
-+ break;
-+ }
-+
- fromlen = sizeof(struct sockaddr_storage);
-
- cc = olsr_recvfrom(fd,
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/lib/secure/src/olsrd_secure.h olsrd-0.4.10/lib/secure/src/olsrd_secure.h
---- olsrd-0.4.10.orig/lib/secure/src/olsrd_secure.h 2005-11-19 09:30:45.000000000 +0100
-+++ olsrd-0.4.10/lib/secure/src/olsrd_secure.h 2006-12-01 08:50:41.000000000 +0100
-@@ -46,7 +46,7 @@
- #include "hashing.h"
-
-
--#define KEYFILE "/root/.olsr/olsrd_secure_key"
-+#define KEYFILE "/etc/olsrd.d/olsrd_secure_key"
-
- /* Schemes */
- #define ONE_CHECKSUM 1
+++ /dev/null
-diff -Nur olsrd-0.4.10.orig/src/cfgparser/oparse.c olsrd-0.4.10/src/cfgparser/oparse.c
---- olsrd-0.4.10.orig/src/cfgparser/oparse.c 2006-01-01 17:15:57.000000000 +0100
-+++ olsrd-0.4.10/src/cfgparser/oparse.c 2006-12-01 08:21:39.000000000 +0100
-@@ -1921,6 +1921,7 @@
- return -1;
- }
- h->netmask.v4 = in.s_addr;
-+ h->net.v4 &= h->netmask.v4;
- /* Queue */
- h->next = cnf->hna4_entries;
- cnf->hna4_entries = h;
-diff -Nur olsrd-0.4.10.orig/src/cfgparser/oparse.y olsrd-0.4.10/src/cfgparser/oparse.y
---- olsrd-0.4.10.orig/src/cfgparser/oparse.y 2005-11-17 05:25:44.000000000 +0100
-+++ olsrd-0.4.10/src/cfgparser/oparse.y 2006-12-01 08:23:05.000000000 +0100
-@@ -701,6 +701,7 @@
- return -1;
- }
- h->netmask.v4 = in.s_addr;
-+ h->net.v4 &= h->netmask.v4;
- /* Queue */
- h->next = cnf->hna4_entries;
- cnf->hna4_entries = h;