Update to new avl/list iteration macros
[olsrd.git] / src / olsr.c
index da29b90..a7b2f58 100644 (file)
@@ -1,33 +1,34 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
  * are met:
  *
- * * Redistributions of source code must retain the above copyright 
+ * * Redistributions of source code must retain the above copyright
  *   notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright 
- *   notice, this list of conditions and the following disclaimer in 
- *   the documentation and/or other materials provided with the 
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
  *   distribution.
- * * Neither the name of olsr.org, olsrd nor the names of its 
- *   contributors may be used to endorse or promote products derived 
+ * * Neither the name of olsr.org, olsrd nor the names of its
+ *   contributors may be used to endorse or promote products derived
  *   from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
  * Visit http://www.olsr.org for more information.
 #include "defs.h"
 #include "olsr.h"
 #include "link_set.h"
-#include "two_hop_neighbor_table.h"
 #include "tc_set.h"
 #include "duplicate_set.h"
-#include "mpr_selector_set.h"
 #include "mid_set.h"
-#include "mpr.h"
 #include "lq_mpr.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "scheduler.h"
-#include "apm.h"
-#include "misc.h"
 #include "neighbor_table.h"
-#include "log.h"
 #include "lq_packet.h"
-#include "lq_avl.h"
+#include "common/avl.h"
 #include "net_olsr.h"
+#include "lq_plugin.h"
+#include "olsr_logging.h"
+#include "os_system.h"
+#include "os_apm.h"
 
+#include <assert.h>
 #include <stdarg.h>
-#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
 
+static void olsr_update_willingness(void *);
+static void olsr_trigger_forced_update(void *);
 
-olsr_bool changes_topology;
-olsr_bool changes_neighborhood;
-olsr_bool changes_hna;
-olsr_bool changes_force;
+bool changes_topology;
+bool changes_neighborhood;
+bool changes_hna;
+bool changes_force;
 
 /**
  * Process changes functions
  */
 
