Initial addittion of new config parser
authorAndreas Tonnesen <andreto@olsr.org>
Sat, 16 Oct 2004 22:59:49 +0000 (22:59 +0000)
committerAndreas Tonnesen <andreto@olsr.org>
Sat, 16 Oct 2004 22:59:49 +0000 (22:59 +0000)
src/cfgparser/Makefile [new file with mode: 0644]
src/cfgparser/README [new file with mode: 0644]
src/cfgparser/olsrd.conf.example [new file with mode: 0644]
src/cfgparser/olsrd_cfgparser.h [new file with mode: 0644]
src/cfgparser/olsrd_conf.c [new file with mode: 0644]
src/cfgparser/olsrd_conf.h [new file with mode: 0644]
src/cfgparser/oparse.y [new file with mode: 0644]
src/cfgparser/oscan.lex [new file with mode: 0644]

diff --git a/src/cfgparser/Makefile b/src/cfgparser/Makefile
new file mode 100644 (file)
index 0000000..1138b91
--- /dev/null
@@ -0,0 +1,54 @@
+CC ?= gcc
+
+LDNAME ?= olsrd_cfgparser.so.0.1
+
+OBJS  = olsrd_conf.o oparse.o oscan.o
+
+ifdef MAKELIB
+NAME ?= $(LDNAME)
+LIBDIR ?= $(INSTALL_PREFIX)/usr/lib
+LDFLAGS ?= -shared -Wl,-soname,$(NAME)
+CFLAGS ?= -Wall -fPIC -g -DMAKELIB -I..
+LIBS  ?= -lm -lc
+DEP = libclean
+else 
+NAME ?= olsrd_cfgparser
+LDFLAGS ?=
+CFLAGS ?= -Wall -g -DMAKEBIN -I..
+endif
+
+BISON ?= bison
+FLEX ?= flex
+
+
+all:   $(NAME)
+
+$(NAME):       $(DEP) $(OBJS)
+               $(CC) $(LDFLAGS) -o $(NAME) $(OBJS) $(LIBS)
+
+oscan.c:       oscan.lex oparse.h olsrd_conf.h
+               $(FLEX) -ooscan.c oscan.lex
+
+oparse.h:      oparse.c
+
+oparse.c:      oparse.y olsrd_conf.h
+               $(BISON) -d -ooparse.c oparse.y
+
+install:
+       install -D -m 755 $(NAME) $(LIBDIR)/$(NAME)
+       /sbin/ldconfig -n $(LIBDIR)
+
+clean:
+               rm -f *.o
+               rm -f $(NAME)
+               rm -f $(LDNAME)
+               rm -f *~
+               rm -f oscan.c
+               rm -f oparse.c oparse.h
+
+
+libclean:
+               rm -f *.o
+
+
+
diff --git a/src/cfgparser/README b/src/cfgparser/README
new file mode 100644 (file)
index 0000000..1ea876f
--- /dev/null
@@ -0,0 +1,3 @@
+TODO
+
+- Andreas
diff --git a/src/cfgparser/olsrd.conf.example b/src/cfgparser/olsrd.conf.example
new file mode 100644 (file)
index 0000000..3129733
--- /dev/null
@@ -0,0 +1,261 @@
+#
+# UniK OLSR daemon config file
+#
+# Lines starting with a # are discarded
+#
+
+# Debug level(0-9)
+# If set to 0 the daemon runs in the background
+
+DebugLevel     1
+
+# IP version to use (4 or 6)
+
+IpVersion      4
+
+# HNA IPv4 routes
+# syntax: netaddr netmask
+# Example Internet gateway:
+# 0.0.0.0 0.0.0.0
+
+Hna4
+{
+    0.0.0.0   0.0.0.0
+    15.15.0.0 255.255.255.0
+    15.16.0.0 255.255.255.0
+}
+
+# HNA IPv6 routes
+# syntax: netaddr prefix
+# Example Internet gateway:
+Hna6
+{
+     ::              0
+    fecb:ab:ed:: 48
+    fecb:ff:dd::dd:d 48
+    fec0:2200:106:: 48
+    fec0:2200:106:0:0:0:0:0 48
+}
+
+# Interfaces and their rulesets
+Interfaces
+{
+    "eth0" "lan"
+    "eth1" "wlan"
+}
+
+# Should olsrd keep on running even if there are
+# no interfaces available? This is a good idea
+# for a PCMCIA/USB hotswap environment.
+# "yes" OR "no"
+
+AllowNoInt     yes
+
+# TOS(type of service) value for
+# the IP header of control traffic.
+# auto is 16
+
+TosValue       auto
+
+# The fixed willingness to use(0-7)
+# or "auto" to set willingness dynammically
+# based on battery/power status
+
+Willingness            auto
+
+# Allow processes like the GUI front-end
+# to connect to the daemon. 'yes' or 'no'
+
+IpcConnect     no
+
+
+# Wether to use hysteresis or not
+# Hysteresis adds more robustness to the
+# link sensing but delays neighbor registration.
+# Used by default. 'yes' or 'no'
+
+UseHysteresis  yes
+
+# Hysteresis parameters
+# Do not alter these unless you know 
+# what you are doing!
+# Set to auto by default. Allowed
+# values are floating point values
+# in the interval 0,1
+# THR_LOW must always be lower than
+# THR_HIGH!!
+
+#HystScaling   0.50
+#HystThrHigh   0.80
+#HystThrLow    0.30
+
+
+# Polling rate in seconds(float). 
+# Auto uses default value 0.1 sec
+
+Pollrate       0.1
+
+
+# TC redundancy
+# Specifies how much neighbor info should
+# be sent in TC messages
+# Possible values are:
+# 0 - only send MPR selectors
+# 1 - send MPR selectors and MPRs
+# 2 - send all neighbors
+#
+# defaults to 0
+
+TcRedundancy   0
+
+
+#
+# MPR coverage
+# Specifies how many MPRs a node should
+# try select to reach every 2 hop neighbor
+#
+# Can be set to any integer >0
+#
+# defaults to 1
+
+MprCoverage    1
+
+
+# Olsrd plugins to load
+# This must be the absolute path to the file
+# or the loader will use the following scheme:
+# - Try the paths in the LD_LIBRARY_PATH 
+#   environment variable.
+# - The list of libraries cached in /etc/ld.so.cache
+# - /lib, followed by /usr/lib
+LoadPlugin
+{
+    PlName     "olsrd_secure.so.0.3"
+    PlParam     "key1"   "value1"
+
+    PlName     "olsrd_dyn_gw.so.0.1"
+    PlParam     "key4"   "value3"
+    # Might be possible to set options here in
+    # future versions
+}
+
+# olsrd_dyn_gw.so.0.1
+# olsrd_power.so.0.1
+
+
+IfSetup "lan"
+{
+
+    # IPv4 broadcast address to use. The
+    # one usefull example would be 255.255.255.255
+    # If not defined the broadcastaddress
+    # every card is configured with is used
+
+    Ip4Broadcast       255.255.255.255
+
+    # IPv6 address scope to use.
+    # Must be 'site-local' or 'global'
+
+    # Ip6AddrType              site-local
+
+    # IPv6 multicast address to use when
+    # using site-local addresses.
+    # If not defined, ff05::15 is used
+
+    Ip6MulticastSite   ff05::11
+
+    # IPv6 multicast address to use when
+    # using global addresses
+    # If not defined, ff0e::1 is used
+
+    # Ip6MulticastGlobal       ff0e::1
+
+
+    # Emission intervals.
+    # If not defined, RFC proposed values will
+    # be used in most cases.
+
+    # Hello interval in seconds(float)
+    # HelloInterval    2.0
+
+    # HELLO validity time
+    # HelloValidityTime        6.0
+
+    # TC interval in seconds(float)
+    TcInterval        5.0
+
+    # TC validity time
+    # TcValidityTime   15.0
+
+    # MID interval in seconds(float)
+    # MidInterval      5.0
+
+    # MID validity time
+    # MidValidityTime  15.0
+
+    # HNA interval in seconds(float)
+    # HnaInterval      5.0
+
+    # HNA validity time
+    # HnaValidityTime  15.0
+
+}
+
+
+IfSetup "wlan"
+{
+
+    # IPv4 broadcast address to use. The
+    # one usefull example would be 255.255.255.255
+    # If not defined the broadcastaddress
+    # every card is configured with is used
+
+    # Ip4Broadcast     255.255.255.255
+
+    # IPv6 address scope to use.
+    # Must be 'site-local' or 'global'
+
+    Ip6AddrType                site-local
+
+    # IPv6 multicast address to use when
+    # using site-local addresses.
+    # If not defined, ff05::15 is used
+
+    Ip6MulticastSite   ff05::15
+
+    # IPv6 multicast address to use when
+    # using global addresses
+    # If not defined, ff0e::1 is used
+
+    Ip6MulticastGlobal ff0e::1
+
+
+    # Emission intervals.
+    # If not defined, RFC proposed values will
+    # be used in most cases.
+
+    # Hello interval in seconds(float)
+    HelloInterval    1.0
+
+    # HELLO validity time
+    HelloValidityTime  3.0
+
+    # TC interval in seconds(float)
+    TcInterval        4.0
+
+    # TC validity time
+    TcValidityTime     14.0
+
+    # MID interval in seconds(float)
+    MidInterval        5.0
+
+    # MID validity time
+    MidValidityTime    15.0
+
+    # HNA interval in seconds(float)
+    HnaInterval        5.0
+
+    # HNA validity time
+    HnaValidityTime    15.0
+
+}
diff --git a/src/cfgparser/olsrd_cfgparser.h b/src/cfgparser/olsrd_cfgparser.h
new file mode 100644 (file)
index 0000000..e94e86a
--- /dev/null
@@ -0,0 +1,106 @@
+
+
+#ifndef _OLSRD_CFGPARSER_H
+#define _OLSRD_CFGPARSER_H
+
+
+#include "olsr_protocol.h"
+
+struct olsr_msg_params
+{
+  float                    emission_interval;
+  float                    validity_time;
+};
+
+struct if_config_options
+{
+  char                     *name;
+  union olsr_ip_addr       ipv4_broadcast;
+  int                      ipv6_addrtype;
+  union olsr_ip_addr       ipv6_multi_site;
+  union olsr_ip_addr       ipv6_multi_glbl;
+  struct olsr_msg_params   hello_params;
+  struct olsr_msg_params   tc_params;
+  struct olsr_msg_params   mid_params;
+  struct olsr_msg_params   hna_params;
+  struct if_config_options *next;
+};
+
+struct olsr_if
+{
+  char                     *name;
+  char                     *config;
+  struct if_config_options *if_options;
+  struct olsr_if           *next;
+};
+
+struct hna4_entry
+{
+  olsr_u32_t               net;
+  olsr_u32_t               netmask;
+  struct hna4_entry        *next;
+};
+
+struct hna6_entry
+{
+  union olsr_ip_addr       net;
+  olsr_u16_t               prefix_len;
+  struct hna6_entry        *next;
+};
+
+struct hyst_param
+{
+  float                    scaling;
+  float                    thr_high;
+  float                    thr_low;
+};
+
+struct plugin_entry
+{
+  char                     *name;
+  struct plugin_entry      *next;
+};
+
+/*
+ * The config struct
+ */
+
+struct olsrd_config
+{
+  olsr_u8_t                debug_level;
+  olsr_u8_t                ip_version;
+  olsr_u8_t                allow_no_interfaces;
+  olsr_u16_t               tos;
+  olsr_u8_t                auto_willingness;
+  olsr_u8_t                fixed_willingness;
+  olsr_u8_t                open_ipc;
+  olsr_u8_t                use_hysteresis;
+  struct hyst_param        hysteresis_param;
+  float                    pollrate;
+  olsr_u8_t                tc_redundancy;
+  olsr_u8_t                mpr_coverage;
+  struct plugin_entry      *plugins;
+  struct hna4_entry        *hna4_entries;
+  struct hna6_entry        *hna6_entries;
+  struct olsr_if           *interfaces;
+  struct if_config_options *if_options;
+};
+
+
+/*
+ * Interface to parser
+ */
+
+struct olsrd_config *
+olsrd_parse_cnf(char *);
+
+void
+olsrd_free_cnf(struct olsrd_config *);
+
+void
+olsrd_print_cnf(struct olsrd_config *);
+
+int
+olsrd_write_cnf(struct olsrd_config *, char *);
+
+#endif
diff --git a/src/cfgparser/olsrd_conf.c b/src/cfgparser/olsrd_conf.c
new file mode 100644 (file)
index 0000000..16bdd91
--- /dev/null
@@ -0,0 +1,581 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "olsrd_conf.h"
+
+
+extern FILE *yyin;
+extern int yyparse(void);
+
+
+#ifdef MAKELIB
+
+/* Build as DLL */
+
+void __attribute__ ((constructor)) 
+my_init(void);
+
+void __attribute__ ((destructor)) 
+my_fini(void);
+
+
+/**
+ *Constructor
+ */
+void
+my_init()
+{
+  /* Print plugin info to stdout */
+  printf("olsrd config file parser %s loaded\n", SOFTWARE_VERSION);
+
+  return;
+}
+
+/**
+ *Destructor
+ */
+void
+my_fini()
+{
+  printf("See you around!\n");
+  return;
+}
+
+#else
+
+#ifdef MAKEBIN
+
+/* Build as standalone binary */
+int 
+main(int argc, char *argv[])
+{
+  struct olsrd_config *cnf;
+
+  if(argc == 1)
+    {
+      fprintf(stderr, "Usage: olsrd_cfgparser [filename] -print\n\n");
+      exit(EXIT_FAILURE);
+    }
+
+  if((cnf = olsrd_parse_cnf(argv[1])) != NULL)
+    {
+      if((argc > 2) && (!strcmp(argv[2], "-print")))
+       olsrd_write_cnf(cnf, "foo");//olsrd_print_cnf(cnf);  
+      else
+        printf("Use -print to view parsed values\n");
+      printf("Configfile parsed OK\n");
+    }
+  else
+    {
+      printf("Failed parsing \"%s\"\n", argv[1]);
+    }
+
+  return 0;
+}
+
+#else
+
+/* Build as part of olsrd */
+
+
+#endif
+
+#endif
+
+struct olsrd_config *
+olsrd_parse_cnf(char *filename)
+{
+  struct olsr_if *in;
+
+  cnf = malloc(sizeof(struct olsrd_config));
+  if (cnf == NULL)
+    {
+      fprintf(stderr, "Out of memory %s\n", __func__);
+      return NULL;
+  }
+
+  set_default_cnf(cnf);
+
+  printf("Parsing file: \"%s\"\n", filename);
+
+  yyin = fopen(filename, "r");
+  
+  if (yyin == NULL)
+    {
+      fprintf(stderr, "Cannot open configuration file '%s': %s.\n",
+             filename, strerror(errno));
+      free(cnf);
+      return NULL;
+  }
+
+  current_line = 1;
+
+  if (yyparse() != 0)
+    {
+      fclose(yyin);
+      olsrd_free_cnf(cnf);
+      return NULL;
+    }
+  
+  fclose(yyin);
+
+  /* Verify interface rulesets */
+  in = cnf->interfaces;
+
+  while(in)
+    {
+      in->if_options = find_if_rule_by_name(cnf->if_options, in->config);
+
+      if(in->if_options == NULL)
+       {
+         fprintf(stderr, "ERROR: Could not find a matching ruleset \"%s\" for %s\n", in->config, in->name);
+         olsrd_free_cnf(cnf);
+         return NULL;
+       }
+      in = in->next;
+    }
+
+  return cnf;
+}
+
+
+
+
+
+
+
+
+void
+olsrd_free_cnf(struct olsrd_config *cnf)
+{
+  struct hna4_entry        *h4d, *h4 = cnf->hna4_entries;
+  struct hna6_entry        *h6d, *h6 = cnf->hna6_entries;
+  struct olsr_if           *ind, *in = cnf->interfaces;
+  struct plugin_entry      *ped, *pe = cnf->plugins;
+  struct if_config_options *iod, *io = cnf->if_options;
+  
+  while(h4)
+    {
+      h4d = h4;
+      h4 = h4->next;
+      free(h4d);
+    }
+
+  while(h6)
+    {
+      h6d = h6;
+      h6 = h6->next;
+      free(h6d);
+    }
+
+  while(in)
+    {
+      ind = in;
+      in = in->next;
+      free(ind->name);
+      free(ind->config);
+      free(ind);
+    }
+
+  while(pe)
+    {
+      ped = pe;
+      pe = pe->next;
+      free(ped->name);
+      free(ped);
+    }
+
+  while(io)
+    {
+      iod = io;
+      io = io->next;
+      free(iod->name);
+      free(iod);
+    }
+
+  return;
+}
+
+
+
+void
+set_default_cnf(struct olsrd_config *cnf)
+{
+    memset(cnf, 0, sizeof(struct olsrd_config));
+    
+    cnf->debug_level = 1;
+    cnf->ip_version  = 4;
+    cnf->allow_no_interfaces = 1;
+    cnf->tos = 16;
+    cnf->auto_willingness = 1;
+    cnf->open_ipc = 0;
+
+    cnf->use_hysteresis = 1;
+    cnf->hysteresis_param.scaling = HYST_SCALING;
+    cnf->hysteresis_param.thr_high = HYST_THRESHOLD_HIGH;
+    cnf->hysteresis_param.thr_low = HYST_THRESHOLD_LOW;
+
+    cnf->pollrate = 0.1;
+
+    cnf->tc_redundancy = TC_REDUNDANCY;
+    cnf->mpr_coverage = MPR_COVERAGE;
+}
+
+
+
+
+
+
+int
+olsrd_write_cnf(struct olsrd_config *cnf, char *fname)
+{
+  struct hna4_entry        *h4 = cnf->hna4_entries;
+  struct hna6_entry        *h6 = cnf->hna6_entries;
+  struct olsr_if           *in = cnf->interfaces;
+  struct plugin_entry      *pe = cnf->plugins;
+  struct if_config_options *io = cnf->if_options;
+  char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
+  struct in_addr in4;
+
+  printf("#\n# Configuration file for olsr.org olsrd\n# automatically generated by olsrd-cnf %s\n#\n\n\n", SOFTWARE_VERSION);
+
+  /* Debug level */
+  printf("# 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 */
+  printf("# IP version to use (4 or 6)\n\nIpVersion\t%d\n\n", cnf->ip_version);
+
+
+  /* HNA IPv4 */
+  printf("# HNA IPv4 routes\n# syntax: netaddr netmask\n# Example Internet gateway:\n# 0.0.0.0 0.0.0.0\n\nHna4\n{\n");
+  if(h4)
+    {
+      while(h4)
+       {
+         in4.s_addr=h4->net;
+         printf("    %s ", inet_ntoa(in4));
+         in4.s_addr=h4->netmask;
+         printf("%s\n", inet_ntoa(in4));
+         h4 = h4->next;
+       }
+    }
+  printf("}\n\n");
+
+
+  /* HNA IPv6 */
+  printf("# HNA IPv6 routes\n# syntax: netaddr prefix\n# Example Internet gateway:\nHna6\n{\n");
+  if(h6)
+    {
+      while(h6)
+       {
+         printf("    %s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
+         h6 = h6->next;
+       }
+    }
+
+  printf("}\n\n");
+
+
+  /* Interfaces */
+  printf("# Interfaces and their rulesets\nInterfaces\n{\n");
+  /* Interfaces */
+  if(in)
+    {
+      while(in)
+       {
+         printf("    \"%s\" \"%s\"\n", in->name, in->config);
+         in = in->next;
+       }
+    }
+  printf("}\n\n");
+
+
+  /* No interfaces */
+  printf("# 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)
+    printf("yes\n\n");
+  else
+    printf("no\n\n");
+
+  /* TOS */
+  printf("# TOS(type of service) value for\n# the IP header of control traffic.\n# default is 16\n\n");
+  printf("TosValue\t%d\n\n", cnf->tos);
+
+  /* Willingness */
+  printf("# The fixed willingness to use(0-7)\n# or \"auto\" to set willingness dynammically\n# based on battery/power status\n\n");
+  if(cnf->auto_willingness)
+    printf("Willingness\tauto\n\n");
+  else
+    printf("Willingness%d\n\n", cnf->fixed_willingness);
+
+  /* IPC */
+  printf("# Allow processes like the GUI front-end\n# to connect to the daemon. 'yes' or 'no'\n\n");
+  if(cnf->open_ipc)
+    printf("IpcConnect\tyes\n\n");
+  else
+    printf("IpcConnect\tno\n\n");
+
+
+
+  /* Hysteresis */
+  printf("# Wether to use hysteresis or not\n# Hysteresis adds more robustness to the\n# link sensing but delays neighbor registration.\n# Used by default. 'yes' or 'no'\n\n");
+
+  if(cnf->use_hysteresis)
+    {
+      printf("UseHysteresis\tyes\n\n");
+      printf("# 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");
+      printf("HystScaling\t%0.2f\n", cnf->hysteresis_param.scaling);
+      printf("HystThrHigh\t%0.2f\n", cnf->hysteresis_param.thr_high);
+      printf("HystThrLow\t%0.2f\n", cnf->hysteresis_param.thr_low);
+    }
+  else
+    printf("UseHysteresis\tno\n\n");
+
+  printf("\n\n");
+
+  /* Pollrate */
+  printf("# Polling rate in seconds(float).\n# Auto uses default value 0.1 sec\n\n");
+  printf("Pollrate\t%0.2f\n", cnf->pollrate);
+
+  /* TC redundancy */
+  printf("# 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");
+  printf("TcRedundancy\t%d\n\n", cnf->tc_redundancy);
+
+  /* MPR coverage */
+  printf("# 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");
+
+  printf("MprCoverage\t%d\n\n", cnf->mpr_coverage);
+   
+
+
+  /* Plugins */
+  printf("# 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\nLoadPlugin\n{\n");
+  if(pe)
+    {
+      while(pe)
+       {
+         printf("    PlName \"%s\"\n", pe->name);
+         pe = pe->next;
+       }
+    }
+  printf("}\n\n");
+
+
+  /* Rulesets */
+  while(io)
+    {
+      printf("IfSetup \"%s\"\n{\n", io->name);
+
+      
+      printf("    # 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(io->ipv4_broadcast.v4)
+       {
+         in4.s_addr = io->ipv4_broadcast.v4;
+         printf("    Ip4Broadcast\t %s\n\n", inet_ntoa(in4));
+       }
+      else
+       {
+         printf("    #Ip4Broadcast\t255.255.255.255\n\n");
+       }
+
+
+      printf("    # IPv6 address scope to use.\n    # Must be 'site-local' or 'global'\n\n");
+      if(io->ipv6_addrtype)
+       printf("    Ip6AddrType \tsite-local\n\n");
+      else
+       printf("    Ip6AddrType \tglobal\n\n");
+
+      printf("    # IPv6 multicast address to use when\n    # using site-local addresses.\n    # If not defined, ff05::15 is used\n");
+      printf("    Ip6MulticastSite\t%s\n\n", (char *)inet_ntop(AF_INET6, &io->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
+      printf("    # IPv6 multicast address to use when\n    # using global addresses\n    # If not defined, ff0e::1 is used\n");
+      printf("    Ip6MulticastGlobal\t%s\n\n", (char *)inet_ntop(AF_INET6, &io->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
+
+
+
+      printf("    # Emission intervals.\n    # If not defined, RFC proposed values will\n    # in most cases be used.\n\n");
+
+
+      printf("    HelloInterval\t%0.2f\n", io->hello_params.emission_interval);
+      printf("    HelloValidityTime\t%0.2f\n", io->hello_params.validity_time);
+      printf("    TcInterval\t\t%0.2f\n", io->tc_params.emission_interval);
+      printf("    TcValidityTime\t%0.2f\n", io->tc_params.validity_time);
+      printf("    MidInterval\t\t%0.2f\n", io->mid_params.emission_interval);
+      printf("    MidValidityTime\t%0.2f\n", io->mid_params.validity_time);
+      printf("    HnaInterval\t\t%0.2f\n", io->hna_params.emission_interval);
+      printf("    HnaValidityTime\t%0.2f\n", io->hna_params.validity_time);
+
+
+
+      io = io->next;
+
+      printf("}\n\n\n");
+    }
+
+  printf("\n# END AUTOGENERATED CONFIG\n");
+
+  return 1;
+}
+
+
+
+
+
+void
+olsrd_print_cnf(struct olsrd_config *cnf)
+{
+  struct hna4_entry        *h4 = cnf->hna4_entries;
+  struct hna6_entry        *h6 = cnf->hna6_entries;
+  struct olsr_if           *in = cnf->interfaces;
+  struct plugin_entry      *pe = cnf->plugins;
+  struct if_config_options *io = cnf->if_options;
+  char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
+  struct in_addr in4;
+
+  printf(" *** olsrd configuration ***\n");
+
+  printf("Debug Level      : %d\n", cnf->debug_level);
+  printf("IpVersion        : %d\n", cnf->ip_version);
+  if(cnf->allow_no_interfaces)
+    printf("No interfaces    : ALLOWED\n");
+  else
+    printf("No interfaces    : NOT ALLOWED\n");
+  printf("TOS              : 0x%02x\n", cnf->tos);
+  if(cnf->auto_willingness)
+    printf("Willingness      : AUTO\n");
+  else
+    printf("Willingness      : %d\n", cnf->fixed_willingness);
+
+  if(cnf->open_ipc)
+    printf("IPC              : ENABLED\n");
+  else
+    printf("IPC              : DISABLED\n");
+
+  printf("Pollrate         : %0.2f\n", cnf->pollrate);
+
+  printf("TC redundancy    : %d\n", cnf->tc_redundancy);
+
+  printf("MPR coverage     : %d\n", cnf->mpr_coverage);
+   
+  /* Interfaces */
+  if(in)
+    {
+      printf("Interfaces:\n");
+      while(in)
+       {
+         printf("\tdev: \"%s\" ruleset: \"%s\"\n", in->name, in->config);
+         in = in->next;
+       }
+    }
+
+  /* Rulesets */
+  while(io)
+    {
+      printf("Interface ruleset \"%s\":\n", io->name);
+
+      
+      if(io->ipv4_broadcast.v4)
+       {
+         in4.s_addr = io->ipv4_broadcast.v4;
+         printf("\tIPv4 broadcast        : %s\n", inet_ntoa(in4));
+       }
+      else
+       {
+         printf("\tIPv4 broadcast        : AUTO\n");
+       }
+
+      if(io->ipv6_addrtype)
+       printf("\tIPv6 addrtype         : site-local\n");
+      else
+       printf("\tIPv6 addrtype         : global\n");
+
+      //union olsr_ip_addr       ipv6_multi_site;
+      //union olsr_ip_addr       ipv6_multi_glbl;
+      printf("\tIPv6 multicast site   : %s\n", (char *)inet_ntop(AF_INET6, &io->ipv6_multi_site.v6, ipv6_buf, sizeof(ipv6_buf)));
+      printf("\tIPv6 multicast global : %s\n", (char *)inet_ntop(AF_INET6, &io->ipv6_multi_glbl.v6, ipv6_buf, sizeof(ipv6_buf)));
+
+      printf("\tHELLO emission int    : %0.2f\n", io->hello_params.emission_interval);
+      printf("\tHELLO validity time   : %0.2f\n", io->hello_params.validity_time);
+      printf("\tTC emission int       : %0.2f\n", io->tc_params.emission_interval);
+      printf("\tTC validity time      : %0.2f\n", io->tc_params.validity_time);
+      printf("\tMID emission int      : %0.2f\n", io->mid_params.emission_interval);
+      printf("\tMID validity time     : %0.2f\n", io->mid_params.validity_time);
+      printf("\tHNA emission int      : %0.2f\n", io->hna_params.emission_interval);
+      printf("\tHNA validity time     : %0.2f\n", io->hna_params.validity_time);
+
+
+
+      io = io->next;
+    }
+
+  /* Plugins */
+  if(pe)
+    {
+      printf("Plugins:\n");
+
+      while(pe)
+       {
+         printf("\tName: \"%s\"\n", pe->name);
+         pe = pe->next;
+       }
+    }
+
+  /* Hysteresis */
+  if(cnf->use_hysteresis)
+    {
+      printf("Using hysteresis:\n");
+      printf("\tScaling : %0.2f\n", cnf->hysteresis_param.scaling);
+      printf("\tThr high: %0.2f\n", cnf->hysteresis_param.thr_high);
+      printf("\tThr low : %0.2f\n", cnf->hysteresis_param.thr_low);
+    }
+  else
+    printf("Not using hysteresis\n");
+
+  /* HNA IPv4 */
+  if(h4)
+    {
+
+      printf("HNA4 entries:\n");
+      while(h4)
+       {
+         in4.s_addr=h4->net;
+         printf("\t%s/", inet_ntoa(in4));
+         in4.s_addr=h4->netmask;
+         printf("%s\n", inet_ntoa(in4));
+
+         h4 = h4->next;
+       }
+    }
+
+  /* HNA IPv6 */
+  if(h6)
+    {
+      printf("HNA6 entries:\n");
+      while(h6)
+       {
+         printf("\t%s/%d\n", (char *)inet_ntop(AF_INET6, &h6->net.v6, ipv6_buf, sizeof(ipv6_buf)), h6->prefix_len);
+         h6 = h6->next;
+       }
+    }
+}
+
+
+
+
+struct if_config_options *
+find_if_rule_by_name(struct if_config_options *io, char *name)
+{
+
+  while(io)
+    {
+      if(strcmp(io->name, name) == 0)
+       return io;
+      io = io->next;
+    }
+  return NULL;
+}
diff --git a/src/cfgparser/olsrd_conf.h b/src/cfgparser/olsrd_conf.h
new file mode 100644 (file)
index 0000000..6b63c4d
--- /dev/null
@@ -0,0 +1,36 @@
+
+
+#ifndef _OLSRD_CONF_H
+#define _OLSRD_CONF_H
+
+#include "olsr_protocol.h"
+#include "olsrd_cfgparser.h"
+
+#define SOFTWARE_VERSION "0.1.1"
+
+
+int current_line;
+
+struct olsrd_config *cnf;
+
+struct conf_token
+{
+  olsr_u32_t integer;
+  float      floating;
+  olsr_u8_t  boolean;
+  char       *string;
+};
+
+void
+set_default_cnf(struct olsrd_config *);
+
+struct if_config_options *
+find_if_rule_by_name(struct if_config_options *, char *);
+
+struct conf_token *
+get_conf_token();
+
+struct if_config_options *
+get_default_if_config();
+
+#endif
diff --git a/src/cfgparser/oparse.y b/src/cfgparser/oparse.y
new file mode 100644 (file)
index 0000000..72aea6e
--- /dev/null
@@ -0,0 +1,617 @@
+%{
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "olsrd_conf.h"
+
+#define PARSER_DEBUG 0
+
+#define YYSTYPE struct conf_token *
+
+void yyerror(char *);
+int yylex(void);
+%}
+
+%token TOK_OPEN
+%token TOK_CLOSE
+%token TOK_SEMI
+
+%token TOK_STRING
+%token TOK_INTEGER
+%token TOK_FLOAT
+%token TOK_BOOLEAN
+
+%token TOK_IP6TYPE
+
+%token TOK_DEBUGLEVEL
+%token TOK_IPVERSION
+%token TOK_HNA4
+%token TOK_HNA6
+%token TOK_PLUGIN
+%token TOK_INTERFACES
+%token TOK_IFSETUP
+%token TOK_NOINT
+%token TOK_TOS
+%token TOK_WILLINGNESS
+%token TOK_IPCCON
+%token TOK_USEHYST
+%token TOK_HYSTSCALE
+%token TOK_HYSTUPPER
+%token TOK_HYSTLOWER
+%token TOK_POLLRATE
+%token TOK_TCREDUNDANCY
+%token TOK_MPRCOVERAGE
+%token TOK_PLNAME
+%token TOK_PLPARAM
+
+%token TOK_IP4BROADCAST
+%token TOK_IP6ADDRTYPE
+%token TOK_IP6MULTISITE
+%token TOK_IP6MULTIGLOBAL
+%token TOK_HELLOINT
+%token TOK_HELLOVAL
+%token TOK_TCINT
+%token TOK_TCVAL
+%token TOK_MIDINT
+%token TOK_MIDVAL
+%token TOK_HNAINT
+%token TOK_HNAVAL
+
+%token TOK_IP4_ADDR
+%token TOK_IP6_ADDR
+
+%token TOK_COMMENT
+
+%%
+
+conf:
+          | conf block
+          | conf stmt
+;
+
+stmt:       idebug
+          | iipversion
+          | bnoint
+          | atos
+          | awillingness
+          | bipccon
+          | busehyst
+          | fhystscale
+          | fhystupper
+          | fhystlower
+          | fpollrate
+          | atcredundancy
+          | amprcoverage
+          | vcomment
+;
+
+block:      TOK_HNA4 hna4body
+          | TOK_HNA6 hna6body
+          | TOK_INTERFACES ifbody
+          | TOK_PLUGIN plbody
+          | isetblock isetbody
+;
+
+hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
+;
+
+hna4stmts: | hna4stmts ihna4entry
+;
+
+hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
+;
+
+hna6stmts: | hna6stmts ihna6entry
+;
+
+ifbody:     TOK_OPEN ifstmts TOK_CLOSE
+;
+
+ifstmts:   | ifstmts ifstmt
+;
+
+ifstmt:     ifentry
+          | vcomment
+;
+
+isetbody:   TOK_OPEN isetstmts TOK_CLOSE
+;
+
+isetstmts:   | isetstmts isetstmt
+;
+
+isetstmt:      vcomment
+             | isetip4br
+             | isetip6addrt
+             | isetip6mults
+             | isetip6multg
+             | isethelloint
+             | isethelloval
+             | isettcint
+             | isettcval
+             | isetmidint
+             | isetmidval
+             | isethnaint
+             | isethnaval
+;
+
+plbody:     TOK_OPEN plstmts TOK_CLOSE
+;
+
+plstmts:   | plstmts plstmt
+;
+
+plstmt:     plname
+          | plparam
+          | vcomment
+;
+
+
+
+
+isetblock:    TOK_IFSETUP TOK_STRING
+{
+  struct if_config_options *io = get_default_if_config();
+  if(io == NULL)
+    {
+      fprintf(stderr, "Out of memory(ADD IFRULE)\n");
+      YYABORT;
+    }
+
+  if(PARSER_DEBUG) printf("Interface setup: \"%s\"\n", $2->string);
+  
+  io->name = $2->string;
+  
+  
+  /* Queue */
+  io->next = cnf->if_options;
+  cnf->if_options = io;
+
+  free($2);
+}
+;
+
+
+isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
+{
+  struct in_addr in;
+
+  if(PARSER_DEBUG) printf("\tIPv4 broadcast: %s\n", $2->string);
+
+  if(inet_aton($2->string, &in) == 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", $1->string);
+      exit(EXIT_FAILURE);
+    }
+
+  cnf->if_options->ipv4_broadcast.v4 = in.s_addr;
+
+  free($2->string);
+  free($2);
+}
+;
+
+isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
+{
+  cnf->if_options->ipv6_addrtype = $2->boolean;
+  
+  free($2);
+}
+;
+
+isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
+{
+  struct in6_addr in6;
+
+  if(PARSER_DEBUG) printf("\tIPv6 site-local multicast: %s\n", $2->string);
+
+  if(inet_pton(AF_INET6, $2->string, &in6) < 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", $2->string);
+      exit(EXIT_FAILURE);
+    }
+  memcpy(&cnf->if_options->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
+
+
+  free($2->string);
+  free($2);
+}
+;
+
+
+isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
+{
+  struct in6_addr in6;
+
+  if(PARSER_DEBUG) printf("\tIPv6 global multicast: %s\n", $2->string);
+
+  if(inet_pton(AF_INET6, $2->string, &in6) < 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", $2->string);
+      exit(EXIT_FAILURE);
+    }
+  memcpy(&cnf->if_options->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
+
+
+  free($2->string);
+  free($2);
+}
+;
+isethelloint: TOK_HELLOINT TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tHELLO interval: %0.2f\n", $2->floating);
+    cnf->if_options->hello_params.emission_interval = $2->floating;
+    free($2);
+}
+;
+isethelloval: TOK_HELLOVAL TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tHELLO validity: %0.2f\n", $2->floating);
+    cnf->if_options->hello_params.validity_time = $2->floating;
+    free($2);
+}
+;
+isettcint: TOK_TCINT TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tTC interval: %0.2f\n", $2->floating);
+    cnf->if_options->tc_params.emission_interval = $2->floating;
+    free($2);
+}
+;
+isettcval: TOK_TCVAL TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tTC validity: %0.2f\n", $2->floating);
+    cnf->if_options->tc_params.validity_time = $2->floating;
+    free($2);
+}
+;
+isetmidint: TOK_MIDINT TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tMID interval: %0.2f\n", $2->floating);
+    cnf->if_options->mid_params.emission_interval = $2->floating;
+    free($2);
+}
+;
+isetmidval: TOK_MIDVAL TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tMID validity: %0.2f\n", $2->floating);
+    cnf->if_options->mid_params.validity_time = $2->floating;
+    free($2);
+}
+;
+isethnaint: TOK_HNAINT TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tHNA interval: %0.2f\n", $2->floating);
+    cnf->if_options->hna_params.emission_interval = $2->floating;
+    free($2);
+}
+;
+isethnaval: TOK_HNAVAL TOK_FLOAT
+{
+    if(PARSER_DEBUG) printf("\tHNA validity: %0.2f\n", $2->floating);
+    cnf->if_options->hna_params.validity_time = $2->floating;
+    free($2);
+}
+;
+
+
+idebug:       TOK_DEBUGLEVEL TOK_INTEGER
+{
+
+  if($2->boolean == 1)
+    {
+      if(PARSER_DEBUG) printf("Debug levl AUTO\n");
+    }
+  else
+    {
+      cnf->debug_level = $2->integer;
+      if(PARSER_DEBUG) printf("Debug level: %d\n", cnf->debug_level);
+    }
+
+  free($2);
+}
+;
+
+
+iipversion:    TOK_IPVERSION TOK_INTEGER
+{
+  if(($2->integer != 4) && ($2->integer != 6))
+    {
+      fprintf(stderr, "IPversion must be 4 or 6!\n");
+      YYABORT;
+    }
+  cnf->ip_version = $2->integer;
+  if(PARSER_DEBUG) printf("IpVersion: %d\n", cnf->ip_version);
+  free($2);
+}
+;
+
+
+ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
+{
+  struct hna4_entry *h = malloc(sizeof(struct hna4_entry));
+  struct in_addr in;
+
+  if(PARSER_DEBUG) printf("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
+
+  if(h == NULL)
+    {
+      fprintf(stderr, "Out of memory(HNA4)\n");
+      YYABORT;
+    }
+
+  if(inet_aton($1->string, &in) == 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", $1->string);
+      exit(EXIT_FAILURE);
+    }
+  h->net = in.s_addr;
+  if(inet_aton($2->string, &in) == 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", $1->string);
+      exit(EXIT_FAILURE);
+    }
+  h->netmask = in.s_addr;
+  /* Queue */
+  h->next = cnf->hna4_entries;
+  cnf->hna4_entries = h;
+
+  free($1->string);
+  free($1);
+  free($2->string);
+  free($2);
+
+}
+
+ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
+{
+  struct hna6_entry *h = malloc(sizeof(struct hna6_entry));
+  struct in6_addr in6;
+
+  if(PARSER_DEBUG) printf("HNA IPv6 entry: %s/%d\n", $1->string, $2->integer);
+
+  if(h == NULL)
+    {
+      fprintf(stderr, "Out of memory(HNA6)\n");
+      YYABORT;
+    }
+
+  if(inet_pton(AF_INET6, $1->string, &in6) < 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", $1->string);
+      exit(EXIT_FAILURE);
+    }
+  memcpy(&h->net, &in6, sizeof(struct in6_addr));
+
+  if(($2->integer < 0) || ($2->integer > 128))
+    {
+      fprintf(stderr, "Illegal IPv6 prefix length %d\n", $2->integer);
+      exit(EXIT_FAILURE);
+    }
+
+  h->prefix_len = $2->integer;
+  /* Queue */
+  h->next = cnf->hna6_entries;
+  cnf->hna6_entries = h;
+
+  free($1->string);
+  free($1);
+  free($2);
+
+}
+
+ifentry: TOK_STRING TOK_STRING
+{
+  struct olsr_if *in = malloc(sizeof(struct olsr_if));
+  
+  if(in == NULL)
+    {
+      fprintf(stderr, "Out of memory(ADD IF)\n");
+      YYABORT;
+    }
+
+  in->name = $1->string;
+  in->config = $2->string;
+
+  if(PARSER_DEBUG) printf("Interface: %s Ruleset: %s\n", $1->string, $2->string);
+
+  /* Queue */
+  in->next = cnf->interfaces;
+  cnf->interfaces = in;
+
+  free($1);
+  free($2);
+}
+;
+
+bnoint: TOK_NOINT TOK_BOOLEAN
+{
+  if(PARSER_DEBUG) printf("Noint set to %d\n", $2->boolean);
+  free($2);
+}
+;
+
+atos: TOK_TOS TOK_INTEGER
+{
+  if($2->boolean == 1)
+    {
+      if(PARSER_DEBUG) printf("Tos AUTO\n");
+    }
+  else
+    {
+      if(PARSER_DEBUG) printf("TOS: %d\n", $2->integer);
+    }
+  free($2);
+
+}
+;
+
+awillingness: TOK_WILLINGNESS TOK_INTEGER
+{
+  if($2->boolean == 1)
+    {
+      if(PARSER_DEBUG) printf("Willingness AUTO\n");
+    }
+  else
+    {
+      if(PARSER_DEBUG) printf("Willingness: %d\n", $2->integer);
+    }
+  free($2);
+
+}
+;
+
+bipccon: TOK_IPCCON TOK_BOOLEAN
+{
+  if($2->boolean == 1)
+    {
+      if(PARSER_DEBUG) printf("IPC allowed\n");
+    }
+  else
+    {
+      if(PARSER_DEBUG) printf("IPC blocked\n");
+    }
+  free($2);
+
+}
+;
+
+
+busehyst: TOK_USEHYST TOK_BOOLEAN
+{
+  if($2->boolean == 1)
+    {
+      if(PARSER_DEBUG) printf("Hysteresis enabled\n");
+    }
+  else
+    {
+      if(PARSER_DEBUG) printf("Hysteresis disabled\n");
+    }
+  free($2);
+
+}
+;
+
+
+fhystscale: TOK_HYSTSCALE TOK_FLOAT
+{
+  cnf->hysteresis_param.scaling = $2->floating;
+  if(PARSER_DEBUG) printf("Hysteresis Scaling: %0.2f\n", $2->floating);
+  free($2);
+}
+;
+
+
+fhystupper: TOK_HYSTUPPER TOK_FLOAT
+{
+  cnf->hysteresis_param.thr_high = $2->floating;
+  if(PARSER_DEBUG) printf("Hysteresis UpperThr: %0.2f\n", $2->floating);
+  free($2);
+}
+;
+
+
+fhystlower: TOK_HYSTLOWER TOK_FLOAT
+{
+  cnf->hysteresis_param.thr_low = $2->floating;
+  if(PARSER_DEBUG) printf("Hysteresis LowerThr: %0.2f\n", $2->floating);
+  free($2);
+}
+;
+
+fpollrate: TOK_POLLRATE TOK_FLOAT
+{
+  if(PARSER_DEBUG) printf("Pollrate %0.2f\n", $2->floating);
+  cnf->pollrate = $2->floating;
+
+  free($2);
+}
+;
+
+
+atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
+{
+  if($2->boolean == 1)
+    {
+      if(PARSER_DEBUG) printf("TC redundancy AUTO\n");
+    }
+  else
+    {
+      if(PARSER_DEBUG) printf("TC redundancy %d\n", $2->integer);
+      cnf->tc_redundancy = $2->integer;
+    }
+  free($2);
+
+}
+;
+
+amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
+{
+  if($2->boolean == 1)
+    {
+      if(PARSER_DEBUG) printf("MPR coverage AUTO\n");
+    }
+  else
+    {
+      if(PARSER_DEBUG) printf("MPR coverage %d\n", $2->integer);
+      cnf->mpr_coverage = $2->integer;
+    }
+  free($2);
+}
+;
+
+
+plname: TOK_PLNAME TOK_STRING
+{
+  struct plugin_entry *pe = malloc(sizeof(struct plugin_entry));
+  
+  if(pe == NULL)
+    {
+      fprintf(stderr, "Out of memory(ADD PL)\n");
+      YYABORT;
+    }
+
+  pe->name = $2->string;
+  
+  if(PARSER_DEBUG) printf("Plugin: %s\n", $2->string);
+
+  /* Queue */
+  pe->next = cnf->plugins;
+  cnf->plugins = pe;
+
+  free($2);
+}
+;
+
+plparam: TOK_PLPARAM TOK_STRING TOK_STRING
+{
+
+    if(PARSER_DEBUG) printf("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
+
+    free($2->string);
+    free($2);
+    free($3->string);
+    free($3);
+}
+;
+
+vcomment:       TOK_COMMENT
+{
+    //if(PARSER_DEBUG) printf("Comment\n");
+}
+;
+
+
+
+%%
+
+void yyerror (char *string)
+{
+  fprintf(stderr, "Config line %d: %s\n", current_line, string);
+}
diff --git a/src/cfgparser/oscan.lex b/src/cfgparser/oscan.lex
new file mode 100644 (file)
index 0000000..625e676
--- /dev/null
@@ -0,0 +1,411 @@
+%{
+#define YYSTYPE struct conf_token *
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+#include "olsrd_conf.h"
+
+#include "oparse.h"
+
+
+
+struct conf_token *
+get_conf_token()
+{
+  struct conf_token *t = malloc(sizeof(struct conf_token));
+
+  if (t == NULL)
+    {
+      fprintf(stderr, "Cannot allocate %d bytes for an configuration token.\n",
+             sizeof (struct conf_token));
+      exit(EXIT_FAILURE);
+    }
+
+  memset(t, 0, sizeof(struct conf_token));
+
+  return t;
+}
+
+
+
+struct if_config_options *
+get_default_if_config()
+{
+  struct if_config_options *io = malloc(sizeof(struct if_config_options));
+  struct in6_addr in6;
+  memset(io, 0, sizeof(struct if_config_options));
+
+  io->ipv6_addrtype = 1;
+
+  if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6) < 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_SITE_LOCAL);
+      exit(EXIT_FAILURE);
+    }
+  memcpy(&io->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
+
+  if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6) < 0)
+    {
+      fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_GLOBAL);
+      exit(EXIT_FAILURE);
+    }
+  memcpy(&io->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
+
+
+  io->hello_params.emission_interval = HELLO_INTERVAL;
+  io->hello_params.validity_time = NEIGHB_HOLD_TIME;
+  io->tc_params.emission_interval = TC_INTERVAL;
+  io->tc_params.validity_time = TOP_HOLD_TIME;
+  io->mid_params.emission_interval = MID_INTERVAL;
+  io->mid_params.validity_time = MID_HOLD_TIME;
+  io->hna_params.emission_interval = HNA_INTERVAL;
+  io->hna_params.validity_time = HNA_HOLD_TIME;
+
+  return io;
+
+}
+
+
+%}
+
+%option noyywrap
+
+DECDIGIT [0-9]
+FLOAT {DECDIGIT}+\.{DECDIGIT}+
+HEXDIGIT [a-f][A-F][0-9]
+
+IPV4ADDR ({DECDIGIT}){1,3}\.({DECDIGIT}){1,3}\.({DECDIGIT}){1,3}\.({DECDIGIT}){1,3}
+
+HEXBYTE ([a-f]|[A-F]|[0-9]){1,4}
+
+IP6PAT1 ({HEXBYTE}:){7}{HEXBYTE}
+IP6PAT2 {HEXBYTE}::({HEXBYTE}:){0,5}{HEXBYTE}
+IP6PAT3 ({HEXBYTE}:){2}:({HEXBYTE}:){0,4}{HEXBYTE}
+IP6PAT4 ({HEXBYTE}:){3}:({HEXBYTE}:){0,3}{HEXBYTE}
+IP6PAT5 ({HEXBYTE}:){4}:({HEXBYTE}:){0,2}{HEXBYTE}
+IP6PAT6 ({HEXBYTE}:){5}:({HEXBYTE}:){0,1}{HEXBYTE}
+IP6PAT7 ({HEXBYTE}:){6}:{HEXBYTE}
+IP6PAT8 ({HEXBYTE}:){1,7}:
+IP6PAT9 ::
+
+IPV6ADDR {IP6PAT1}|{IP6PAT2}|{IP6PAT3}|{IP6PAT4}|{IP6PAT5}|{IP6PAT6}|{IP6PAT7}|{IP6PAT8}|{IP6PAT9}
+
+
+%%
+
+\s*"#".*\n {
+
+  current_line++;
+  return TOK_COMMENT;
+}
+
+\{ {
+  yylval = NULL;
+  return TOK_OPEN;
+}
+
+\} {
+  yylval = NULL;
+  return TOK_CLOSE;
+}
+
+\; {
+  yylval = NULL;
+  return TOK_SEMI;
+}
+
+\"[^\"]*\" {
+  yylval = get_conf_token();
+
+  yylval->string = malloc(yyleng - 1);
+
+  if (yylval->string == NULL)
+  {
+    fprintf(stderr,
+            "Cannot allocate %d bytes for string token data.\n", yyleng - 1);
+    yyterminate();
+  }
+
+  strncpy(yylval->string, yytext + 1, yyleng - 2);
+  yylval->string[yyleng - 2] = 0;
+
+  return TOK_STRING;
+}
+
+0x{HEXDIGIT}+ {
+  yylval = get_conf_token();
+
+  yylval->integer = strtol(yytext, NULL, 0);
+
+  return TOK_INTEGER;
+}
+
+{FLOAT} {
+  yylval = get_conf_token();
+
+  sscanf(yytext, "%f", &yylval->floating);
+  return TOK_FLOAT;
+}
+
+{IPV4ADDR} {
+  yylval = get_conf_token();
+  
+  yylval->string = malloc(yyleng + 1);
+  
+  if (yylval->string == NULL)
+    {
+      fprintf(stderr,
+             "Cannot allocate %d bytes for string token data.\n", yyleng + 1);
+      yyterminate();
+    }
+  
+  strncpy(yylval->string, yytext, yyleng+1);
+
+  return TOK_IP4_ADDR;
+}
+
+
+
+{IPV6ADDR} {
+
+  yylval = get_conf_token();
+  
+  yylval->string = malloc(yyleng+1);
+  
+  if (yylval->string == NULL)
+    {
+      fprintf(stderr,
+             "Cannot allocate %d bytes for string token data.\n", yyleng + 1);
+      yyterminate();
+    }
+  
+  strncpy(yylval->string, yytext, yyleng+1);
+  
+  return TOK_IP6_ADDR;
+}
+
+
+"auto"|{DECDIGIT}+ {
+
+  yylval = get_conf_token();
+
+  if (strncmp(yytext, "auto", 4) == 0)
+    {
+      yylval->boolean = 1;
+    }
+  else
+    {
+      yylval->boolean = 0;
+      yylval->integer = atoi(yytext);
+    }
+
+  return TOK_INTEGER;
+
+}
+
+
+"yes"|"no" {
+  yylval = get_conf_token();
+
+  if (strncmp(yytext, "yes", 3) == 0)
+    yylval->boolean = 1;
+
+  else
+    yylval->boolean = 0;
+
+  return TOK_BOOLEAN;
+}
+
+
+
+"site-local"|"global" {
+  yylval = get_conf_token();
+
+  if (strncmp(yytext, "site-local", 10) == 0)
+    yylval->boolean = 1;
+
+  else
+    yylval->boolean = 0;
+
+  return TOK_IP6TYPE;
+}
+
+
+"DebugLevel" {
+  yylval = NULL;
+  return TOK_DEBUGLEVEL;
+}
+
+"IpVersion" {
+  yylval = NULL;
+  return TOK_IPVERSION;
+}
+
+"Hna4" {
+  yylval = NULL;
+  return TOK_HNA4;
+}
+
+"Hna6" {
+  yylval = NULL;
+  return TOK_HNA6;
+}
+
+"LoadPlugin" {
+  yylval = NULL;
+  return TOK_PLUGIN;
+}
+
+"PlName" {
+  yylval = NULL;
+  return TOK_PLNAME;
+}
+
+"PlParam" {
+  yylval = NULL;
+  return TOK_PLPARAM;
+}
+
+"Interfaces" {
+  yylval = NULL;
+  return TOK_INTERFACES;
+}
+
+"AllowNoInt" {
+  yylval = NULL;
+  return TOK_NOINT;
+}
+
+"TosValue" {
+  yylval = NULL;
+  return TOK_TOS;
+}
+
+"Willingness" {
+  yylval = NULL;
+  return TOK_WILLINGNESS;
+}
+
+"IpcConnect" {
+  yylval = NULL;
+  return TOK_IPCCON;
+}
+
+"UseHysteresis" {
+  yylval = NULL;
+  return TOK_USEHYST;
+}
+
+"HystScaling" {
+  yylval = NULL;
+  return TOK_HYSTSCALE;
+}
+
+"HystThrHigh" {
+  yylval = NULL;
+  return TOK_HYSTUPPER;
+}
+
+"HystThrLow" {
+  yylval = NULL;
+  return TOK_HYSTLOWER;
+}
+
+"Pollrate" {
+  yylval = NULL;
+  return TOK_POLLRATE;
+}
+
+
+"TcRedundancy" {
+  yylval = NULL;
+  return TOK_TCREDUNDANCY;
+}
+
+"MprCoverage" {
+  yylval = NULL;
+  return TOK_MPRCOVERAGE;
+}
+
+
+"IfSetup" {
+  yylval = NULL;
+  return TOK_IFSETUP;
+}
+
+
+"Ip4Broadcast" {
+  yylval = NULL;
+  return TOK_IP4BROADCAST;
+}
+"Ip6AddrType" {
+  yylval = NULL;
+  return TOK_IP6ADDRTYPE;
+}
+"Ip6MulticastSite" {
+  yylval = NULL;
+  return TOK_IP6MULTISITE;
+}
+"Ip6MulticastGlobal" {
+  yylval = NULL;
+  return TOK_IP6MULTIGLOBAL;
+}
+"HelloInterval" {
+  yylval = NULL;
+  return TOK_HELLOINT;
+}
+"HelloValidityTime" {
+  yylval = NULL;
+  return TOK_HELLOVAL;
+}
+"TcInterval" {
+  yylval = NULL;
+  return TOK_TCINT;
+}
+"TcValidityTime" {
+  yylval = NULL;
+  return TOK_TCVAL;
+}
+"MidInterval" {
+  yylval = NULL;
+  return TOK_MIDINT;
+}
+"MidValidityTime" {
+  yylval = NULL;
+  return TOK_MIDVAL;
+}
+"HnaInterval" {
+  yylval = NULL;
+  return TOK_HNAINT;
+}
+"HnaValidityTime" {
+  yylval = NULL;
+  return TOK_HNAVAL;
+}
+
+
+
+\n|\r\n {
+  current_line++;
+}
+
+\ |\t
+
+. {
+  /* Do nothing */
+  //fprintf(stderr, "Failed to parse line %d of configuration file.\n",
+  //      current_line);
+  //yyterminate();
+  //yy_fatal_error("Parsing failed.\n");
+
+  /* To avoid compiler warning (stupid...) */
+  if(0)
+    yyunput(0, NULL);
+}
+
+%%