From: Tim Yardley Date: Tue, 6 Feb 2007 16:45:04 +0000 (+0000) Subject: merge olsrd changes with freifunks code changes. compiles completely, but have not... X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=76cdad857fcb79ad90091234f9a4eac8101a4806;p=openwrt%2Fsvn-archive%2Farchive.git merge olsrd changes with freifunks code changes. compiles completely, but have not tested with an actually mesh. SVN-Revision: 6273 --- diff --git a/net/olsrd/patches/110-olsrd-libsmake.patch b/net/olsrd/patches/110-olsrd-libsmake.patch new file mode 100644 index 0000000000..018604d4cd --- /dev/null +++ b/net/olsrd/patches/110-olsrd-libsmake.patch @@ -0,0 +1,9 @@ +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) + diff --git a/net/olsrd/patches/120-olsrd-dyngwplain.patch b/net/olsrd/patches/120-olsrd-dyngwplain.patch new file mode 100644 index 0000000000..2d0d5f3617 --- /dev/null +++ b/net/olsrd/patches/120-olsrd-dyngwplain.patch @@ -0,0 +1,364 @@ +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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 diff --git a/net/olsrd/patches/120-secure_path.patch b/net/olsrd/patches/120-secure_path.patch deleted file mode 100644 index fcae759862..0000000000 --- a/net/olsrd/patches/120-secure_path.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -ruN olsrd-0.4.9-orig/lib/secure/src/olsrd_secure.h olsrd-0.4.9-1/lib/secure/src/olsrd_secure.h ---- olsrd-0.4.9-orig/lib/secure/src/olsrd_secure.h 2005-03-10 20:57:48.000000000 +0100 -+++ olsrd-0.4.9-1/lib/secure/src/olsrd_secure.h 2005-04-05 00:51:40.000000000 +0200 -@@ -43,7 +43,7 @@ - - #include "olsrd_plugin.h" - --#define KEYFILE "/root/.olsr/olsrd_secure_key" -+#define KEYFILE "/etc/olsrd.d/olsrd_secure_key" - - /* Schemes */ - #define ONE_CHECKSUM 1 diff --git a/net/olsrd/patches/130-olsrd-nameservice+services.patch b/net/olsrd/patches/130-olsrd-nameservice+services.patch new file mode 100644 index 0000000000..6d23dadbd0 --- /dev/null +++ b/net/olsrd/patches/130-olsrd-nameservice+services.patch @@ -0,0 +1,1287 @@ +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 + * Copyright (c) 2005, Bruno Randolf + * Copyright (c) 2004, Andreas Tønnesen(andreto-at-olsr.org) + * All rights reserved. +@@ -39,6 +40,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #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;indextimer)) + { + 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 && postype = 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 ++#include + + #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 + */ diff --git a/net/olsrd/patches/130-olsrd_fixes.patch b/net/olsrd/patches/130-olsrd_fixes.patch deleted file mode 100644 index e806bedd26..0000000000 --- a/net/olsrd/patches/130-olsrd_fixes.patch +++ /dev/null @@ -1,212 +0,0 @@ -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-01-01 16:59:02.000000000 +0100 -+++ olsrd-0.4.10/src/defs.h 2006-10-31 19:34:52.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 16 - - /* 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-10-31 19:44:52.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 2005-11-17 05:25:44.000000000 +0100 -+++ olsrd-0.4.10/src/link_set.c 2006-10-31 19:31:19.000000000 +0100 -@@ -952,8 +952,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-10-31 21:51:11.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 2005-11-17 05:25:44.000000000 +0100 -+++ olsrd-0.4.10/src/olsr.c 2006-10-31 19:31:19.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) -@@ -239,6 +235,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-10-31 19:31:19.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-10-31 19:31:19.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 2005-12-29 19:37:16.000000000 +0100 -+++ olsrd-0.4.10/src/unix/ifnet.c 2006-10-31 21:44:59.000000000 +0100 -@@ -689,6 +689,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. -@@ -832,10 +843,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 +907,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; diff --git a/net/olsrd/patches/140-olsrd-txtinfo.patch b/net/olsrd/patches/140-olsrd-txtinfo.patch new file mode 100644 index 0000000000..a7344cee4a --- /dev/null +++ b/net/olsrd/patches/140-olsrd-txtinfo.patch @@ -0,0 +1,853 @@ +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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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;indexnext) ++ { ++ 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], "\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;indexdestinations.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;indexnetworks.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: ++ *; ++}; diff --git a/net/olsrd/patches/140-olsrd_optimize.patch b/net/olsrd/patches/140-olsrd_optimize.patch deleted file mode 100644 index ddea522c56..0000000000 --- a/net/olsrd/patches/140-olsrd_optimize.patch +++ /dev/null @@ -1,426 +0,0 @@ -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 -+#ifndef DISABLE_SVEN_OLA -+#include -+#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; - }; - diff --git a/net/olsrd/patches/150-hna_ip_fix.patch b/net/olsrd/patches/150-hna_ip_fix.patch deleted file mode 100644 index 2f359a22a9..0000000000 --- a/net/olsrd/patches/150-hna_ip_fix.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -ur olsrd.old/src/cfgparser/oparse.c olsrd.dev/src/cfgparser/oparse.c ---- olsrd.old/src/cfgparser/oparse.c 2006-01-01 17:15:57.000000000 +0100 -+++ olsrd.dev/src/cfgparser/oparse.c 2006-10-09 01:06:27.000000000 +0200 -@@ -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 --git a/net/olsrd/patches/150-olsrd-quagga.patch b/net/olsrd/patches/150-olsrd-quagga.patch new file mode 100644 index 0000000000..50d32dcac7 --- /dev/null +++ b/net/olsrd/patches/150-olsrd-quagga.patch @@ -0,0 +1,3231 @@ +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 : ++ * 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 : ++ * Initial release, too :-) ++ * Added support for route-export to the zebra/quagga ++ ++0.1.0: Immo 'FaUl' Wehrenberg : ++ * 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 @@ ++ ++ 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 @@ ++ ++ ++ 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 ++--------------------------------------------------------------------- ++ ++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" "" ++ 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" "" ++ 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 ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef HAVE_STROPTS_H ++#include ++#endif /* HAVE_STROPTS_H */ ++#include ++#ifdef HAVE_SYS_SELECT_H ++#include ++#endif /* HAVE_SYS_SELECT_H */ ++#include ++#include ++#include ++#include ++#ifdef HAVE_SYS_SYSCTL_H ++#include ++#endif /* HAVE_SYS_SYSCTL_H */ ++#include ++#ifdef HAVE_SYS_CONF_H ++#include ++#endif /* HAVE_SYS_CONF_H */ ++#ifdef HAVE_SYS_KSYM_H ++#include ++#endif /* HAVE_SYS_KSYM_H */ ++#include ++#include ++#include ++#include ++#ifdef HAVE_RUSAGE ++#include ++#endif /* HAVE_RUSAGE */ ++#ifdef HAVE_LIMITS_H ++#include ++#endif /* HAVE_LIMITS_H */ ++ ++/* machine dependent includes */ ++#ifdef SUNOS_5 ++#include ++#endif /* SUNOS_5 */ ++ ++/* machine dependent includes */ ++#ifdef HAVE_LINUX_VERSION_H ++#include ++#endif /* HAVE_LINUX_VERSION_H */ ++ ++#ifdef HAVE_ASM_TYPES_H ++#include ++#endif /* HAVE_ASM_TYPES_H */ ++ ++/* misc include group */ ++#include ++#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 ++#include ++#endif /* HAVE_LCAPS */ ++ ++/* network include group */ ++ ++#include ++ ++#ifdef HAVE_SYS_SOCKIO_H ++#include ++#endif /* HAVE_SYS_SOCKIO_H */ ++ ++#ifdef HAVE_NETINET_IN_H ++#include ++#endif /* HAVE_NETINET_IN_H */ ++#include ++#include ++#include ++ ++#ifdef HAVE_NET_NETOPT_H ++#include ++#endif /* HAVE_NET_NETOPT_H */ ++ ++#include ++ ++#ifdef HAVE_NET_IF_DL_H ++#include ++#endif /* HAVE_NET_IF_DL_H */ ++ ++#ifdef HAVE_NET_IF_VAR_H ++#include ++#endif /* HAVE_NET_IF_VAR_H */ ++ ++#ifdef HAVE_NET_ROUTE_H ++#include ++#endif /* HAVE_NET_ROUTE_H */ ++ ++#ifdef HAVE_NETLINK ++#include ++#include ++#else ++#define RT_TABLE_MAIN 0 ++#endif /* HAVE_NETLINK */ ++ ++#ifdef HAVE_NETDB_H ++#include ++#endif /* HAVE_NETDB_H */ ++ ++#include ++#include ++ ++#ifdef HAVE_INET_ND_H ++#include ++#endif /* HAVE_INET_ND_H */ ++ ++#ifdef HAVE_NETINET_IN_VAR_H ++#include ++#endif /* HAVE_NETINET_IN_VAR_H */ ++ ++#ifdef HAVE_NETINET6_IN6_VAR_H ++#include ++#endif /* HAVE_NETINET6_IN6_VAR_H */ ++ ++#ifdef HAVE_NETINET_IN6_VAR_H ++#include ++#endif /* HAVE_NETINET_IN6_VAR_H */ ++ ++#ifdef HAVE_NETINET6_IN_H ++#include ++#endif /* HAVE_NETINET6_IN_H */ ++ ++ ++#ifdef HAVE_NETINET6_IP6_H ++#include ++#endif /* HAVE_NETINET6_IP6_H */ ++ ++#ifdef HAVE_NETINET_ICMP6_H ++#include ++#endif /* HAVE_NETINET_ICMP6_H */ ++ ++#ifdef HAVE_NETINET6_ND6_H ++#include ++#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 ++#endif /* HAVE_LIBUTIL_H */ ++ ++#ifdef HAVE_GLIBC_BACKTRACE ++#include ++#endif /* HAVE_GLIBC_BACKTRACE */ ++ ++#ifdef BSDI_NRL ++ ++#ifdef HAVE_NETINET6_IN6_H ++#include ++#endif /* HAVE_NETINET6_IN6_H */ ++ ++#ifdef NRL ++#include ++#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 ; ++ 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 ++#endif ++ ++#define HAVE_SOCKLEN_T ++#include ++ ++#include ++#include ++#include ++#include ++#include "quagga.h" ++ ++#include "olsr.h" ++#include "log.h" ++#include "defs.h" ++#include "local_hna_set.h" ++ ++#ifdef USE_UNIX_DOMAIN_SOCKET ++#include ++#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 ++#include ++#include ++#include "routing_table.h" ++#define HAVE_SOCKLEN_T ++#include ++ ++#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 ++ * ++ * This code is covered by the GPLv2 ++ * ++ */ ++ ++#include ++#ifdef MY_DEBUG ++#include ++#endif ++#include ++#include ++#include ++#define HAVE_SOCKLEN_T ++#include ++#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: ++ *; ++}; diff --git a/net/olsrd/patches/160-olsrd-quagga-routehandler.patch b/net/olsrd/patches/160-olsrd-quagga-routehandler.patch new file mode 100644 index 0000000000..f8a1201e26 --- /dev/null +++ b/net/olsrd/patches/160-olsrd-quagga-routehandler.patch @@ -0,0 +1,259 @@ +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 ++ * ++ * + * 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); + diff --git a/net/olsrd/patches/170-olsrd-bmf.patch b/net/olsrd/patches/170-olsrd-bmf.patch new file mode 100644 index 0000000000..1bec8672a3 --- /dev/null +++ b/net/olsrd/patches/170-olsrd-bmf.patch @@ -0,0 +1,3573 @@ +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() */ ++#include /* struct ip */ ++#include /* 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 /* NULL */ ++#include /* ssize_t */ ++#include /* strerror() */ ++#include /* errno */ ++#include /* assert() */ ++#include /* struct sockaddr_ll, PACKET_MULTICAST */ ++#include /* pthread_t, pthread_create() */ ++#include /* sigset_t, sigfillset(), sigdelset(), SIGINT */ ++#include /* 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() */ ++#include /* NULL */ ++#include /* malloc */ ++#include /* 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() */ ++#include /* strerror() */ ++#include /* errno */ ++#include /* close() */ ++#include /* ioctl() */ ++#include /* fcntl() */ ++#include /* assert() */ ++#include /* socket(), ifreq, if_indextoname(), if_nametoindex() */ ++#include /* htons() */ ++#include /* ETH_P_ALL */ ++#include /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */ ++#include /* 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 /* 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() */ ++#include ++ ++/* 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() */ ++#include /* u_int32_t */ ++#include /* ntohs(), htons() */ ++#include ++ ++/* ------------------------------------------------------------------------- ++ * 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 /* IFNAMSIZ, IFHWADDRLEN */ ++#include /* 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() */ ++#include /* u_int16_t, u_int32_t */ ++#include /* 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 /* 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 diff --git a/net/olsrd/patches/180-olsrd-bmf-fixes.patch b/net/olsrd/patches/180-olsrd-bmf-fixes.patch new file mode 100644 index 0000000000..4ff162734c --- /dev/null +++ b/net/olsrd/patches/180-olsrd-bmf-fixes.patch @@ -0,0 +1,336 @@ +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() */ + #include /* u_int32_t */ + #include /* ntohs(), htons() */ ++/* Fixes (k)ubuntu linux-kernel-headers package */ ++#include + #include + + /* ------------------------------------------------------------------------- +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) diff --git a/net/olsrd/patches/190-olsrd-optimize.patch b/net/olsrd/patches/190-olsrd-optimize.patch new file mode 100644 index 0000000000..ddea522c56 --- /dev/null +++ b/net/olsrd/patches/190-olsrd-optimize.patch @@ -0,0 +1,426 @@ +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 ++#ifndef DISABLE_SVEN_OLA ++#include ++#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; + }; + diff --git a/net/olsrd/patches/200-olsrd-fixes-eric.patch b/net/olsrd/patches/200-olsrd-fixes-eric.patch new file mode 100644 index 0000000000..95bb06ddac --- /dev/null +++ b/net/olsrd/patches/200-olsrd-fixes-eric.patch @@ -0,0 +1,1284 @@ +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], "

