--- /dev/null
+diff -Naur olsrd-0.5.6-r5/lib/quagga/Makefile olsrd-0.5.6-r5.patched/lib/quagga/Makefile
+--- olsrd-0.5.6-r5/lib/quagga/Makefile 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/Makefile 2009-07-04 16:38:27.000000000 +0300
+@@ -40,21 +40,19 @@
+ PLUGIN_NAME = olsrd_quagga
+ PLUGIN_VER = 0.2.2
+
+-TOPDIR= ../..
++TOPDIR = ../..
+ include $(TOPDIR)/Makefile.inc
+
+-#CPPFLAGS +=-DMY_DEBUG
+ CFLAGS += -g
+ CPPFLAGS +=-DUSE_UNIX_DOMAIN_SOCKET
+
+-#uncomment the following line only if you are sure what you're doing, it will
+-#probably break things!
+-# CPPFLAGS +=-DZEBRA_HEADER_MARKER=255
+-
+ ifeq ($(OS),win32)
++
+ default_target install clean:
+- @echo "**** Quagga not supportet on Windows (so it would be pointless to build the Quagga Plugin)"
++ @echo "*** Quagga not supported on Windows (so it would be pointless to build the Quagga plugin)"
++
+ else
++
+ default_target: $(PLUGIN_FULLNAME)
+
+ $(PLUGIN_FULLNAME): $(OBJS) version-script.txt
+@@ -66,4 +64,5 @@
+
+ clean:
+ rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
++
+ endif
+diff -Naur olsrd-0.5.6-r5/lib/quagga/patches/quagga-0.98.6.diff olsrd-0.5.6-r5.patched/lib/quagga/patches/quagga-0.98.6.diff
+--- olsrd-0.5.6-r5/lib/quagga/patches/quagga-0.98.6.diff 1970-01-01 02:00:00.000000000 +0200
++++ olsrd-0.5.6-r5.patched/lib/quagga/patches/quagga-0.98.6.diff 2009-07-04 16:38:26.000000000 +0300
+@@ -0,0 +1,860 @@
++diff -Nur quagga-0.98.6/bgpd/bgp_vty.c quagga-0.98.6.patched/bgpd/bgp_vty.c
++--- quagga-0.98.6/bgpd/bgp_vty.c 2006-03-30 18:12:25.000000000 +0200
+++++ quagga-0.98.6.patched/bgpd/bgp_vty.c 2007-12-30 14:18:22.000000000 +0200
++@@ -3,6 +3,9 @@
++
++ This file is part of GNU Zebra.
++
+++This file was modified from the original on 30/12/2007
+++by Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+++
++ 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
++@@ -7793,8 +7796,12 @@
++ 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;
+++ else if (strncmp (str, "ba", 2) == 0)
+++ return ZEBRA_ROUTE_BATMAN;
++ }
++ if (afi == AFI_IP6)
++ {
++@@ -7806,21 +7813,28 @@
++ 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;
+++ else if (strncmp (str, "ba", 2) == 0)
+++ return ZEBRA_ROUTE_BATMAN;
++ }
++ return 0;
++ }
++
++ DEFUN (bgp_redistribute_ipv4,
++ bgp_redistribute_ipv4_cmd,
++- "redistribute (connected|kernel|ospf|rip|static)",
+++ "redistribute (connected|kernel|ospf|rip|static|olsr|batman)",
++ "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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
+++ )
++ {
++ int type;
++
++@@ -7835,13 +7849,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n")
++ {
++@@ -7860,13 +7876,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n")
++ {
++@@ -7887,13 +7905,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n"
++ "Metric for redistributed routes\n"
++@@ -7917,13 +7937,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n"
++ "Route map reference\n"
++@@ -7947,14 +7969,17 @@
++
++ 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|batman)",
++ 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
+++ )
++ {
++ int type;
++
++@@ -7970,7 +7995,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|batman) route-map WORD",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -7978,6 +8003,8 @@
++ "Open Shurtest Path First (OSPF)\n"
++ "Routing Information Protocol (RIP)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n")
++ {
++@@ -7996,7 +8023,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|batman) metric <0-4294967295>",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -8004,6 +8031,8 @@
++ "Open Shurtest Path First (OSPF)\n"
++ "Routing Information Protocol (RIP)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n")
++ {
++@@ -8022,7 +8051,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|batman) route-map WORD metric <0-4294967295>",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -8030,6 +8059,8 @@
++ "Open Shurtest Path First (OSPF)\n"
++ "Routing Information Protocol (RIP)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n"
++ "Metric for redistributed routes\n"
++@@ -8051,7 +8082,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|batman) metric <0-4294967295> route-map WORD",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -8059,6 +8090,8 @@
++ "Open Shurtest Path First (OSPF)\n"
++ "Routing Information Protocol (RIP)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n"
++ "Route map reference\n"
++@@ -8067,13 +8100,16 @@
++ #ifdef HAVE_IPV6
++ DEFUN (bgp_redistribute_ipv6,
++ bgp_redistribute_ipv6_cmd,
++- "redistribute (connected|kernel|ospf6|ripng|static)",
+++ "redistribute (connected|kernel|ospf6|ripng|static|olsr|batman)",
++ "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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
+++ )
++ {
++ int type;
++
++@@ -8089,13 +8125,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n")
++ {
++@@ -8114,13 +8152,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n")
++ {
++@@ -8141,13 +8181,15 @@
++
++ 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|olsr|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n"
++ "Metric for redistributed routes\n"
++@@ -8171,13 +8213,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n"
++ "Route map reference\n"
++@@ -8201,14 +8245,17 @@
++
++ 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|batman)",
++ 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
+++ )
++ {
++ int type;
++
++@@ -8224,7 +8271,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|batman) route-map WORD",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -8232,6 +8279,8 @@
++ "Open Shurtest Path First (OSPFv3)\n"
++ "Routing Information Protocol (RIPng)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n")
++ {
++@@ -8250,7 +8299,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|batman) metric <0-4294967295>",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -8258,6 +8307,8 @@
++ "Open Shurtest Path First (OSPFv3)\n"
++ "Routing Information Protocol (RIPng)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n")
++ {
++@@ -8276,7 +8327,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|batman) route-map WORD metric <0-4294967295>",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -8284,6 +8335,8 @@
++ "Open Shurtest Path First (OSPFv3)\n"
++ "Routing Information Protocol (RIPng)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n"
++ "Metric for redistributed routes\n"
++@@ -8305,7 +8358,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|batman) metric <0-4294967295> route-map WORD",
++ NO_STR
++ "Redistribute information from another routing protocol\n"
++ "Connected\n"
++@@ -8313,6 +8366,8 @@
++ "Open Shurtest Path First (OSPFv3)\n"
++ "Routing Information Protocol (RIPng)\n"
++ "Static routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "Default metric\n"
++ "Route map reference\n"
++@@ -8325,7 +8380,7 @@
++ {
++ int i;
++ const char *str[] = { "system", "kernel", "connected", "static", "rip",
++- "ripng", "ospf", "ospf6", "isis", "bgp"};
+++ "ripng", "ospf", "ospf6", "isis", "bgp", "hsls", "olsr", "batman"};
++
++ /* Unicast redistribution only. */
++ if (safi != SAFI_UNICAST)
++diff -Nur quagga-0.98.6/lib/zebra.h quagga-0.98.6.patched/lib/zebra.h
++--- quagga-0.98.6/lib/zebra.h 2005-06-15 14:54:18.000000000 +0300
+++++ quagga-0.98.6.patched/lib/zebra.h 2007-12-30 14:18:22.000000000 +0200
++@@ -3,6 +3,9 @@
++
++ This file is part of GNU Zebra.
++
+++This file was modified from the original on 30/12/2007
+++by Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+++
++ 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
++@@ -378,7 +381,9 @@
++ #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_BATMAN 12
+++#define ZEBRA_ROUTE_MAX 13
++
++ /* Zebra's family types. */
++ #define ZEBRA_FAMILY_IPV4 1
++diff -Nur quagga-0.98.6/ospfd/ospf_vty.c quagga-0.98.6.patched/ospfd/ospf_vty.c
++--- quagga-0.98.6/ospfd/ospf_vty.c 2006-03-30 17:41:20.000000000 +0200
+++++ quagga-0.98.6.patched/ospfd/ospf_vty.c 2007-12-30 14:18:22.000000000 +0200
++@@ -3,6 +3,9 @@
++ *
++ * This file is part of GNU Zebra.
++ *
+++ * This file was modified from the original on 30/12/2007
+++ * by Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+++ *
++ * 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
++@@ -106,11 +109,15 @@
++ *source = ZEBRA_ROUTE_STATIC;
++ else if (strncmp (str, "r", 1) == 0)
++ *source = ZEBRA_ROUTE_RIP;
++- else if (strncmp (str, "b", 1) == 0)
+++ else if (strncmp (str, "bg", 2) == 0)
++ *source = ZEBRA_ROUTE_BGP;
+++ else if (strncmp (str, "ol", 2) == 0)
+++ *source = ZEBRA_ROUTE_OLSR;
+++ else if (strncmp (str, "ba", 2) == 0)
+++ *source = ZEBRA_ROUTE_BATMAN;
++ else
++ return 0;
++-
+++
++ return 1;
++ }
++
++@@ -5302,13 +5309,15 @@
++ \f
++ DEFUN (ospf_redistribute_source_metric_type,
++ ospf_redistribute_source_metric_type_routemap_cmd,
++- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> metric-type (1|2) route-map WORD",
+++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "OSPF default metric\n"
++ "OSPF exterior metric type for redistributed routes\n"
++@@ -5346,13 +5355,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "OSPF default metric\n"
++ "OSPF exterior metric type for redistributed routes\n"
++@@ -5361,25 +5372,29 @@
++
++ ALIAS (ospf_redistribute_source_metric_type,
++ ospf_redistribute_source_metric_cmd,
++- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214>",
+++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\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 +5432,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\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 +5449,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|batman) metric-type (1|2)",
++ "Redistribute information from another routing protocol\n"
++ "Kernel routes\n"
++ "Connected\n"
++@@ -5440,28 +5457,35 @@
++ "Routing Information Protocol (RIP)\n"
++ "Border Gateway Protocol (BGP)\n"
++ "OSPF exterior metric type for redistributed routes\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\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|batman)",
++ "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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Metric for redistributed routes\n"
++ "OSPF default metric\n"
++ "Route map reference\n"
++@@ -5490,13 +5514,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\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 +5552,15 @@
++
++ 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|batman) 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Route map reference\n"
++ "Pointer to route-map entries\n")
++ {
++@@ -5553,14 +5581,17 @@
++
++ 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|batman)",
++ 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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
+++ )
++ {
++ struct ospf *ospf = vty->index;
++ int source;
++@@ -5574,7 +5605,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|batman)",
++ "Filter networks in routing updates\n"
++ "Access-list name\n"
++ OUT_STR
++@@ -5582,7 +5613,10 @@
++ "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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
+++)
++ {
++ struct ospf *ospf = vty->index;
++ int source;
++@@ -5596,7 +5630,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|batman)",
++ NO_STR
++ "Filter networks in routing updates\n"
++ "Access-list name\n"
++@@ -5605,7 +5639,10 @@
++ "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"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
+++)
++ {
++ struct ospf *ospf = vty->index;
++ int source;
++@@ -7121,7 +7158,8 @@
++
++ \f
++ const char *distribute_str[] = { "system", "kernel", "connected", "static",
++- "rip", "ripng", "ospf", "ospf6", "isis", "bgp"};
+++ "rip", "ripng", "ospf", "ospf6", "isis", "bgp",
+++ "hsls","olsr","batman"};
++ int
++ config_write_ospf_redistribute (struct vty *vty, struct ospf *ospf)
++ {
++diff -Nur quagga-0.98.6/zebra/redistribute.c quagga-0.98.6.patched/zebra/redistribute.c
++--- quagga-0.98.6/zebra/redistribute.c 2005-06-15 14:54:51.000000000 +0300
+++++ quagga-0.98.6.patched/zebra/redistribute.c 2007-12-30 14:18:22.000000000 +0200
++@@ -3,6 +3,9 @@
++ *
++ * This file is part of GNU Zebra.
++ *
+++ * This file was modified from the original on 30/12/2007
+++ * by Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+++ *
++ * 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
++@@ -253,6 +256,8 @@
++ case ZEBRA_ROUTE_OSPF:
++ case ZEBRA_ROUTE_OSPF6:
++ case ZEBRA_ROUTE_BGP:
+++ case ZEBRA_ROUTE_OLSR:
+++ case ZEBRA_ROUTE_BATMAN:
++ if (! client->redist[type])
++ {
++ client->redist[type] = 1;
++@@ -281,6 +286,8 @@
++ case ZEBRA_ROUTE_OSPF:
++ case ZEBRA_ROUTE_OSPF6:
++ case ZEBRA_ROUTE_BGP:
+++ case ZEBRA_ROUTE_OLSR:
+++ case ZEBRA_ROUTE_BATMAN:
++ client->redist[type] = 0;
++ break;
++ default:
++diff -Nur quagga-0.98.6/zebra/zebra_vty.c quagga-0.98.6.patched/zebra/zebra_vty.c
++--- quagga-0.98.6/zebra/zebra_vty.c 2004-12-18 18:03:29.000000000 +0200
+++++ quagga-0.98.6.patched/zebra/zebra_vty.c 2007-12-30 14:25:48.000000000 +0200
++@@ -53,6 +53,10 @@
++ return "isis";
++ case ZEBRA_ROUTE_BGP:
++ return "bgp";
+++ case ZEBRA_ROUTE_OLSR:
+++ return "olsr";
+++ case ZEBRA_ROUTE_BATMAN:
+++ return "batman";
++ default:
++ return "unknown";
++ }
++@@ -84,6 +88,12 @@
++ return 'I';
++ case ZEBRA_ROUTE_BGP:
++ return 'B';
+++ case ZEBRA_ROUTE_HSLS:
+++ return 'H';
+++ case ZEBRA_ROUTE_OLSR:
+++ return 'L';
+++ case ZEBRA_ROUTE_BATMAN:
+++ return 'M';
++ default:
++ return '?';
++ }
++@@ -755,8 +765,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, M - BATMAN, > - selected route, * - FIB route%s%s"
++
++ DEFUN (show_ip_route,
++ show_ip_route_cmd,
++@@ -874,7 +884,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|batman|static)",
++ SHOW_STR
++ IP_STR
++ "IP routing table\n"
++@@ -884,6 +894,8 @@
++ "Kernel\n"
++ "Open Shortest Path First (OSPF)\n"
++ "Routing Information Protocol (RIP)\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Static routes\n")
++ {
++ int type;
++@@ -892,13 +904,13 @@
++ struct rib *rib;
++ int first = 1;
++
++- if (strncmp (argv[0], "b", 1) == 0)
+++ if (strncmp (argv[0], "bg", 2) == 0)
++ type = ZEBRA_ROUTE_BGP;
++ else if (strncmp (argv[0], "c", 1) == 0)
++ 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 +918,10 @@
++ 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 if (strncmp (argv[0], "ba", 2) == 0)
+++ type = ZEBRA_ROUTE_BATMAN;
++ else
++ {
++ vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
++@@ -1732,7 +1748,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|batman|static)",
++ SHOW_STR
++ IP_STR
++ "IP routing table\n"
++@@ -1742,6 +1758,8 @@
++ "Kernel\n"
++ "Open Shortest Path First (OSPFv3)\n"
++ "Routing Information Protocol (RIPng)\n"
+++ "Optimized Link State Routing (OLSR)\n"
+++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n"
++ "Static routes\n")
++ {
++ int type;
++@@ -1750,13 +1768,13 @@
++ struct rib *rib;
++ int first = 1;
++
++- if (strncmp (argv[0], "b", 1) == 0)
+++ if (strncmp (argv[0], "bg", 2) == 0)
++ type = ZEBRA_ROUTE_BGP;
++ else if (strncmp (argv[0], "c", 1) == 0)
++ 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 +1782,11 @@
++ 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 if (strncmp (argv[0], "ba", 2) == 0)
+++ type = ZEBRA_ROUTE_BATMAN;
+++ else
++ {
++ vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
++ return CMD_WARNING;
+diff -Naur olsrd-0.5.6-r5/lib/quagga/README_QUAGGA olsrd-0.5.6-r5.patched/lib/quagga/README_QUAGGA
+--- olsrd-0.5.6-r5/lib/quagga/README_QUAGGA 2009-06-24 20:00:41.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/README_QUAGGA 2009-07-04 16:38:26.000000000 +0300
+@@ -1,20 +1,20 @@
+ ---------------------------------------------------------------------
+ QUAGGA PLUGIN FOR OLSRD
+ by Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
++
++addittions by: Sven-Ola Tuecke <sven-ola-aet-gmx.de>
++ Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+ ---------------------------------------------------------------------
+
+-This is the Quagga Plugin for the OLSRD.
+-It allowes olsrd to redistribute from various quagga-protocols
++This is the Quagga Plugin for OLSRd.
++It allows 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.
++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.diff, compiled and installed via
++'make install'.
+
+ ---------------------------------------------------------------------
+ PLUGIN PARAMETERS (PlParam)
+@@ -27,22 +27,22 @@
+ May be used more then once
+
+ PlParam "ExportRoutes" "<only/both>"
+- exportes olsr-routes to quagga or to both, quagga and kernel
++ exports olsr-routes to quagga or to both, quagga and kernel
+ no routes are exported to quagga (normal behaviour) if not set.
+
+-PlParam "LocalPref" "true"
++PlParam "LocalPref" "<true/false>"
+ 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 the administrative distance to routes exported
+- to Zebra.
++ allows to set the administrative distance to routes exported
++ to zebra.
+
+ ---------------------------------------------------------------------
+ SAMPLE CONFIG
+ ---------------------------------------------------------------------
+
+-add in /etc/olsrd.conf:
++add in /usr/local/etc/olsrd.conf:
+
+ LoadPlugin "olsrd_quagga.so.0.2.2"
+ {
+@@ -55,4 +55,4 @@
+
+
+ ---------------------------------------------------------------------
+-EOF / 8.5.2006
++EOF / 29.12.2008
+diff -Naur olsrd-0.5.6-r5/lib/quagga/src/olsrd_plugin.c olsrd-0.5.6-r5.patched/lib/quagga/src/olsrd_plugin.c
+--- olsrd-0.5.6-r5/lib/quagga/src/olsrd_plugin.c 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/src/olsrd_plugin.c 2009-07-04 16:38:26.000000000 +0300
+@@ -1,19 +1,22 @@
++/*
++ * OLSRd Quagga plugin
++ *
++ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
++ * Copyright (C) 2007-2008 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ *
++ * 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 or - at your option - under
++ * the terms of the GNU General Public Licence version 2 but can be
++ * linked to any BSD-Licenced Software with public available sourcecode
++ *
++ */
++
++/* -------------------------------------------------------------------------
++ * File : olsrd_plugin.c
++ * Description : functions to setup plugin
++ * ------------------------------------------------------------------------- */
+
+-/***************************************************************************
+- projekt : olsrd-quagga
+- file : olsrd_plugin.c
+- usage : olsrd-plugin-handler-stuff
+- copyright : (C) 2006 by Immo 'FaUl' Wehrenberg
+- e-mail : immo@chaostreff-dortmund.de
+- ***************************************************************************/
+-
+-/***************************************************************************
+- * *
+- * This program is free software; you can redistribute it and/or modify *
+- * it under the terms of the GNU General Public License version 2 as *
+- * published by the Free Software Foundation. *
+- * *
+- ***************************************************************************/
+
+ #include <stdio.h>
+ #include <string.h>
+@@ -24,7 +27,6 @@
+ #include "scheduler.h"
+ #include "defs.h"
+ #include "quagga.h"
+-#include "kernel_routes.h"
+ #include "net_olsr.h"
+
+ #define PLUGIN_NAME "OLSRD quagga plugin"
+@@ -41,120 +43,94 @@
+ static set_plugin_parameter set_distance;
+ static set_plugin_parameter set_localpref;
+
+-static export_route_function orig_addroute_function;
+-static export_route_function orig_delroute_function;
+
+-int
+-olsrd_plugin_interface_version(void)
+-{
++int olsrd_plugin_interface_version (void) {
+ return PLUGIN_INTERFACE_VERSION;
+ }
+
+ static const struct olsrd_plugin_parameters plugin_parameters[] = {
+- {.name = "redistribute",.set_plugin_parameter = &set_redistribute,},
+- {.name = "ExportRoutes",.set_plugin_parameter = &set_exportroutes,},
+- {.name = "Distance",.set_plugin_parameter = &set_distance,},
+- {.name = "LocalPref",.set_plugin_parameter = &set_localpref,},
++ { .name = "redistribute", .set_plugin_parameter = &set_redistribute, },
++ { .name = "ExportRoutes", .set_plugin_parameter = &set_exportroutes, },
++ { .name = "Distance", .set_plugin_parameter = &set_distance, },
++ { .name = "LocalPref", .set_plugin_parameter = &set_localpref, },
+ };
+
+-void
+-olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
+-{
++void olsrd_get_plugin_parameters (const struct olsrd_plugin_parameters **params,
++ int *size) {
+ *params = plugin_parameters;
+- *size = sizeof plugin_parameters / sizeof *plugin_parameters;
++ *size = ARRAYSIZE(plugin_parameters);
+ }
+
+-static int
+-set_redistribute(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
+-{
+- const char *zebra_route_types[] = { "system", "kernel", "connect",
+- "static", "rip", "ripng", "ospf",
+- "ospf6", "isis", "bgp", "hsls"
+- };
++static int set_redistribute (const char *value,
++ void *data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused))) {
++ const char *zebra_route_types[] = {"system","kernel","connect",
++ "static","rip","ripng","ospf",
++ "ospf6","isis","bgp","hsls"};
+ unsigned int i;
+
+ for (i = 0; i < ARRAYSIZE(zebra_route_types); i++) {
+- if (!strcmp(value, zebra_route_types[i])) {
+- zebra_redistribute(i);
+- return 0;
+- }
++ if (!strcmp(value, zebra_route_types[i]))
++ if (zebra_redistribute (i)) return 1;
+ }
+- return 1;
++
++ return 0;
+ }
+
+-static int
+-set_exportroutes(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
+-{
++static int set_exportroutes (const char *value,
++ void *data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused))) {
+ if (!strcmp(value, "only")) {
+- orig_addroute_function = NULL;
+- orig_delroute_function = NULL;
+- olsr_addroute_function = zebra_add_olsr_v4_route;
+- olsr_delroute_function = zebra_del_olsr_v4_route;
++ olsr_addroute_function = zebra_add_route;
++ olsr_delroute_function = zebra_del_route;
+ zebra_export_routes(1);
+- } else if (!strcmp(value, "additional")) {
+- orig_addroute_function = olsr_addroute_function;
+- orig_delroute_function = olsr_delroute_function;
+- olsr_addroute_function = zebra_add_olsr_v4_route;
+- olsr_delroute_function = zebra_del_olsr_v4_route;
++ }
++ else if (!strcmp(value, "additional")) {
++ olsr_addroute_function = zebra_add_route;
++ olsr_delroute_function = zebra_del_route;
+ zebra_export_routes(1);
+- } else
+- zebra_export_routes(0);
++ }
++ else zebra_export_routes(0);
+ return 0;
+ }
+
+-static int
+-set_distance(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
+-{
++static int set_distance(const char *value, void *data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused))) {
+ int distance;
+
+- if (set_plugin_int(value, &distance, addon))
+- return 1;
+- if (distance < 0 || distance > 255)
+- return 1;
++ if (set_plugin_int(value, &distance, addon)) return 1;
++ if (distance < 0 || distance > 255) return 1;
+ zebra_olsr_distance(distance);
+ return 0;
+ }
+
+-static int
+-set_localpref(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused)))
+-{
++static int set_localpref(const char *value, void *data __attribute__((unused)),
++ set_plugin_parameter_addon addon __attribute__((unused))) {
+ int b;
+
+- if (set_plugin_boolean(value, &b, addon))
+- return 1;
+- if (b)
+- zebra_olsr_localpref();
++ if (set_plugin_boolean(value, &b, addon)) return 1;
++ if (b) zebra_olsr_localpref();
+ return 0;
+ }
+
+-int
+-olsrd_plugin_init(void)
+-{
+- if (olsr_cnf->ip_version != AF_INET) {
+- fputs("see the source - ipv6 so far not supported\n", stderr);
++
++int olsrd_plugin_init(void) {
++ if(olsr_cnf->ip_version != AF_INET) {
++ fputs("see the source - ipv6 so far not supported\n" ,stderr);
+ return 1;
+ }
+
+- olsr_start_timer(1 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, &zebra_check, NULL, 0);
++ olsr_start_timer(1 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
++ &zebra_parse, NULL, 0);
+
+ return 0;
+ }
+
+-static void
+-my_init(void)
+-{
++static void my_init(void) {
+ init_zebra();
+ }
+
+-static void
+-my_fini(void)
+-{
++static void my_fini(void) {
+ zebra_cleanup();
+ }
+
+-/*
+- * Local Variables:
+- * c-basic-offset: 2
+- * indent-tabs-mode: nil
+- * End:
+- */
+diff -Naur olsrd-0.5.6-r5/lib/quagga/src/quagga/zassert.h olsrd-0.5.6-r5.patched/lib/quagga/src/quagga/zassert.h
+--- olsrd-0.5.6-r5/lib/quagga/src/quagga/zassert.h 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/src/quagga/zassert.h 1970-01-01 02:00:00.000000000 +0200
+@@ -1,33 +0,0 @@
+-
+-/*
+- */
+-
+-#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 */
+-
+-/*
+- * Local Variables:
+- * c-basic-offset: 2
+- * indent-tabs-mode: nil
+- * End:
+- */
+diff -Naur olsrd-0.5.6-r5/lib/quagga/src/quagga/zebra.h olsrd-0.5.6-r5.patched/lib/quagga/src/quagga/zebra.h
+--- olsrd-0.5.6-r5/lib/quagga/src/quagga/zebra.h 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/src/quagga/zebra.h 1970-01-01 02:00:00.000000000 +0200
+@@ -1,503 +0,0 @@
+-
+-/* Zebra common header.
+- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Kunihiro Ishiguro
+-
+-This file is part of GNU Zebra.
+-
+-GNU Zebra is free software; you can redistribute it and/or modify it
+-under the terms of the GNU General Public License as published by the
+-Free Software Foundation; either version 2, or (at your option) any
+-later version.
+-
+-GNU Zebra is distributed in the hope that it will be useful, but
+-WITHOUT ANY WARRANTY; without even the implied warranty of
+-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-General Public License for more details.
+-
+-You should have received a copy of the GNU General Public License
+-along with GNU Zebra; see the file COPYING. If not, write to the Free
+-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+-02111-1307, USA. */
+-
+-#ifndef _ZEBRA_H
+-#define _ZEBRA_H
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif /* HAVE_CONFIG_H */
+-
+-#ifdef SUNOS_5
+-#define _XPG4_2
+-#define __EXTENSIONS__
+-typedef unsigned int u_int32_t;
+-typedef unsigned short u_int16_t;
+-typedef unsigned char u_int8_t;
+-#endif /* SUNOS_5 */
+-
+-#ifndef HAVE_SOCKLEN_T
+-typedef int socklen_t;
+-#endif /* HAVE_SOCKLEN_T */
+-
+-#include <unistd.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <ctype.h>
+-#include <errno.h>
+-#include <fcntl.h>
+-#include <signal.h>
+-#include <string.h>
+-#include <pwd.h>
+-#include <grp.h>
+-#ifdef HAVE_STROPTS_H
+-#include <stropts.h>
+-#endif /* HAVE_STROPTS_H */
+-#include <sys/fcntl.h>
+-#ifdef HAVE_SYS_SELECT_H
+-#include <sys/select.h>
+-#endif /* HAVE_SYS_SELECT_H */
+-#include <sys/stat.h>
+-#include <sys/time.h>
+-#include <sys/types.h>
+-#include <sys/param.h>
+-#ifdef HAVE_SYS_SYSCTL_H
+-#include <sys/sysctl.h>
+-#endif /* HAVE_SYS_SYSCTL_H */
+-#include <sys/ioctl.h>
+-#ifdef HAVE_SYS_CONF_H
+-#include <sys/conf.h>
+-#endif /* HAVE_SYS_CONF_H */
+-#ifdef HAVE_SYS_KSYM_H
+-#include <sys/ksym.h>
+-#endif /* HAVE_SYS_KSYM_H */
+-#include <syslog.h>
+-#include <time.h>
+-#include <sys/uio.h>
+-#include <sys/utsname.h>
+-#ifdef HAVE_RUSAGE
+-#include <sys/resource.h>
+-#endif /* HAVE_RUSAGE */
+-#ifdef HAVE_LIMITS_H
+-#include <limits.h>
+-#endif /* HAVE_LIMITS_H */
+-
+-/* machine dependent includes */
+-#ifdef SUNOS_5
+-#include <strings.h>
+-#endif /* SUNOS_5 */
+-
+-/* machine dependent includes */
+-#ifdef HAVE_LINUX_VERSION_H
+-#include <linux/version.h>
+-#endif /* HAVE_LINUX_VERSION_H */
+-
+-#ifdef HAVE_ASM_TYPES_H
+-#include <asm/types.h>
+-#endif /* HAVE_ASM_TYPES_H */
+-
+-/* misc include group */
+-#include <stdarg.h>
+-#if !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+-
+-/* Not C99; do we need to define va_copy? */
+-#ifndef va_copy
+-#ifdef __va_copy
+-#define va_copy(DST,SRC) __va_copy(DST,SRC)
+-#else
+-
+-/* Now we are desperate; this should work on many typical platforms.
+- But this is slightly dangerous, because the standard does not require
+- va_copy to be a macro. */
+-#define va_copy(DST,SRC) memcpy(&(DST), &(SRC), sizeof(va_list))
+-#warning "Not C99 and no va_copy macro available, falling back to memcpy"
+-#endif /* __va_copy */
+-#endif /* !va_copy */
+-#endif /* !C99 */
+-
+-#ifdef HAVE_LCAPS
+-#include <sys/capability.h>
+-#include <sys/prctl.h>
+-#endif /* HAVE_LCAPS */
+-
+-/* network include group */
+-
+-#include <sys/socket.h>
+-
+-#ifdef HAVE_SYS_SOCKIO_H
+-#include <sys/sockio.h>
+-#endif /* HAVE_SYS_SOCKIO_H */
+-
+-#ifdef HAVE_NETINET_IN_H
+-#include <netinet/in.h>
+-#endif /* HAVE_NETINET_IN_H */
+-#include <netinet/in_systm.h>
+-#include <netinet/ip.h>
+-#include <netinet/tcp.h>
+-
+-#ifdef HAVE_NET_NETOPT_H
+-#include <net/netopt.h>
+-#endif /* HAVE_NET_NETOPT_H */
+-
+-#include <net/if.h>
+-
+-#ifdef HAVE_NET_IF_DL_H
+-#include <net/if_dl.h>
+-#endif /* HAVE_NET_IF_DL_H */
+-
+-#ifdef HAVE_NET_IF_VAR_H
+-#include <net/if_var.h>
+-#endif /* HAVE_NET_IF_VAR_H */
+-
+-#ifdef HAVE_NET_ROUTE_H
+-#include <net/route.h>
+-#endif /* HAVE_NET_ROUTE_H */
+-
+-#ifdef HAVE_NETLINK
+-#include <linux/netlink.h>
+-#include <linux/rtnetlink.h>
+-#else
+-#define RT_TABLE_MAIN 0
+-#endif /* HAVE_NETLINK */
+-
+-#ifdef HAVE_NETDB_H
+-#include <netdb.h>
+-#endif /* HAVE_NETDB_H */
+-
+-#include <arpa/inet.h>
+-#include <arpa/telnet.h>
+-
+-#ifdef HAVE_INET_ND_H
+-#include <inet/nd.h>
+-#endif /* HAVE_INET_ND_H */
+-
+-#ifdef HAVE_NETINET_IN_VAR_H
+-#include <netinet/in_var.h>
+-#endif /* HAVE_NETINET_IN_VAR_H */
+-
+-#ifdef HAVE_NETINET6_IN6_VAR_H
+-#include <netinet6/in6_var.h>
+-#endif /* HAVE_NETINET6_IN6_VAR_H */
+-
+-#ifdef HAVE_NETINET_IN6_VAR_H
+-#include <netinet/in6_var.h>
+-#endif /* HAVE_NETINET_IN6_VAR_H */
+-
+-#ifdef HAVE_NETINET6_IN_H
+-#include <netinet6/in.h>
+-#endif /* HAVE_NETINET6_IN_H */
+-
+-#ifdef HAVE_NETINET6_IP6_H
+-#include <netinet6/ip6.h>
+-#endif /* HAVE_NETINET6_IP6_H */
+-
+-#ifdef HAVE_NETINET_ICMP6_H
+-#include <netinet/icmp6.h>
+-#endif /* HAVE_NETINET_ICMP6_H */
+-
+-#ifdef HAVE_NETINET6_ND6_H
+-#include <netinet6/nd6.h>
+-#endif /* HAVE_NETINET6_ND6_H */
+-
+-/* Some systems do not define UINT32_MAX */
+-#ifndef UINT32_MAX
+-#define UINT32_MAX 0xFFFFFFFFU
+-#endif /* UINT32_MAX */
+-
+-#ifdef HAVE_LIBUTIL_H
+-#include <libutil.h>
+-#endif /* HAVE_LIBUTIL_H */
+-
+-#ifdef HAVE_GLIBC_BACKTRACE
+-#include <execinfo.h>
+-#endif /* HAVE_GLIBC_BACKTRACE */
+-
+-#ifdef BSDI_NRL
+-
+-#ifdef HAVE_NETINET6_IN6_H
+-#include <netinet6/in6.h>
+-#endif /* HAVE_NETINET6_IN6_H */
+-
+-#ifdef NRL
+-#include <netinet6/in6.h>
+-#endif /* NRL */
+-
+-#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
+-
+-#endif /* BSDI_NRL */
+-
+-/* Local includes: */
+-#if !(defined(__GNUC__) || defined(VTYSH_EXTRACT_PL))
+-#define __attribute__(x)
+-#endif /* !__GNUC__ || VTYSH_EXTRACT_PL */
+-
+-#include "zassert.h"
+-
+-#ifdef HAVE_BROKEN_CMSG_FIRSTHDR
+-
+-/* This bug is present in Solaris 8 and pre-patch Solaris 9 <sys/socket.h>;
+- please refer to http://bugzilla.quagga.net/show_bug.cgi?id=142 */
+-
+-/* Check that msg_controllen is large enough. */
+-#define ZCMSG_FIRSTHDR(mhdr) \
+- (((size_t)((mhdr)->msg_controllen) >= sizeof(struct cmsghdr)) ? \
+- CMSG_FIRSTHDR(mhdr) : (struct cmsghdr *)NULL)
+-
+-#warning "CMSG_FIRSTHDR is broken on this platform, using a workaround"
+-
+-#else /* HAVE_BROKEN_CMSG_FIRSTHDR */
+-#define ZCMSG_FIRSTHDR(M) CMSG_FIRSTHDR(M)
+-#endif /* HAVE_BROKEN_CMSG_FIRSTHDR */
+-
+-/*
+- * RFC 3542 defines several macros for using struct cmsghdr.
+- * Here, we define those that are not present
+- */
+-
+-/*
+- * Internal defines, for use only in this file.
+- * These are likely wrong on other than ILP32 machines, so warn.
+- */
+-#ifndef _CMSG_DATA_ALIGN
+-#define _CMSG_DATA_ALIGN(n) (((n) + 3) & ~3)
+-#endif /* _CMSG_DATA_ALIGN */
+-
+-#ifndef _CMSG_HDR_ALIGN
+-#define _CMSG_HDR_ALIGN(n) (((n) + 3) & ~3)
+-#endif /* _CMSG_HDR_ALIGN */
+-
+-/*
+- * CMSG_SPACE and CMSG_LEN are required in RFC3542, but were new in that
+- * version.
+- */
+-#ifndef CMSG_SPACE
+-#define CMSG_SPACE(l) (_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)) + \
+- _CMSG_HDR_ALIGN(l))
+-#warning "assuming 4-byte alignment for CMSG_SPACE"
+-#endif /* CMSG_SPACE */
+-
+-#ifndef CMSG_LEN
+-#define CMSG_LEN(l) (_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)) + (l))
+-#warning "assuming 4-byte alignment for CMSG_LEN"
+-#endif /* CMSG_LEN */
+-
+-/* The definition of struct in_pktinfo is missing in old version of
+- GLIBC 2.1 (Redhat 6.1). */
+-#if defined (GNU_LINUX) && ! defined (HAVE_INPKTINFO)
+-struct in_pktinfo {
+- int ipi_ifindex;
+- struct in_addr ipi_spec_dst;
+- struct in_addr ipi_addr;
+-};
+-#endif
+-
+-/*
+- * OSPF Fragmentation / fragmented writes
+- *
+- * ospfd can support writing fragmented packets, for cases where
+- * kernel will not fragment IP_HDRINCL and/or multicast destined
+- * packets (ie TTBOMK all kernels, BSD, SunOS, Linux). However,
+- * SunOS, probably BSD too, clobber the user supplied IP ID and IP
+- * flags fields, hence user-space fragmentation will not work.
+- * Only Linux is known to leave IP header unmolested.
+- * Further, fragmentation really should be done the kernel, which already
+- * supports it, and which avoids nasty IP ID state problems.
+- *
+- * Fragmentation of OSPF packets can be required on networks with router
+- * with many many interfaces active in one area, or on networks with links
+- * with low MTUs.
+- */
+-#ifdef GNU_LINUX
+-#define WANT_OSPF_WRITE_FRAGMENT
+-#endif
+-
+-/*
+- * IP_HDRINCL / struct ip byte order
+- *
+- * Linux: network byte order
+- * *BSD: network, except for length and offset. (cf Stevens)
+- * SunOS: nominally as per BSD. but bug: network order on LE.
+- * OpenBSD: network byte order, apart from older versions which are as per
+- * *BSD
+- */
+-#if defined(__NetBSD__) || defined(__FreeBSD__) \
+- || (defined(__OpenBSD__) && (OpenBSD < 200311)) \
+- || (defined(SUNOS_5) && defined(WORDS_BIGENDIAN))
+-#define HAVE_IP_HDRINCL_BSD_ORDER
+-#endif
+-
+-/* MAX / MIN are not commonly defined, but useful */
+-#ifndef MAX
+-#define MAX(a, b) ((a) > (b) ? (a) : (b))
+-#endif
+-#ifndef MIN
+-#define MIN(a, b) ((a) < (b) ? (a) : (b))
+-#endif
+-
+-/* For old definition. */
+-#ifndef IN6_ARE_ADDR_EQUAL
+-#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
+-#endif /* IN6_ARE_ADDR_EQUAL */
+-
+-/* Zebra message types. */
+-#define ZEBRA_INTERFACE_ADD 1
+-#define ZEBRA_INTERFACE_DELETE 2
+-#define ZEBRA_INTERFACE_ADDRESS_ADD 3
+-#define ZEBRA_INTERFACE_ADDRESS_DELETE 4
+-#define ZEBRA_INTERFACE_UP 5
+-#define ZEBRA_INTERFACE_DOWN 6
+-#define ZEBRA_IPV4_ROUTE_ADD 7
+-#define ZEBRA_IPV4_ROUTE_DELETE 8
+-#define ZEBRA_IPV6_ROUTE_ADD 9
+-#define ZEBRA_IPV6_ROUTE_DELETE 10
+-#define ZEBRA_REDISTRIBUTE_ADD 11
+-#define ZEBRA_REDISTRIBUTE_DELETE 12
+-#define ZEBRA_REDISTRIBUTE_DEFAULT_ADD 13
+-#define ZEBRA_REDISTRIBUTE_DEFAULT_DELETE 14
+-#define ZEBRA_IPV4_NEXTHOP_LOOKUP 15
+-#define ZEBRA_IPV6_NEXTHOP_LOOKUP 16
+-#define ZEBRA_IPV4_IMPORT_LOOKUP 17
+-#define ZEBRA_IPV6_IMPORT_LOOKUP 18
+-#define ZEBRA_INTERFACE_RENAME 19
+-#define ZEBRA_ROUTER_ID_ADD 20
+-#define ZEBRA_ROUTER_ID_DELETE 21
+-#define ZEBRA_ROUTER_ID_UPDATE 22
+-#define ZEBRA_MESSAGE_MAX 23
+-
+-/* Zebra route's types. */
+-#define ZEBRA_ROUTE_SYSTEM 0
+-#define ZEBRA_ROUTE_KERNEL 1
+-#define ZEBRA_ROUTE_CONNECT 2
+-#define ZEBRA_ROUTE_STATIC 3
+-#define ZEBRA_ROUTE_RIP 4
+-#define ZEBRA_ROUTE_RIPNG 5
+-#define ZEBRA_ROUTE_OSPF 6
+-#define ZEBRA_ROUTE_OSPF6 7
+-#define ZEBRA_ROUTE_ISIS 8
+-#define ZEBRA_ROUTE_BGP 9
+-#define ZEBRA_ROUTE_HSLS 10
+-#define ZEBRA_ROUTE_OLSR 11
+-#define ZEBRA_ROUTE_MAX 12
+-
+-/* Zebra's family types. */
+-#define ZEBRA_FAMILY_IPV4 1
+-#define ZEBRA_FAMILY_IPV6 2
+-#define ZEBRA_FAMILY_MAX 3
+-
+-/* Error codes of zebra. */
+-#define ZEBRA_ERR_RTEXIST -1
+-#define ZEBRA_ERR_RTUNREACH -2
+-#define ZEBRA_ERR_EPERM -3
+-#define ZEBRA_ERR_RTNOEXIST -4
+-
+-/* Zebra message flags */
+-#define ZEBRA_FLAG_INTERNAL 0x01
+-#define ZEBRA_FLAG_SELFROUTE 0x02
+-#define ZEBRA_FLAG_BLACKHOLE 0x04
+-#define ZEBRA_FLAG_IBGP 0x08
+-#define ZEBRA_FLAG_SELECTED 0x10
+-#define ZEBRA_FLAG_CHANGED 0x20
+-#define ZEBRA_FLAG_STATIC 0x40
+-#define ZEBRA_FLAG_REJECT 0x80
+-
+-/* Zebra nexthop flags. */
+-#define ZEBRA_NEXTHOP_IFINDEX 1
+-#define ZEBRA_NEXTHOP_IFNAME 2
+-#define ZEBRA_NEXTHOP_IPV4 3
+-#define ZEBRA_NEXTHOP_IPV4_IFINDEX 4
+-#define ZEBRA_NEXTHOP_IPV4_IFNAME 5
+-#define ZEBRA_NEXTHOP_IPV6 6
+-#define ZEBRA_NEXTHOP_IPV6_IFINDEX 7
+-#define ZEBRA_NEXTHOP_IPV6_IFNAME 8
+-#define ZEBRA_NEXTHOP_BLACKHOLE 9
+-
+-#ifndef INADDR_LOOPBACK
+-#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */
+-#endif
+-
+-/* Address family numbers from RFC1700. */
+-#define AFI_IP 1
+-#define AFI_IP6 2
+-#define AFI_MAX 3
+-
+-/* Subsequent Address Family Identifier. */
+-#define SAFI_UNICAST 1
+-#define SAFI_MULTICAST 2
+-#define SAFI_UNICAST_MULTICAST 3
+-#define SAFI_MPLS_VPN 4
+-#define SAFI_MAX 5
+-
+-/* Filter direction. */
+-#define FILTER_IN 0
+-#define FILTER_OUT 1
+-#define FILTER_MAX 2
+-
+-/* Default Administrative Distance of each protocol. */
+-#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
+-#define ZEBRA_CONNECT_DISTANCE_DEFAULT 0
+-#define ZEBRA_STATIC_DISTANCE_DEFAULT 1
+-#define ZEBRA_RIP_DISTANCE_DEFAULT 120
+-#define ZEBRA_RIPNG_DISTANCE_DEFAULT 120
+-#define ZEBRA_OSPF_DISTANCE_DEFAULT 110
+-#define ZEBRA_OSPF6_DISTANCE_DEFAULT 110
+-#define ZEBRA_ISIS_DISTANCE_DEFAULT 115
+-#define ZEBRA_IBGP_DISTANCE_DEFAULT 200
+-#define ZEBRA_EBGP_DISTANCE_DEFAULT 20
+-
+-/* Flag manipulation macros. */
+-#define CHECK_FLAG(V,F) ((V) & (F))
+-#define SET_FLAG(V,F) (V) = (V) | (F)
+-#define UNSET_FLAG(V,F) (V) = (V) & ~(F)
+-
+-/* AFI and SAFI type. */
+-typedef u_int16_t afi_t;
+-typedef u_int8_t safi_t;
+-
+-/* Zebra types. */
+-typedef u_int16_t zebra_size_t;
+-typedef u_int8_t zebra_command_t;
+-
+-/* FIFO -- first in first out structure and macros. */
+-struct fifo {
+- struct fifo *next;
+- struct fifo *prev;
+-};
+-
+-#define FIFO_INIT(F) \
+- do { \
+- struct fifo *Xfifo = (struct fifo *)(F); \
+- Xfifo->next = Xfifo->prev = Xfifo; \
+- } while (0)
+-
+-#define FIFO_ADD(F,N) \
+- do { \
+- struct fifo *Xfifo = (struct fifo *)(F); \
+- struct fifo *Xnode = (struct fifo *)(N); \
+- Xnode->next = Xfifo; \
+- Xnode->prev = Xfifo->prev; \
+- Xfifo->prev = Xfifo->prev->next = Xnode; \
+- } while (0)
+-
+-#define FIFO_DEL(N) \
+- do { \
+- struct fifo *Xnode = (struct fifo *)(N); \
+- Xnode->prev->next = Xnode->next; \
+- Xnode->next->prev = Xnode->prev; \
+- } while (0)
+-
+-#define FIFO_HEAD(F) \
+- ((((struct fifo *)(F))->next == (struct fifo *)(F)) \
+- ? NULL : (F)->next)
+-
+-#define FIFO_EMPTY(F) \
+- (((struct fifo *)(F))->next == (struct fifo *)(F))
+-
+-#define FIFO_TOP(F) \
+- (FIFO_EMPTY(F) ? NULL : ((struct fifo *)(F))->next)
+-
+-#endif /* _ZEBRA_H */
+-
+-/*
+- * Local Variables:
+- * c-basic-offset: 2
+- * indent-tabs-mode: nil
+- * End:
+- */
+diff -Naur olsrd-0.5.6-r5/lib/quagga/src/quagga.c olsrd-0.5.6-r5.patched/lib/quagga/src/quagga.c
+--- olsrd-0.5.6-r5/lib/quagga/src/quagga.c 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/src/quagga.c 2009-07-04 16:38:26.000000000 +0300
+@@ -1,865 +1,555 @@
++/*
++ * OLSRd Quagga plugin
++ *
++ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
++ * Copyright (C) 2007-2008 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ *
++ * 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 or - at your option - under
++ * the terms of the GNU General Public Licence version 2 but can be
++ * linked to any BSD-Licenced Software with public available sourcecode
++ *
++ */
+
+-/***************************************************************************
+- 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. *
+- * *
+- ***************************************************************************/
++/* -------------------------------------------------------------------------
++ * File : quagga.c
++ * Description : functions to interface to the zebra daemon
++ * ------------------------------------------------------------------------- */
+
+-#ifdef MY_DEBUG
+-#include <stdio.h>
+-#endif
+
+ #define HAVE_SOCKLEN_T
+
++#include "quagga.h"
++#include "olsr.h" /* olsr_exit
++ olsr_malloc */
++#include "log.h" /* olsr_syslog */
++
+ #include <stdint.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <fcntl.h>
++#include <errno.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+-#include <fcntl.h>
+-
+-#include "quagga.h"
+-#include "olsr.h"
+-#include "log.h"
+-#include "defs.h"
+-#include "routing_table.h"
+-
++#include <arpa/inet.h>
+ #ifdef USE_UNIX_DOMAIN_SOCKET
+ #include <sys/un.h>
+-#define ZEBRA_SOCKET "/var/run/quagga/zserv.api"
+ #endif
+
+-#define ZEBRA_IPV4_ROUTE_ADD 7
+-#define ZEBRA_IPV4_ROUTE_DELETE 8
+-#define ZEBRA_REDISTRIBUTE_ADD 11
+-#define ZEBRA_REDISTRIBUTE_DELETE 12
+-#define ZEBRA_MESSAGE_MAX 23
+-
+-#define ZEBRA_ROUTE_OLSR 11
+-#define ZEBRA_ROUTE_MAX 12
+-
+-#define ZEBRA_FLAG_SELECTED 0x10
+-
+-#define ZEBRA_NEXTHOP_IPV4 3
+-#define ZEBRA_NEXTHOP_IPV4_IFINDEX 4
+-
+-#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
+-#define OPTION_EXPORT 1
+
++/* prototypes intern */
+ static struct {
+- char status; // internal status
+- char options; // internal options
+- int sock; // Socket to zebra...
++ char status; // internal status
++ char options; // internal options
++ int sock; // Socket to zebra...
+ char redistribute[ZEBRA_ROUTE_MAX];
+ char distance;
+ char flags;
+- struct ipv4_route *v4_rt; // routes currently exportet to zebra
++ struct zebra_route *v4_rt; // routes currently exportet to zebra
+ } zebra;
+
+-/* prototypes intern */
+-static unsigned char *try_read(ssize_t *);
+-static unsigned char *zebra_route_packet(struct ipv4_route r, ssize_t *);
+-static int parse_interface_add(unsigned char *, size_t);
+-static int parse_interface_delete(unsigned char *, size_t);
+-static int parse_interface_up(unsigned char *, size_t);
+-static int parse_interface_down(unsigned char *, size_t);
+-static int parse_interface_address_add(unsigned char *, size_t);
+-static int parse_interface_address_delete(unsigned char *, size_t);
+-static int parse_ipv4_route(unsigned char *, size_t, struct ipv4_route *);
+-static int ipv4_route_add(unsigned char *, size_t);
+-static int ipv4_route_delete(unsigned char *, size_t);
+-static int parse_ipv6_route_add(unsigned char *, size_t);
+-static void zebra_reconnect(void);
+-static void zebra_connect(void);
+-
+-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");
+- }
+-}
++static void *my_realloc (void *, size_t, const char *);
++static void zebra_connect (void);
++static unsigned char *try_read (ssize_t *);
++static int zebra_send_command (unsigned char *);
++static unsigned char* zebra_route_packet (uint16_t, struct zebra_route *);
++static unsigned char *zebra_redistribute_packet (unsigned char, unsigned char);
++static struct zebra_route *zebra_parse_route (unsigned char *);
++#if 0
++static void zebra_reconnect (void);
+ #endif
++static void free_ipv4_route (struct zebra_route *);
++
+
+-void *
+-my_realloc(void *buf, size_t s, const char *c)
+-{
+- buf = realloc(buf, s);
++static void *my_realloc (void *buf, size_t s, const char *c) {
++ buf = realloc (buf, s);
+ if (!buf) {
+- OLSR_PRINTF(1, "(QUAGGA) OUT OF MEMORY: %s\n", strerror(errno));
++ OLSR_PRINTF (1, "(QUAGGA) 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;
+ }
+
+-void
+-init_zebra(void)
+-{
++
++void init_zebra (void) {
+ zebra_connect();
+- if (!(zebra.status & STATUS_CONNECTED))
+- olsr_exit("(QUAGGA) AIIIII, could not connect to zebra! is zebra running?", EXIT_FAILURE);
++ if (!(zebra.status&STATUS_CONNECTED))
++ olsr_exit ("(QUAGGA) AIIIII, could not connect to zebra! is zebra running?",
++ EXIT_FAILURE);
+ }
+
+-void
+-zebra_cleanup(void)
+-{
++
++void zebra_cleanup (void) {
+ int i;
+ struct rt_entry *tmp;
+
+ if (zebra.options & OPTION_EXPORT) {
+ OLSR_FOR_ALL_RT_ENTRIES(tmp) {
+- zebra_del_olsr_v4_route(tmp);
+- }
+- OLSR_FOR_ALL_RT_ENTRIES_END(tmp);
++ zebra_del_route(tmp);
++ } OLSR_FOR_ALL_RT_ENTRIES_END(tmp);
+ }
+
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
+- if (zebra.redistribute[i])
+- zebra_disable_redistribute(i + 1);
++ if (zebra.redistribute[i]) zebra_disable_redistribute(i);
+ }
+
+-static void
+-zebra_reconnect(void)
+-{
++
++#if 0
++static void zebra_reconnect (void) {
+ struct rt_entry *tmp;
+ int i;
+
+ zebra_connect();
+- if (!(zebra.status & STATUS_CONNECTED))
+- return; // try again next time
++ if (!(zebra.status & STATUS_CONNECTED)) return; // try again next time
+
+ if (zebra.options & OPTION_EXPORT) {
+ OLSR_FOR_ALL_RT_ENTRIES(tmp) {
+- zebra_add_olsr_v4_route(tmp);
+- }
+- OLSR_FOR_ALL_RT_ENTRIES_END(tmp);
++ zebra_add_route (tmp);
++ } OLSR_FOR_ALL_RT_ENTRIES_END(tmp);
+ }
+
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
+- if (zebra.redistribute[i])
+- zebra_redistribute(i + 1);
++ if (zebra.redistribute[i]) zebra_redistribute(i + 1);
+ /* Zebra sends us all routes of type it knows after
+ zebra_redistribute(type) */
+ }
++#endif
++
+
+ /* Connect to the zebra-daemon, returns a socket */
+-static void
+-zebra_connect(void)
+-{
++static void zebra_connect (void) {
+
+ int ret;
+
+ #ifndef USE_UNIX_DOMAIN_SOCKET
+ struct sockaddr_in i;
+- if (close(zebra.sock) < 0)
+- olsr_exit("(QUAGGA) Could not close socket!", EXIT_FAILURE);
++ if (close (zebra.sock) < 0) olsr_exit ("(QUAGGA) Could not close socket!", EXIT_FAILURE);
+
+- zebra.sock = socket(AF_INET, SOCK_STREAM, 0);
++
++ zebra.sock = socket (AF_INET,SOCK_STREAM, 0);
+ #else
+ struct sockaddr_un i;
+- if (close(zebra.sock) < 0)
+- olsr_exit("(QUAGGA) Could not close socket!", EXIT_FAILURE);
++ if (close (zebra.sock) < 0) olsr_exit ("(QUAGGA) Could not close socket!", EXIT_FAILURE);
+
+- zebra.sock = socket(AF_UNIX, SOCK_STREAM, 0);
++ zebra.sock = socket (AF_UNIX,SOCK_STREAM, 0);
+ #endif
+
+- if (zebra.sock < 0)
++ if (zebra.sock <0 )
+ olsr_exit("(QUAGGA) Could not create socket!", EXIT_FAILURE);
+
+- memset(&i, 0, sizeof i);
++ 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);
++ i.sin_port = htons (ZEBRA_PORT);
++ i.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ #else
+ i.sun_family = AF_UNIX;
+- strscpy(i.sun_path, ZEBRA_SOCKET, sizeof(i.sun_path));
++ strcpy (i.sun_path, ZEBRA_SOCKET);
+ #endif
+
+- ret = connect(zebra.sock, (struct sockaddr *)&i, sizeof i);
+- if (ret < 0)
+- zebra.status &= ~STATUS_CONNECTED;
+- else
+- zebra.status |= STATUS_CONNECTED;
++ ret = connect (zebra.sock, (struct sockaddr *)&i, sizeof i);
++ if (ret < 0) zebra.status &= ~STATUS_CONNECTED;
++ else zebra.status |= STATUS_CONNECTED;
+ }
+
++
+ /* Sends a command to zebra, command is
+ the command defined in zebra.h, options is the packet-payload,
+ optlen the length, of the payload */
+-unsigned char
+-zebra_send_command(unsigned char command, unsigned char *options, int optlen)
+-{
++static int zebra_send_command (unsigned char *options) {
+
+- char *p, *pnt;
++ unsigned char *pnt;
+ uint16_t len;
+ int ret;
+
+-#ifdef ZEBRA_HEADER_MARKER
+- uint16_t cmd;
+- uint16_t length = optlen + 6; /* length of option + command + packet_length +
+- marker + zserv-version */
+-#else
+- uint16_t length = optlen + 3; // length of option + command + packet_length
+-#endif
++ if (!(zebra.status & STATUS_CONNECTED)) return 0;
+
+- if (!(zebra.status & STATUS_CONNECTED))
+- return 0;
++ pnt = options;
++ memcpy (&len, pnt, 2);
+
+- p = olsr_malloc(length, "zebra_send_command");
+- pnt = p;
+-
+- 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);
+-#else
+- p[2] = command;
+-#endif
+- memcpy(p + length - optlen, options, optlen);
+-
+- errno = 0;
++ len = ntohs(len);
+
+ do {
+- ret = write(zebra.sock, p, length);
++ ret = write (zebra.sock, pnt, len);
+ if (ret < 0) {
+- if (errno == EINTR) {
+- errno = 0;
+- continue;
+- } else {
+- olsr_printf(1, "(QUAGGA) Disconnected from zebra\n");
+- zebra.status &= ~STATUS_CONNECTED;
+- free(pnt);
+- return -1;
++ if ((errno == EINTR) || (errno == EAGAIN)) {
++ errno = 0;
++ ret = 0;
++ continue;
++ }
++ else {
++ OLSR_PRINTF (1, "(QUAGGA) Disconnected from zebra\n");
++ zebra.status &= ~STATUS_CONNECTED;
++ free (options);
++ return -1;
+ }
+ }
+- p = p + ret;
+- }
+- while ((length -= ret));
+- free(pnt);
++ pnt = pnt+ret;
++ } while ((len -= ret));
++ free (options);
+ return 0;
+ }
+
++
+ /* Creates a Route-Packet-Payload, needs address, netmask, nexthop,
+ distance, and a pointer of an size_t */
+-static unsigned char *
+-zebra_route_packet(struct ipv4_route r, ssize_t * optlen)
+-{
++static unsigned char* zebra_route_packet (uint16_t cmd, struct zebra_route *r) {
+
+ int count;
++ uint8_t len;
++ uint16_t size;
++ uint32_t ind, metric;
+
+ unsigned 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_DISTANCE)
+- *t++ = r.distance;
+- if (r.message & ZAPI_MESSAGE_METRIC) {
+- memcpy(t, &r.metric, sizeof r.metric);
+- t += sizeof r.metric;
+- }
+- return cmdopt;
+-}
+-
+-/* adds a route to zebra-daemon */
+-int
+-zebra_add_v4_route(const struct ipv4_route r)
+-{
+
+- unsigned char *cmdopt;
+- ssize_t optlen;
+- int retval;
++ cmdopt = olsr_malloc (ZEBRA_MAX_PACKET_SIZ , "zebra add_v4_route");
+
+- cmdopt = zebra_route_packet(r, &optlen);
++ t = &cmdopt[2];
++ *t++ = cmd;
++ *t++ = r->type;
++ *t++ = r->flags;
++ *t++ = r->message;
++ *t++ = r->prefixlen;
++ len = (r->prefixlen + 7) / 8;
++ memcpy (t, &r->prefix.v4.s_addr, len);
++ t = t + len;
+
+- retval = zebra_send_command(ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);
+- free(cmdopt);
+- return retval;
++ if (r->message & ZAPI_MESSAGE_NEXTHOP) {
++ *t++ = r->nexthop_num + r->ifindex_num;
++
++ for (count = 0; count < r->nexthop_num; count++)
++ {
++ *t++ = ZEBRA_NEXTHOP_IPV4;
++ memcpy (t, &r->nexthop[count].v4.s_addr,
++ sizeof r->nexthop[count].v4.s_addr);
++ t += sizeof r->nexthop[count].v4.s_addr;
++ }
++ for (count = 0; count < r->ifindex_num; count++)
++ {
++ *t++ = ZEBRA_NEXTHOP_IFINDEX;
++ ind = htonl(r->ifindex[count]);
++ memcpy (t, &ind, sizeof ind);
++ t += sizeof ind;
++ }
++ }
++ if ((r->message & ZAPI_MESSAGE_DISTANCE) > 0)
++ *t++ = r->distance;
++ if ((r->message & ZAPI_MESSAGE_METRIC) > 0)
++ {
++ metric = htonl (r->metric);
++ memcpy (t, &metric, sizeof metric);
++ t += sizeof metric;
++ }
++ size = htons (t - cmdopt);
++ memcpy (cmdopt, &size, 2);
+
++ return cmdopt;
+ }
+
+-/* deletes a route from the zebra-daemon */
+-int
+-zebra_delete_v4_route(struct ipv4_route r)
+-{
+-
+- unsigned 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 __attribute__ ((unused)))
+-{
++void zebra_parse (void* foo __attribute__((unused))) {
+ unsigned char *data, *f;
+- ssize_t len, ret;
++ unsigned char command;
++ uint16_t length;
++ ssize_t len;
++ struct zebra_route *route;
+
+ if (!(zebra.status & STATUS_CONNECTED)) {
+- zebra_reconnect();
++// zebra_reconnect();
+ return;
+ }
+- data = try_read(&len);
++ data = try_read (&len);
+ if (data) {
+ f = data;
+ do {
+- ret = zebra_parse_packet(f, len);
+- if (!ret) // something wired happened
+- olsr_exit("(QUAGGA) Zero message length??? ", EXIT_FAILURE);
+- f += ret;
+- }
+- while ((f - data) < len);
+- free(data);
++ memcpy (&length, f, sizeof length);
++ length = ntohs (length);
++ if (!length) // something wired happened
++ olsr_exit ("(QUAGGA) Zero message length??? ", EXIT_FAILURE);
++ command = f[2];
++ switch (command) {
++ case ZEBRA_IPV4_ROUTE_ADD:
++ route = zebra_parse_route(f);
++ ip_prefix_list_add(&olsr_cnf->hna_entries, &route->prefix, route->prefixlen);
++ free_ipv4_route (route);
++ free (route);
++ break;
++ case ZEBRA_IPV4_ROUTE_DELETE:
++ route = zebra_parse_route(f);
++ ip_prefix_list_remove(&olsr_cnf->hna_entries, &route->prefix, route->prefixlen);
++ free_ipv4_route (route);
++ free (route);
++ break;
++ default:
++ break;
++ }
++ f += length;
++ } 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 unsigned char *
+-try_read(ssize_t * len)
+-{
+- unsigned 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);
++static unsigned char *try_read (ssize_t *size) {
++ unsigned char *buf;
++ ssize_t bytes, bufsize;
++ uint16_t length, offset;
++ int sockstatus;
++
++ /* initialize variables */
++ buf = NULL;
++ offset = 0;
++ *size = 0;
++ bufsize = 0;
++
++ /* save socket status and set non-blocking for read */
++ sockstatus = fcntl (zebra.sock, F_GETFL);
++ fcntl (zebra.sock, F_SETFL, sockstatus|O_NONBLOCK);
+
++ /* read whole packages */
+ do {
+- if (*len == bsize) {
+- bsize += BUFSIZE;
+- buf = my_realloc(buf, bsize, "Zebra try_read");
++
++ /* (re)allocate buffer */
++ if (*size == bufsize) {
++ bufsize += BUFSIZE;
++ buf = my_realloc (buf, bufsize, "Zebra try_read");
+ }
+- ret = read(zebra.sock, buf + l, bsize - l);
+- if (!ret) { // nothing more to read, packet is broken, discard!
+- free(buf);
++
++ /* read from socket */
++ bytes = read (zebra.sock, buf + *size, bufsize - *size);
++ /* handle broken packet */
++ if (!bytes) {
++ free (buf);
+ return NULL;
+ }
+-
+- if (ret < 0) {
+- if (errno != EAGAIN) { // oops - we got disconnected
+- olsr_printf(1, "(QUAGGA) Disconnected from zebra\n");
++ /* handle no data available */
++ if (bytes < 0) {
++ /* handle disconnect */
++ if (errno != EAGAIN) { // oops - we got disconnected
++ OLSR_PRINTF (1, "(QUAGGA) Disconnected from zebra\n");
+ zebra.status &= ~STATUS_CONNECTED;
+ }
+- free(buf);
++ 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(unsigned char *packet, ssize_t maxlen)
+-{
+-
+- uint16_t command;
+- int skip;
+-
+- /* Array of functions */
+- int (*foo[ZEBRA_MESSAGE_MAX]) (unsigned 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};
+-
+- uint16_t length;
+- int ret;
+-
+-#ifdef MY_DEBUG
+- puts("DEBUG: zebra_parse_packet");
+-#endif
+-
+- memcpy(&length, packet, 2);
+- length = ntohs(length);
+-
+- if (maxlen < length) {
+- olsr_printf(1, "(QUAGGA) maxlen = %lu, packet_length = %d\n", (unsigned long)maxlen, length);
+- olsr_exit("(QUAGGA) programmer is an idiot", EXIT_FAILURE);
+- }
+-#ifdef ZEBRA_HEADER_MARKER
+- if (packet[2] == 255) { // found header marker!!
+- //packet[3] == ZSERV_VERSION: FIXME: HANDLE THIS!
+- memcpy(&command, packet + 4, sizeof command); // two bytes command now!
+- command = ntohs(command) - 1;
+- skip = 6;
+- }
+-#else
+- command = packet[2] - 1;
+- skip = 3;
+-#endif
++ *size += bytes;
+
+- if (command < ZEBRA_MESSAGE_MAX && foo[command]) {
+- if (!(ret = foo[command] (packet + skip, length - skip)))
+- return length;
+- else
+- olsr_printf(1, "(QUAGGA) Parse error: %d\n", ret);
+- } else
+- olsr_printf(1, "(QUAGGA) Unknown packet type: %d\n", packet[2]);
+-
+- olsr_printf(1, "(Quagga) RECIVED PACKET FROM ZEBRA THAT I CAN'T PARSE");
+-
+- return length;
+-}
+-
+-static int
+-parse_interface_add(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused)))
+-{
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_delete(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused)))
+-{
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_address_add(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused)))
+-{
+-
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_up(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused)))
+-{
+-
+- //todo
+- return 0;
+-}
++ /* detect zebra packet fragmentation */
++ do {
++ memcpy (&length, buf + offset, sizeof length);
++ length = ntohs (length);
++ offset += length;
++ } while (*size >= (ssize_t) (offset + sizeof length));
++ /* set blocking socket on fragmented packet */
++ if (*size != offset)
++ fcntl (zebra.sock, F_SETFL, sockstatus);
++
++ } while (*size != offset);
+
+-static int
+-parse_interface_down(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused)))
+-{
++ /* restore socket status */
++ fcntl (zebra.sock, F_SETFL, sockstatus);
+
+- //todo
+- return 0;
++ return buf;
+ }
+
+-static int
+-parse_interface_address_delete(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused)))
+-{
+- //todo
+- return 0;
+-}
+
+ /* Parse an ipv4-route-packet recived from zebra
+ */
+-static int
+-parse_ipv4_route(unsigned char *opt, size_t len, struct ipv4_route *r)
+-{
++static struct zebra_route *zebra_parse_route (unsigned char *opt) {
++
++ struct zebra_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);
++ size_t size;
++ uint16_t length;
++ unsigned char *pnt;
++
++ memcpy (&length, opt, sizeof length);
++ length = ntohs (length);
++
++ r = olsr_malloc (sizeof *r , "zebra_parse_route");
++ pnt = &opt[3];
++ r->type = *pnt++;
++ r->flags = *pnt++;
++ r->message = *pnt++;
++ r->prefixlen = *pnt++;
++ r->prefix.v4.s_addr = 0;
++
++ size = (r->prefixlen + 7) / 8;
++ memcpy (&r->prefix.v4.s_addr, pnt, size);
++ pnt += size;
+
+ 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;
++ r->nexthop_num = *pnt++;
++ r->nexthop = olsr_malloc ((sizeof *r->nexthop) * r->nexthop_num,
++ "quagga: zebra_parse_route");
++ for (c = 0; c < r->nexthop_num; c++) {
++ memcpy (&r->nexthop[c].v4.s_addr, pnt, sizeof r->nexthop[c].v4.s_addr);
++ pnt += sizeof r->nexthop[c].v4.s_addr;
+ }
+ }
+
+ 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;
++ r->ifindex_num = *pnt++;
++ r->ifindex = olsr_malloc (sizeof (uint32_t) * r->ifindex_num,
++ "quagga: zebra_parse_route");
++ for (c = 0; c < r->ifindex_num; c++) {
++ memcpy (&r->ifindex[c], pnt, sizeof r->ifindex[c]);
++ r->ifindex[c] = ntohl (r->ifindex[c]);
++ pnt += sizeof r->ifindex[c];
++ }
+ }
+
+ if (r->message & ZAPI_MESSAGE_DISTANCE) {
+- if (len < 1)
+- return -1;
+- r->distance = *opt++;
+- len--;
++ r->distance = *pnt++;
+ }
+
+- if (r->message & ZAPI_MESSAGE_METRIC) {
+- if (len < sizeof(uint32_t))
+- return -1;
+- memcpy(&r->metric, opt, sizeof(uint32_t));
+- }
++// Quagga v0.98.6 BUG workaround: metric is always sent by zebra
++// even without ZAPI_MESSAGE_METRIC message.
++// if (r.message & ZAPI_MESSAGE_METRIC) {
++ memcpy (&r->metric, pnt, sizeof (uint32_t));
++ r->metric = ntohl (r->metric);
++ pnt += sizeof r->metric;
++// }
++
++ if (pnt - opt != length) { olsr_exit ("(QUAGGA) length does not match ??? ", EXIT_FAILURE);
++ }
+
+- return 0;
++ return r;
+ }
+
+-static int
+-ipv4_route_add(unsigned char *opt, size_t len)
+-{
+
+- struct ipv4_route r;
+- int f;
++static unsigned char *zebra_redistribute_packet (unsigned char cmd, unsigned char type) {
++ unsigned char *data, *pnt;
++ uint16_t size;
+
+- f = parse_ipv4_route(opt, len, &r);
+- if (f < 0)
+- return f;
++ data = olsr_malloc (ZEBRA_MAX_PACKET_SIZ , "zebra_redistribute_packet");
+
+- return add_hna4_route(r);
+-}
+-
+-static int
+-ipv4_route_delete(unsigned 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);
++ pnt = &data[2];
++ *pnt++ = cmd;
++ *pnt++ = type;
++ size = htons (pnt - data);
++ memcpy (data, &size, 2);
+
++ return data;
+ }
+
+-static int
+-parse_ipv6_route_add(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused)))
+-{
+- //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;
++int zebra_redistribute (unsigned char type) {
+
+- return zebra_send_command(ZEBRA_REDISTRIBUTE_DELETE, &type, 1);
++ if (zebra_send_command(zebra_redistribute_packet (ZEBRA_REDISTRIBUTE_ADD, type)) < 0)
++ olsr_exit("(QUAGGA) could not send redistribute add command", EXIT_FAILURE);
+
+-}
++ if (type > ZEBRA_ROUTE_MAX-1) return -1;
++ zebra.redistribute[type] = 1;
+
+-int
+-add_hna4_route(struct ipv4_route r)
+-{
+- union olsr_ip_addr net;
+-
+-#ifdef MY_DEBUG
+- dump_ipv4_route(r, "add_hna4_route");
+-#endif
+-
+- net.v4.s_addr = r.prefix;
+-
+- ip_prefix_list_add(&olsr_cnf->hna_entries, &net, r.prefixlen);
+- free_ipv4_route(r);
+ return 0;
++
+ }
+
+-int
+-delete_hna4_route(struct ipv4_route r)
+-{
+
+- union olsr_ip_addr net;
++/* end redistribution FROM zebra */
++int zebra_disable_redistribute (unsigned char type) {
+
+-#ifdef MY_DEBUG
+- dump_ipv4_route(r, "delete_hna4_route");
+-#endif
++ if (zebra_send_command(zebra_redistribute_packet (ZEBRA_REDISTRIBUTE_DELETE, type)) < 0)
++ olsr_exit("(QUAGGA) could not send redistribute delete command", EXIT_FAILURE);
+
+- net.v4.s_addr = r.prefix;
++ if (type > ZEBRA_ROUTE_MAX-1) return -1;
++ zebra.redistribute[type] = 0;
+
+- ip_prefix_list_remove(&olsr_cnf->hna_entries, &net, r.prefixlen) ? 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);
++static void free_ipv4_route (struct zebra_route *r) {
+
+- if (mask) while (mask << ++prefixlen && prefixlen < 32);
+-
+- return prefixlen;
++ if(r->ifindex_num) free(r->ifindex);
++ if(r->nexthop_num) free(r->nexthop);
+
+ }
+-*/
+
+-int
+-zebra_add_olsr_v4_route(const struct rt_entry *r)
+-{
+
+- struct ipv4_route route;
++int zebra_add_route (const struct rt_entry *r) {
++
++ struct zebra_route route;
+ int retval;
+
+- route.index = NULL;
+- route.distance = 0;
+- route.type = ZEBRA_ROUTE_OLSR; // OLSR
+- route.message = ZAPI_MESSAGE_METRIC;
++ route.type = ZEBRA_ROUTE_OLSR;
+ route.flags = zebra.flags;
++ route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
+ route.prefixlen = r->rt_dst.prefix_len;
+- route.prefix = r->rt_dst.prefix.v4.s_addr;
+- if ((r->rt_best->rtp_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr && 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_best->rtp_nexthop.iif_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_best->rtp_nexthop.gateway.v4.s_addr;
++ route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
++ route.ifindex_num = 0;
++ route.ifindex = NULL;
++ route.nexthop_num = 0;
++ route.nexthop = NULL;
++
++ if (r->rt_best->rtp_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr &&
++ route.prefixlen == 32) {
++ return 0; /* Quagga BUG workaround: don't add routes with destination = gateway
++ see http://lists.olsr.org/pipermail/olsr-users/2006-June/001726.html */
++ route.ifindex_num++;
++ route.ifindex = olsr_malloc (sizeof *route.ifindex,
++ "zebra_add_route");
++ *route.ifindex = r->rt_best->rtp_nexthop.iif_index;
++ }
++ else {
++ route.nexthop_num++;
++ route.nexthop = olsr_malloc (sizeof *route.nexthop, "zebra_add_route");
++ route.nexthop->v4.s_addr = r->rt_best->rtp_nexthop.gateway.v4.s_addr;
+ }
+
+ route.metric = r->rt_best->rtp_metric.hops;
+- route.metric = htonl(route.metric);
+
+ if (zebra.distance) {
+ route.message |= ZAPI_MESSAGE_DISTANCE;
+ route.distance = zebra.distance;
+ }
+
+- retval = zebra_add_v4_route(route);
+- free_ipv4_route(route);
++ retval = zebra_send_command (zebra_route_packet (ZEBRA_IPV4_ROUTE_ADD, &route));
+ return retval;
++
+ }
+
+-int
+-zebra_del_olsr_v4_route(const struct rt_entry *r)
+-{
++int zebra_del_route (const struct rt_entry *r) {
+
+- struct ipv4_route route;
++ struct zebra_route route;
+ int retval;
+- route.index = NULL;
+- route.distance = 0;
+- route.type = ZEBRA_ROUTE_OLSR; // OLSR
+- route.message = ZAPI_MESSAGE_METRIC;
++
++ route.type = ZEBRA_ROUTE_OLSR;
+ route.flags = zebra.flags;
++ route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
+ route.prefixlen = r->rt_dst.prefix_len;
+- route.prefix = r->rt_dst.prefix.v4.s_addr;
+- if ((r->rt_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr && 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_nexthop.iif_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_nexthop.gateway.v4.s_addr;
++ route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
++ route.ifindex_num = 0;
++ route.ifindex = NULL;
++ route.nexthop_num = 0;
++ route.nexthop = NULL;
++
++ if (r->rt_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr &&
++ route.prefixlen == 32){
++ return 0; /* Quagga BUG workaround: don't delete routes with destination = gateway
++ see http://lists.olsr.org/pipermail/olsr-users/2006-June/001726.html */
++ route.ifindex_num++;
++ route.ifindex = olsr_malloc (sizeof *route.ifindex,
++ "zebra_del_route");
++ *route.ifindex = r->rt_nexthop.iif_index;
++ }
++ else {
++ route.nexthop_num++;
++ route.nexthop = olsr_malloc (sizeof *route.nexthop, "zebra_del_route");
++ route.nexthop->v4.s_addr = r->rt_nexthop.gateway.v4.s_addr;
+ }
++
+ route.metric = 0;
+
+ if (zebra.distance) {
+@@ -867,36 +557,23 @@
+ route.distance = zebra.distance;
+ }
+
+- retval = zebra_delete_v4_route(route);
+
+- free_ipv4_route(route);
++ retval = zebra_send_command (zebra_route_packet (ZEBRA_IPV4_ROUTE_DELETE, &route));
+ return retval;
++
+ }
+
+-void
+-zebra_olsr_distance(unsigned char dist)
+-{
++void zebra_olsr_distance (unsigned char dist) {
+ zebra.distance = dist;
+ }
+
+-void
+-zebra_olsr_localpref(void)
+-{
++void zebra_olsr_localpref (void) {
+ zebra.flags &= ZEBRA_FLAG_SELECTED;
+ }
+
+-void
+-zebra_export_routes(unsigned char t)
+-{
++void zebra_export_routes (unsigned char t) {
+ if (t)
+ zebra.options |= OPTION_EXPORT;
+ else
+ zebra.options &= ~OPTION_EXPORT;
+ }
+-
+-/*
+- * Local Variables:
+- * c-basic-offset: 2
+- * indent-tabs-mode: nil
+- * End:
+- */
+diff -Naur olsrd-0.5.6-r5/lib/quagga/src/quagga.h olsrd-0.5.6-r5.patched/lib/quagga/src/quagga.h
+--- olsrd-0.5.6-r5/lib/quagga/src/quagga.h 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/src/quagga.h 2009-07-04 16:38:26.000000000 +0300
+@@ -1,77 +1,102 @@
++/*
++ * OLSRd Quagga plugin
++ *
++ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
++ * Copyright (C) 2007-2008 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ *
++ * 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 or - at your option - under
++ * the terms of the GNU General Public Licence version 2 but can be
++ * linked to any BSD-Licenced Software with public available sourcecode
++ *
++ */
++
++/* -------------------------------------------------------------------------
++ * File : quagga.h
++ * Description : header file for quagga.c
++ * ------------------------------------------------------------------------- */
+
+-/***************************************************************************
+- 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 "routing_table.h" /* rt_entry */
++#include "olsr_types.h" /* olsr_ip_addr */
+
+ #include <stdint.h>
+-#include <stdio.h>
+ #include <stdlib.h>
+-#include "routing_table.h"
++
+ #define HAVE_SOCKLEN_T
+
++/* Zebra port */
+ #ifndef ZEBRA_PORT
+ #define ZEBRA_PORT 2600
+ #endif
+
++/* Zebra version */
+ #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;
++/* Zebra socket */
++#define ZEBRA_SOCKET "/var/run/quagga/zserv.api"
++
++/* Zebra packet size */
++#define ZEBRA_MAX_PACKET_SIZ 4096
++
++/* Zebra message types */
++#define ZEBRA_IPV4_ROUTE_ADD 7
++#define ZEBRA_IPV4_ROUTE_DELETE 8
++#define ZEBRA_REDISTRIBUTE_ADD 11
++#define ZEBRA_REDISTRIBUTE_DELETE 12
++#define ZEBRA_MESSAGE_MAX 23
++
++/* Zebra route types */
++#define ZEBRA_ROUTE_OLSR 11
++#define ZEBRA_ROUTE_MAX 13
++
++/* Zebra flags */
++#define ZEBRA_FLAG_SELECTED 0x10
++
++/* Zebra nexthop flags */
++#define ZEBRA_NEXTHOP_IFINDEX 1
++#define ZEBRA_NEXTHOP_IPV4 3
++
++/* Zebra message flags */
++#define ZAPI_MESSAGE_NEXTHOP 0x01
++#define ZAPI_MESSAGE_IFINDEX 0x02
++#define ZAPI_MESSAGE_DISTANCE 0x04
++#define ZAPI_MESSAGE_METRIC 0x08
++
++/* Buffer size */
++#define BUFSIZE 1024
++
++/* Quagga plugin flags */
++#define STATUS_CONNECTED 1
++#define OPTION_EXPORT 1
++
++
++struct zebra_route {
++ unsigned char type;
++ unsigned char flags;
++ unsigned char message;
++ unsigned char prefixlen;
++ union olsr_ip_addr prefix;
++ unsigned char nexthop_num;
++ union olsr_ip_addr *nexthop;
++ unsigned char ifindex_num;
++ uint32_t *ifindex;
+ uint32_t metric;
+ uint8_t distance;
+- struct ipv4_route *next;
+ };
+
+-void init_zebra(void);
+-void zebra_cleanup(void);
+-unsigned char zebra_send_command(unsigned char, unsigned char *, int);
+-int zebra_add_v4_route(const struct ipv4_route r);
+-int zebra_delete_v4_route(const struct ipv4_route r);
+-void zebra_check(void *);
+-int zebra_parse_packet(unsigned 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(const struct rt_entry *);
+-int zebra_del_olsr_v4_route(const struct rt_entry *);
+-void zebra_olsr_localpref(void);
+-void zebra_olsr_distance(unsigned char);
++void init_zebra (void);
++void zebra_cleanup (void);
++void zebra_parse (void*);
++int zebra_redistribute (unsigned char);
++int zebra_disable_redistribute (unsigned char);
++int zebra_add_route (const struct rt_entry *);
++int zebra_del_route (const struct rt_entry *);
++void zebra_olsr_localpref (void);
++void zebra_olsr_distance (unsigned char);
+ void zebra_export_routes(unsigned char);
+-
+-/*
+- * Local Variables:
+- * c-basic-offset: 2
+- * indent-tabs-mode: nil
+- * End:
+- */
+diff -Naur olsrd-0.5.6-r5/lib/quagga/test/foo.c olsrd-0.5.6-r5.patched/lib/quagga/test/foo.c
+--- olsrd-0.5.6-r5/lib/quagga/test/foo.c 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/test/foo.c 1970-01-01 02:00:00.000000000 +0200
+@@ -1,20 +0,0 @@
+-#include "quagga.h"
+-
+-int
+-main(void)
+-{
+-
+- init_zebra();
+- zebra_redistribute(2);
+- // zebra_redistribute (1);
+- while (!sleep(1))
+- zebra_check();
+- return 0;
+-}
+-
+-/*
+- * Local Variables:
+- * c-basic-offset: 2
+- * indent-tabs-mode: nil
+- * End:
+- */
+diff -Naur olsrd-0.5.6-r5/lib/quagga/test/foo.pl olsrd-0.5.6-r5.patched/lib/quagga/test/foo.pl
+--- olsrd-0.5.6-r5/lib/quagga/test/foo.pl 2009-06-24 20:00:41.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/test/foo.pl 1970-01-01 02:00:00.000000000 +0200
+@@ -1,19 +0,0 @@
+-#!/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 -Naur olsrd-0.5.6-r5/lib/quagga/test/quagga.try1.c olsrd-0.5.6-r5.patched/lib/quagga/test/quagga.try1.c
+--- olsrd-0.5.6-r5/lib/quagga/test/quagga.try1.c 2009-06-24 20:00:51.000000000 +0300
++++ olsrd-0.5.6-r5.patched/lib/quagga/test/quagga.try1.c 1970-01-01 02:00:00.000000000 +0200
+@@ -1,728 +0,0 @@
+-
+-/*
+- * (C) 2006 by Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- *
+- * This code is covered by the GPLv2
+- *
+- */
+-
+-#include <stdint.h>
+-#ifdef MY_DEBUG
+-#include <stdio.h>
+-#endif
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include <netinet/in.h>
+-#define HAVE_SOCKLEN_T
+-#include <quagga/zebra.h>
+-#include "quagga.h"
+-
+-#ifdef OLSR_PLUGIN
+-#include "olsr.h"
+-#include "log.h"
+-#include "defs.h"
+-#include "local_hna_set.h"
+-#endif
+-
+-#define ZAPI_MESSAGE_NEXTHOP 0x01
+-#define ZAPI_MESSAGE_IFINDEX 0x02
+-#define ZAPI_MESSAGE_DISTANCE 0x04
+-#define ZAPI_MESSAGE_METRIC 0x08
+-
+-#define STATUS_CONNECTED 1
+-#define BUFSIZE 1024
+-static char status = 0;
+-
+-static int zsock; // Socket to zebra...
+-struct ipv4_route *quagga_routes = 0; // routes currently exportet to zebra
+-
+-/* prototypes ntern */
+-static char *try_read(ssize_t *);
+-static char *zebra_route_packet(struct ipv4_route r, ssize_t *);
+-static int parse_interface_add(char *, size_t);
+-static int parse_interface_delete(char *, size_t);
+-static int parse_interface_up(char *, size_t);
+-static int parse_interface_down(char *, size_t);
+-static int parse_interface_address_add(char *, size_t);
+-static int parse_interface_address_delete(char *, size_t);
+-static int parse_ipv4_route(char *, size_t, struct ipv4_route *);
+-static int ipv4_route_add(char *, size_t);
+-static int ipv4_route_delete(char *, size_t);
+-static int parse_ipv6_route_add(char *, size_t);
+-static uint32_t prefixlentomask(uint8_t);
+-static void free_ipv4_route(struct ipv4_route);
+-static void update_olsr_zebra_routes(struct ipv4_route *, struct ipv4_route *);
+-static struct ipv4_route *zebra_create_ipv4_route_table_entry(uint32_t, uint32_t, uint32_t);
+-static struct ipv4_route *zebra_create_ipv4_route_table(void);
+-static void zebra_free_ipv4_route_table(struct ipv4_route *);
+-static uint8_t masktoprefixlen(uint32_t);
+-
+-#ifdef MY_DEBUG
+-static void
+-dump_ipv4_route(struct ipv4_route r, char *c)
+-{
+- int i = 0, x = 0;
+-
+- puts(c);
+- printf("type: %d\n", r.type);
+- puts("flags:");
+- printf(" Internal: %s\n", r.flags & ZEBRA_FLAG_INTERNAL ? "yes" : "no");
+- printf(" Selfroute %s\n", r.flags & ZEBRA_FLAG_SELFROUTE ? "yes" : "no");
+- printf(" Blackhole %s\n", r.flags & ZEBRA_FLAG_BLACKHOLE ? "yes" : "no");
+- printf(" IBGP: %s\n", r.flags & ZEBRA_FLAG_IBGP ? "yes" : "no");
+- printf(" Selected: %s\n", r.flags & ZEBRA_FLAG_SELECTED ? "yes" : "no");
+- printf(" Changed: %s\n", r.flags & ZEBRA_FLAG_CHANGED ? "yes" : "no");
+- printf(" static: %s\n", r.flags & ZEBRA_FLAG_STATIC ? "yes" : "no");
+- printf(" reject: %s\n", r.flags & ZEBRA_FLAG_REJECT ? "yes" : "no");
+- puts("message:");
+- printf(" nexthop: %s\n", r.message & ZAPI_MESSAGE_NEXTHOP ? "yes" : "no");
+- printf(" ifindex: %s\n", r.message & ZAPI_MESSAGE_IFINDEX ? "yes" : "no");
+- printf(" distance: %s\n", r.message & ZAPI_MESSAGE_DISTANCE ? "yes" : "no");
+- printf(" metric: %s\n", r.message & ZAPI_MESSAGE_METRIC ? "yes" : "no");
+- printf("Prefixlen: %d\n", r.prefixlen);
+- printf("Prefix: %d", (unsigned char)r.prefix);
+- c = (char *)&r.prefix;
+- while (++i < (r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0)))
+- printf(".%d", (unsigned char)*(c + i));
+- while (i++ < 4)
+- printf(".0");
+- puts("");
+- i = 0;
+- if (r.message & ZAPI_MESSAGE_NEXTHOP) {
+-
+- printf("nexthop-count: %d\n", r.nh_count);
+- while (i++ < r.nh_count) {
+- c = (unsigned char *)&r.nexthops[i];
+- printf("Nexthop %d: %d", i, (unsigned char)*c);
+- while (++x < 4) {
+- printf(".%d", (unsigned char)c[x]);
+- }
+- puts("");
+- }
+- i = 0;
+- }
+- if (r.message & ZAPI_MESSAGE_IFINDEX) {
+-
+- printf("index-number: %d\n", r.ind_num);
+- while (i++ < r.ind_num)
+- printf("Index: %d: %d\n", i, r.index[i]);
+- i = 0;
+- if (r.message & ZAPI_MESSAGE_DISTANCE)
+- printf("Distance: %d\n", r.distance);
+- if (r.message & ZAPI_MESSAGE_METRIC)
+- printf("Metric: %d\n", r.metric);
+- puts("\n");
+- }
+-}
+-#endif
+-
+-void *
+-my_realloc(void *buf, size_t s, const char *c)
+-{
+- buf = realloc(buf, s);
+- if (!buf) {
+-#ifdef OLSR_PLUGIN
+- OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", strerror(errno));
+- olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n");
+- olsr_exit(c, EXIT_FAILURE);
+-#else
+- exit(EXIT_FAILURE);
+-#endif
+- }
+- return buf;
+-}
+-
+-#ifndef OLSR_PLUGIN
+-void *
+-olsr_malloc(size_t f, const char *c)
+-{
+- void *v = malloc(f);
+- return v;
+-}
+-#endif
+-
+-/* Connect to the zebra-daemon, returns a socket */
+-int
+-init_zebra()
+-{
+- struct sockaddr_in i;
+- int ret;
+-
+- zsock = socket(AF_INET, SOCK_STREAM, 0);
+- if (zsock < 0) // TODO: Could not create socket
+- return -1;
+- memset(&i, 0, sizeof i);
+- i.sin_family = AF_INET;
+- i.sin_port = htons(ZEBRA_PORT);
+- // i.sin_len = sizeof i;
+- i.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+-
+- ret = connect(zsock, (struct sockaddr *)&i, sizeof i);
+- if (ret < 0) {
+- close(zsock);
+- return -1;
+- }
+- status |= STATUS_CONNECTED;
+- return zsock;
+-}
+-
+-/* Sends a command to zebra, command is
+- the command defined in zebra.h, options is the packet-payload,
+- optlen the length, of the payload */
+-char
+-zebra_send_command(unsigned char command, char *options, int optlen)
+-{
+-
+- char *p = olsr_malloc(optlen + 3, "zebra send_command");
+- uint16_t length = optlen + 3; // length of option + command + packet_length
+-
+- int ret;
+-
+- uint16_t len = htons(length);
+- memcpy(p, &len, 2);
+- p[2] = command;
+- memcpy(p + 3, options, optlen);
+-
+- do {
+- ret = write(zsock, p, length);
+- if (ret < 0) {
+- if (errno == EINTR)
+- continue;
+- } else
+- return -1;
+- p = p + ret;
+- }
+- while ((length -= ret));
+-
+- return 0;
+-}
+-
+-/* Creates a Route-Packet-Payload, needs address, netmask, nexthop,
+- distance, and a pointer of an size_t */
+-static char *
+-zebra_route_packet(struct ipv4_route r, ssize_t * optlen)
+-{
+-
+- char *cmdopt, *t;
+- *optlen = 9; // first: type, flags, message, prefixlen, nexthop number, nexthop)
+- *optlen += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0);
+-
+- cmdopt = olsr_malloc(*optlen, "zebra add_v4_route");
+- t = cmdopt;
+- *t++ = 10; // Type: olsr
+- *t++ = r.flags; // flags
+- *t++ = r.message; // message: contains nexthop
+- *t++ = r.prefixlen;
+- memcpy(t, &r.prefix, r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0));
+- *t += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0);
+- *t++ = r.nh_count;
+- memcpy(t, r.nexthops, r.nh_count * sizeof *r.nexthops);
+- return cmdopt;
+-}
+-
+-/* adds a route to zebra-daemon (needs socket from zebra,
+- address = prefix of the route
+- mask = netmask of the route
+- nexthop = nexthop of the route
+- distance = distance-value of the route
+-*/
+-int
+-zebra_add_v4_route(struct ipv4_route r)
+-{
+-
+- char *cmdopt;
+- ssize_t optlen;
+-
+- cmdopt = zebra_route_packet(r, &optlen);
+-
+- puts("DEBUG: zebra_route_packet returned");
+-
+- return zebra_send_command(ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);
+-
+-}
+-
+-/* deletes a route from the zebra-daemon (
+- needs socket from zebra,
+- address = prefix of the route
+- mask = netmask of the route
+- nexthop = nexthop of the route
+- distance = distance-value of the route
+-*/
+-int
+-zebra_delete_v4_route(struct ipv4_route r)
+-{
+-
+- char *cmdopt;
+- ssize_t optlen;
+-
+- cmdopt = zebra_route_packet(r, &optlen);
+-
+- return zebra_send_command(ZEBRA_IPV4_ROUTE_DELETE, cmdopt, optlen);
+-
+-}
+-
+-/* Check wether there is data from zebra aviable */
+-void
+-zebra_check(void *foo)
+-{
+- char *data, *f;
+- ssize_t len, ret;
+-
+- if (!status & STATUS_CONNECTED) {
+- }
+- data = try_read(&len);
+- if (data) {
+- f = data;
+- do {
+- ret = zebra_parse_packet(f, len);
+- if (!ret) { //something wired happened
+- puts("DEBUG: IIIIIIIIIIRGS");
+- exit(EXIT_FAILURE);
+- }
+- f += ret;
+- }
+- while ((f - data) < len);
+- free(data);
+- }
+-}
+-
+-// tries to read a packet from zebra_socket
+-// if there is something to read - make sure to read whole packages
+-static char *
+-try_read(ssize_t * len)
+-{
+- char *buf = NULL;
+- ssize_t ret = 0, bsize = 0;
+- uint16_t length = 0, l = 0;
+- int sockstate;
+-
+- *len = 0;
+-
+- sockstate = fcntl(zsock, F_GETFL, 0);
+- fcntl(zsock, F_SETFL, sockstate | O_NONBLOCK);
+-
+- do {
+- if (*len == bsize) {
+- bsize += BUFSIZE;
+- buf = my_realloc(buf, bsize, "Zebra try_read");
+- }
+- ret = read(zsock, buf + l, bsize - l);
+- if (ret <= 0) {
+- if (errno == EAGAIN) {
+- errno = 0;
+- } else {
+- // TODO: errorhandling
+- ;
+- }
+- free(buf);
+- return NULL;
+- }
+- *len += ret;
+-
+- while ((*len - l) > length) {
+- // printf ("DEBUG: *len -l > length - %d - %d > %d\n", *len, l, length);
+- l += length;
+- memcpy(&length, buf + l, 2);
+- length = ntohs(length);
+- }
+- // printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);
+- if (((*len) - l) == length)
+- break; // GOT FULL PACKAGE!!
+- if (*len < l) {
+- // printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);
+- fcntl(zsock, F_SETFL, sockstate);
+- continue;
+- }
+- }
+- while (1);
+-
+- fcntl(zsock, F_SETFL, sockstate);
+- return buf;
+-}
+-
+-/* Parse a packet recived from zebra */
+-int
+-zebra_parse_packet(char *packet, ssize_t maxlen)
+-{
+-
+- /* Array of functions */
+- int (*foo[ZEBRA_MESSAGE_MAX]) (char *, size_t) = {
+- parse_interface_add, parse_interface_delete, parse_interface_address_add, parse_interface_address_delete, parse_interface_up,
+- parse_interface_down, ipv4_route_add, ipv4_route_delete, parse_ipv6_route_add};
+-
+- puts("DEBUG: zebra_parse_packet");
+- uint16_t length;
+-
+- int ret;
+- memcpy(&length, packet, 2);
+- length = ntohs(length);
+-
+- if (maxlen < length) {
+- puts("Error: programmer is an idiot");
+- printf("DEBUG: maxlen = %d, packet_length = %d\n", maxlen, length);
+- return maxlen;
+- }
+-
+- if (packet[2] - 1 < ZEBRA_MESSAGE_MAX && foo[packet[2] - 1]) {
+- if (!(ret = foo[packet[2] - 1] (packet + 3, length - 3)))
+- return length;
+- else
+- printf("DEBUG: Parse error: %d\n", ret);
+- } else
+- printf("Unknown packet type: %d\n", packet[2]);
+-
+- puts("Quagga: RECIVED PACKET FROM ZEBRA THAT I CAN'T PARSE");
+-
+- return length;
+-}
+-
+-static int
+-parse_interface_add(char *opt, size_t len)
+-{
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_delete(char *opt, size_t len)
+-{
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_address_add(char *opt, size_t len)
+-{
+-
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_up(char *opt, size_t len)
+-{
+-
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_down(char *opt, size_t len)
+-{
+-
+- //todo
+- return 0;
+-}
+-
+-static int
+-parse_interface_address_delete(char *opt, size_t len)
+-{
+- //todo
+- return 0;
+-}
+-
+-/* Parse an ipv4-route-packet recived from zebra
+- */
+-static int
+-parse_ipv4_route(char *opt, size_t len, struct ipv4_route *r)
+-{
+- // puts ("DEBUG: parse_ipv4_route");
+- if (len < 4)
+- return -1;
+-
+- r->type = *opt++;
+- r->flags = *opt++;
+- r->message = *opt++;
+- r->prefixlen = *opt++;
+- len -= 4;
+- r->prefix = 0;
+-
+- if ((int)len < r->prefixlen / 8 + (r->prefixlen % 8 ? 1 : 0))
+- return -1;
+-
+- memcpy(&r->prefix, opt, r->prefixlen / 8 + (r->prefixlen % 8 ? 1 : 0));
+- opt += r->prefixlen / 8 + (r->prefixlen % 8 ? 1 : 0);
+-
+- if (r->message & ZAPI_MESSAGE_NEXTHOP) {
+- if (len < 1)
+- return -1;
+- r->nh_count = *opt++;
+- if (len < sizeof(uint32_t) * r->nh_count)
+- return -1;
+- r->nexthops = olsr_malloc(sizeof(uint32_t) * r->nh_count, "quagga: parse_ipv4_route_add");
+- memcpy(r->nexthops, opt, sizeof(uint32_t) * r->nh_count);
+- opt += sizeof(uint32_t) * r->nh_count;
+- len -= sizeof(uint32_t) * r->nh_count + 1;
+- }
+-
+- if (r->message & ZAPI_MESSAGE_IFINDEX) {
+- if (len < 1)
+- return -2;
+- r->ind_num = *opt++;
+- if (len < sizeof(uint32_t) * r->ind_num)
+- return -3;
+- r->index = olsr_malloc(sizeof(uint32_t) * r->ind_num, "quagga: parse_ipv4_route_add");
+- memcpy(r->index, opt, r->ind_num * sizeof(uint32_t));
+- opt += sizeof(uint32_t) * r->ind_num;
+- len -= sizeof(uint32_t) * r->ind_num;
+- }
+-
+- if (r->message & ZAPI_MESSAGE_DISTANCE)
+- // todo
+- ;
+-
+- if (r->message & ZAPI_MESSAGE_METRIC) {
+- if (len < sizeof(uint32_t))
+- return -4;
+- memcpy(&r->metric, opt, sizeof(uint32_t));
+- }
+-
+- return 0;
+-}
+-
+-static int
+-ipv4_route_add(char *opt, size_t len)
+-{
+-
+- struct ipv4_route r;
+- int f;
+-
+- // puts ("DEBUG: ipv4_route_add");
+-
+- f = parse_ipv4_route(opt, len, &r);
+- if (f < 0) {
+- printf("parse-error: %d\n", f);
+- return f;
+- }
+-
+- add_hna4_route(r);
+- return 0;
+-}
+-
+-static int
+-ipv4_route_delete(char *opt, size_t len)
+-{
+- struct ipv4_route r;
+- int f;
+-
+- f = parse_ipv4_route(opt, len, &r);
+- if (f < 0)
+- return f;
+-
+- return delete_hna4_route(r);
+- // OK, now delete that foo
+-
+-}
+-
+-static int
+-parse_ipv6_route_add(char *opt, size_t len)
+-{
+- //todo
+- return 0;
+-}
+-
+-/* start redistribution FROM zebra */
+-int
+-zebra_redistribute(unsigned char type)
+-{
+-
+- return zebra_send_command(ZEBRA_REDISTRIBUTE_ADD, &type, 1);
+-
+-}
+-
+-/* end redistribution FROM zebra */
+-int
+-zebra_disable_redistribute(unsigned char type)
+-{
+-
+- return zebra_send_command(ZEBRA_REDISTRIBUTE_DELETE, &type, 1);
+-
+-}
+-
+-static uint32_t
+-prefixlentomask(uint8_t prefix)
+-{
+- uint32_t mask;
+- mask = prefix_to_netmask4(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;}
+- }
+-
+-/*
+- * Local Variables:
+- * c-basic-offset: 2
+- * indent-tabs-mode: nil
+- * End:
+- */