-struct pcf
-{
-  int (*function)(int, int, int);
+struct pcf {
+  int (*function) (int, int, int);
   struct pcf *next;
 };
 
 static struct pcf *pcf_list;
 
-static olsr_u16_t message_seqno;
+static uint16_t message_seqno;
 
 /**
  *Initialize the message sequence number as a random value
@@ -92,6 +94,7 @@ void
 init_msg_seqno(void)
 {
   message_seqno = random() & 0xFFFF;
+  OLSR_DEBUG(LOG_MAIN, "Settings initial message sequence number to %u\n", message_seqno);
 }
 
 /**
@@ -99,7 +102,7 @@ init_msg_seqno(void)
  *
  *@return the seqno
  */
-olsr_u16_t
+uint16_t
 get_msg_seqno(void)
 {
   return message_seqno++;
@@ -107,11 +110,11 @@ get_msg_seqno(void)
 
 
 void
-register_pcf(int (*f)(int, int, int))
+register_pcf(int (*f) (int, int, int))
 {
   struct pcf *new_pcf;
 
-  OLSR_PRINTF(1, "Registering pcf function\n");
+  OLSR_DEBUG(LOG_MAIN, "Registering pcf function\n");
 
   new_pcf = olsr_malloc(sizeof(struct pcf), "New PCF");
 
@@ -124,7 +127,7 @@ register_pcf(int (*f)(int, int, int))
 
 /**
  *Process changes in neighborhood or/and topology.
- *Re-calculates the neighborhooh/topology if there
+ *Re-calculates the neighborhood/topology if there
  *are any updates - then calls the right functions to
  *update the routing table.
  *@return 0
@@ -134,86 +137,64 @@ olsr_process_changes(void)
 {
   struct pcf *tmp_pc_list;
 
-#ifdef DEBUG
-  if(changes_neighborhood)
-    OLSR_PRINTF(3, "CHANGES IN NEIGHBORHOOD\n");
-  if(changes_topology)
-    OLSR_PRINTF(3, "CHANGES IN TOPOLOGY\n");
-  if(changes_hna)
-    OLSR_PRINTF(3, "CHANGES IN HNA\n");
-#endif
-  
-  if(!changes_force &&
-     2 <= olsr_cnf->lq_level &&
-     0 >= olsr_cnf->lq_dlimit)
+  if (changes_neighborhood)
+    OLSR_DEBUG(LOG_MAIN, "CHANGES IN NEIGHBORHOOD\n");
+  if (changes_topology)
+    OLSR_DEBUG(LOG_MAIN, "CHANGES IN TOPOLOGY\n");
+  if (changes_hna)
+    OLSR_DEBUG(LOG_MAIN, "CHANGES IN HNA\n");
+
+  if (!changes_force && 0 >= olsr_cnf->lq_dlimit)
     return;
-    
-  if(!changes_neighborhood &&
-     !changes_topology &&
-     !changes_hna)
+
+  if (!changes_neighborhood && !changes_topology && !changes_hna)
     return;
 
-  if (olsr_cnf->debug_level > 0 && olsr_cnf->clear_screen && isatty(1))
-  {
-      clear_console();
-      printf("       *** %s (%s on %s) ***\n", olsrd_version, build_date, build_host);
+  if (olsr_cnf->log_target_stderr && olsr_cnf->clear_screen && isatty(STDOUT_FILENO)) {
+    os_clear_console();
+    printf("       *** %s (%s on %s) ***\n", olsrd_version, build_date, build_host);
   }
 
   if (changes_neighborhood) {
-    if (olsr_cnf->lq_level < 1) {
-      olsr_calculate_mpr();
-    } else {
-      olsr_calculate_lq_mpr();
-    }
+    olsr_calculate_lq_mpr();
   }
 
   /* calculate the routing table */
   if (changes_neighborhood || changes_topology || changes_hna) {
-    olsr_calculate_routing_table(NULL);
+    olsr_calculate_routing_table(false);
   }
-  
-  if (olsr_cnf->debug_level > 0)
-    {      
-      if (olsr_cnf->debug_level > 2) 
-        {
-          olsr_print_mid_set();
-         
-          if (olsr_cnf->debug_level > 3)
-            {
-             if (olsr_cnf->debug_level > 8)
-               {
-                 olsr_print_duplicate_table();
-               }
-              olsr_print_hna_set();
-            }
-        }
 
-#if 1     
-      olsr_print_link_set();
-      olsr_print_neighbor_table();
-      olsr_print_two_hop_neighbor_table();
-      olsr_print_tc_table();
-#endif
-    }
+  olsr_print_link_set();
+  olsr_print_neighbor_table();
+  olsr_print_tc_table();
+  olsr_print_mid_set();
+  olsr_print_duplicate_table();
+  olsr_print_hna_set();
 
-  for(tmp_pc_list = pcf_list; 
-      tmp_pc_list != NULL;
-      tmp_pc_list = tmp_pc_list->next)
-    {
-      tmp_pc_list->function(changes_neighborhood,
-                           changes_topology,
-                           changes_hna);
-    }
+  for (tmp_pc_list = pcf_list; tmp_pc_list != NULL; tmp_pc_list = tmp_pc_list->next) {
+    tmp_pc_list->function(changes_neighborhood, changes_topology, changes_hna);
+  }
 
-  changes_neighborhood = OLSR_FALSE;
-  changes_topology = OLSR_FALSE;
-  changes_hna = OLSR_FALSE;
-  changes_force = OLSR_FALSE;
+  changes_neighborhood = false;
+  changes_topology = false;
+  changes_hna = false;
+  changes_force = false;
 }
 
+/*
+ * Callback for the periodic route calculation.
+ */
+static void
+olsr_trigger_forced_update(void *unused __attribute__ ((unused)))
+{
 
+  changes_force = true;
+  changes_neighborhood = true;
+  changes_topology = true;
+  changes_hna = true;
 
-
+  olsr_process_changes();
+}
 
 /**
  *Initialize all the tables used(neighbor,
@@ -222,201 +203,192 @@ olsr_process_changes(void)
  */
 void
 olsr_init_tables(void)
-{  
-  changes_topology = OLSR_FALSE;
-  changes_neighborhood = OLSR_FALSE;
-  changes_hna = OLSR_FALSE;
-
-  /* Set avl tree comparator */
-  if (olsr_cnf->ipsize == 4) {
-    avl_comp_default = NULL;
-    avl_comp_prefix_default = avl_comp_ipv4_prefix;
-  } else {
-    avl_comp_default = avl_comp_ipv6;
-    avl_comp_prefix_default = avl_comp_ipv6_prefix;
-  }
+{
+  /* Some cookies for stats keeping */
+  static struct olsr_timer_info *periodic_spf_timer_info = NULL;
+
+  changes_topology = false;
+  changes_neighborhood = false;
+  changes_hna = false;
 
   /* Initialize link set */
   olsr_init_link_set();
 
+  /* Initialize duplicate table */
+  olsr_init_duplicate_set();
+
   /* Initialize neighbor table */
   olsr_init_neighbor_table();
 
   /* Initialize routing table */
   olsr_init_routing_table();
 
-  /* Initialize two hop table */
-  olsr_init_two_hop_table();
-
   /* Initialize topology */
   olsr_init_tc();
 
-  /* Initialize mpr selector table */
-  olsr_init_mprs_set();
-
   /* Initialize MID set */
   olsr_init_mid_set();
 
   /* Initialize HNA set */
-  olsr_init_hna_set();  
+  olsr_init_hna_set();
 
-  /* Initialize Layer 1/2 database */
-  // olsr_initialize_layer12();
-  
   /* Start periodic SPF and RIB recalculation */
-  if (olsr_cnf->lq_dinter > 0.0) {
-    olsr_start_timer((unsigned int)(olsr_cnf->lq_dinter * MSEC_PER_SEC), 5,
-                     OLSR_TIMER_PERIODIC, &olsr_calculate_routing_table, NULL, 0);
+  if (olsr_cnf->lq_dinter > 0) {
+    periodic_spf_timer_info = olsr_alloc_timerinfo("Periodic SPF", &olsr_trigger_forced_update, true);
+    olsr_start_timer(olsr_cnf->lq_dinter, 5,
+                     NULL, periodic_spf_timer_info);
   }
 }
 
+/**
+ * Shared code to write the message header
+ */
+uint8_t *olsr_put_msg_hdr(uint8_t **curr, struct olsr_message *msg)
+{
+  uint8_t *sizeptr;
+
+  assert(msg);
+  assert(curr);
+
+  pkt_put_u8(curr, msg->type);
+  pkt_put_reltime(curr, msg->vtime);
+  sizeptr = *curr;
+  pkt_put_u16(curr, msg->size);
+  pkt_put_ipaddress(curr, &msg->originator);
+  pkt_put_u8(curr, msg->ttl);
+  pkt_put_u8(curr, msg->hopcnt);
+  pkt_put_u16(curr, msg->seqno);
+
+  return sizeptr;
+}
+
 /**
  *Check if a message is to be forwarded and forward
  *it if necessary.
  *
  *@param m the OLSR message recieved
- *@param originator the originator of this message
- *@param seqno the seqno of the message
  *
  *@returns positive if forwarded
  */
 int
-olsr_forward_message(union olsr_message *m, 
-                    union olsr_ip_addr *from_addr)
+olsr_forward_message(struct olsr_message *msg, uint8_t *binary, struct interface *in_if, union olsr_ip_addr *from_addr)
 {
   union olsr_ip_addr *src;
-  struct neighbor_entry *neighbor;
-  int msgsize;
-  struct interface *ifn;
-
-  /*
-   * Sven-Ola: We should not flood the mesh with overdue messages. Because
-   * of a bug in parser.c:parse_packet, we have a lot of messages because
-   * all older olsrd's have lq_fish enabled.
-   */
-  if (AF_INET == olsr_cnf->ip_version)
-  {
-    if (2 > m->v4.ttl || 255 < (int)m->v4.hopcnt + (int)m->v4.ttl) return 0;
-  }
-  else
-  {
-    if (2 > m->v6.ttl || 255 < (int)m->v6.hopcnt + (int)m->v6.ttl) return 0;
-  }
+  struct nbr_entry *neighbor;
+  struct interface *ifn, *iterator;
+  uint8_t *tmp;
+#if !defined REMOVE_LOG_DEBUG
+  struct ipaddr_str buf;
+#endif
 
   /* Lookup sender address */
-  src = mid_lookup_main_addr(from_addr);
-  if(!src)
+  src = olsr_lookup_main_addr_by_alias(from_addr);
+  if (!src)
     src = from_addr;
 
-  neighbor=olsr_lookup_neighbor_table(src);
-  if(!neighbor)
+  neighbor = olsr_lookup_nbr_entry(src, true);
+  if (!neighbor) {
+    OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d because no nbr entry found for %s\n",
+        msg->type, olsr_ip_to_string(&buf, src));
     return 0;
-
-  if(neighbor->status != SYM)
+  }
+  if (!neighbor->is_sym) {
+    OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d because received by non-symmetric neighbor %s\n",
+        msg->type, olsr_ip_to_string(&buf, src));
     return 0;
+  }
 
   /* Check MPR */
-  if(olsr_lookup_mprs_set(src) == NULL)
-    {
-#ifdef DEBUG
-#ifndef NODEBUG
-      struct ipaddr_str buf;
-#endif
-      OLSR_PRINTF(5, "Forward - sender %s not MPR selector\n", olsr_ip_to_string(&buf, src));
-#endif
-      return 0;
-    }
+  if (neighbor->mprs_count == 0) {
+    OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d because we are no MPR for %s\n",
+        msg->type, olsr_ip_to_string(&buf, src));
+    /* don't forward packages if not a MPR */
+    return 0;
+  }
 
-  /* Treat TTL hopcnt */
-  if(olsr_cnf->ip_version == AF_INET)
-    {
-      /* IPv4 */
-      m->v4.hopcnt++;
-      m->v4.ttl--; 
-    }
-  else
-    {
-      /* IPv6 */
-      m->v6.hopcnt++;
-      m->v6.ttl--; 
-    }
+  /* check if we already forwarded this message */
+  if (olsr_is_duplicate_message(msg, true, NULL)) {
+    OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d from %s because we already forwarded it.\n",
+        msg->type, olsr_ip_to_string(&buf, src));
+    return 0;                   /* it's a duplicate, forget about it */
+  }
 
-  /* Update packet data */
-  msgsize = ntohs(m->v4.olsr_msgsize);
+  /* Treat TTL hopcnt */
+  msg->hopcnt++;
+  msg->ttl--;
+  tmp = binary;
+  olsr_put_msg_hdr(&tmp, msg);
+
+  if (msg->ttl == 0) {
+    OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d from %s because TTL is 0.\n",
+        msg->type, olsr_ip_to_string(&buf, src));
+    return 0;                   /* TTL 0, forget about it */
+  }
+  OLSR_DEBUG(LOG_PACKET_PARSING, "Forwarding message type %d from %s.\n",
+      msg->type, olsr_ip_to_string(&buf, src));
 
   /* looping trough interfaces */