OLSR routes in kernel

\n"); + +- size += sprintf(&buf[size], "\n"); ++ size += sprintf(&buf[size], "
DestinationGatewayMetricETXInterfaceType
"); ++ if (olsr_cnf->lq_level > 0) ++ size += sprintf(&buf[size], ""); ++ size += sprintf(&buf[size], "\n"); + + /* Neighbors */ + for(index = 0;index < HASHSIZE;index++) +@@ -722,12 +725,23 @@ + routes != &routingtable[index]; + routes = routes->next) + { +- size += sprintf(&buf[size], "\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], ++ "" ++ "" ++ "", ++ 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], "", routes->rt_etx); ++ size += sprintf(&buf[size], ++ "" ++ "\n", ++ routes->rt_if->int_name); + } + } + +@@ -738,11 +752,21 @@ + routes != &hna_routes[index]; + routes = routes->next) + { +- size += sprintf(&buf[size], "\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], ++ "" ++ "" ++ "", ++ 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], "", routes->rt_etx); ++ size += sprintf(&buf[size], ++ "" ++ "\n", ++ routes->rt_if->int_name); + } + } + +@@ -816,17 +840,24 @@ + + size += sprintf(&buf[size], "\n\n"); + +- size += sprintf(&buf[size], "\n", olsr_cnf->use_hysteresis ? "Enabled" : "Disabled"); +- +- size += sprintf(&buf[size], "\n", olsr_cnf->hysteresis_param.scaling); +- size += sprintf(&buf[size], "\n", olsr_cnf->hysteresis_param.thr_low, olsr_cnf->hysteresis_param.thr_high); ++ if (olsr_cnf->lq_level == 0) ++ { ++ size += sprintf(&buf[size], "\n", olsr_cnf->use_hysteresis ? "Enabled" : "Disabled"); ++ if (olsr_cnf->use_hysteresis) ++ { ++ size += sprintf(&buf[size], "\n", olsr_cnf->hysteresis_param.scaling); ++ size += sprintf(&buf[size], "\n", olsr_cnf->hysteresis_param.thr_low, olsr_cnf->hysteresis_param.thr_high); ++ } ++ } + + size += sprintf(&buf[size], "\n\n"); + +- size += sprintf(&buf[size], "\n", olsr_cnf->lq_level ? "Enabled" : "Disabled"); +- size += sprintf(&buf[size], "\n", olsr_cnf->lq_level); +- size += sprintf(&buf[size], "\n", olsr_cnf->lq_wsize); +- size += sprintf(&buf[size], "\n"); ++ size += sprintf(&buf[size], "\n", olsr_cnf->lq_level ? "Enabled" : "Disabled"); ++ if (olsr_cnf->lq_level) ++ { ++ size += sprintf(&buf[size], "\n", olsr_cnf->lq_level); ++ size += sprintf(&buf[size], "\n", olsr_cnf->lq_wsize); ++ } + + size += sprintf(&buf[size], "
DestinationGatewayMetricETXInterfaceType
%s%s%d%.2f%sHOST
%s%s%d%.2f%sHOST
%s%s%d%sHNA
%s%s%d%.2f%sHNA
Hysteresis: %sHyst scaling: %0.2fHyst lower/upper: %0.2f/%0.2fHysteresis: %sHyst scaling: %0.2fHyst lower/upper: %0.2f/%0.2f
LQ extention: %sLQ level: %dLQ winsize: %dLQ extension: %sLQ level: %dLQ winsize: %d
\n"); + +@@ -868,7 +899,6 @@ + size += sprintf(&buf[size], "WLAN: %s\n", rifs->is_wireless ? "Yes" : "No"); + size += sprintf(&buf[size], "STATUS: UP\n"); + } +- + } + + size += sprintf(&buf[size], "\n"); +@@ -950,21 +980,39 @@ + int size = 0, index, thop_cnt; + + size += sprintf(&buf[size], "

Links

\n"); +- size += sprintf(&buf[size], "\n"); ++ size += sprintf(&buf[size], "
Local IPremote IPHysteresisLinkQualitylosttotalNLQETX
\n"); ++ if (olsr_cnf->lq_level > 0) ++ size += sprintf(&buf[size], "\n"); ++ size += sprintf(&buf[size], "\n"); + + /* Link set */ + link = link_set; + while(link) + { +- size += sprintf(&buf[size], "\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], ++ "" ++ "" ++ "", ++ 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], ++ "" ++ "" ++ "" ++ "" ++ "\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], "\n"); + + link = link->next; + } +@@ -981,7 +1029,13 @@ + neigh = neigh->next) + { + size += sprintf(&buf[size], +- "", ++ "" ++ "" ++ "" ++ "" ++ "", ++ 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], "

