Update to new avl/list iteration macros
[olsrd.git] / src / olsr.c
index 44883bf..a7b2f58 100644 (file)
@@ -1,6 +1,7 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas Tonnesen(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
 #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 "olsr_spf.h"
 #include "scheduler.h"
-#include "apm.h"
-#include "misc.h"
 #include "neighbor_table.h"
-#include "log.h"
 #include "lq_packet.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 <errno.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;
-
-/* initialize it with all zeroes */
-const union olsr_ip_addr all_zero = { .v6 = IN6ADDR_ANY_INIT };
+static uint16_t message_seqno;
 
 /**
  *Initialize the message sequence number as a random value
@@ -98,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);
 }
 
 /**
@@ -105,7 +102,7 @@ init_msg_seqno(void)
  *
  *@return the seqno
  */
-olsr_u16_t
+uint16_t
 get_msg_seqno(void)
 {
   return message_seqno++;
@@ -113,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");
 
@@ -140,93 +137,61 @@ 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_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 &&
-     2 <= olsr_cnf->lq_level &&
-     0 >= olsr_cnf->lq_dlimit)
+  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();
+    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.
  */
-void
-olsr_trigger_forced_update(void *unused __attribute__((unused))) {
+static void
+olsr_trigger_forced_update(void *unused __attribute__ ((unused)))
+{
 
-  changes_force = OLSR_TRUE;
-  changes_neighborhood = OLSR_TRUE;
-  changes_topology = OLSR_TRUE;
-  changes_hna = OLSR_TRUE;
+  changes_force = true;
+  changes_neighborhood = true;
+  changes_topology = true;
+  changes_hna = true;
 
   olsr_process_changes();
 }
@@ -240,23 +205,11 @@ void
 olsr_init_tables(void)
 {
   /* Some cookies for stats keeping */
-  static struct olsr_cookie_info *periodic_spf_timer_cookie = NULL;
-
-  changes_topology = OLSR_FALSE;
-  changes_neighborhood = OLSR_FALSE;
-  changes_hna = OLSR_FALSE;
-
-  /* Set avl tree comparator */
-  if (olsr_cnf->ipsize == 4) {
-    avl_comp_default = avl_comp_ipv4;
-    avl_comp_prefix_default = avl_comp_ipv4_prefix;
-  } else {
-    avl_comp_default = avl_comp_ipv6;
-    avl_comp_prefix_default = avl_comp_ipv6_prefix;
-  }
+  static struct olsr_timer_info *periodic_spf_timer_info = NULL;
 
-  /* Initialize lq plugin set */
-  init_lq_handler_tree();
+  changes_topology = false;
+  changes_neighborhood = false;
+  changes_hna = false;
 
   /* Initialize link set */
   olsr_init_link_set();
@@ -270,9 +223,6 @@ olsr_init_tables(void)
   /* Initialize routing table */
   olsr_init_routing_table();
 
-  /* Initialize two hop table */
-  olsr_init_two_hop_table();
-
   /* Initialize topology */
   olsr_init_tc();
 
@@ -282,238 +232,163 @@ olsr_init_tables(void)
   /* Initialize HNA set */
   olsr_init_hna_set();
 
-  /* Initialize MPRS */
-  olsr_init_mprs();
-
-#if 0
-  /* Initialize Layer 1/2 database */
-  olsr_initialize_layer12();
-#endif
-
   /* Start periodic SPF and RIB recalculation */
-  if (olsr_cnf->lq_dinter > 0.0) {
-    periodic_spf_timer_cookie = olsr_alloc_cookie("Periodic SPF",
-                                                  OLSR_COOKIE_TYPE_TIMER);
-    olsr_start_timer((unsigned int)(olsr_cnf->lq_dinter * MSEC_PER_SEC), 5,
-                     OLSR_TIMER_PERIODIC, &olsr_trigger_forced_update, NULL,
-                     periodic_spf_timer_cookie->ci_id);
+  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 (m->v4.ttl < 2 || 255 < (int)m->v4.hopcnt + (int)m->v4.ttl) return 0;
-  }
-  else
-  {
-    if (m->v6.ttl < 2|| 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 = olsr_lookup_main_addr_by_alias(from_addr);
-  if(!src)
+  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
-      struct ipaddr_str buf;
-      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;
+  }
 
   /* check if we already forwarded this message */
-  if (AF_INET == olsr_cnf->ip_version)
-  {
-    if (olsr_message_is_duplicate(from_addr, m->v4.seqno, true)) {
-      return 0; /* it's a duplicate, forget about it */
-    }
-  }
-  else {
-    if (olsr_message_is_duplicate(from_addr, m->v6.seqno, true)) {
-      return 0; /* it's a duplicate, forget about it */
-    }
+  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 */
   }
 
   /* 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--;
-    }
-
-  /* Update packet data */
-  msgsize = ntohs(m->v4.olsr_msgsize);
+  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;
 }
 
-/**
- * Wrapper for the timer callback.
- */
 static void
-olsr_expire_buffer_timer(void *context)
+olsr_update_willingness(void *foo __attribute__ ((unused)))
 {
-  struct interface *ifn;
-
-  ifn = (struct interface *)context;
-
-  /*
-   * Clear the pointer to indicate that this timer has
-   * been expired and needs to be restarted in case there
-   * will be another message queued in the future.
-   */
-  ifn->buffer_hold_timer = NULL;
-
-#ifdef DEBUG
-  OLSR_PRINTF(1, "Buffer Holdtimer for %s timed out\n", ifn->int_name);
-#endif
-
-  /*
-   * Do we have something to emit ?
-   */
-  if (!net_output_pending(ifn)) {
-    return;
-  }
-
-  net_output(ifn);
-}
+  int tmp_will = olsr_cnf->willingness;
 
-/*
- * set_buffer_timer
- *
- * Kick a hold-down timer which defers building of a message.
- * This has the desired effect that olsr messages get bigger.
- */
-void
-set_buffer_timer(struct interface *ifn)
-{
+  /* Re-calculate willingness */
+  olsr_calculate_willingness();
 
-  /*
-   * Bail if there is already a timer running.
-   */
-  if (ifn->buffer_hold_timer) {
-    return;
+  if (tmp_will != olsr_cnf->willingness) {
+    OLSR_INFO(LOG_MAIN, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness);
   }
-
-  /*
-   * This is the first message since the last time this interface has
-   * been drained. Flush the buffer in second or so.
-   */
-  ifn->buffer_hold_timer =
-    olsr_start_timer(OLSR_BUFFER_HOLD_TIME, OLSR_BUFFER_HOLD_JITTER,
-                     OLSR_TIMER_ONESHOT, &olsr_expire_buffer_timer, ifn,
-                     buffer_hold_timer_cookie->ci_id);
 }
 
 void
 olsr_init_willingness(void)
 {
   /* Some cookies for stats keeping */
-  static struct olsr_cookie_info *willingness_timer_cookie = NULL;
+  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);
 
-    willingness_timer_cookie = olsr_alloc_cookie("Update Willingness",
-                                                 OLSR_COOKIE_TYPE_TIMER);
-    olsr_start_timer((unsigned int)olsr_cnf->will_int * MSEC_PER_SEC, 5,
-                     OLSR_TIMER_PERIODIC, &olsr_update_willingness, NULL,
-                     willingness_timer_cookie->ci_id);
+    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
@@ -522,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 (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;
@@ -578,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;
@@ -604,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;
@@ -629,16 +508,17 @@ 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;
+  if (app_state == STATE_INIT) {
+    os_exit(val);
+  }
   app_state = STATE_SHUTDOWN;
 }
 
@@ -653,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;
 
@@ -664,43 +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);
   }
-
-#if 0
-  /* useful for debugging */
-  olsr_printf(1, "MEMORY: alloc %s %p, %u bytes\n",
-              id, ptr, size);
-#endif
-
   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:
  */