-  for (ifn = ifnet; ifn ; ifn = ifn->int_next) 
-    { 
-      if(net_output_pending(ifn))
-       {
-         /*
-          * Check if message is to big to be piggybacked
-          */
-         if(net_outbuffer_push(ifn, m, msgsize) != msgsize)
-           {
-             /* Send */
-             net_output(ifn);
-             /* Buffer message */
-             set_buffer_timer(ifn);
-             
-             if(net_outbuffer_push(ifn, m, msgsize) != msgsize)
-               {
-                 OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
-                 olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
-               }
-           }
-       }
-      else
-       {
-         /* No forwarding pending */
-         set_buffer_timer(ifn);
-         
-         if(net_outbuffer_push(ifn, m, msgsize) != msgsize)
-           {
-             OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
-             olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
-           }
-       }
+  OLSR_FOR_ALL_INTERFACES(ifn, iterator) {
+    if (net_output_pending(ifn)) {
+      /* dont forward to incoming interface if interface is mode ether */
+      if (in_if->mode == IF_MODE_ETHER && ifn == in_if)
+        continue;
+
+      /*
+       * Check if message is to big to be piggybacked
+       */
+      if (net_outbuffer_push(ifn, binary, msg->size) != msg->size) {
+        /* Send */
+        net_output(ifn);
+        /* Buffer message */
+        set_buffer_timer(ifn);
+
+        if (net_outbuffer_push(ifn, binary, msg->size) != msg->size) {
+          OLSR_WARN(LOG_NETWORKING, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msg->size);
+        }
+      }
+    } else {
+      /* No forwarding pending */
+      set_buffer_timer(ifn);
+
+      if (net_outbuffer_push(ifn, binary, msg->size) != msg->size) {
+        OLSR_WARN(LOG_NETWORKING, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msg->size);
+      }
     }
+  }
+
   return 1;
 }
 
