Update config writer to new configfile
authorHenning Rogge <hrogge@googlemail.com>
Mon, 8 Mar 2010 20:21:01 +0000 (21:21 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Mon, 8 Mar 2010 20:21:01 +0000 (21:21 +0100)
14 files changed:
files/olsrd.conf.default.full
lib/httpinfo/src/olsrd_httpinfo.c
lib/mdns/src/NetworkInterfaces.c
lib/txtinfo/src/olsrd_txtinfo.c
src/cfgparser/cfgfile_gen.c
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/common/autobuf.h
src/interfaces.h
src/ipcalc.c
src/ipcalc.h
src/lq_plugin.c
src/olsr_cfg.h
src/olsr_protocol.h

index 3fca103..87ed920 100644 (file)
@@ -326,15 +326,11 @@ IpcConnect
      # MaxConnections  0
 
      # By default only 127.0.0.1 is allowed
-     # to connect. Here allowed hosts can
+     # to connect. Here allowed hosts and networks can
      # be added
 
      # Host            127.0.0.1
      # Host            10.0.0.5
-
-     # Specify entire net-ranges that are 
-     # allowed to connect
-
      # Net             192.168.1.0 255.255.255.0     
 }
 
@@ -476,7 +472,7 @@ Interface "<OLSRd-Interface1>" "<OLSRd-Interface2>"
     # Ip4Broadcast      0.0.0.0
 
     # IPv6 multicast address
-    # (default is FF02::6D, the "manet-router linklocal multicast)
+    # (default is FF02::6D, the manet-router linklocal multicast)
 
     # IPv6Multicast    FF02::6D
 
index da0bce3..1f25443 100644 (file)
@@ -853,9 +853,7 @@ build_config_body(struct autobuf *abuf)
              olsr_ip_to_string(&mainaddrbuf, &olsr_cnf->main_addr));
   abuf_appendf(abuf, "<td>IP version: %d</td>\n", olsr_cnf->ip_version == AF_INET ? 4 : 6);
   abuf_appendf(abuf, "<td>Debug level: %d</td>\n", olsr_cnf->debug_level);
-  abuf_appendf(abuf, "<td>FIB Metrics: %s</td>\n",
-             FIBM_FLAT == olsr_cnf->fib_metric ? CFG_FIBM_FLAT : FIBM_CORRECT ==
-             olsr_cnf->fib_metric ? CFG_FIBM_CORRECT : CFG_FIBM_APPROX);
+  abuf_appendf(abuf, "<td>FIB Metrics: %s</td>\n", FIB_METRIC_TXT[olsr_cnf->fib_metric]);
 
   abuf_puts(abuf, "</tr>\n<tr>\n");
 
@@ -1141,21 +1139,7 @@ build_cfgfile_body(struct autobuf *abuf)
   abuf_puts(abuf,
              "\n\n" "<strong>This is a automatically generated configuration\n"
              "file based on the current olsrd configuration of this node.<br/>\n" "<hr/>\n" "<pre>\n");
-
-  {
-    /* Hack to make netdirect stuff work with
-       olsrd_write_cnf_buf
-     */
-    char tmpBuf[10000];
-    int size;
-    size = olsrd_write_cnf_buf(olsr_cnf, tmpBuf, 10000);
-    if (size < 0) {
-      abuf_puts(abuf, "ERROR GENERATING CONFIGFILE!\n");
-    }
-    else {
-      abuf_puts(abuf, tmpBuf);
-    }
-  }
+  olsrd_write_cnf_autobuf(abuf, olsr_cnf);
 
   abuf_puts(abuf, "</pre>\n<hr/>\n");
 
index 750867d..27da808 100644 (file)
 #include <assert.h>             /* assert() */
 #include <net/if.h>             /* socket(), ifreq, if_indextoname(), if_nametoindex() */
 #include <netinet/in.h>         /* htons() */
+#if defined linux
 #include <linux/if_ether.h>     /* ETH_P_IP */
 #include <linux/if_packet.h>    /* packet_mreq, PACKET_MR_PROMISC, PACKET_ADD_MEMBERSHIP */
 #include <linux/if_tun.h>       /* IFF_TAP */
+#endif
 #include <netinet/ip.h>         /* struct ip */
 #include <netinet/udp.h>        /* SOL_UDP */
 #include <stdlib.h>             /* atoi, malloc */
index 8f693e3..e014b5a 100644 (file)
@@ -109,6 +109,8 @@ static void ipc_print_mid(struct autobuf *);
 
 static void ipc_print_gateway(struct autobuf *);
 
+static void ipc_print_config(struct autobuf *);
+
 #define TXT_IPC_BUFSIZE 256
 
 #define SIW_ALL 0
@@ -120,6 +122,7 @@ static void ipc_print_gateway(struct autobuf *);
 #define SIW_TOPO 6
 #define SIW_NEIGHLINK 7
 #define SIW_GATEWAY 8
+#define SIW_CONFIG 9
 
 #define MAX_CLIENTS 3
 
@@ -316,6 +319,8 @@ ipc_action(int fd, void *data __attribute__ ((unused)), unsigned int flags __att
         send_what = SIW_TOPO;
       else if (0 != strstr(requ, "/gateway"))
         send_what = SIW_GATEWAY;
+      else if (0 != strstr(requ, "/config"))
+        send_what = SIW_CONFIG;
     }
   }
 
@@ -603,6 +608,12 @@ ipc_print_gateway(struct autobuf *abuf)
 }
 
 static void