Topology entries

\n
Local IPremote IPHysteresisLinkQualitylosttotalNLQETX
%s%s%0.2f%0.2f%d%d%0.2f%0.2f
%s%s%0.2f%0.2f%d%d%0.2f%0.2f
%s%s%s%s%d
%s%s%s%s%d
\n"); ++ size += sprintf(&buf[size], "

Topology entries

\n
Destination IPLast hop IPLQILQETX
"); ++ if (olsr_cnf->lq_level > 0) ++ size += sprintf(&buf[size], ""); ++ size += sprintf(&buf[size], "\n"); + + + /* Topology */ +@@ -1035,12 +1092,26 @@ + dst_entry = entry->destinations.next; + while(dst_entry != &entry->destinations) + { +- size += sprintf(&buf[size], "\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], ++ "" ++ "", ++ 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], ++ "" ++ "" ++ "\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], "\n"); + + dst_entry = dst_entry->next; + } +@@ -1083,7 +1154,9 @@ + olsr_ip_to_string(&tmp_net->A_network_addr)); + size += sprintf(&buf[size], "", + olsr_netmask_to_string(&tmp_net->A_netmask)); +- size += sprintf(&buf[size], "\n", ++ size += sprintf(&buf[size], "\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], "\n", olsr_ip_to_string(&entry->main_addr)); ++ size += sprintf(&buf[size], "\n", ++ olsr_ip_to_string(&entry->main_addr), ++ http_port, ++ olsr_ip_to_string(&entry->main_addr)); + size += sprintf(&buf[size], "\n"); ++ size += sprintf(&buf[size], " (%d)\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 + #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 + #include + #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 diff --git a/net/olsrd/patches/210-olsrd-fixes-sven-ola.patch b/net/olsrd/patches/210-olsrd-fixes-sven-ola.patch new file mode 100644 index 0000000000..4232df582f --- /dev/null +++ b/net/olsrd/patches/210-olsrd-fixes-sven-ola.patch @@ -0,0 +1,212 @@ +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; diff --git a/net/olsrd/patches/220-olsrd-fixes-jhay-bsd.patch b/net/olsrd/patches/220-olsrd-fixes-jhay-bsd.patch new file mode 100644 index 0000000000..4bb3d0752b --- /dev/null +++ b/net/olsrd/patches/220-olsrd-fixes-jhay-bsd.patch @@ -0,0 +1,425 @@ +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 + #include + #include ++#include + #ifndef FBSD_NO_80211 + #include + #include +@@ -71,8 +73,8 @@ + #endif + #endif + +-#ifdef SPOOF + #include ++#ifdef SPOOF + #include + #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++; + } + } diff --git a/net/olsrd/patches/230-olsrd-fixes-backport.patch b/net/olsrd/patches/230-olsrd-fixes-backport.patch new file mode 100644 index 0000000000..92616dff9b --- /dev/null +++ b/net/olsrd/patches/230-olsrd-fixes-backport.patch @@ -0,0 +1,306 @@ +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 ] [-tcint ]\n"); + fprintf(stderr, " [-midint ] [-hnaint ]\n"); + fprintf(stderr, " [-T ] [-nofork] [-hemu ] \n"); ++ fprintf(stderr, " [-lql ] [-lqw ]\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); + } + diff --git a/net/olsrd/patches/240-olsrd-fixes-routedel.patch b/net/olsrd/patches/240-olsrd-fixes-routedel.patch new file mode 100644 index 0000000000..ae61bab164 --- /dev/null +++ b/net/olsrd/patches/240-olsrd-fixes-routedel.patch @@ -0,0 +1,137 @@ +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 + #include + #include +@@ -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 + */ diff --git a/net/olsrd/patches/250-olsrd-cpu-overload.patch b/net/olsrd/patches/250-olsrd-cpu-overload.patch new file mode 100644 index 0000000000..b76ef915b1 --- /dev/null +++ b/net/olsrd/patches/250-olsrd-cpu-overload.patch @@ -0,0 +1,36 @@ +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, diff --git a/net/olsrd/patches/260-olsrd-secure_key_path.patch b/net/olsrd/patches/260-olsrd-secure_key_path.patch new file mode 100644 index 0000000000..7be25c021f --- /dev/null +++ b/net/olsrd/patches/260-olsrd-secure_key_path.patch @@ -0,0 +1,12 @@ +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 diff --git a/net/olsrd/patches/270-olsrd-hna_ip_fix.patch b/net/olsrd/patches/270-olsrd-hna_ip_fix.patch new file mode 100644 index 0000000000..f7f11400f7 --- /dev/null +++ b/net/olsrd/patches/270-olsrd-hna_ip_fix.patch @@ -0,0 +1,22 @@ +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;
Destination IPLast hop IPLQILQETX
%s%s%0.2f%0.2f%0.2f
%s%s%0.2f%0.2f%0.2f
%s%s
%s
%s
%s\n"); +- +- size += sprintf(&buf[size], "