+static void
+olsr_update_willingness(void *foo __attribute__ ((unused)))
+{
+  int tmp_will = olsr_cnf->willingness;
 
-void
-set_buffer_timer(struct interface *ifn)
-{      
-  /* Set timer */
-  ifn->fwdtimer = GET_TIMESTAMP(random() * olsr_cnf->max_jitter * 1000 / RAND_MAX);
+  /* Re-calculate willingness */
+  olsr_calculate_willingness();
+
+  if (tmp_will != olsr_cnf->willingness) {
+    OLSR_INFO(LOG_MAIN, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness);
+  }
 }
 
 void
 olsr_init_willingness(void)
 {
-  if (olsr_cnf->willingness_auto) {
+  /* Some cookies for stats keeping */
+  static struct olsr_timer_info *willingness_timer_info = NULL;
 
+  if (olsr_cnf->willingness_auto) {
+    OLSR_INFO(LOG_MAIN, "Initialize automatic willingness...\n");
     /* Run it first and then periodic. */
     olsr_update_willingness(NULL);
 
-    olsr_start_timer((unsigned int)olsr_cnf->will_int * MSEC_PER_SEC, 5,
-                     OLSR_TIMER_PERIODIC, &olsr_update_willingness, NULL, 0);
+    willingness_timer_info = olsr_alloc_timerinfo("Update Willingness", &olsr_update_willingness, true);
+    olsr_start_timer(olsr_cnf->will_int, 5, NULL, willingness_timer_info);
   }
 }
 
-void
-olsr_update_willingness(void *foo __attribute__((unused)))
-{
-  int tmp_will = olsr_cnf->willingness;
-
-  /* Re-calculate willingness */
-  olsr_cnf->willingness = olsr_calculate_willingness();
-
-  if(tmp_will != olsr_cnf->willingness)
-    {
-      OLSR_PRINTF(1, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness);
-    }
-}
-
-
 /**
  *Calculate this nodes willingness to act as a MPR
  *based on either a fixed value or the power status
@@ -425,55 +397,63 @@ olsr_update_willingness(void *foo __attribute__((unused)))
  *@return a 8bit value from 0-7 representing the willingness
  */
 
-olsr_u8_t
+void
 olsr_calculate_willingness(void)
 {
   struct olsr_apm_info ainfo;
+  struct millitxt_buf tbuf;
 
   /* If fixed willingness */
-  if(!olsr_cnf->willingness_auto)
-    return olsr_cnf->willingness;
+  if (!olsr_cnf->willingness_auto)
+    return;
 
-  if(apm_read(&ainfo) < 1)
-    return WILL_DEFAULT;
+  if (os_apm_read(&ainfo) < 1) {
+    olsr_cnf->willingness = WILL_DEFAULT;
+    olsr_cnf->willingness_auto = false;
+    OLSR_WARN(LOG_MAIN, "Cannot read APM info, setting willingness to default value (%d)", olsr_cnf->willingness);
+    return;
+  }
 
-  apm_printinfo(&ainfo);
+  os_apm_printinfo(&ainfo);
 
   /* If AC powered */
-  if(ainfo.ac_line_status == OLSR_AC_POWERED)
-    return 6;
-
-  /* If battery powered 
+  if (ainfo.ac_line_status == OLSR_AC_POWERED) {
+    olsr_cnf->willingness = 6;
+  }
+  else {
+  /* If battery powered
    *
    * juice > 78% will: 3
    * 78% > juice > 26% will: 2
    * 26% > juice will: 1
    */
-  return (ainfo.battery_percentage / 26);
+    olsr_cnf->willingness = (ainfo.battery_percentage / 26);
+  }
+  OLSR_INFO(LOG_MAIN, "Willingness set to %d - next update in %s secs\n",
+      olsr_cnf->willingness, olsr_milli_to_txt(&tbuf, olsr_cnf->will_int));
 }
 
 const char *
-olsr_msgtype_to_string(olsr_u8_t msgtype)
+olsr_msgtype_to_string(uint8_t msgtype)
 {
   static char type[20];
 
-  switch(msgtype)
-    {
-    case(HELLO_MESSAGE):
-      return "HELLO";
-    case(TC_MESSAGE):
-      return "TC";
-    case(MID_MESSAGE):
-      return "MID";
-    case(HNA_MESSAGE):
-      return "HNA";
-    case(LQ_HELLO_MESSAGE):
-      return("LQ-HELLO");
-    case(LQ_TC_MESSAGE):
-      return("LQ-TC");
-    default:
-      break;
-    }
+  switch (msgtype) {
+  case (HELLO_MESSAGE):
+    return "HELLO";
+  case (TC_MESSAGE):
+    return "TC";
+  case (MID_MESSAGE):
+    return "MID";
+  case (HNA_MESSAGE):
+    return "HNA";
+  case (LQ_HELLO_MESSAGE):
+    return ("LQ-HELLO");
+  case (LQ_TC_MESSAGE):
+    return ("LQ-TC");
+  default:
+    break;
+  }
 
   snprintf(type, sizeof(type), "UNKNOWN(%d)", msgtype);
   return type;
@@ -481,25 +461,22 @@ olsr_msgtype_to_string(olsr_u8_t msgtype)
 
 
 const char *
-olsr_link_to_string(olsr_u8_t linktype)
+olsr_link_to_string(uint8_t linktype)
 {
   static char type[20];
 
-  switch(linktype)
-    {
-    case(UNSPEC_LINK):
-      return "UNSPEC";
-    case(ASYM_LINK):
-      return "ASYM";
-    case(SYM_LINK):
-      return "SYM";
-    case(LOST_LINK):
-      return "LOST";
-    case(HIDE_LINK):
-      return "HIDE";
-    default:
-      break;
-    }
+  switch (linktype) {
+  case (UNSPEC_LINK):
+    return "UNSPEC";
+  case (ASYM_LINK):
+    return "ASYM";
+  case (SYM_LINK):
+    return "SYM";
+  case (LOST_LINK):
+    return "LOST";
+  default:
+    break;
+  }
 
   snprintf(type, sizeof(type), "UNKNOWN(%d)", linktype);
   return type;
@@ -507,21 +484,20 @@ olsr_link_to_string(olsr_u8_t linktype)
 
 
 const char *
-olsr_status_to_string(olsr_u8_t status)
+olsr_status_to_string(uint8_t status)
 {
   static char type[20];
 
-  switch(status)
-    {
-    case(NOT_NEIGH):
-      return "NOT NEIGH";
-    case(SYM_NEIGH):
-      return "NEIGHBOR";
-    case(MPR_NEIGH):
-      return "MPR";
-    default:
-      break;
-    }
+  switch (status) {
+  case (NOT_NEIGH):
+    return "NOT NEIGH";
+  case (SYM_NEIGH):
+    return "NEIGHBOR";
+  case (MPR_NEIGH):
+    return "MPR";
+  default:
+    break;
+  }
 
   snprintf(type, sizeof(type), "UNKNOWN(%d)", status);
   return type;
@@ -532,18 +508,18 @@ olsr_status_to_string(olsr_u8_t status)
  *Termination function to be called whenever a error occures
  *that requires the daemon to terminate
  *
- *@param msg the message to write to the syslog and possibly stdout
+ *@param val the exit code for OLSR
  */
 
 void
-olsr_exit(const char *msg, int val)
+olsr_exit(int val)
 {
-  OLSR_PRINTF(1, "OLSR EXIT: %s\n", msg);
-  olsr_syslog(OLSR_LOG_ERR, "olsrd exit: %s\n", msg);
   fflush(stdout);
   olsr_cnf->exit_value = val;
-
-  raise(SIGTERM);
+  if (app_state == STATE_INIT) {
+    os_exit(val);
+  }
+  app_state = STATE_SHUTDOWN;
 }
 
 
@@ -557,7 +533,7 @@ olsr_exit(const char *msg, int val)
  * @return a void pointer to the memory allocated
  */
 void *
-olsr_malloc(size_t size, const char *id)
+olsr_malloc(size_t size, const char *id __attribute__ ((unused)))
 {
   void *ptr;
 
@@ -568,37 +544,39 @@ olsr_malloc(size_t size, const char *id)
   ptr = calloc(1, size);
 
   if (!ptr) {
-      const char * const err_msg = strerror(errno);
-      OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", err_msg);
-      olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %s\n", err_msg);
-      olsr_exit(id, EXIT_FAILURE);
+    OLSR_ERROR(LOG_MAIN, "Out of memory for id '%s': %s\n", id, strerror(errno));
+    olsr_exit(EXIT_FAILURE);
   }
-
   return ptr;
 }
 
-
-/**
- *Wrapper for printf that prints to a specific
- *debuglevel upper limit
- *
+/*
+ * Same as strdup but works with olsr_malloc
  */
+char *
+olsr_strdup(const char *s)
+{
+  char *ret = olsr_malloc(1 + strlen(s), "olsr_strdup");
+  strcpy(ret, s);
+  return ret;
+}
 
-int
-olsr_printf(int loglevel, const char *format, ...)
+/*
+ * Same as strndup but works with olsr_malloc
+ */
+char *
+olsr_strndup(const char *s, size_t n)
 {
-  if((loglevel <= olsr_cnf->debug_level) && debug_handle)
-    {
-      va_list arglist;
-      va_start(arglist, format);
-      vfprintf(debug_handle, format, arglist);
-      va_end(arglist);
-    }
-  return 0;
+  size_t len = n < strlen(s) ? n : strlen(s);
+  char *ret = olsr_malloc(1 + len, "olsr_strndup");
+  strncpy(ret, s, len);
+  ret[len] = 0;
+  return ret;
 }
 
 /*
  * Local Variables:
  * c-basic-offset: 2
+ * indent-tabs-mode: nil
  * End:
  */