+ipc_print_config(struct autobuf *abuf)
+{
+  olsrd_write_cnf_autobuf(abuf, olsr_cnf);
+}
+
+static void
 txtinfo_write_data(void *foo __attribute__ ((unused))) {
   fd_set set;
   int result, i, j, max;
@@ -691,9 +702,13 @@ send_info(int send_what, int the_socket)
     ipc_print_routes(&abuf);
 
   /* gateways */
-  if ((send_what == SIW_ALL) || (send_what == SIW_GATEWAY))
+  if (send_what == SIW_GATEWAY)
     ipc_print_gateway(&abuf);
 
+  /* config */
+  if (send_what == SIW_CONFIG)
+    ipc_print_config(&abuf);
+
   outbuffer[outbuffer_count] = olsr_malloc(abuf.len, "txt output buffer");
   outbuffer_size[outbuffer_count] = abuf.len;
   outbuffer_written[outbuffer_count] = 0;
index 8bdaa36..3656ce3 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2005, Andreas Tonnesen(andreto@olsr.org)
@@ -42,7 +41,9 @@
 #include "olsrd_conf.h"
 #include "../ipcalc.h"
 #include "../net_olsr.h"
+#include "../common/autobuf.h"
 
+#include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
-int
-olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
-{
-  struct ip_prefix_list *h = cnf->hna_entries;
-  struct olsr_if *in = cnf->interfaces;
-  struct plugin_entry *pe = cnf->plugins;
-  struct plugin_param *pp;
-  struct ip_prefix_list *ie = cnf->ipc_nets;
-  struct olsr_lq_mult *mult;
-
-  char ipv6_buf[100];                  /* buffer for IPv6 inet_htop */
-
+int olsrd_write_cnf(struct olsrd_config *cnf, const char *fname) {
   FILE *fd;
+  struct autobuf abuf;
 
   fd = fopen(fname, "w");
 
@@ -72,621 +63,693 @@ olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
   }
 
   printf("Writing config to file \"%s\".... ", fname);
-
-  fprintf(fd, "#\n# Configuration file for s%s\n# automatically generated by olsrd-cnf parser v. %s\n#\n\n", olsrd_version,
-          PARSER_VERSION);
-
-  /* Debug level */
-  fprintf(fd, "# Debug level(0-9)\n# If set to 0 the daemon runs in the background\n\nDebugLevel\t%d\n\n", cnf->debug_level);
-
-  /* IP version */
-  fprintf(fd, "# IP version to use (4 or 6)\n\nIpVersion\t%d\n\n", cnf->ip_version == AF_INET ? 4 : 6);
-
-  /* FIB Metric */
-  fprintf(fd, "# FIBMetric (\"%s\", \"%s\", or \"%s\")\n\nFIBMetric\t\"%s\"\n\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX,
-          FIBM_FLAT == cnf->fib_metric ? CFG_FIBM_FLAT : FIBM_CORRECT == cnf->fib_metric ? CFG_FIBM_CORRECT : CFG_FIBM_APPROX);
-
-  /* HNA IPv4/IPv6 */
-  fprintf(fd, "# HNA IPv%d routes\n# syntax: netaddr/prefix\n\nHna%d {\n", cnf->ip_version == AF_INET ? 4 : 6,
-          cnf->ip_version == AF_INET ? 4 : 6);
-  while (h) {
-    struct ipaddr_str strbuf;
-    fprintf(fd, "    %s/%d\n", olsr_ip_to_string(&strbuf, &h->net.prefix), h->net.prefix_len);
-    h = h->next;
-  }
-  fprintf(fd, "}\n\n");
-
-  /* No interfaces */
-  fprintf(fd,
-          "# Should olsrd keep on running even if there are\n# no interfaces available? This is a good idea\n# for a PCMCIA/USB hotswap environment.\n# \"yes\" OR \"no\"\n\nAllowNoInt\t");
-  if (cnf->allow_no_interfaces)
-    fprintf(fd, "yes\n\n");
-  else
-    fprintf(fd, "no\n\n");
-
-  /* TOS */
-  fprintf(fd, "# TOS(type of service) to use. Default is 16\n\n");
-  fprintf(fd, "TosValue\t%d\n\n", cnf->tos);
-
-  /* OlsrPort */
-  fprintf(fd, "# Port to use. Default is 698! and using other port than IANA assigned one needs a really good reason!\n#possible values 698 or >1000\n\n");
-  fprintf(fd, "OlsrPort\t\t%d\n\n", cnf->olsrport);
-
-  /* RtPolicy */
-  fprintf(fd, "# Switch the policy routing system on/off (default is true)\n");
-  fprintf(fd, "%sRtPolicy %s\n", cnf->rt_policy ? "# " : "", cnf->rt_policy ? "true" : "false");
-
-  /* RtTable */
-  fprintf(fd, "# Policy Routing Table to use. Default is 254\n\n");
-  fprintf(fd, "RtTable\t\t%d\n\n", cnf->rt_table);
-
-  /* RtProto */
-  fprintf(fd, "# Policy Routing Proto to use. Default is 3\n\n");
-  fprintf(fd, "RtProto\t\t%d\n\n", cnf->rt_proto);
-
-  /* RtTableDefault */
-  fprintf(fd,
-          "# Policy Routing Table to use for the default Route. Default is 0 (Take the same table as specified by RtTable)\n\n");
-  fprintf(fd, "RtTableDefault\t\t%d\n\n", cnf->rt_table_default);
-
-  /* RtTableTunnel */
-  fprintf(fd,
-          "# Policy Routing Table to use for the tunnel Routes. Default is 0 (Take the same table as specified by RtTable)\n\n");
-  fprintf(fd, "RtTableTunnel\t\t%d\n\n", cnf->rt_table_tunnel);
-
-  /* Willingness */
-  fprintf(fd,
-          "# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n");
-  if (cnf->willingness_auto)
-    fprintf(fd, "#Willingness\t4\n\n");
-  else
-    fprintf(fd, "Willingness\t%d\n\n", cnf->willingness);
-
-  /* IPC */
-  fprintf(fd, "# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
-  fprintf(fd, "IpcConnect {\n");
-  fprintf(fd, "    MaxConnections\t%d\n", cnf->ipc_connections);
-
-  while (ie) {
-    struct ipaddr_str strbuf;
-    if (ie->net.prefix_len == olsr_cnf->maxplen) {
-      fprintf(fd, "    Host\t\t%s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
-    } else {
-      fprintf(fd, "    Net\t\t\t%s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
-    }
-    ie = ie->next;
-  }
-
-  fprintf(fd, "}\n\n");
-
-  /* Hysteresis */
-  fprintf(fd, "# Hysteresis adds more robustness to the\n# link sensing.\n# Used by default. 'yes' or 'no'\n\n");
-
-  if (cnf->use_hysteresis) {
-    fprintf(fd, "UseHysteresis\tyes\n\n");
-    fprintf(fd,
-            "# Hysteresis parameters\n# Do not alter these unless you know \n# what you are doing!\n# Set to auto by default. Allowed\n# values are floating point values\n# in the interval 0,1\n# THR_LOW must always be lower than\n# THR_HIGH!!\n\n");
-    fprintf(fd, "HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
-    fprintf(fd, "HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
-    fprintf(fd, "HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
-  } else {
-    fprintf(fd, "UseHysteresis\tno\n\n");
-    fprintf(fd,
-            "# Hysteresis parameters\n# Do not alter these unless you know \n# what you are doing!\n# Set to auto by default. Allowed\n# values are floating point values\n# in the interval 0,1\n# THR_LOW must always be lower than\n# THR_HIGH!!\n\n");
-    fprintf(fd, "#HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
-    fprintf(fd, "#HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
-    fprintf(fd, "#HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
-  }
-
-  /* Pollrate */
-  fprintf(fd, "# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
-  fprintf(fd, "Pollrate\t%0.2f\n", cnf->pollrate);
-
-  /* NIC Changes Pollrate */
-  fprintf(fd, "# Interval to poll network interfaces for configuration\n# changes. Defaults to 2.5 seconds\n");
-  fprintf(fd, "NicChgsPollInt\t%0.2f\n", cnf->nic_chgs_pollrate);
-
-  /* TC redundancy */
-  fprintf(fd,
-          "# TC redundancy\n# Specifies how much neighbor info should\n# be sent in TC messages\n# Possible values are:\n# 0 - only send MPR selectors\n# 1 - send MPR selectors and MPRs\n# 2 - send all neighbors\n#\n# defaults to 0\n\n");
-  fprintf(fd, "TcRedundancy\t%d\n\n", cnf->tc_redundancy);
-
-  /* MPR coverage */
-  fprintf(fd,
-          "# MPR coverage\n# Specifies how many MPRs a node should\n# try select to reach every 2 hop neighbor\n# Can be set to any integer >0\n# defaults to 1\n\n");
-
-  fprintf(fd, "MprCoverage\t%d\n\n", cnf->mpr_coverage);
-
-  fprintf(fd,
-          "# Link quality level\n# 0 = do not use link quality\n# 1 = use link quality for MPR selection\n# 2 = use link quality for MPR selection and routing\n\n");
-  fprintf(fd, "LinkQualityLevel\t%d\n\n", cnf->lq_level);
-
-  fprintf(fd, "# Fish Eye algorithm\n# 0 = do not use fish eye\n# 1 = use fish eye\n\n");
-  fprintf(fd, "LinkQualityFishEye\t%d\n\n", cnf->lq_fish);
-
-  if (NULL != cnf->lq_algorithm) {
-    fprintf(fd,
-            "# Link quality algorithm (if LinkQualityLevel > 0)\n# etx_fpm (hello loss, fixed point math)\n# etx_float (hello loss, floating point)\n# etx_ff (packet loss for freifunk compat)\n\n");
-    fprintf(fd, "LinkQualityAlgorithm\t\"%s\"\n\n", cnf->lq_algorithm);
-  }
-
-  fprintf(fd, "# Link quality aging factor\n\n");
-  fprintf(fd, "LinkQualityAging\t%f\n\n", cnf->lq_aging);
-
-  fprintf(fd, "# NAT threshold\n\n");
-  fprintf(fd, "NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
-
-  fprintf(fd, "# Clear screen when printing debug output?\n\n");
-  fprintf(fd, "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
-
-  fprintf(fd, "# NIIT support\n\n");
-  fprintf(fd, "UseNiit\t%s\n\n", cnf->use_niit ? "yes" : "no");
-
-  fprintf(fd, "# Smart gateway system\n\n");
-  fprintf(fd, "SmartGateway\t%s\n\n", cnf->smart_gw_active ? "yes" : "no");
-
-  fprintf(fd, "# Smart gateway allow NAT\n\n");
-  fprintf(fd, "SmartGatewayAllowNAT\t%s\n\n", cnf->smart_gw_allow_nat ? "yes" : "no");
-
-  fprintf(fd, "# Smart gateway uplink type\n\n");
-  fprintf(fd, "SmartGatewayUplink\t%s\n\n", GW_UPLINK_TXT[cnf->smart_gw_type]);
-
-  fprintf(fd, "# Smart gateway uplink use NAT\n\n");
-  fprintf(fd, "SmartGatewayUplinkNAT\t%s\n\n", cnf->smart_gw_uplink_nat ? "yes" : "no");
-
-  fprintf(fd, "# Smart gateway uplink/downlink speed (in kbit/s)\n\n");
-  fprintf(fd, "SmartGatewaySpeed\t%d %d\n\n", cnf->smart_gw_uplink, cnf->smart_gw_downlink);
-
-  fprintf(fd, "# Smart gateway prefix\n\n");
-  fprintf(fd, "SmartGatewayPrefix\t%s\n\n", olsr_ip_prefix_to_string(&cnf->smart_gw_prefix));
-
-  /* Plugins */
-  fprintf(fd,"# Olsrd plugins to load\n"
-             "# This must be the absolute path to the file\n"
-             "# or the loader will use the following scheme:\n"
-             "# - Try the paths in the LD_LIBRARY_PATH \n"
-             "#   environment variable.\n"
-             "# - The list of libraries cached in /etc/ld.so.cache\n"
-             "# - /lib, followed by /usr/lib\n\n");
-  if (pe) {
-    while (pe) {
-      fprintf(fd, "LoadPlugin \"%s\" {\n", pe->name);
-      pp = pe->params;
-      while (pp) {
-        fprintf(fd, "    PlParam \"%s\"\t\"%s\"\n", pp->key, pp->value);
-        pp = pp->next;
-      }
-      fprintf(fd, "}\n");
-      pe = pe->next;
-    }
-  }
-  fprintf(fd, "\n");
-
-  /* Interfaces */
-  fprintf(fd,
-          "# Interfaces\n# Multiple interfaces with the same configuration\n# can shar the same config block. Just list the\n# interfaces(e.g. Interface \"eth0\" \"eth2\"\n\n");
-  /* Interfaces */
-  if (in) {
-    while (in) {
-      fprintf(fd, "Interface \"%s\" {\n", in->name);
-      fprintf(fd, "\n");
-
-      fprintf(fd,
-              "    # IPv4 broadcast address to use. The\n    # one usefull example would be 255.255.255.255\n    # If not defined the broadcastaddress\n    # every card is configured with is used\n\n");
-
-      if (in->cnf->ipv4_multicast.v4.s_addr) {
-        fprintf(fd, "    Ip4Broadcast\t%s\n\n", inet_ntoa(in->cnf->ipv4_multicast.v4));
-      } else {
-        fprintf(fd, "    #Ip4Broadcast\t255.255.255.255\n\n");
-      }
-      fprintf(fd,
-              "    # Interface Mode to use. Defines\n    # forward behaviour depending on\n    # interface type\n    # valid option are mesh and ether\nDefault is mesh!\n\n");
-
-      if (in->cnf->mode!=IF_MODE_ETHER) {
-        fprintf(fd, "    #Mode\tMesh\n\n");
-      } else {
-        fprintf(fd, "    Mode\tEther\n\n");
-      }
-
-      fprintf(fd,
-              "    # IPv6 multicast address.\n    # If not defined, "OLSR_IPV6_MCAST" is used\n");
-      fprintf(fd, "    IPv6Multicast\t%s\n\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)));
-
-      fprintf(fd,
-              "    # IPv4 src address.\n    # If not defined, the interface IP is used\n");
-      fprintf(fd, "    IPv4Src\t%s\n\n", inet_ntop(AF_INET6, &in->cnf->ipv4_src.v4, ipv6_buf, sizeof(ipv6_buf)));
-
-      fprintf(fd,
-              "    # IPv6 src prefix.\n    # If not defined, a not-linklocal interface IP is used\n");
-      fprintf(fd, "    IPv6Src\t%s\n\n", olsr_ip_prefix_to_string(&in->cnf->ipv6_src));
-
-      fprintf(fd,
-              "    # Olsrd can autodetect changes in\n    # interface configurations. Enabled by default\n    # turn off to save CPU.\n    AutoDetectChanges: %s\n",
-              in->cnf->autodetect_chg ? "yes" : "no");
-
-      fprintf(fd,
-              "    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
-
-      if (in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
-        fprintf(fd, "    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
-      else
-        fprintf(fd, "    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
-      if (in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
-        fprintf(fd, "    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
-      else
-        fprintf(fd, "    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
-      if (in->cnf->tc_params.emission_interval != TC_INTERVAL)
-        fprintf(fd, "    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
-      else
-        fprintf(fd, "    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
-      if (in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
-        fprintf(fd, "    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
-      else
-        fprintf(fd, "    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
-      if (in->cnf->mid_params.emission_interval != MID_INTERVAL)
-        fprintf(fd, "    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
-      else
-        fprintf(fd, "    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
-      if (in->cnf->mid_params.validity_time != MID_HOLD_TIME)
-        fprintf(fd, "    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
-      else
-        fprintf(fd, "    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
-      if (in->cnf->hna_params.emission_interval != HNA_INTERVAL)
-        fprintf(fd, "    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
-      else
-        fprintf(fd, "    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
-      if (in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
-        fprintf(fd, "    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
-      else
-        fprintf(fd, "    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
-
-      mult = in->cnf->lq_mult;
-
-      if (mult == NULL) {
-        fprintf(fd, "    #LinkQualityMult\tdefault 1.0\n");
-      } else {
-        while (mult != NULL) {
-          fprintf(fd, "    LinkQualityMult\t%s %0.2f\n", inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
-                  (float)(mult->value) / 65536.0);
-          mult = mult->next;
-        }
-      }
-
-      fprintf(fd, "    # When multiple links exist between hosts\n");
-      fprintf(fd, "    # the weight of interface is used to determine\n");
-      fprintf(fd, "    # the link to use. Normally the weight is\n");
-      fprintf(fd, "    # automatically calculated by olsrd based\n");
-      fprintf(fd, "    # on the characteristics of the interface,\n");
-      fprintf(fd, "    # but here you can specify a fixed value.\n");
-      fprintf(fd, "    # Olsrd will choose links with the lowest value.\n");
-      fprintf(fd, "    # Note:\n");
-      fprintf(fd, "    # Interface weight is used only when LinkQualityLevel is 0.\n");
-      fprintf(fd, "    # For any other value of LinkQualityLevel, the interface ETX\n");
-      fprintf(fd, "    # value is used instead.\n\n");
-      if (in->cnf->weight.fixed) {
-        fprintf(fd, "    Weight\t %d\n\n", in->cnf->weight.value);
-      } else {
-        fprintf(fd, "    #Weight\t 0\n\n");
-      }
-
-      fprintf(fd, "}\n\n");
-      in = in->next;
-    }
-
-  }
-
-  fprintf(fd, "\n# END AUTOGENERATED CONFIG\n");
-
+  abuf_init(&abuf, 1024);
+  olsrd_write_cnf_autobuf(&abuf, cnf);
+  fwrite(abuf.buf, abuf.len, 1, fd);
+  abuf_free(&abuf);
   fclose(fd);
+
   printf("DONE\n");
 
   return 1;
 }
 
-#define MAX_LINESIZE 250
+static int
+if_appendf(struct autobuf *autobuf, bool comments, const char *fmt, ...)  __attribute__ ((format(printf, 3, 4)));
 
-#define WRITE_TO_BUF(fmt, args...)                                      \
-    do {                                                                \
-        if((bufsize - size) < MAX_LINESIZE) {                           \
-            return -1;                                                  \
-        }                                                               \
-        size += snprintf(&buf[size], MAX_LINESIZE, fmt, ##args);        \
-    } while (0)
-
-int
-olsrd_write_cnf_buf(struct olsrd_config *cnf, char *buf, uint32_t bufsize)
+static int
+if_appendf(struct autobuf *autobuf, bool comments, const char *fmt, ...)
 {
-  struct ip_prefix_list *h = cnf->hna_entries;
-  struct olsr_if *in = cnf->interfaces;
-  struct plugin_entry *pe = cnf->plugins;
-  struct plugin_param *pp;
-  struct ip_prefix_list *ie = cnf->ipc_nets;
-  struct olsr_lq_mult *mult;
-
-  int size = 0;
-
-  char ipv6_buf[100];                  /* buffer for IPv6 inet_htop */
-
-#if 0
-  printf("\n\n\n\nolsrd_write_cnf_buf bufsize  %d\n\n\n\n\n", bufsize);
-#endif
-  if (buf == NULL || bufsize < MAX_LINESIZE) {
-    return -1;
+  int rv;
+  va_list ap;
+  char *first;
+
+  va_start(ap, fmt);
+  first = va_arg(ap, char*);
+  va_end(ap);
+  if (!comments && *first) {
+    return 0;
   }
 
-  WRITE_TO_BUF("#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", PARSER_VERSION);
-
-  /* Debug level */
-  WRITE_TO_BUF("# Debug level(0-9)\n# If set to 0 the daemon runs in the background\n\nDebugLevel\t%d\n\n", cnf->debug_level);
-
-  /* IP version */
-  WRITE_TO_BUF("# IP version to use (4 or 6)\n\nIpVersion\t%d\n\n", cnf->ip_version == AF_INET ? 4 : 6);
+  va_start(ap, fmt);
+  rv = abuf_vappendf(autobuf, fmt, ap);
+  va_end(ap);
+  return rv;
+}
 
-  /* FIB Metric */
-  WRITE_TO_BUF("# FIBMetric (\"%s\", \"%s\", or \"%s\")\n\nFIBMetric\t\"%s\"\n\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX,
-               FIBM_FLAT == cnf->fib_metric ? CFG_FIBM_FLAT : FIBM_CORRECT == cnf->fib_metric ? CFG_FIBM_CORRECT : CFG_FIBM_APPROX);
+static void olsrd_write_if_autobuf(struct autobuf *out, struct if_config_options *cnfi, bool comments) {
+  struct ipaddr_str ipbuf;
+  struct olsr_lq_mult *mult;
 
-  /* HNA IPv4/IPv6 */
-  WRITE_TO_BUF("# HNA IPv%1$d routes\n# syntax: netaddr netmask\n\nHna%1$d {\n", cnf->ip_version == AF_INET ? 4 : 6);
-  while (h) {
-    struct ipaddr_str strbuf;
-    WRITE_TO_BUF("    %s/%d\n", olsr_ip_to_string(&strbuf, &h->net.prefix), h->net.prefix_len);
-    h = h->next;
+  abuf_puts(out, "{\n");
+  if (comments) abuf_puts(out,
+    "    # Interface Mode is used to prevent unnecessary\n"
+    "    # packet forwarding on switched ethernet interfaces\n"
+    "    # valid Modes are \"mesh\" and \"ether\"\n"
+    "    # (default is \"mesh\")\n"
+    "    \n");
+  if_appendf(out, comments, "    %sMode \"%s\"\n",
+      cnfi->mode == DEF_IF_MODE ? "# " : "",
+      OLSR_IF_MODE[cnfi->mode]);
+  if (comments) abuf_puts(out,
+    "    \n"
+    "    # IPv4 broadcast address for outgoing OLSR packets.\n"
+    "    # One usefull example would be 255.255.255.255\n"
+    "    # The second useful value would be to\n"
+    "    # specify the peer adress of an ptp-tunnel.\n"
+    "    # another name of this parameter is \"IPv4Multicast\"\n"
+    "    # (default is 0.0.0.0, which triggers the usage of the\n"
+    "    # interface broadcast IP)\n"
+    "    \n");
+  if_appendf(out, comments, "    %sIp4Broadcast      %s\n",
+      cnfi->ipv4_multicast.v4.s_addr == 0 ? "# " : "",
+      inet_ntop(AF_INET, &cnfi->ipv4_multicast, ipbuf.buf, sizeof(ipbuf)));
+  if (comments) abuf_puts(out,
+    "    \n"
+    "    # IPv6 multicast address\n"
+    "    # (default is FF02::6D, the manet-router linklocal multicast)\n"
+    "    \n");
+  if_appendf(out, comments, "    %sIPv6Multicast %s\n",
+      memcmp(&cnfi->ipv6_multicast, &ipv6_def_multicast, sizeof(ipv6_def_multicast)) == 0 ? "# " : "",
+      inet_ntop(AF_INET6, &cnfi->ipv6_multicast, ipbuf.buf, sizeof(ipbuf)));
+  if (comments) abuf_puts(out,
+    "    \n"
+    "    # IPv4 src address for outgoing OLSR packages\n"
+    "    # (default is 0.0.0.0, which triggers usage of the interface IP)\n"
+    "    \n");
+  if_appendf(out, comments, "    %sIPv4Src %s\n",
+      cnfi->ipv4_src.v4.s_addr == 0 ? "# " : "",
+      inet_ntop(AF_INET, &cnfi->ipv4_src, ipbuf.buf, sizeof(ipbuf)));
+  if (comments) abuf_puts(out,
+    "    \n"
+    "    # IPv6 src prefix. OLSRd will choose one of the interface IPs\n"
+    "    # which matches the prefix of this parameter.\n"
+    "    # (default is 0::/0, which triggers the usage\n"
+    "    # of a not-linklocal interface IP)\n"
+    "    \n");
+  if_appendf(out, comments, "    %sIPv6Src %s\n",
+      cnfi->ipv6_src.prefix_len == 0 ? "# " : "",
+      inet_ntop(AF_INET6, &cnfi->ipv6_src, ipbuf.buf, sizeof(ipbuf)));
+  if (comments) abuf_puts(out,
+    "    \n"
+    "    # Emission intervals in seconds.\n"
+    "    # If not defined, Freifunk network defaults are used\n"
+    "    # (default is 2.0/20.0 for Hello and 5.0/300.0 for Tc/Mid/Hna)\n"
+    "    \n");
+  if_appendf(out, comments, "    %sHelloInterval       %3.1f\n",
+      cnfi->hello_params.emission_interval == HELLO_INTERVAL ? "# " : "",
+      cnfi->hello_params.emission_interval);
+  if_appendf(out, comments, "    %sHelloValidityTime   %3.1f\n",
+      cnfi->hello_params.validity_time == NEIGHB_HOLD_TIME ? "# " : "",
+      cnfi->hello_params.validity_time);
+  if_appendf(out, comments, "    %sTcInterval          %3.1f\n",
+      cnfi->tc_params.emission_interval == TC_INTERVAL ? "# " : "",
+      cnfi->tc_params.emission_interval);
+  if_appendf(out, comments, "    %sTcValidityTime      %3.1f\n",
+      cnfi->tc_params.validity_time == TOP_HOLD_TIME ? "# " : "",
+      cnfi->tc_params.validity_time);
+  if_appendf(out, comments, "    %sMidInterval         %3.1f\n",
+      cnfi->mid_params.emission_interval == MID_INTERVAL ? "# " : "",
+      cnfi->mid_params.emission_interval);
+  if_appendf(out, comments, "    %sMidValidityTime     %3.1f\n",
+      cnfi->mid_params.validity_time == MID_HOLD_TIME ? "# " : "",
+      cnfi->mid_params.validity_time);
+  if_appendf(out, comments, "    %sHnaInterval         %3.1f\n",
+      cnfi->hna_params.emission_interval == HNA_INTERVAL ? "# " : "",
+      cnfi->hna_params.emission_interval);
+  if_appendf(out, comments, "    %sHnaValidityTime     %3.1f\n",
+      cnfi->hna_params.validity_time == HNA_HOLD_TIME ? "# " : "",
+      cnfi->hna_params.validity_time);
+  if (comments) abuf_puts(out,
+    "    \n"
+    "    # When multiple links exist between hosts\n"
+    "    # the weight of interface is used to determine\n"
+    "    # the link to use. Normally the weight is\n"
+    "    # automatically calculated by olsrd based\n"
+    "    # on the characteristics of the interface,\n"
+    "    # but here you can specify a fixed value.\n"
+    "    # Olsrd will choose links with the lowest value.\n"
+    "    # Note:\n"
+    "    # Interface weight is used only when LinkQualityLevel is set to 0.\n"
+    "    # For any other value of LinkQualityLevel, the interface ETX\n"
+    "    # value is used instead.\n");
+  if_appendf(out, comments, "    %sWeight %d\n",
+      !cnfi->weight.fixed ? "# " : "",
+      cnfi->weight.value);
+  if (comments) abuf_puts(out,
+    "    \n"
+    "    # If a certain route should be preferred\n"
+    "    # or ignored by the mesh, the Link Quality\n"
+    "    # value of a node can be multiplied with a factor\n"
+    "    # entered here. In the example the route\n"
+    "    # using 192.168.0.1 would rather be ignored.\n"
+    "    # A multiplier of 0.5 will result in a small\n"
+    "    # (bad) LinkQuality value and a high (bad)\n"
+    "    # ETX value.\n"
+    "    # Note:\n"
+    "    # Link quality multiplier is used only when\n"
+    "    # LinkQualityLevel is > 0.\n"
+    "    \n");
+  mult = cnfi->lq_mult;
+
+  if (mult == NULL) {
+    if (comments) abuf_puts(out, "    # LinkQualityMult 192.168.0.1 0.5\n");
+  } else {
+    while (mult != NULL) {
+      if_appendf(out, comments, "    LinkQualityMult    %s %0.2f\n",
+          olsr_ip_to_string(&ipbuf, &mult->addr),
+          (float)(mult->value) / 65536.0);
+      mult = mult->next;
+    }
   }
-  WRITE_TO_BUF("}\n\n");
-
-  /* No interfaces */
-  WRITE_TO_BUF
-    ("# Should olsrd keep on running even if there are\n# no interfaces available? This is a good idea\n# for a PCMCIA/USB hotswap environment.\n# \"yes\" OR \"no\"\n\nAllowNoInt\t");
-  if (cnf->allow_no_interfaces)
-    WRITE_TO_BUF("yes\n\n");
-  else
-    WRITE_TO_BUF("no\n\n");
-
-  /* TOS */
-  WRITE_TO_BUF("# TOS(type of service) to use. Default is 16\n\n");
-  WRITE_TO_BUF("TosValue\t%d\n\n", cnf->tos);
-
-  /* RtTable */
-  WRITE_TO_BUF("# Port to use. Default is 698! and using other port than IANA assigned one needs a really good reason!!\n\n");
-  WRITE_TO_BUF("OlsrPort\t\t%d\n\n", cnf->olsrport);
-
-  /* RtTable */
-  WRITE_TO_BUF("# Policy Routing Table to use. Default is 254\n\n");
-  WRITE_TO_BUF("RtTable\t\t%d\n\n", cnf->rt_table);
-
-  /* RtProto */
-  WRITE_TO_BUF("# Routing proto flag to use. Default is 3 (BOOT)\n\n");
-  WRITE_TO_BUF("RtProto\t\t%d\n\n", cnf->rt_proto);
-
-  /* Willingness */
-  WRITE_TO_BUF
-    ("# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n");
-  if (cnf->willingness_auto)
-    WRITE_TO_BUF("#Willingness\t4\n\n");
-  else
-    WRITE_TO_BUF("Willingness\t%d\n\n", cnf->willingness);
+  abuf_puts(out, "}\n");
+}
 
-  /* IPC */
-  WRITE_TO_BUF("# Allow processes like the GUI front-end\n# to connect to the daemon.\n\n");
-  WRITE_TO_BUF("IpcConnect {\n");
-  WRITE_TO_BUF("    MaxConnections\t%d\n", cnf->ipc_connections);
-  while (ie) {
+void olsrd_write_cnf_autobuf(struct autobuf *out, struct olsrd_config *cnf) {
+  struct ip_prefix_list *hna = cnf->hna_entries;
+  struct olsr_if *interf = cnf->interfaces;
+  struct plugin_entry *plugins = cnf->plugins;
+  struct plugin_param *pl_param;
+  struct ip_prefix_list *ipc_nets = cnf->ipc_nets;
+
+  struct ipaddr_str ipbuf;
+  bool first;
+
+  abuf_appendf(out, "#\n"
+      "# Configuration file for %s\n"
+      "# automatically generated by olsrd-cnf parser v. %s\n"
+      "#\n"
+      "\n",
+      olsrd_version, PARSER_VERSION);
+  abuf_puts(out,
+    "# OLSR.org routing daemon config file\n"
+    "# This file contains ALL available options and explanations about them\n"
+    "#\n"
+    "# Lines starting with a # are discarded\n"
+    "#\n"
+    "\n"
+    "#### ATTENTION for IPv6 users ####\n"
+    "# Because of limitations in the parser IPv6 addresses must NOT\n"
+    "# begin with a \":\", so please add a \"0\" as a prefix.\n"
+    "\n"
+    "###########################\n"
+    "### Basic configuration ###\n"
+    "###########################\n"
+    "# keep this settings at the beginning of your first configuration file\n"
+    "\n"
+    "# Debug level (0-9)\n"
+    "# If set to 0 the daemon runs in the background, unless \"NoFork\" is set to true\n"
+    "# (Default is 1)\n"
+    "\n");
+  abuf_appendf(out, "%sDebugLevel  %d\n",
+      cnf->debug_level == DEF_DEBUGLVL ? "# " : "",
+      cnf->debug_level);
+  abuf_puts(out,
+    "\n"
+    "# IP version to use (4 or 6)\n"
+    "# (Default is 4)\n"
+    "\n");
+  abuf_appendf(out, "%sIpVersion %d\n",
+      cnf->ip_version == DEF_IP_VERSION ? "# " : "",
+      cnf->ip_version == AF_INET ? 4 : 6);
+  abuf_puts(out,
+    "\n"
+    "#################################\n"
+    "### OLSRd agent configuration ###\n"
+    "#################################\n"
+    "# this parameters control the settings of the routing agent which are not\n"
+    "# related to the OLSR protocol and it's extensions\n"
+    "\n"
+    "# Clear the screen each time the internal state changes\n"
+    "# (Default is yes)\n"
+    "\n");
+  abuf_appendf(out, "%sClearScreen     %s\n",
+      cnf->clear_screen == DEF_CLEAR_SCREEN ? "# " : "",
+      cnf->clear_screen ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Should olsrd keep on running even if there are\n"
+    "# no interfaces available? This is a good idea\n"
+    "# for a PCMCIA/USB hotswap environment.\n"
+    "# (Default is yes)\n"
+    "\n");
+  abuf_appendf(out, "%sAllowNoInt  %s\n",
+      cnf->allow_no_interfaces == DEF_ALLOW_NO_INTS ? "# " : "",
+      cnf->allow_no_interfaces ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# LockFile\n"
+    "# The lockfile is used to prevent multiple OLSR instances running at the same\n"
+    "# time.\n"
+    "# (Linux/BSD default is \"/var/run/olsrd-ipv(4/6).lock\")\n"
+    "# (Win32 default is \"<configfile>-ipv(4/6).lock\")\n"
+    "\n");
+  abuf_appendf(out, "%sLockFile \"%s\"\n",
+      cnf->lock_file == NULL ? "# " : "",
+      cnf->lock_file ? cnf->lock_file : "lockfile");
+  abuf_puts(out,
+    "\n"
+    "# Polling rate for OLSR sockets in seconds (float). \n"
+    "# (Default is 0.05)\n"
+    "\n");
+  abuf_appendf(out, "%sPollrate  %.2f\n",
+      cnf->pollrate == DEF_POLLRATE ? "# " : "",
+      cnf->pollrate);
+  abuf_puts(out,
+    "\n"
+    "# Interval to poll network interfaces for configuration changes (in seconds).\n"
+    "# Linux systems can detect interface statechange via netlink sockets.\n"
+    "# (Defaults is 2.5)\n"
+    "\n");
+  abuf_appendf(out, "%sNicChgsPollInt  %.1f\n",
+      cnf->nic_chgs_pollrate == DEF_NICCHGPOLLRT ? "# " : "",
+      cnf->nic_chgs_pollrate);
+  abuf_puts(out,
+    "\n"
+    "# TOS(type of service) value for the IP header of control traffic.\n"
+    "# (Default is 16)\n"
+    "\n");
+  abuf_appendf(out, "%sTosValue %u\n",
+      cnf->tos == DEF_TOS ? "# " : "",
+      cnf->tos);
+  abuf_puts(out,
+    "\n"
+    "# FIBMetric controls the metric value of the host-routes OLSRd sets.\n"
+    "# - \"flat\" means that the metric value is always 2. This is the preferred value\n"
+    "#   because it helps the linux kernel routing to clean up older routes\n"
+    "# - \"correct\" use the hopcount as the metric value.\n"
+    "# - \"approx\" use the hopcount as the metric value too, but does only update the\n"
+    "#   hopcount if the nexthop changes too\n"
+    "# (Default is \"flat\")\n"
+    "\n");
+  abuf_appendf(out, "%sFIBMetric \"%s\"\n",
+      cnf->fib_metric == DEF_FIB_METRIC ? "# " : "",
+      FIB_METRIC_TXT[cnf->fib_metric]);
+  abuf_puts(out,
+    "\n"
+    "#######################################\n"
+    "### Linux specific OLSRd extensions ###\n"
+    "#######################################\n"
+    "# these parameters are only working on linux at the moment, but might become\n"
+    "# useful on BSD in the future\n"
+    "\n"
+    "# SrcIpRoutes tells OLSRd to set the Src flag of host routes to the originator-ip\n"
+    "# of the node. In addition to this an additional localhost device is created\n"
+    "# to make sure the returning traffic can be received.\n"
+    "# (Default is \"no\")\n"
+    "\n");
+  abuf_appendf(out, "%sSrcIpRoutes %s\n",
+      cnf->use_src_ip_routes == DEF_USE_SRCIP_ROUTES ? "# " : "",
+      cnf->use_src_ip_routes ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Specify the proto tag to be used for routes olsr inserts into kernel\n"
+    "# currently only implemented for linux\n"
+    "# valid values under linux are 1 .. 254\n"
+    "# 1 gets remapped by olsrd to 0 UNSPECIFIED (1 is reserved for ICMP redirects)\n"
+    "# 2 KERNEL routes (not very wise to use)\n"
+    "# 3 BOOT (should in fact not be used by routing daemons)\n"
+    "# 4 STATIC \n"
+    "# 8 .. 15 various routing daemons (gated, zebra, bird, & co)\n"
+    "# (defaults to 0 which gets replaced by an OS-specific default value\n"
+    "# under linux 3 (BOOT) (for backward compatibility)\n"
+    "\n");
+  abuf_appendf(out, "%sRtProto %u\n",
+      cnf->rt_proto == DEF_RTPROTO ? "# " : "",
+      cnf->rt_proto);
+  abuf_puts(out,
+    "\n"
+    "# RtPolicy activates the usage of routing tables and policy rules for OLSRd\n"
+    "# routing. It's used to keep host and default route in different tables and\n"
+    "# to handle more complicated routing setups with SmartGateway\n"
+    "# (Default is \"yes\")\n"
+    "\n");
+  abuf_appendf(out, "%sRtPolicy %s\n",
+      cnf->rt_policy == DEF_RTPOLICY ? "# " : "",
+      cnf->rt_policy ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Specifies the routing Table olsr uses\n"
+    "# RtTable is for host routes, RtTableDefault for the route to the default\n"
+    "# internet gateway (2 in case of IPv6+NIIT) and RtTableTunnel is for\n"
+    "# routes to the ipip tunnels, valid values are 1 to 254\n"
+    "# (default is 254/112/113, the first is the \"main\" table in linux)\n"
+    "\n");
+  abuf_appendf(out, "%sRtTable %u\n",
+      cnf->rt_policy ? "# " : "",
+      cnf->rt_table);
+  abuf_appendf(out, "%sRtTableDefault %u\n",
+      cnf->rt_policy ? "# " : "",
+      cnf->rt_table_default);
+  abuf_appendf(out, "%sRtTableTunnel %u\n",
+      cnf->rt_policy ? "# " : "",
+      cnf->rt_table_tunnel);
+  abuf_puts(out,
+    "\n"
+    "# Specifies the policy rule priorities for the three routing tables and\n"
+    "# a special rule for smartgateway routing (see README_NIIT_SMARTGW)\n"
+    "# Priorities can only be set if three different routing tables are set.\n"
+    "# 0 means \"set no policy rule\", if set the values must obey to condition\n"
+    "# RtTablePriority < RtTableDefaultOlsrPriority\n"
+    "# < RtTableTunnelPriority < RtTableDefaultPriority\n"
+    "# (default is 32766/32776/32786/32796)\n"
+    "\n");
+  abuf_appendf(out, "%sRtTablePriority %u\n",
+      cnf->rt_policy ? "# " : "",
+      cnf->rt_table_pri);
+  abuf_appendf(out, "%sRtTableDefaultOlsrPriority %u\n",
+      cnf->rt_policy ? "# " : "",
+      cnf->rt_table_default_pri);
+  abuf_appendf(out, "%sRtTableTunnelPriority %u\n",
+      cnf->rt_policy ? "# " : "",
+      cnf->rt_table_tunnel_pri);
+  abuf_appendf(out, "%sRtTableDefaultPriority %u\n",
+      cnf->rt_policy ? "# " : "",
+      cnf->rt_table_defaultolsr_pri);
+  abuf_puts(out,
+    "\n"
+    "# Activates (in IPv6 mode) the automatic use of NIIT\n"
+    "# (see README_NIIT_SMARTGW)\n"
+    "# (default is \"yes\")\n"
+    "\n");
+  abuf_appendf(out, "%sUseNiit %s\n",
+      cnf->use_niit == DEF_USE_NIIT ? "# " : "",
+      cnf->use_niit ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Activates the smartgateway ipip tunnel feature.\n"
+    "# See README_NIIT_SMARTGW for a description of smartgateways.\n"
+    "# (default is \"yes\")\n"
+    "\n");
+  abuf_appendf(out, "%sSmartGateway %s\n",
+      cnf->smart_gw_active == DEF_SMART_GW ? "# " : "",
+      cnf->smart_gw_active ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Allows the selection of a smartgateway with NAT (only for IPv4)\n"
+    "# (default is \"yes\")\n"
+    "\n");
+  abuf_appendf(out, "%sSmartGatewayAllowNAT %s\n",
+      cnf->smart_gw_allow_nat == DEF_GW_ALLOW_NAT ? "# " : "",
+      cnf->smart_gw_allow_nat ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Defines what kind of Uplink this node will publish as a\n"
+    "# smartgateway. The existence of the uplink is detected by\n"
+    "# a route to 0.0.0.0/0, ::ffff:0:0/96 and/or 2000::/3.\n"
+    "# possible values are \"none\", \"ipv4\", \"ipv6\", \"both\"\n"
+    "# (default is \"both\")\n"
+    "\n");
+  abuf_appendf(out, "%sSmartGatewayUplink \"%s\"\n",
+      cnf->smart_gw_type == DEF_GW_TYPE ? "# " : "",
+      GW_UPLINK_TXT[cnf->smart_gw_type]);
+  abuf_puts(out,
+    "\n"
+    "# Specifies if the local ipv4 uplink use NAT\n"
+    "# (default is \"yes\")\n"
+    "\n");
+  abuf_appendf(out, "%sSmartGatewayUplinkNAT %s\n",
+      cnf->smart_gw_uplink_nat == DEF_GW_UPLINK_NAT ? "# " : "",
+      cnf->smart_gw_uplink_nat ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Specifies the speed of the uplink in kilobit/s.\n"
+    "# First parameter is upstream, second parameter is downstream\n"
+    "# (default is 128/1024)\n"
+    "\n");
+  abuf_appendf(out, "%sSmartGatewaySpeed %d %d\n",
+      cnf->smart_gw_uplink == DEF_UPLINK_SPEED && cnf->smart_gw_downlink == DEF_DOWNLINK_SPEED ? "# " : "",
+      cnf->smart_gw_uplink, cnf->smart_gw_downlink);
+  abuf_puts(out,
+    "\n"
+    "# Specifies the EXTERNAL ipv6 prefix of the uplink. A prefix\n"
+    "# length of more than 64 is not allowed.\n"
+    "# (default is 0::/0\n"
+    "\n");
+  abuf_appendf(out, "%sSmartGatewayPrefix %s\n",
+      cnf->smart_gw_prefix.prefix_len == 0 ? "# " : "",
+      olsr_ip_prefix_to_string(&cnf->smart_gw_prefix));
+  abuf_puts(out,
+    "\n"
+    "##############################\n"
+    "### OLSR protocol settings ###\n"
+    "##############################\n"
+    "\n"
+    "# For testing purposes it may be nice to use another port for olsrd\n"
+    "# for using another port than the IANA assigned one \n"
+    "# for a production network, there should be a good reason!!\n"
+    "# valid values are integers >1, please be careful with using reserved\n"
+    "# port numbers\n"
+    "# (default is 698, the IANA assigned olsr-port)\n"
+    "\n");
+  abuf_appendf(out, "%sOlsrPort %u\n",
+      cnf->olsrport == DEF_OLSRPORT ? "# " : "",
+      cnf->olsrport);
+  abuf_puts(out,
+    "\n"
+    "# Sets the main IP (originator ip) of the router. This IP will NEVER\n"
+    "# change during the uptime of olsrd.\n"
+    "# (default is 0.0.0.0, which triggers usage of the IP of the first interface)\n"
+    "\n");
+  abuf_appendf(out, "MainIp %s\n",
+      olsr_ip_to_string(&ipbuf, &cnf->main_addr));
+  abuf_puts(out,
+    "\n"
+    "# The fixed willingness to use (0-7)\n"
+    "# If not set willingness will be calculated\n"
+    "# dynamically based on battery/power status\n"
+    "# (default is 3)\n"
+    "\n");
+  abuf_appendf(out, "%sWillingness     %u\n",
+      cnf->willingness == DEF_WILLINGNESS ? "# " : "",
+      cnf->willingness);
+  abuf_puts(out,
+    "\n"
+    "# HNA (Host network association) allows the OLSR to announce\n"
+    "# additional IPs or IP subnets to the net that are reachable\n"
+    "# through this node.\n"
+    "# Syntax for HNA4 is \"network-address    network-mask\"\n"
+    "# Syntax for HNA6 is \"network-address    prefix-length\"\n"
+    "# (default is no HNA)\n");
+  abuf_appendf(out, "Hna%u\n"
+    "{\n",
+    cnf->ip_version == AF_INET ? 4 : 6);
+  while (hna) {
     struct ipaddr_str strbuf;
-    if (ie->net.prefix_len == olsr_cnf->maxplen) {
-      WRITE_TO_BUF("    Host\t\t%s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix));
+    abuf_appendf(out, "    %s\n", olsr_ip_prefix_to_string(&hna->net));
+    hna = hna->next;
+  }
+  abuf_puts(out,
+    "}\n"
+    "\n"
+    "# Hysteresis for link sensing (only for hopcount metric)\n"
+    "# Hysteresis adds more robustness to the link sensing\n"
+    "# but delays neighbor registration.\n"
+    "# (defaults to yes)\n"
+    "\n");
+  abuf_appendf(out, "%sUseHysteresis %s\n",
+      cnf->use_hysteresis == DEF_USE_HYST ? "# " : "",
+      cnf->use_hysteresis ? "yes" : "no");
+  abuf_puts(out,
+    "\n"
+    "# Hysteresis parameters (only for hopcount metric)\n"
+    "# Do not alter these unless you know what you are doing!\n"
+    "# Set to auto by default. Allowed values are floating point\n"
+    "# values in the interval 0,1\n"
+    "# THR_LOW must always be lower than THR_HIGH!!\n"
+    "# (default is 0.5/0.8/0.3)\n"
+    "\n");
+  abuf_appendf(out, "%sHystScaling  %.2f\n",
+      cnf->hysteresis_param.scaling == HYST_SCALING ? "# " : "",
+      cnf->hysteresis_param.scaling);
+  abuf_appendf(out, "%sHystThrHigh  %.2f\n",
+      cnf->hysteresis_param.thr_high == HYST_THRESHOLD_HIGH ? "# " : "",
+      cnf->hysteresis_param.thr_high);
+  abuf_appendf(out, "%sHystThrLow  %.2f\n",
+      cnf->hysteresis_param.thr_low == HYST_THRESHOLD_LOW ? "# " : "",
+      cnf->hysteresis_param.thr_low);
+  abuf_puts(out,
+    "\n"
+    "# TC redundancy\n"
+    "# Specifies how much neighbor info should be sent in\n"
+    "# TC messages. Because of a design problem in the 0.5.x\n"
+    "# dijkstra implementation this value must be set to 2.\n"
+    "# 2 - send all neighbors\n"
+    "# (default is 2)\n"
+    "\n");
+  abuf_appendf(out, "%sTcRedundancy  %d\n",
+      cnf->tc_redundancy == TC_REDUNDANCY ? "# " : "",
+      cnf->tc_redundancy);
+  abuf_puts(out,
+    "\n"
+    "# MPR coverage specifies how many MPRs a node should\n"
+    "# try select to reach every 2 hop neighbor. Because of\n"
+    "# a design problem in the 0.5.x dijkstra algorithm this\n"
+    "# value should be set to 7.\n"
+    "# (default is 7)\n"
+    "\n");
+  abuf_appendf(out, "%sMprCoverage %d\n",
+      cnf->mpr_coverage == MPR_COVERAGE ? "# " : "",
+      cnf->mpr_coverage);
+  abuf_puts(out,
+    "\n"
+    "################################\n"
+    "### OLSR protocol extensions ###\n"
+    "################################\n"
+    "\n"
+    "# Link quality level switch between hopcount and \n"
+    "# cost-based (mostly ETX) routing. Because of\n"
+    "# a design problem in the 0.5.x dijkstra algorithm this\n"
+    "# value should not be set to 1.\n"
+    "# 0 = do not use link quality\n"
+    "# 2 = use link quality for MPR selection and routing\n"
+    "# (default is 2)\n"
+    "\n");
+  abuf_appendf(out, "%sLinkQualityLevel %d\n",
+      cnf->lq_level == DEF_LQ_LEVEL ? "# " : "",
+      cnf->lq_level);
+  abuf_puts(out,
+    "\n"
+    "# Link quality algorithm (only for lq level 2)\n"
+    "# (see README_LQ_ALGORITHMS)\n"
+    "# - \"etx_float\", a floating point  ETX with exponential aging\n"
+    "# - \"etx_fpm\", same as ext_float, but with integer arithmetic\n"
+    "# - \"etx_ff\" (ETX freifunk), an etx variant which use all OLSR\n"
+    "#   traffic (instead of only hellos) for ETX calculation\n"
+    "# - \"etx_ffeth\", an incompatible variant of etx_ff that allows\n"
+    "#   ethernet links with ETX 0.1.\n"
+    "# (defaults to \"etx_ff\")\n"
+    "\n");
+  abuf_appendf(out, "%sLinkQualityAlgorithm    \"%s\"\n",
+      cnf->lq_algorithm == NULL ? "# " : "",
+      cnf->lq_algorithm == NULL ? DEF_LQ_ALGORITHM : cnf->lq_algorithm);
+  abuf_puts(out,
+    "\n"
+    "# Link quality aging factor (only for lq level 2)\n"
+    "# Tuning parameter for etx_float and etx_fpm, smaller values\n"
+    "# mean slower changes of ETX value. (allowed values are\n"
+    "# between 0.01 and 1.0)\n"
+    "# (default is 0.05)\n"
+    "\n");
+  abuf_appendf(out, "%sLinkQualityAging %.2f\n",
+      cnf->lq_aging == DEF_LQ_AGING ? "# " : "",
+      cnf->lq_aging);
+  abuf_puts(out,
+    "\n"
+    "# Fisheye mechanism for TCs (0 meansoff, 1 means on)\n"
+    "# (default is 1)\n"
+    "\n");
+  abuf_appendf(out, "%sLinkQualityFishEye  %d\n",
+      cnf->lq_fish == DEF_LQ_FISH ? "# " : "",
+      cnf->lq_fish);
+  abuf_puts(out,
+    "\n"
+    "#\n"
+    "# NatThreshold \n"
+    "#\n"
+    "# (currently this is only in the freifunk firmware)\n"
+    "# If the NAT-Endpoint (the preferred 0/0 HNA emitting node)\n"
+    "# is to be changed, the ETX value of the current 0/0 is \n"
+    "# multiplied with the NatThreshold value before being\n"
+    "# compared to the new one.\n"
+    "# The parameter can be a value between 0.1 and 1.0, but\n"
+    "# should be close to 1.0 if changed.\n"
+    "# WARNING: This parameter should not be used together with\n"
+    "# the etx_ffeth metric !!\n"
+    "# (defaults to 1.0)\n"
+    "\n");
+  abuf_appendf(out, "%sNatThreshold  %.1f\n",
+      cnf->lq_nat_thresh == DEF_LQ_NAT_THRESH ? "# " : "",
+      cnf->lq_nat_thresh);
+
+  abuf_puts(out,
+    "\n"
+    "#############################################################\n"
+    "### Configuration of the IPC to the windows GUI interface ###\n"
+    "#############################################################\n"
+    "\n"
+    "IpcConnect\n"
+    "{\n"
+    "    # Determines how many simultaneously\n"
+    "    # IPC connections that will be allowed\n"
+    "    # Setting this to 0 disables IPC\n"
+    "\n");
+  abuf_appendf(out, "  %sMaxConnections  %d\n",
+      cnf->ipc_connections == DEF_IPC_CONNECTIONS ? "# " : "",
+      cnf->ipc_connections);
+  abuf_puts(out,
+    "\n"
+    "    # By default only 127.0.0.1 is allowed\n"
+    "    # to connect. Here allowed hosts and networks can\n"
+    "    # be added\n"
+    "\n");
+
+  while (ipc_nets) {
+    if (ipc_nets->net.prefix_len == olsr_cnf->maxplen) {
+      abuf_appendf(out, "    Host %s\n", olsr_ip_to_string(&ipbuf, &ipc_nets->net.prefix));
     } else {
-      WRITE_TO_BUF("    Net\t\t\t%s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len);
+      abuf_appendf(out, "    Net  %s\n", olsr_ip_prefix_to_string(&ipc_nets->net));
     }
-    ie = ie->next;
+    ipc_nets = ipc_nets->next;
   }
-
-  WRITE_TO_BUF("}\n\n");
-
-  /* Hysteresis */
-  WRITE_TO_BUF("# Hysteresis adds more robustness to the\n# link sensing.\n# Used by default. 'yes' or 'no'\n\n");
-
-  if (cnf->use_hysteresis) {
-    WRITE_TO_BUF("UseHysteresis\tyes\n\n");
-    WRITE_TO_BUF
-      ("# Hysteresis parameters\n# Do not alter these unless you know \n# what you are doing!\n# Set to auto by default. Allowed\n# values are floating point values\n# in the interval 0,1\n# THR_LOW must always be lower than\n# THR_HIGH!!\n\n");
-    WRITE_TO_BUF("HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
-    WRITE_TO_BUF("HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
-    WRITE_TO_BUF("HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
-  } else {
-    WRITE_TO_BUF("UseHysteresis\tno\n\n");
-    WRITE_TO_BUF
-      ("# Hysteresis parameters\n# Do not alter these unless you know \n# what you are doing!\n# Set to auto by default. Allowed\n# values are floating point values\n# in the interval 0,1\n# THR_LOW must always be lower than\n# THR_HIGH!!\n\n");
-    WRITE_TO_BUF("#HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
-    WRITE_TO_BUF("#HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
-    WRITE_TO_BUF("#HystThrLow\t%0.2f\n\n", cnf->hysteresis_param.thr_low);
-  }
-
-  /* Pollrate */
-  WRITE_TO_BUF("# Polling rate in seconds(float).\n# Auto uses default value 0.05 sec\n\n");
-  WRITE_TO_BUF("Pollrate\t%0.2f\n", cnf->pollrate);
-
-  /* TC redundancy */
-  WRITE_TO_BUF
-    ("# TC redundancy\n# Specifies how much neighbor info should\n# be sent in TC messages\n# Possible values are:\n# 0 - only send MPR selectors\n# 1 - send MPR selectors and MPRs\n# 2 - send all neighbors\n#\n# defaults to 0\n\n");
-  WRITE_TO_BUF("TcRedundancy\t%d\n\n", cnf->tc_redundancy);
-
-  /* MPR coverage */
-  WRITE_TO_BUF
-    ("# MPR coverage\n# Specifies how many MPRs a node should\n# try select to reach every 2 hop neighbor\n# Can be set to any integer >0\n# defaults to 1\n\n");
-
-  WRITE_TO_BUF("MprCoverage\t%d\n\n", cnf->mpr_coverage);
-
-  WRITE_TO_BUF
-    ("# Link quality level\n# 0 = do not use link quality\n# 1 = use link quality for MPR selection\n# 2 = use link quality for MPR selection and routing\n\n");
-  WRITE_TO_BUF("LinkQualityLevel\t%d\n\n", cnf->lq_level);
-
-  WRITE_TO_BUF("# Link quality aging factor\n\n");
-  WRITE_TO_BUF("LinkQualityAging\t%f\n\n", cnf->lq_aging);
-
-  WRITE_TO_BUF("# NAT threshold\n\n");
-  WRITE_TO_BUF("NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
-
-  WRITE_TO_BUF("# Clear screen when printing debug output?\n\n");
-  WRITE_TO_BUF("ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
-
-  /* Plugins */
-  WRITE_TO_BUF
-    ("# Olsrd plugins to load\n# This must be the absolute path to the file\n# or the loader will use the following scheme:\n");
-  WRITE_TO_BUF
-    ("# - Try the paths in the LD_LIBRARY_PATH \n#   environment variable.\n# - The list of libraries cached in /etc/ld.so.cache\n# - /lib, followed by /usr/lib\n\n");
-  if (pe) {
-    while (pe) {
-      WRITE_TO_BUF("LoadPlugin \"%s\" {\n", pe->name);
-      pp = pe->params;
-      while (pp) {
-        WRITE_TO_BUF("    PlParam \"%s\"\t\"%s\"\n", pp->key, pp->value);
-        pp = pp->next;
-      }
-      WRITE_TO_BUF("}\n");
-      pe = pe->next;
+  abuf_puts(out,
+    "}\n"
+    "\n"
+    "#####################################\n"
+    "### Example plugin configurations ###\n"
+    "#####################################\n"
+    "# Olsrd plugins to load\n"
+    "# This must be the absolute path to the file\n"
+    "# or the loader will use the following scheme:\n"
+    "# - Try the paths in the LD_LIBRARY_PATH \n"
+    "#   environment variable.\n"
+    "# - The list of libraries cached in /etc/ld.so.cache\n"
+    "# - /lib, followed by /usr/lib\n"
+    "\n");
+
+  while (plugins) {
+    abuf_appendf(out, "LoadPlugin \"%s\" {\n", plugins->name);
+    pl_param = plugins->params;
+    while (pl_param) {
+      abuf_appendf(out, "    PlParam \"%s\"\t\"%s\"\n", pl_param->key, pl_param->value);
+      pl_param = pl_param->next;
     }
+    abuf_puts(out, "}\n"
+        "\n");
+    plugins = plugins->next;
   }
-  WRITE_TO_BUF("\n");
-
-  /* Interfaces */
-  WRITE_TO_BUF("# Interfaces\n# Multiple interfaces with the same configuration\n");
-  WRITE_TO_BUF("# can shar the same config block. Just list the\n# interfaces(e.g. Interface \"eth0\" \"eth2\"\n\n");
-  /* Interfaces */
-  if (in) {
-    bool first = true;
-    while (in) {
-      WRITE_TO_BUF("Interface \"%s\" {\n", in->name);
-
-      if (first)
-        WRITE_TO_BUF
-          ("   # Interface Mode to use. Defines\n    # forward behaviour depending on\n    # interface type\n    # valid option are [mesh] and ether\n\n");
-
-      if (in->cnf->mode!=1) {
-        WRITE_TO_BUF("    #Mode\tmesh\n\n");
-      } else {
-        if (first)
-          WRITE_TO_BUF("    Mode\tether\n\n");
-      }
-
-      if (first)
-        WRITE_TO_BUF("\n");
-
-      if (first)
-        WRITE_TO_BUF
-          ("    # IPv4 broadcast address to use. The\n    # one usefull example would be 255.255.255.255\n    # If not defined the broadcastaddress\n    # every card is configured with is used\n\n");
-
-      if (in->cnf->ipv4_multicast.v4.s_addr) {
-        WRITE_TO_BUF("    Ip4Broadcast\t%s\n", inet_ntoa(in->cnf->ipv4_multicast.v4));
-      } else {
-        if (first)
-          WRITE_TO_BUF("    #Ip4Broadcast\t255.255.255.255\n");
-      }
-
-      if (first)
-        WRITE_TO_BUF
-          ("    # IPv6 multicast address.\n    # If not defined, "OLSR_IPV6_MCAST" is used\n");
-      WRITE_TO_BUF("    IPv6Multicast\t%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)));
-      if (first)
-        WRITE_TO_BUF("\n");
-
-      if (first)
-        WRITE_TO_BUF
-          ("    # IPv4 src address.\n    # If not defined, the interface IP is used\n");
-      WRITE_TO_BUF("    IPv6Multicast\t%s\n", inet_ntop(AF_INET6, &in->cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)));
-      if (first)
-        WRITE_TO_BUF("\n");
-
-      if (first)
-        WRITE_TO_BUF
-          ("    # IPv6 src prefix.\n    # If not defined, a not-linklocal interface IP is used\n");
-      WRITE_TO_BUF("    IPv6Src\t%s\n", olsr_ip_prefix_to_string(&in->cnf->ipv6_src));
-      if (first)
-        WRITE_TO_BUF("\n");
-
-      if (first)
-        WRITE_TO_BUF
-          ("    # Emission and validity intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
-
-      if (in->cnf->hello_params.emission_interval != HELLO_INTERVAL)
-        WRITE_TO_BUF("    HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
-      else if (first)
-        WRITE_TO_BUF("    #HelloInterval\t%0.2f\n", in->cnf->hello_params.emission_interval);
-      if (in->cnf->hello_params.validity_time != NEIGHB_HOLD_TIME)
-        WRITE_TO_BUF("    HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
-      else if (first)
-        WRITE_TO_BUF("    #HelloValidityTime\t%0.2f\n", in->cnf->hello_params.validity_time);
-      if (in->cnf->tc_params.emission_interval != TC_INTERVAL)
-        WRITE_TO_BUF("    TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
-      else if (first)
-        WRITE_TO_BUF("    #TcInterval\t\t%0.2f\n", in->cnf->tc_params.emission_interval);
-      if (in->cnf->tc_params.validity_time != TOP_HOLD_TIME)
-        WRITE_TO_BUF("    TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
-      else if (first)
-        WRITE_TO_BUF("    #TcValidityTime\t%0.2f\n", in->cnf->tc_params.validity_time);
-      if (in->cnf->mid_params.emission_interval != MID_INTERVAL)
-        WRITE_TO_BUF("    MidInterval\t\t%0.2f\n", in->cnf->mid_params.emission_interval);
-      else if (first)
-        WRITE_TO_BUF("    #MidInterval\t%0.2f\n", in->cnf->mid_params.emission_interval);
-      if (in->cnf->mid_params.validity_time != MID_HOLD_TIME)
-        WRITE_TO_BUF("    MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
-      else if (first)
-        WRITE_TO_BUF("    #MidValidityTime\t%0.2f\n", in->cnf->mid_params.validity_time);
-      if (in->cnf->hna_params.emission_interval != HNA_INTERVAL)
-        WRITE_TO_BUF("    HnaInterval\t\t%0.2f\n", in->cnf->hna_params.emission_interval);
-      else if (first)
-        WRITE_TO_BUF("    #HnaInterval\t%0.2f\n", in->cnf->hna_params.emission_interval);
-      if (in->cnf->hna_params.validity_time != HNA_HOLD_TIME)
-        WRITE_TO_BUF("    HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
-      else if (first)
-        WRITE_TO_BUF("    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);
-
-      mult = in->cnf->lq_mult;
-
-      if (mult == NULL) {
-        if (first)
-          WRITE_TO_BUF("    #LinkQualityMult\tdefault 1.0\n");
-      } else {
-        while (mult != NULL) {
-          WRITE_TO_BUF("    LinkQualityMult\t%s %0.2f\n", inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
-                       (float)(mult->value) / 65536.0);
-          mult = mult->next;
-        }
-      }
-
-      if (first) {
-        WRITE_TO_BUF("    # When multiple links exist between hosts\n");;
-        WRITE_TO_BUF("    # the weight of interface is used to determine\n");;
-        WRITE_TO_BUF("    # the link to use. Normally the weight is\n");
-        WRITE_TO_BUF("    # automatically calculated by olsrd based\n");;
-        WRITE_TO_BUF("    # on the characteristics of the interface,\n");;
-        WRITE_TO_BUF("    # but here you can specify a fixed value.\n");;
-        WRITE_TO_BUF("    # Olsrd will choose links with the lowest value.\n");
-        WRITE_TO_BUF("    # Note:\n");;
-        WRITE_TO_BUF("    # Interface weight is used only when LinkQualityLevel is 0.\n");;
-        WRITE_TO_BUF("    # For any other value of LinkQualityLevel, the interface ETX\n");;
-        WRITE_TO_BUF("    # value is used instead.\n\n");;
-      }
-      if (in->cnf->weight.fixed) {
-        WRITE_TO_BUF("    Weight\t %d\n\n", in->cnf->weight.value);
-      } else {
-        if (first)
-          WRITE_TO_BUF("    #Weight\t 0\n\n");
-      }
-
-      WRITE_TO_BUF("}\n\n");
-      in = in->next;
-      first = false;
-    }
 
+  abuf_puts(out,
+    "#############################################\n"
+    "### OLSRD default interface configuration ###\n"
+    "#############################################\n"
+    "# the default interface section can have the same values as the following\n"
+    "# interface configuration. It will allow you so set common options for all\n"
+    "# interfaces.\n"
+    "\n"
+    "InterfaceDefaults\n");
+  olsrd_write_if_autobuf(out, cnf->interface_defaults, false);
+  abuf_puts(out,
+    "\n"
+    "######################################\n"
+    "### OLSRd Interfaces configuration ###\n"
+    "######################################\n"
+    "# multiple interfaces can be specified for a single configuration block\n"
+    "# multiple configuration blocks can be specified\n"
+    "\n");
+  first = true;
+  while (interf) {
+    abuf_appendf(out, "Interface \"%s\"\n", interf->name);
+    olsrd_write_if_autobuf(out, interf->cnf, first);
+
+    first = false;
+    interf = interf->next;
   }
 
-  WRITE_TO_BUF("\n# END AUTOGENERATED CONFIG\n");
-
-  return size;
+  abuf_puts(out,
+      "\n"
+      "# END AUTOGENERATED CONFIG\n");
 }
-
 /*
  * Local Variables:
  * c-basic-offset: 2
index ff792c8..d4c1718 100644 (file)
@@ -66,6 +66,12 @@ extern int yyparse(void);
 
 static char interface_defaults_name[] = "[InterfaceDefaults]";
 
+const char *FIB_METRIC_TXT[] = {
+  "flat",
+  "correct",
+  "approx",
+};
+
 const char *GW_UPLINK_TXT[] = {
   "none",
   "ipv4",
@@ -73,6 +79,11 @@ const char *GW_UPLINK_TXT[] = {
   "both"
 };
 
+const char *OLSR_IF_MODE[] = {
+  "mesh",
+  "ether"
+};
+
 static char copyright_string[] __attribute__ ((unused)) =
   "The olsr.org Optimized Link-State Routing daemon(olsrd) Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org) All rights reserved.";
 
@@ -370,12 +381,13 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
     return -1;
   }
 
-#if defined linux && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#if defined linux
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   if (cnf->ip_version == AF_INET6 && cnf->smart_gw_active) {
     fprintf(stderr, "Smart gateways are not supported for linux kernel 2.4 and ipv6\n");
     return -1;
   }
-
+#endif
 #endif
 
 #ifdef linux
@@ -680,7 +692,6 @@ set_default_cnf(struct olsrd_config *cnf)
 struct if_config_options *
 get_default_if_config(void)
 {
-  struct in6_addr in6;
   struct if_config_options *io = malloc(sizeof(*io));
 
   if (io == NULL) {
@@ -690,8 +701,9 @@ get_default_if_config(void)
 
   memset(io, 0, sizeof(*io));
 
-  inet_pton(AF_INET6, OLSR_IPV6_MCAST, &in6);
-  io->ipv6_multicast.v6 = in6;
+  io->mode = DEF_IF_MODE;
+
+  io->ipv6_multicast = ipv6_def_multicast;
 
   io->lq_mult = NULL;
 
index 705f552..4d73914 100644 (file)
@@ -799,15 +799,16 @@ iipversion:    TOK_IPVERSION TOK_INTEGER
 
 fibmetric:    TOK_FIBMETRIC TOK_STRING
 {
+  int i;
   PARSER_DEBUG_PRINTF("FIBMetric: %s\n", $2->string);
-  if (strcmp($2->string, CFG_FIBM_FLAT) == 0) {
-      olsr_cnf->fib_metric = FIBM_FLAT;
-  } else if (strcmp($2->string, CFG_FIBM_CORRECT) == 0) {
-      olsr_cnf->fib_metric = FIBM_CORRECT;
-  } else if (strcmp($2->string, CFG_FIBM_APPROX) == 0) {
-      olsr_cnf->fib_metric = FIBM_APPROX;
-  } else {
-    fprintf(stderr, "FIBMetric must be \"%s\", \"%s\", or \"%s\"!\n", CFG_FIBM_FLAT, CFG_FIBM_CORRECT, CFG_FIBM_APPROX);
+  for (i=0; i<FIBM_CNT; i++) {
+    if (strcmp($2->string, FIB_METRIC_TXT[i]) == 0) {
+      olsr_cnf->fib_metric = i;
+      break;
+    }
+  }
+  if (i == FIBM_CNT) {
+    fprintf(stderr, "Bad FIBMetric value: %s\n", $2->string);
     YYABORT;
   }
   free($1);
index 0076920..5abaed8 100644 (file)
@@ -42,6 +42,8 @@
 #ifndef _COMMON_AUTOBUF_H
 #define _COMMON_AUTOBUF_H
 
+struct autobuf;
+
 #include "defs.h"
 #include <stdarg.h>
 #include <time.h>
index b257ca3..b8f0d52 100644 (file)
@@ -89,9 +89,6 @@
 #define WEIGHT_HIGH             4096    /* High                 */
 #define WEIGHT_HIGHEST          8192    /* Really high          */
 
-#define IF_MODE_MESH           0
-#define IF_MODE_ETHER   1
-
 struct if_gen_property {
   uint32_t owner_id;
   void *data;
index 51c398d..0f22bcd 100644 (file)
@@ -63,6 +63,11 @@ const struct olsr_ip_prefix ipv6_internet_route =
     .prefix_len = 3
 };
 
+/* Default IPv6 multicast addresses FF02::6D(linklocal manet routers, see RFC 5498) */
+const union olsr_ip_addr ipv6_def_multicast = {
+    .v6.s6_addr = { 0xFF, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0x6D }
+};
+
 int
 prefix_to_netmask(uint8_t * a, int len, uint8_t prefixlen)
 {
index 2a0276c..f9f65a4 100644 (file)
@@ -53,6 +53,8 @@ extern const struct olsr_ip_prefix ipv4_internet_route;
 extern const struct olsr_ip_prefix ipv6_mappedv4_route;
 extern const struct olsr_ip_prefix ipv6_internet_route;
 
+extern const union olsr_ip_addr ipv6_def_multicast;
+
 struct ipaddr_str {
   char buf[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
 } __attribute__ ((unused));
index c7d33e1..bdf467b 100644 (file)
@@ -74,7 +74,7 @@ init_lq_handler_tree(void)
   register_lq_handler(&lq_etx_ffeth_handler, LQ_ALGORITHM_ETX_FFETH_NAME);
 
   if (olsr_cnf->lq_algorithm == NULL) {
-    activate_lq_handler(LQ_ALGORITHM_ETX_FF_NAME);
+    activate_lq_handler(DEF_LQ_ALGORITHM);
   }
   else {
     activate_lq_handler(olsr_cnf->lq_algorithm);
index 41382c8..aa17fc3 100644 (file)
@@ -43,6 +43,7 @@
 #define _OLSRD_CFGPARSER_H
 
 #include "olsr_types.h"
+#include "common/autobuf.h"
 
 /*set to 1 to collect all startup sleep into one sleep (just as long as the longest sleep) useful if many errors on many interfaces*/
 #define OLSR_COLLECT_STARTUP_SLEEP 1
@@ -51,6 +52,7 @@
 #define SYSLOG_NUMBERING 0
 
 /* Default values not declared in olsr_protocol.h */
+#define DEF_IP_VERSION       AF_INET
 #define DEF_POLLRATE         0.05
 #define DEF_NICCHGPOLLRT     2.5
 #define DEF_WILL_AUTO        false
@@ -62,6 +64,7 @@
 #define DEF_USE_HYST         false
 #define DEF_FIB_METRIC       FIBM_FLAT
 #define DEF_LQ_LEVEL         2
+#define DEF_LQ_ALGORITHM     "etxff"
 #define DEF_LQ_FISH          1
 #define DEF_LQ_NAT_THRESH    1.0
 #define DEF_LQ_AGING         0.05
@@ -81,7 +84,9 @@
 #define DEF_GW_UPLINK_NAT    true
 #define DEF_UPLINK_SPEED     128
 #define DEF_DOWNLINK_SPEED   1024
-#define DEF_USE_SRCIP_ROUTES false;
+#define DEF_USE_SRCIP_ROUTES false
+
+#define DEF_IF_MODE          IF_MODE_MESH
 
 /* Bounds */
 
 #define MIN_SMARTGW_SPEED    1
 #define MAX_SMARTGW_SPEED    320000000
 
-/* Option values */
-#define CFG_FIBM_FLAT          "flat"
-#define CFG_FIBM_CORRECT       "correct"
-#define CFG_FIBM_APPROX        "approx"
-
 #ifndef IPV6_ADDR_SITELOCAL
 #define IPV6_ADDR_SITELOCAL    0x0040U
 #endif
@@ -130,6 +130,21 @@ enum smart_gw_uplinktype {
   GW_UPLINK_CNT,
 };
 
+
+typedef enum {
+  FIBM_FLAT,
+  FIBM_CORRECT,
+  FIBM_APPROX,
+  FIBM_CNT
+} olsr_fib_metric_options;
+
+enum olsr_if_mode {
+  IF_MODE_MESH,
+  IF_MODE_ETHER,
+  IF_MODE_CNT
+};
+
+
 struct olsr_msg_params {
   float emission_interval;
   float validity_time;
@@ -198,12 +213,6 @@ struct plugin_entry {
   struct plugin_entry *next;
 };
 
-typedef enum {
-  FIBM_FLAT,
-  FIBM_CORRECT,
-  FIBM_APPROX
-} olsr_fib_metric_options;
-
 /*
  * The config struct
  */
@@ -287,6 +296,8 @@ extern "C" {
 #endif
 
   extern const char *GW_UPLINK_TXT[];
+  extern const char *FIB_METRIC_TXT[];
+  extern const char *OLSR_IF_MODE[];
 
 /*
  * List functions
@@ -310,9 +321,9 @@ extern "C" {
 
   void olsrd_print_cnf(struct olsrd_config *);
 
-  int olsrd_write_cnf(struct olsrd_config *, const char *);
+  void olsrd_write_cnf_autobuf(struct autobuf *out, struct olsrd_config *cnf);
 
-  int olsrd_write_cnf_buf(struct olsrd_config *, char *, uint32_t);
+  int olsrd_write_cnf(struct olsrd_config *, const char *);
 
   struct if_config_options *get_default_if_config(void);
 
index 72cd870..e4aa4a5 100644 (file)
 #ifndef _PROTOCOLS_OLSR_H
 #define        _PROTOCOLS_OLSR_H
 
+struct olsr;
+
 #include "olsr_types.h"
 #include "olsr_cfg.h"
 
 #include <string.h>
 
-/* Default IPv6 multicast addresses (linklocal manet routers, see RFC 5498) */
-#define OLSR_IPV6_MCAST "FF02::6D"
-
 #define OLSR_HEADERSIZE (sizeof(uint16_t) + sizeof(uint16_t))
 
 #define OLSR_MSGHDRSZ_IPV4 12