Port all olsrd 0.6.0 OS specific files and adapt them to the new interface.
authorHenning Rogge <hrogge@googlemail.com>
Thu, 7 Oct 2010 18:03:24 +0000 (20:03 +0200)
committerHenning Rogge <hrogge@googlemail.com>
Thu, 7 Oct 2010 18:03:24 +0000 (20:03 +0200)
(win32 is still missing)

24 files changed:
lib/arprefresh/src/olsrd_arprefresh.c
src/bsd/apm.c
src/bsd/bsd_net.h [new file with mode: 0644]
src/bsd/dummy.c [new file with mode: 0644]
src/bsd/kernel_routes.c
src/bsd/net.c
src/interfaces.c
src/interfaces.h
src/linux/apm.c
src/linux/kernel_routes.c
src/linux/kernel_tunnel.c [new file with mode: 0644]
src/linux/linux_net.h [new file with mode: 0644]
src/linux/net.c
src/main.c
src/olsr.c
src/olsr_cfg_data.c
src/olsr_cfg_data.h
src/os_kernel_tunnel.h [new file with mode: 0644]
src/os_log.h
src/os_misc.h [deleted file]
src/os_net.h
src/unix/ifnet.c
src/unix/log.c
src/unix/misc.c [deleted file]

index 2fbd984..af74256 100644 (file)
@@ -63,7 +63,7 @@
 
 #include "olsrd_arprefresh.h"
 #include "scheduler.h"
-#include "os_misc.h"
+#include "os_net.h"
 #include "olsr_logging.h"
 #include "olsr_cfg.h"
 
index fc6e867..059176b 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
+ * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/bsd/bsd_net.h b/src/bsd/bsd_net.h
new file mode 100644 (file)
index 0000000..d0b0247
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * bsd_net.h
+ *
+ *  Created on: Oct 7, 2010
+ *      Author: rogge
+ */
+
+#ifndef BSD_NET_H_
+#define BSD_NET_H_
+
+int join_mcast(struct interface *, int);
+
+#endif /* BSD_NET_H_ */
diff --git a/src/bsd/dummy.c b/src/bsd/dummy.c
new file mode 100644 (file)
index 0000000..1d8f1ae
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * dummy.c
+ *
+ *  Created on: 12.02.2010
+ *      Author: henning
+ */
+
+#include "../defs.h"
+#include "../kernel_routes.h"
+#include "../kernel_tunnel.h"
+#include "../net_os.h"
+
+/* prototypes: have them here or disable the warnings about missing prototypes! */
+int olsr_if_setip(const char *dev __attribute__ ((unused)), union olsr_ip_addr *ip __attribute__ ((unused)), int ipversion __attribute__ ((unused))); 
+
+
+
+int olsr_os_init_iptunnel(void) {
+  return -1;
+}
+
+void olsr_os_cleanup_iptunnel(void) {
+}
+
+struct olsr_iptunnel_entry *olsr_os_add_ipip_tunnel(union olsr_ip_addr *target __attribute__ ((unused)),
+    bool transportV4 __attribute__ ((unused))) {
+  return NULL;
+}
+
+void olsr_os_del_ipip_tunnel(struct olsr_iptunnel_entry *t __attribute__ ((unused))) {
+  return;
+}
+
+bool olsr_if_isup(const char * dev __attribute__ ((unused))) {
+  return false;
+}
+
+int olsr_if_setip(const char *dev __attribute__ ((unused)),
+    union olsr_ip_addr *ip __attribute__ ((unused)),
+    int ipversion __attribute__ ((unused))) {
+  return -1;
+}
+
+void olsr_os_niit_4to6_route(const struct olsr_ip_prefix *dst_v4 __attribute__ ((unused)),
+    bool set __attribute__ ((unused))) {
+}
+void olsr_os_niit_6to4_route(const struct olsr_ip_prefix *dst_v6 __attribute__ ((unused)),
+    bool set __attribute__ ((unused))) {
+}
+void olsr_os_inetgw_tunnel_route(uint32_t if_idx __attribute__ ((unused)),
+    bool ipv4 __attribute__ ((unused)),
+    bool set __attribute__ ((unused))) {
+}
+
+int olsr_os_policy_rule(int family __attribute__ ((unused)),
+    int rttable __attribute__ ((unused)),
+    uint32_t priority __attribute__ ((unused)),
+    const char *if_name __attribute__ ((unused)),
+    bool set __attribute__ ((unused))) {
+  return -1;
+}
+
+int olsr_os_localhost_if(union olsr_ip_addr *ip __attribute__ ((unused)),
+    bool create __attribute__ ((unused))) {
+  return -1;
+}
+
+int olsr_os_ifip(int ifindex __attribute__ ((unused)),
+    union olsr_ip_addr *ip __attribute__ ((unused)), bool create __attribute__ ((unused))) {
+  return -1;
+}
index 8977344..f248af6 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
+ * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
 #include "process_routes.h"
 #include "net_olsr.h"
 #include "ipcalc.h"
-#include "olsr_logging.h"
 
 #include <errno.h>
 #include <unistd.h>
 #define OLSR_PID getpid ()
 #endif
 
-/**
- *
- * Calculate the kernel route flags.
- * Called before enqueuing a change/delete operation
- *
- */
-static uint8_t
-olsr_rt_flags(const struct rt_entry *rt)
-{
-  const struct rt_nexthop *nh;
-  uint8_t flags = RTF_UP;
-
-  /* destination is host */
-  if (rt->rt_dst.prefix_len == 8 * olsr_cnf->ipsize) {
-    flags |= RTF_HOST;
-  }
-
-  nh = olsr_get_nh(rt);
-
-  if (olsr_ipcmp(&rt->rt_dst.prefix, &nh->gateway) != 0) {
-    flags |= RTF_GATEWAY;
-  }
-
-  return flags;
-}
-
 static unsigned int seq = 0;
 
 /*
@@ -111,9 +84,9 @@ add_del_route(const struct rt_entry *rt, int add)
   int len;                             /* message size written to routing socket */
 
   if (add) {
-    OLSR_DEBUG(LOG_ROUTING, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+    OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
   } else {
-    OLSR_DEBUG(LOG_ROUTING, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+    OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
   }
 
   memset(buff, 0, sizeof(buff));
@@ -122,8 +95,8 @@ add_del_route(const struct rt_entry *rt, int add)
   sin4.sin_len = sizeof(sin4);
   sin4.sin_family = AF_INET;
 
-  sin_size = 1 + ((sizeof(struct sockaddr_in) - 1) | 3);
-  sdl_size = 1 + ((sizeof(struct sockaddr_dl) - 1) | 3);
+  sin_size = 1 + ((sizeof(struct sockaddr_in) - 1) | (sizeof(long) - 1));
+  sdl_size = 1 + ((sizeof(struct sockaddr_dl) - 1) | (sizeof(long) - 1));
 
   /**********************************************************************
    *                  FILL THE ROUTING MESSAGE HEADER
@@ -150,9 +123,9 @@ add_del_route(const struct rt_entry *rt, int add)
   /*
    * vxWorks: change proto or tos
    */
-  OLSR_DEBUG(LOG_ROUTING, "\t- Setting Protocol: 0\n");
+  OLSR_PRINTF(8, "\t- Setting Protocol: 0\n");
   ((struct sockaddr_rt *)(&sin4))->srt_proto = 0;
-  OLSR_DEBUG(LOG_ROUTING, "\t- Setting TOS: 0\n");
+  OLSR_PRINTF(8, "\t- Setting TOS: 0\n");
   ((struct sockaddr_rt *)(&sin4))->srt_tos = 0;
 #endif
 
@@ -177,22 +150,23 @@ add_del_route(const struct rt_entry *rt, int add)
       memcpy(walker, &sin4, sizeof(sin4));
       walker += sin_size;
       rtm->rtm_addrs |= RTA_GATEWAY;
-    } else {
+    }
+    else {
       /*
        * Host is directly reachable, so add
        * the output interface MAC address.
        */
       if (getifaddrs(&addrs)) {
-        OLSR_WARN(LOG_ROUTING, "\ngetifaddrs() failed\n");
+        fprintf(stderr, "\ngetifaddrs() failed\n");
         return -1;
       }
 
       for (awalker = addrs; awalker != NULL; awalker = awalker->ifa_next)
-        if (awalker->ifa_addr->sa_family == AF_LINK && strcmp(awalker->ifa_name, nexthop->interface->int_name) == 0)
+        if (awalker->ifa_addr->sa_family == AF_LINK && strcmp(awalker->ifa_name, if_ifwithindex_name(nexthop->iif_index)) == 0)
           break;
 
       if (awalker == NULL) {
-        OLSR_WARN(LOG_ROUTING, "\nInterface %s not found\n", nexthop->interface->int_name);
+        fprintf(stderr, "\nInterface %s not found\n", if_ifwithindex_name(nexthop->iif_index));
         freeifaddrs(addrs);
         return -1;
       }
@@ -231,14 +205,26 @@ add_del_route(const struct rt_entry *rt, int add)
    **********************************************************************/
 
   rtm->rtm_msglen = (unsigned short)(walker - buff);
-  len = write(olsr_cnf->rts_bsd, buff, rtm->rtm_msglen);
+  len = write(olsr_cnf->rts, buff, rtm->rtm_msglen);
   if (0 != rtm->rtm_errno || len < rtm->rtm_msglen) {
-    OLSR_WARN(LOG_ROUTING, "\nCannot write to routing socket: (rtm_errno= 0x%x) (last error message: %s)\n", rtm->rtm_errno,
-              strerror(errno));
+    fprintf(stderr, "\nCannot write to routing socket: (rtm_errno= 0x%x) (last error message: %s)\n", rtm->rtm_errno,
+            strerror(errno));
   }
   return 0;
 }
 
+int
+olsr_ioctl_add_route(const struct rt_entry *rt)
+{
+  return add_del_route(rt, 1);
+}
+
+int
+olsr_ioctl_del_route(const struct rt_entry *rt)
+{
+  return add_del_route(rt, 0);
+}
+
 static int
 add_del_route6(const struct rt_entry *rt, int add)
 {
@@ -252,9 +238,9 @@ add_del_route6(const struct rt_entry *rt, int add)
   int len;
 
   if (add) {
-    OLSR_DEBUG(LOG_ROUTING, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+    OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
   } else {
-    OLSR_DEBUG(LOG_ROUTING, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+    OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
   }
 
   memset(buff, 0, sizeof(buff));
@@ -266,8 +252,8 @@ add_del_route6(const struct rt_entry *rt, int add)
   sdl.sdl_len = sizeof(sdl);
   sdl.sdl_family = AF_LINK;
 
-  sin_size = 1 + ((sizeof(struct sockaddr_in6) - 1) | 3);
-  sdl_size = 1 + ((sizeof(struct sockaddr_dl) - 1) | 3);
+  sin_size = 1 + ((sizeof(struct sockaddr_in6) - 1) | (sizeof(long) - 1));
+  sdl_size = 1 + ((sizeof(struct sockaddr_dl) - 1) | (sizeof(long) - 1));
 
   /**********************************************************************
    *                  FILL THE ROUTING MESSAGE HEADER
@@ -304,7 +290,7 @@ add_del_route6(const struct rt_entry *rt, int add)
     memset(&sin6.sin6_addr.s6_addr, 0, 8);
     sin6.sin6_addr.s6_addr[0] = 0xfe;
     sin6.sin6_addr.s6_addr[1] = 0x80;
-    sin6.sin6_scope_id = nexthop->interface->if_index;
+    sin6.sin6_scope_id = nexthop->iif_index;
 #ifdef __KAME__
     *(u_int16_t *) & sin6.sin6_addr.s6_addr[2] = htons(sin6.sin6_scope_id);
     sin6.sin6_scope_id = 0;
@@ -312,7 +298,8 @@ add_del_route6(const struct rt_entry *rt, int add)
     memcpy(walker, &sin6, sizeof(sin6));
     walker += sin_size;
     rtm->rtm_addrs |= RTA_GATEWAY;
-  } else {
+  }
+  else {
     /*
      * Host is directly reachable, so add
      * the output interface MAC address.
@@ -321,7 +308,7 @@ add_del_route6(const struct rt_entry *rt, int add)
     memset(&sin6.sin6_addr.s6_addr, 0, 8);
     sin6.sin6_addr.s6_addr[0] = 0xfe;
     sin6.sin6_addr.s6_addr[1] = 0x80;
-    sin6.sin6_scope_id = nexthop->interface->if_index;
+    sin6.sin6_scope_id = nexthop->iif_index;
 #ifdef __KAME__
     *(u_int16_t *) & sin6.sin6_addr.s6_addr[2] = htons(sin6.sin6_scope_id);
     sin6.sin6_scope_id = 0;
@@ -348,9 +335,9 @@ add_del_route6(const struct rt_entry *rt, int add)
    **********************************************************************/
 
   rtm->rtm_msglen = (unsigned short)(walker - buff);
-  len = write(olsr_cnf->rts_bsd, buff, rtm->rtm_msglen);
+  len = write(olsr_cnf->rts, buff, rtm->rtm_msglen);
   if (len < 0 && !(errno == EEXIST || errno == ESRCH)) {
-    OLSR_WARN(LOG_ROUTING, "cannot write to routing socket: %s\n", strerror(errno));
+    fprintf(stderr, "cannot write to routing socket: %s\n", strerror(errno));
   }
 
   /*
@@ -374,29 +361,29 @@ add_del_route6(const struct rt_entry *rt, int add)
     walker += sin_size;
     drtm->rtm_addrs = RTA_DST;
     drtm->rtm_msglen = (unsigned short)(walker - dbuff);
-    len = write(olsr_cnf->rts_bsd, dbuff, drtm->rtm_msglen);
+    len = write(olsr_cnf->rts, dbuff, drtm->rtm_msglen);
     if (len < 0) {
-      OLSR_WARN(LOG_ROUTING, "cannot delete route: %s\n", strerror(errno));
+      fprintf(stderr, "cannot delete route: %s\n", strerror(errno));
     }
     rtm->rtm_seq = ++seq;
-    len = write(olsr_cnf->rts_bsd, buff, rtm->rtm_msglen);
+    len = write(olsr_cnf->rts, buff, rtm->rtm_msglen);
     if (len < 0) {
-      OLSR_WARN(LOG_ROUTING, "still cannot add route: %s\n", strerror(errno));
+      fprintf(stderr, "still cannot add route: %s\n", strerror(errno));
     }
   }
   return 0;
 }
 
 int
-olsr_kernel_add_route(const struct rt_entry *rt, int ip_version)
+olsr_ioctl_add_route6(const struct rt_entry *rt)
 {
-  return AF_INET == ip_version ? add_del_route(rt, 1) : add_del_route6(rt, 1);
+  return add_del_route6(rt, 1);
 }
 
 int
-olsr_kernel_del_route(const struct rt_entry *rt, int ip_version)
+olsr_ioctl_del_route6(const struct rt_entry *rt)
 {
-  return AF_INET == ip_version ? add_del_route(rt, 0) : add_del_route6(rt, 0);
+  return add_del_route6(rt, 0);
 }
 
 /*
index b50d43f..9240eee 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
+ * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  *
  */
 
-#include "defs.h"
-#include "net_os.h"
-#include "ipcalc.h"
-#include "parser.h"             /* dnc: needed for call to packet_parser() */
-#include "olsr_protocol.h"
-#include "common/string.h"
-#include "misc.h"
-#include "olsr_logging.h"
-#include "olsr.h"
+#if defined __FreeBSD_kernel__
+#define _GNU_SOURCE 1
+#endif
+
+#include "../defs.h"
+#include "../net_os.h"
+#include "../ipcalc.h"
+#include "../parser.h"          /* dnc: needed for call to packet_parser() */
+#include "../olsr_protocol.h"
+#include "../olsr_cfg.h"
+#include "../olsr.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include <netinet/in.h>
-
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
 #include <fcntl.h>
 #include <syslog.h>
-#include <errno.h>
-#include <unistd.h>
-
+#include <netinet/in.h>
 #include <net/if.h>
 
 #ifdef _WRS_KERNEL
 #include "wrn/coreip/net/ifaddrs.h"
 #include <selectLib.h>
 #include <logLib.h>
-// #define syslog(a, b) fdprintf(a, b);
+#define syslog(a, b) fdprintf(a, b);
 #else
 #include <sys/param.h>
 #endif
 
-
 #ifdef __NetBSD__
 #include <net/if_ether.h>
+#include <netinet6/in6_var.h>   /* For struct in6_ifreq */
+#include <net80211/ieee80211_ioctl.h>
+#include <ifaddrs.h>
 #endif
 
 #ifdef __OpenBSD__
 #include <net80211/ieee80211_ioctl.h>
 #endif
 
-#ifdef __FreeBSD__
-#include <ifaddrs.h>
+#if defined __FreeBSD__ || __FreeBSD_kernel__
 #include <net/if_var.h>
 #include <net/ethernet.h>
 #include <netinet/in_var.h>
+#include <ifaddrs.h>
 #ifndef FBSD_NO_80211
 #include <net80211/ieee80211.h>
 #include <net80211/ieee80211_ioctl.h>
 #endif
 
 #include <sys/sysctl.h>
-#include <sys/sockio.h>
 
 static int ignore_redir;
 static int send_redir;
@@ -136,7 +135,7 @@ static int
 set_sysctl_int(const char *name, int new)
 {
   int old;
-#if __MacOSX__ || __OpenBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__MacOSX__) || defined(__OpenBSD__) || defined(__NetBSD__)
   size_t len = sizeof(old);
 #else
   unsigned int len = sizeof(old);
@@ -179,36 +178,27 @@ set_sysctl_int(const char *name, int new)
   return old;
 }
 
-int
-enable_ip_forwarding(int version)
-{
-  const char *name = version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
+void
+os_init_global_ifoptions(void) {
+  const char *name = olsr_cnf->ip_version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
 
   gateway = set_sysctl_int(name, 1);
   if (gateway < 0) {
-    OLSR_WARN(LOG_NETWORKING, "Cannot enable IP forwarding. Please enable IP forwarding manually." " Continuing in 3 seconds...\n");
-    sleep(3);
+    fprintf(stderr, "Cannot enable IP forwarding. Please enable IP forwarding manually." " Continuing in 3 seconds...\n");
+    olsr_startup_sleep(3);
   }
 
-  return 1;
-}
-
-int
-disable_redirects_global(int version)
-{
-  const char *name;
-
   /* do not accept ICMP redirects */
 
-#ifdef __OpenBSD__
-  if (version == AF_INET)
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+  if (olsr_cnf->ip_version == AF_INET)
     name = "net.inet.icmp.rediraccept";
   else
     name = "net.inet6.icmp6.rediraccept";
 
   ignore_redir = set_sysctl_int(name, 0);
-#elif defined __FreeBSD__ || defined __MacOSX__
-  if (version == AF_INET) {
+#elif defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__
+  if (olsr_cnf->ip_version == AF_INET) {
     name = "net.inet.icmp.drop_redirect";
     ignore_redir = set_sysctl_int(name, 1);
   } else {
@@ -216,7 +206,7 @@ disable_redirects_global(int version)
     ignore_redir = set_sysctl_int(name, 0);
   }
 #else
-  if (version == AF_INET)
+  if (olsr_cnf->ip_version == AF_INET)
     name = "net.inet.icmp.drop_redirect";
   else
     name = "net.inet6.icmp6.drop_redirect";
@@ -225,215 +215,240 @@ disable_redirects_global(int version)
 #endif
 
   if (ignore_redir < 0) {
-    OLSR_WARN(LOG_NETWORKING,
-              "Cannot disable incoming ICMP redirect messages. " "Please disable them manually. Continuing in 3 seconds...\n");
-    sleep(3);
+    fprintf(stderr,
+            "Cannot disable incoming ICMP redirect messages. " "Please disable them manually. Continuing in 3 seconds...\n");
+    olsr_startup_sleep(3);
   }
 
   /* do not send ICMP redirects */
 
-  if (version == AF_INET)
+  if (olsr_cnf->ip_version == AF_INET)
     name = "net.inet.ip.redirect";
   else
     name = "net.inet6.ip6.redirect";
 
   send_redir = set_sysctl_int(name, 0);
   if (send_redir < 0) {
-    OLSR_WARN(LOG_NETWORKING,
-              "Cannot disable outgoing ICMP redirect messages. " "Please disable them manually. Continuing in 3 seconds...\n");
-    sleep(3);
+    fprintf(stderr,
+            "Cannot disable outgoing ICMP redirect messages. " "Please disable them manually. Continuing in 3 seconds...\n");
+    olsr_startup_sleep(3);
   }
-
-  return 1;
 }
 
 int
-disable_redirects(const char *if_name
-                  __attribute__ ((unused)), struct interface *iface __attribute__ ((unused)), int version __attribute__ ((unused)))
-{
-  /*
-   *  this function gets called for each interface olsrd uses; however,
-   * FreeBSD can only globally control ICMP redirects, and not on a
-   * per-interface basis; hence, only disable ICMP redirects in the "global"
-   * function
-   */
-  return 1;
-}
-
-int
-deactivate_spoof(const char *if_name
-                 __attribute__ ((unused)), struct interface *iface __attribute__ ((unused)), int version __attribute__ ((unused)))
-{
-  return 1;
-}
-
-int
-restore_settings(int version)
-{
+os_cleanup_global_ifoptions(void) {
   /* reset IP forwarding */
-  const char *name = version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
+  const char *name = olsr_cnf->ip_version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
 
   set_sysctl_int(name, gateway);
 
   /* reset incoming ICMP redirects */
 
 #ifdef __OpenBSD__
-  name = version == AF_INET ? "net.inet.icmp.rediraccept" : "net.inet6.icmp6.rediraccept";
-#elif defined __FreeBSD__ || defined __MacOSX__
-  name = version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.rediraccept";
+  name = olsr_cnf->ip_version == AF_INET ? "net.inet.icmp.rediraccept" : "net.inet6.icmp6.rediraccept";
+#elif defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __MacOSX__
+  name = olsr_cnf->ip_version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.rediraccept";
 #else
-  name = version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.drop_redirect";
+  name = olsr_cnf->ip_version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.drop_redirect";
 #endif
   set_sysctl_int(name, ignore_redir);
 
   /* reset outgoing ICMP redirects */
-  name = version == AF_INET ? "net.inet.ip.redirect" : "net.inet6.ip6.redirect";
+  name = olsr_cnf->ip_version == AF_INET ? "net.inet.ip.redirect" : "net.inet6.ip6.redirect";
   set_sysctl_int(name, send_redir);
   return 1;
 }
 
+/**
+ *Creates a nonblocking broadcast socket.
+ *@param sa sockaddr struct. Used for bind(2).
+ *@return the FD of the socket or -1 on error.
+ */
+int
+gethemusocket(struct sockaddr_in *pin)
+{
+  int sock, on = 1;
+
+  OLSR_PRINTF(1, "       Connecting to switch daemon port 10150...");
+
+  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    perror("hcsocket");
+    syslog(LOG_ERR, "hcsocket: %m");
+    return (-1);
+  }
+
+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
+    perror("SO_REUSEADDR failed");
+    close(sock);
+    return (-1);
+  }
+  /* connect to PORT on HOST */
+  if (connect(sock, (struct sockaddr *)pin, sizeof(*pin)) < 0) {
+    printf("FAILED\n");
+    fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
+    printf("connection refused\n");
+    close(sock);
+    return (-1);
+  }
+
+  printf("OK\n");
+
+  /* Keep TCP socket blocking */
+  return (sock);
+}
 
 int
-getsocket4(int bufspace, struct interface *ifp, bool bind_to_unicast, uint16_t port)
+getsocket(int bufspace, struct interface *ifp __attribute__ ((unused)))
 {
-  struct sockaddr_in sin4;
+  struct sockaddr_in sin;
   int on;
   int sock = socket(AF_INET, SOCK_DGRAM, 0);
   if (sock < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot open socket for OLSR PDUs (%s)\n", strerror(errno));
-    olsr_exit(EXIT_FAILURE);
+    perror("socket");
+    syslog(LOG_ERR, "socket: %m");
+    return -1;
   }
 
   on = 1;
   if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot set socket for OLSR PDUs to broadcast mode (%s)\n", strerror(errno));
+    perror("setsockopt");
+    syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 
   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot reuse address for OLSR PDUs (%s)\n", strerror(errno));
+    perror("SO_REUSEADDR failed");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 
   if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot reuse port for OLSR PDUs (%s)\n", strerror(errno));
+    perror("SO_REUSEPORT failed");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 
   if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, (char *)&on, sizeof(on)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot set protocol option REECVIF for OLSR PDUs (%s)\n", strerror(errno));
+    perror("IP_RECVIF failed");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 
-  if (bufspace > 0) {
+  if(bufspace > 0) {
     for (on = bufspace;; on -= 1024) {
-      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0) {
-        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
         break;
-      }
       if (on <= 8 * 1024) {
-        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
+        perror("setsockopt");
+        syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
         break;
       }
     }
   }
-  memset(&sin4, 0, sizeof(sin4));
-  sin4.sin_family = AF_INET;
-  sin4.sin_port = htons(port);
 
-  if(bind_to_unicast) {
-    sin4.sin_addr.s_addr = ifp->int_src.v4.sin_addr.s_addr;
-  }
-  else {
-    sin4.sin_addr.s_addr = INADDR_ANY;
+  memset(&sin, 0, sizeof(sin));
+  sin.sin_family = AF_INET;
+  sin.sin_port = htons(olsr_cnf->olsrport);
+
+  if(bufspace <= 0) {
+    sin.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
   }
 
-  if (bind(sock, (struct sockaddr *)&sin4, sizeof(sin4)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Coult not bind socket for OLSR PDUs to port (%s)\n", strerror(errno));
+  if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+    perror("bind");
+    syslog(LOG_ERR, "bind: %m");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 
-  set_nonblocking(sock);
+  on = fcntl(sock, F_GETFL);
+  if (on == -1) {
+    syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
+  } else {
+    if (fcntl(sock, F_SETFL, on | O_NONBLOCK) == -1) {
+      syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
+    }
+  }
   return (sock);
 }
 
 int
-getsocket6(int bufspace, struct interface *ifp, bool bind_to_unicast, uint16_t port)
+getsocket6(int bufspace, struct interface *ifp __attribute__ ((unused)))
 {
-  struct sockaddr_in6 sin6;
+  struct sockaddr_in6 sin;
   int on;
   int sock = socket(AF_INET6, SOCK_DGRAM, 0);
 
   if (sock < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot open socket for OLSR PDUs (%s)\n", strerror(errno));
-    olsr_exit(EXIT_FAILURE);
+    perror("socket");
+    syslog(LOG_ERR, "socket: %m");
+    return -1;
   }
 
-  if (bufspace > 0) {
+  if(bufspace > 0) {
     for (on = bufspace;; on -= 1024) {
-      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0) {
-        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
         break;
-      }
       if (on <= 8 * 1024) {
-        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
+        perror("setsockopt");
+        syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
         break;
       }
     }
   }
 
   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot reuse address for OLSR PDUs (%s)\n", strerror(errno));
+    perror("SO_REUSEADDR failed");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 
   if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on)) < 0) {
-    perror("SO_REUSEADDR failed");
+    perror("SO_REUSEPORT failed");
     close(sock);
     return -1;
   }
 #ifdef IPV6_RECVPKTINFO
   if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on, sizeof(on)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot set protocol options RECVPKTINFO for OLSR PDUs (%s)\n", strerror(errno));
+    perror("IPV6_RECVPKTINFO failed");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 #elif defined IPV6_PKTINFO
   if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&on, sizeof(on)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot set protocol options PKTINFO for OLSR PDUs (%s)\n", strerror(errno));
+    perror("IPV6_PKTINFO failed");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 #endif
 
-  memset(&sin6, 0, sizeof(sin6));
-  sin6.sin6_family = AF_INET6;
-  sin6.sin6_port = htons(port);
+  memset(&sin, 0, sizeof(sin));
+  sin.sin6_family = AF_INET6;
+  sin.sin6_port = htons(olsr_cnf->olsrport);
 
-  if(bind_to_unicast) {
-    memcpy(&sin6.sin6_addr, &ifp->int_src.v6.sin6_addr, sizeof(struct in6_addr));
+  if(bufspace <= 0) {
+    memcpy(&sin.sin6_addr, &ifp->int6_addr.sin6_addr, sizeof(struct in6_addr));
   }
 
-  if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Coult not bind socket for OLSR PDUs to port (%s)\n", strerror(errno));
+  if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+    perror("bind");
+    syslog(LOG_ERR, "bind: %m");
     close(sock);
-    olsr_exit(EXIT_FAILURE);
+    return -1;
   }
 
-  set_nonblocking(sock);
+  on = fcntl(sock, F_GETFL);
+  if (on == -1) {
+    syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
+  } else {
+    if (fcntl(sock, F_SETFL, on | O_NONBLOCK) == -1) {
+      syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
+    }
+  }
   return sock;
 }
 
-void
-os_set_olsr_socketoptions(int sock __attribute__ ((unused))) {
-}
-
 int
 join_mcast(struct interface *ifs, int sock)
 {
@@ -444,31 +459,30 @@ join_mcast(struct interface *ifs, int sock)
   int on;
 #endif
 
-  mcastreq.ipv6mr_multiaddr = ifs->int_multicast.v6.sin6_addr;
+  mcastreq.ipv6mr_multiaddr = ifs->int6_multaddr.sin6_addr;
   mcastreq.ipv6mr_interface = ifs->if_index;
 
-  OLSR_INFO(LOG_NETWORKING, "Interface %s joining multicast %s.\n", ifs->int_name,
-            olsr_ip_to_string(&addrstr, (union olsr_ip_addr *)&ifs->int_multicast.v6.sin6_addr));
+  OLSR_PRINTF(3, "Interface %s joining multicast %s...", ifs->int_name,
+              olsr_ip_to_string(&addrstr, (union olsr_ip_addr *)&ifs->int6_multaddr.sin6_addr));
 
   /* rfc 3493 */
 #ifdef IPV6_JOIN_GROUP
   /* Join reciever group */
-  if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mcastreq, sizeof(struct ipv6_mreq))
-      < 0)
+  if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mcastreq, sizeof(struct ipv6_mreq)) < 0)
 #else /* rfc 2133, obsoleted */
   /* Join receiver group */
   if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mcastreq, sizeof(struct ipv6_mreq)) < 0)
 #endif
   {
-    OLSR_WARN(LOG_NETWORKING, "Cannot join multicast group (%s)\n", strerror(errno));
+    perror("Join multicast send");
     return -1;
   }
 
-
   if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&mcastreq.ipv6mr_interface, sizeof(mcastreq.ipv6mr_interface)) < 0) {
-    OLSR_WARN(LOG_NETWORKING, "Cannot set multicast interface (%s)\n", strerror(errno));
+    perror("Set multicast if");
     return -1;
   }
+
 #ifdef IPV6_USE_MIN_MTU
   /*
    * This allow multicast packets to use the full interface MTU and not
@@ -481,24 +495,24 @@ join_mcast(struct interface *ifs, int sock)
     return -1;
   }
 #endif
+
+  OLSR_PRINTF(3, "OK\n");
   return 0;
 }
 
-
-
-
 int
-get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int addrtype6)
+get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, struct olsr_ip_prefix *prefix)
 {
   struct ifaddrs *ifap, *ifa;
   const struct sockaddr_in6 *sin6 = NULL;
+  const union olsr_ip_addr *tmp_ip;
   struct in6_ifreq ifr6;
   int found = 0;
   int s6;
   u_int32_t flags6;
 
   if (getifaddrs(&ifap) != 0) {
-    OLSR_WARN(LOG_NETWORKING, "getifaddrs() failed (%s).\n", strerror(errno));
+    OLSR_PRINTF(3, "get_ipv6_address: getifaddrs() failed.\n");
     return 0;
   }
 
@@ -509,12 +523,12 @@ get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int addrtype6)
         continue;
       strscpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
       if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-        OLSR_WARN(LOG_NETWORKING, "Cannot open datagram socket (%s)\n", strerror(errno));
+        OLSR_PRINTF(3, "socket(AF_INET6,SOCK_DGRAM)");
         break;
       }
       ifr6.ifr_addr = *sin6;
       if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
-        OLSR_WARN(LOG_NETWORKING, "ioctl(SIOCGIFAFLAG_IN6) failed (%s)", strerror(errno));
+        OLSR_PRINTF(3, "ioctl(SIOCGIFAFLAG_IN6)");
         close(s6);
         break;
       }
@@ -522,17 +536,12 @@ get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int addrtype6)
       flags6 = ifr6.ifr_ifru.ifru_flags6;
       if ((flags6 & IN6_IFF_ANYCAST) != 0)
         continue;
-      if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
-        if (addrtype6 == OLSR_IP6T_SITELOCAL)
-          found = 1;
-      } else {
-        if (addrtype6 == OLSR_IP6T_GLOBAL && (sin6->sin6_addr.s6_addr[0] != 0xfc && sin6->sin6_addr.s6_addr[0] != 0xfd))
-          found = 1;
-        else if (addrtype6 == OLSR_IP6T_UNIQUELOCAL && (sin6->sin6_addr.s6_addr[0] == 0xfc || sin6->sin6_addr.s6_addr[0] == 0xfd))
-          found = 1;
-      }
-      if (found) {
+
+      tmp_ip = (const union olsr_ip_addr *) &sin6->sin6_addr;
+      if ((prefix == NULL && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+          || (prefix != NULL && ip_in_net(tmp_ip, prefix))) {
         memcpy(&saddr6->sin6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
+        found = 1;
         break;
       }
     }
@@ -544,9 +553,6 @@ get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int addrtype6)
   return 0;
 }
 
-
-
-
 /**
  * Wrapper for sendto(2)
  */
@@ -556,7 +562,7 @@ static u_int16_t ip_id = 0;
 #endif /* SPOOF */
 
 ssize_t
-olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused)), const union olsr_sockaddr *sock)
+olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused)), const struct sockaddr *to, socklen_t tolen)
 {
 #ifdef SPOOF
   /* IPv4 for now! */
@@ -577,7 +583,7 @@ olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused
   /* initialize libnet */
   context = libnet_init(LIBNET_LINK, iface->int_name, errbuf);
   if (context == NULL) {
-    OLSR_WARN(LOG_NETWORKING, "libnet init: %s\n", libnet_geterror(context));
+    OLSR_PRINTF(1, "libnet init: %s\n", libnet_geterror(context));
     return (0);
   }
 
@@ -586,16 +592,16 @@ olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused
     ip_id = (u_int16_t) (arc4random() & 0xffff);
   }
 
-  udp_tag = libnet_build_udp(olsr_cnf->olsr_port,       /* src port */
-                             olsr_cnf->olsr_port,       /* dest port */
+  udp_tag = libnet_build_udp(olsr_cnf->olsrport,        /* src port */
+                             olsr_cnf->olsrport,        /* dest port */
                              LIBNET_UDP_H + len,        /* length */
-                             0, /* checksum */
+                             0,         /* checksum */
                              buf,       /* payload */
                              len,       /* payload size */
                              context,   /* context */
                              udp_tag);  /* pblock */
   if (udp_tag == -1) {
-    OLSR_WARN(LOG_NETWORKING, "libnet UDP header: %s\n", libnet_geterror(context));
+    OLSR_PRINTF(1, "libnet UDP header: %s\n", libnet_geterror(context));
     return (0);
   }
 
@@ -613,7 +619,7 @@ olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused
                              context,   /* context */
                              ip_tag);   /* pblock */
   if (ip_tag == -1) {
-    OLSR_WARN(LOG_NETWORKING, "libnet IP header: %s\n", libnet_geterror(context));
+    OLSR_PRINTF(1, "libnet IP header: %s\n", libnet_geterror(context));
     return (0);
   }
 
@@ -625,13 +631,13 @@ olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused
                                     context,    /* libnet handle */
                                     ether_tag); /* pblock tag */
   if (ether_tag == -1) {
-    OLSR_WARN(LOG_NETWORKING, "libnet ethernet header: %s\n", libnet_geterror(context));
+    OLSR_PRINTF(1, "libnet ethernet header: %s\n", libnet_geterror(context));
     return (0);
   }
 
   status = libnet_write(context);
   if (status == -1) {
-    OLSR_WARN(LOG_NETWORKING, "libnet packet write: %s\n", libnet_geterror(context));
+    OLSR_PRINTF(1, "libnet packet write: %s\n", libnet_geterror(context));
     return (0);
   }
 
@@ -640,17 +646,16 @@ olsr_sendto(int s, const void *buf, size_t len, int flags __attribute__ ((unused
   return (len);
 
 #else
-  return sendto(s, buf, len, flags, &sock->std, sizeof(*sock));
+  return sendto(s, buf, len, flags, (const struct sockaddr *)to, tolen);
 #endif
 }
 
-
 /**
  * Wrapper for recvfrom(2)
  */
 
 ssize_t
-olsr_recvfrom(int s, void *buf, size_t len, int flags __attribute__ ((unused)), union olsr_sockaddr *from, socklen_t * fromlen)
+olsr_recvfrom(int s, void *buf, size_t len, int flags __attribute__ ((unused)), struct sockaddr *from, socklen_t * fromlen)
 {
   struct msghdr mhdr;
   struct iovec iov;
@@ -660,19 +665,19 @@ olsr_recvfrom(int s, void *buf, size_t len, int flags __attribute__ ((unused)),
   } cmu;
   struct cmsghdr *cm;
   struct sockaddr_dl *sdl;
+  struct sockaddr_in *sin = (struct sockaddr_in *)from;
+  struct sockaddr_in6 *sin6;
   struct in6_addr *iaddr6;
   struct in6_pktinfo *pkti;
   struct interface *ifc;
+  char addrstr[INET6_ADDRSTRLEN];
   char iname[IFNAMSIZ];
   int count;
-#ifndef REMOVE_LOG_DEBUG
-  struct ipaddr_str ipbuf;
-#endif
 
   memset(&mhdr, 0, sizeof(mhdr));
   memset(&iov, 0, sizeof(iov));
 
-  mhdr.msg_name = from;
+  mhdr.msg_name = (caddr_t) from;
   mhdr.msg_namelen = *fromlen;
   mhdr.msg_iov = &iov;
   mhdr.msg_iovlen = 1;
@@ -706,13 +711,16 @@ olsr_recvfrom(int s, void *buf, size_t len, int flags __attribute__ ((unused)),
 
   ifc = if_ifwithsock(s);
 
-  OLSR_DEBUG(LOG_NETWORKING,
-             "%d bytes from %s, socket associated %s really received on %s\n",
-             count, olsr_sockaddr_to_string(&ipbuf, from), ifc->int_name, iname);
+  sin6 = (struct sockaddr_in6 *)from;
+  OLSR_PRINTF(4, "%d bytes from %s, socket associated %s really received on %s\n", count,
+              inet_ntop(olsr_cnf->ip_version, olsr_cnf->ip_version == AF_INET6 ? (char *)&sin6->sin6_addr : (char *)&sin->sin_addr,
+                        addrstr, sizeof(addrstr)), ifc->int_name, iname);
 
+#ifndef __NetBSD__
   if (strcmp(ifc->int_name, iname) != 0) {
     return (0);
   }
+#endif
 
   return (count);
 }
@@ -727,6 +735,72 @@ olsr_select(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, s
   return select(nfds, readfds, writefds, exceptfds, timeout);
 }
 
+int
+check_wireless_interface(char *ifname)
+{
+#if (defined __FreeBSD__ || defined __FreeBSD_kernel__ ) &&  !defined FBSD_NO_80211
+
+/* From FreeBSD ifconfig/ifieee80211.c ieee80211_status() */
+  struct ieee80211req ireq;
+  u_int8_t data[32];
+
+  memset(&ireq, 0, sizeof(ireq));
+  strscpy(ireq.i_name, ifname, sizeof(ireq.i_name));
+  ireq.i_data = &data;
+  ireq.i_type = IEEE80211_IOC_SSID;
+  ireq.i_val = -1;
+  return (ioctl(olsr_cnf->ioctl_s, SIOCG80211, &ireq) >= 0) ? 1 : 0;
+#elif defined __OpenBSD__
+  struct ieee80211_nodereq nr;
+  bzero(&nr, sizeof(nr));
+  strscpy(nr.nr_ifname, ifname, sizeof(nr.nr_ifname));
+  return (ioctl(olsr_cnf->ioctl_s, SIOCG80211FLAGS, &nr) >= 0) ? 1 : 0;
+#elif defined __NetBSD__
+  struct ifreq ireq;
+  struct ieee80211_nwid data;
+  int ret;
+
+  memset(&ireq, 0, sizeof(ireq));
+  strscpy(ireq.ifr_name, ifname, sizeof(ireq.ifr_name));
+  ireq.ifr_data = &data;
+  ret = ioctl(olsr_cnf->ioctl_s, SIOCG80211NWID, &ireq);
+  if(ret == 0)
+         return 1;
+  return 0;
+#else
+  ifname = NULL;                /* squelsh compiler warning */
+  return 0;
+#endif
+}
+
+#include <sys/sockio.h>
+
+int
+calculate_if_metric(char *ifname)
+{
+  if (check_wireless_interface(ifname)) {
+    /* Wireless */
+    return 1;
+  } else {
+    /* Ethernet */
+#if 0
+    /* Andreas: Perhaps SIOCGIFMEDIA is the way to do this? */
+    struct ifmediareq ifm;
+
+    memset(&ifm, 0, sizeof(ifm));
+    strscpy(ifm.ifm_name, ifname, sizeof(ifm.ifm_name));
+
+    if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMEDIA, &ifm) < 0) {
+      OLSR_PRINTF(1, "Error SIOCGIFMEDIA(%s)\n", ifm.ifm_name);
+      return WEIGHT_ETHERNET_DEFAULT;
+    }
+
+    OLSR_PRINTF(1, "%s: STATUS 0x%08x\n", ifm.ifm_name, ifm.ifm_status);
+#endif
+    return WEIGHT_ETHERNET_DEFAULT;
+  }
+}
+
 /*
  * Local Variables:
  * c-basic-offset: 2
index 41f69fe..46e169e 100644 (file)
@@ -166,8 +166,7 @@ void destroy_interfaces(void) {
   struct list_iterator iterator;
 
   OLSR_FOR_ALL_INTERFACES(iface, iterator) {
-    struct interface **ptr = &iface;
-    remove_interface(ptr);
+    remove_interface(iface);
   }
 
   OLSR_FOR_ALL_LOSTIF_ENTRIES(lost, iterator) {
@@ -180,44 +179,21 @@ add_interface(struct olsr_if_config *iface) {
   struct interface *ifp;
 
   ifp = olsr_cookie_malloc(interface_mem_cookie);
+
+  ifp->olsr_socket = getsocket46(olsr_cnf->ip_version, BUFSPACE, ifp, false, olsr_cnf->olsr_port);
+  ifp->send_socket = getsocket46(olsr_cnf->ip_version, 0, ifp, true, olsr_cnf->olsr_port);
+  if (ifp->olsr_socket < 0 || ifp->send_socket < 0) {
+    OLSR_ERROR(LOG_INTERFACE, "Could not initialize socket... exiting!\n\n");
+    olsr_exit(EXIT_FAILURE);
+  }
+
   if ((os_init_interface(ifp, iface))) {
+    CLOSESOCKET(ifp->olsr_socket);
+    CLOSESOCKET(ifp->send_socket);
     olsr_cookie_free(interface_mem_cookie, ifp);
     return NULL;
   }
 
-  if (olsr_cnf->ip_version == AF_INET) {
-    /* IP version 4 */
-    /*
-     * We create one socket for each interface and bind
-     * the socket to it. This to ensure that we can control
-     * on what interface the message is transmitted
-     */
-    ifp->olsr_socket = getsocket4(BUFSPACE, ifp, false, olsr_cnf->olsr_port);
-    ifp->send_socket = getsocket4(0, ifp, true, olsr_cnf->olsr_port);
-
-    if (ifp->olsr_socket < 0 || ifp->send_socket < 0) {
-      OLSR_ERROR(LOG_INTERFACE, "Could not initialize socket... exiting!\n\n");
-      olsr_exit(EXIT_FAILURE);
-    }
-  } else {
-    /* IP version 6 */
-
-    /*
-     * We create one socket for each interface and bind
-     * the socket to it. This to ensure that we can control
-     * on what interface the message is transmitted
-     */
-    ifp->olsr_socket = getsocket6(BUFSPACE, ifp, false, olsr_cnf->olsr_port);
-    ifp->send_socket = getsocket6(0, ifp, true, olsr_cnf->olsr_port);
-
-    if (ifp->olsr_socket < 0 || ifp->send_socket < 0) {
-      OLSR_ERROR(LOG_INTERFACE, "Could not initialize socket... exiting!\n\n");
-      olsr_exit(EXIT_FAILURE);
-    }
-
-    join_mcast(ifp, ifp->olsr_socket);
-  }
-
   set_buffer_timer(ifp);
 
   /* Register sockets */
@@ -325,16 +301,16 @@ check_interface_updates(void *foo __attribute__ ((unused)))
  * Remove and cleanup a physical interface.
  */
 void
-remove_interface(struct interface **pinterf)
+remove_interface(struct interface *ifp)
 {
-  struct interface *ifp = *pinterf;
-
   if (!ifp) {
     return;
   }
 
   OLSR_INFO(LOG_INTERFACE, "Removing interface %s\n", ifp->int_name);
 
+  os_cleanup_interface(ifp);
+
   olsr_delete_link_entry_by_if(ifp);
 
   /*
@@ -368,8 +344,7 @@ remove_interface(struct interface **pinterf)
   /*
    * Unlink from config.
    */
-  unlock_interface(*pinterf);
-  *pinterf = NULL;
+  unlock_interface(ifp);
 
   /* Close olsr socket */
   remove_olsr_socket(ifp->olsr_socket, &olsr_input, NULL);
@@ -377,7 +352,7 @@ remove_interface(struct interface **pinterf)
   CLOSESOCKET(ifp->send_socket);
   ifp->olsr_socket = -1;
 
-//  free(ifp->int_name);
+  free(ifp->int_name);
   unlock_interface(ifp);
 
   if (list_is_empty(&interface_head) && !olsr_cnf->allow_no_interfaces) {
index 17d0a5e..6c02ecc 100644 (file)
@@ -201,7 +201,7 @@ bool init_interfaces(void);
 bool EXPORT(is_lost_interface_ip)(union olsr_ip_addr *ip);
 void destroy_interfaces(void);
 struct interface *add_interface(struct olsr_if_config *iface);
-void remove_interface(struct interface **);
+void remove_interface(struct interface *);
 void run_ifchg_cbs(struct interface *, int);
 struct interface *if_ifwithsock(int);
 struct interface *EXPORT(if_ifwithaddr) (const union olsr_ip_addr *);
index a7c579a..0228dee 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
+ * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,6 @@
 
 #include "apm.h"
 #include "defs.h"
-#include "olsr_cfg.h"
 #include "olsr_logging.h"
 
 #include <stdio.h>
@@ -70,7 +69,6 @@ struct linux_apm_info {
   int using_minutes;
 };
 
-
 /* ACPI related stuff */
 static const char *const acpi_info[] = {
   "/proc/acpi/battery/0/info",
@@ -88,10 +86,8 @@ static const char *const acpi_state[] = {
   "/proc/acpi/battery/BAT1/state"
 };
 
-
 #define ACPI_BT_CNT  ARRAYSIZE(acpi_state)
 
-
 static const char *const acpi_ac[] = {
   "/proc/acpi/ac_adapter/0/status",
   "/proc/acpi/ac_adapter/AC/state",
@@ -100,7 +96,6 @@ static const char *const acpi_ac[] = {
 
 #define ACPI_AC_CNT  ARRAYSIZE(acpi_ac)
 
-
 #define USE_APM    1
 #define USE_ACPI   2
 
@@ -112,15 +107,11 @@ static int ac_power_on;
 
 /* Prototypes */
 
-static int
-  apm_read_apm(struct olsr_apm_info *);
-
-static int
-  apm_read_acpi(struct olsr_apm_info *);
+static int apm_read_apm(struct olsr_apm_info *);
 
-static int
-  acpi_probe(void);
+static int apm_read_acpi(struct olsr_apm_info *);
 
+static int acpi_probe(void);
 
 int
 apm_init(void)
@@ -128,7 +119,7 @@ apm_init(void)
   struct olsr_apm_info ainfo;
 
   method = -1;
-  OLSR_INFO(LOG_MAIN, "Initializing APM\n");
+  OLSR_INFO(LOG_APM, "Initializing APM\n");
 
   if ((((fd_index = acpi_probe()) >= 0) || ac_power_on) && apm_read_acpi(&ainfo))
     method = USE_ACPI;
@@ -141,17 +132,15 @@ apm_init(void)
   return method;
 }
 
-
 void
 apm_printinfo(struct olsr_apm_info *ainfo)
 {
-  OLSR_INFO(LOG_MAIN, "APM info:\n\tAC status %d\n\tBattery percentage %d%%\n\tBattery time left %d mins\n\n",
-            ainfo->ac_line_status, ainfo->battery_percentage, ainfo->battery_time_left);
+  OLSR_DEBUG(LOG_APM, "APM info:\n\tAC status %d\n\tBattery percentage %d%%\n\tBattery time left %d mins\n\n", ainfo->ac_line_status,
+              ainfo->battery_percentage, ainfo->battery_time_left);
 
   ainfo = NULL;                 /* squelch compiler warnings */
 }
 
-
 int
 apm_read(struct olsr_apm_info *ainfo)
 {
@@ -166,7 +155,6 @@ apm_read(struct olsr_apm_info *ainfo)
   return 0;
 }
 
-
 static int
 apm_read_apm(struct olsr_apm_info *ainfo)
 {
@@ -187,24 +175,19 @@ apm_read_apm(struct olsr_apm_info *ainfo)
 
     if (fgets(buffer, sizeof(buffer), apm_procfile) == NULL) {
       /* Giving up */
-      OLSR_WARN(LOG_MAIN, "OLSRD: Could not read APM info - setting willingness to default\n");
+      OLSR_WARN(LOG_APM, "OLSRD: Could not read APM info - setting willingness to default");
       fclose(apm_procfile);
       return 0;
     }
   }
   fclose(apm_procfile);
 
-
   //printf("READ: %s\n", buffer);
 
   /* Get the info */
-  sscanf(buffer, "%s %d.%d %x %x %x %x %d%% %d %s\n",
-         lainfo.driver_version,
-         &lainfo.apm_version_major,
-         &lainfo.apm_version_minor,
-         &lainfo.apm_flags,
-         &lainfo.ac_line_status,
-         &lainfo.battery_status, &lainfo.battery_flags, &lainfo.battery_percentage, &lainfo.battery_time, units);
+  sscanf(buffer, "%s %d.%d %x %x %x %x %d%% %d %s\n", lainfo.driver_version, &lainfo.apm_version_major, &lainfo.apm_version_minor,
+         &lainfo.apm_flags, &lainfo.ac_line_status, &lainfo.battery_status, &lainfo.battery_flags, &lainfo.battery_percentage,
+         &lainfo.battery_time, units);
 
   lainfo.using_minutes = strncmp(units, "min", 3) ? 0 : 1;
 
@@ -231,7 +214,6 @@ apm_read_apm(struct olsr_apm_info *ainfo)
   return 1;
 }
 
-
 static int
 apm_read_acpi(struct olsr_apm_info *ainfo)
 {
@@ -273,7 +255,6 @@ apm_read_acpi(struct olsr_apm_info *ainfo)
   }
   fclose(fd);
 
-
   if ((fd = fopen(acpi_state[fd_index], "r")) == NULL)
     return 0;
 
@@ -299,7 +280,6 @@ apm_read_acpi(struct olsr_apm_info *ainfo)
   return 1;
 }
 
-
 static int
 acpi_probe(void)
 {
index bf623cb..8d49ba4 100644 (file)
@@ -233,7 +233,7 @@ olsr_netlink_send(struct nlmsghdr *nl_hdr)
   iov.iov_len = nl_hdr->nlmsg_len;
   ret = sendmsg(olsr_cnf->rtnl_s, &msg, 0);
   if (ret <= 0) {
-    OLSR_ERROR(LOG_ROUTING, "Cannot send data to netlink socket (%d: %s)", errno, strerror(errno));
+    OLSR_WARN(LOG_ROUTING, "Cannot send data to netlink socket (%d: %s)", errno, strerror(errno));
     return -1;
   }
 
@@ -241,13 +241,13 @@ olsr_netlink_send(struct nlmsghdr *nl_hdr)
   iov.iov_len = sizeof(rcvbuf);
   ret = recvmsg(olsr_cnf->rtnl_s, &msg, 0);
   if (ret <= 0) {
-    OLSR_ERROR(LOG_ROUTING, "Error while reading answer to netlink message (%d: %s)", errno, strerror(errno));
+    OLSR_WARN(LOG_ROUTING, "Error while reading answer to netlink message (%d: %s)", errno, strerror(errno));
     return -1;
   }
 
   h = (struct nlmsghdr *)ARM_NOWARN_ALIGN(rcvbuf);
   if (!NLMSG_OK(h, (unsigned int)ret)) {
-    OLSR_ERROR(LOG_ROUTING, "Received netlink message was malformed (ret=%d, %u)", ret, h->nlmsg_len);
+    OLSR_WARN(LOG_ROUTING, "Received netlink message was malformed (ret=%d, %u)", ret, h->nlmsg_len);
     return -1;
   }
 
diff --git a/src/linux/kernel_tunnel.c b/src/linux/kernel_tunnel.c
new file mode 100644 (file)
index 0000000..23cf7b3
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
+ * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
+ * Copyright (c) 2007, Sven-Ola for the policy routing stuff
+ * All rights reserved.
+ *
+ * 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
+ *   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
+ *   distribution.
+ * * 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
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Visit http://www.olsr.org for more information.
+ *
+ * If you find this software useful feel free to make a donation
+ * to the project. For more information see the website or contact
+ * the copyright holders.
+ *
+ */
+
+#include "defs.h"
+#include "olsr_types.h"
+#include "olsr_cookie.h"
+#include "olsr_logging.h"
+#include "ipcalc.h"
+#include "os_net.h"
+#include "os_kernel_tunnel.h"
+#include "os_kernel_routes.h"
+
+#include <assert.h>
+
+//ipip includes
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/ip.h>
+#include <linux/if_tunnel.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#include <linux/ip6_tunnel.h>
+#endif
+
+//ifup includes
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <net/if.h>
+
+static const char DEV_IPV4_TUNNEL[IFNAMSIZ] = TUNNEL_ENDPOINT_IF;
+static const char DEV_IPV6_TUNNEL[IFNAMSIZ] = TUNNEL_ENDPOINT_IF6;
+
+static bool store_iptunnel_state;
+static struct olsr_cookie_info *tunnel_cookie;
+static struct avl_tree tunnel_tree;
+
+int olsr_os_init_iptunnel(void) {
+  const char *dev = olsr_cnf->ip_version == AF_INET ? DEV_IPV4_TUNNEL : DEV_IPV6_TUNNEL;
+
+  tunnel_cookie = olsr_create_memcookie("iptunnel", sizeof(struct olsr_iptunnel_entry));
+  avl_init(&tunnel_tree, avl_comp_default, false, NULL);
+
+  store_iptunnel_state = olsr_if_isup(dev);
+  if (store_iptunnel_state) {
+    return 0;
+  }
+  if (olsr_if_set_state(dev, true)) {
+    return -1;
+  }
+
+  return olsr_os_ifip(if_nametoindex(dev), &olsr_cnf->main_addr, true);
+}
+
+void olsr_os_cleanup_iptunnel(void) {
+  while (tunnel_tree.count > 0) {
+    struct olsr_iptunnel_entry *t;
+
+    /* kill tunnel */
+    t = avl_first_element(&tunnel_tree, t, node);
+    t->usage = 1;
+
+    olsr_os_del_ipip_tunnel(t);
+  }
+  if (!store_iptunnel_state) {
+    olsr_if_set_state(olsr_cnf->ip_version == AF_INET ? DEV_IPV4_TUNNEL : DEV_IPV6_TUNNEL, false);
+  }
+
+  olsr_cleanup_memcookie(tunnel_cookie);
+}
+
+/**
+ * creates an ipip tunnel (for ipv4)
+ * @param name interface name
+ * @param target pointer to tunnel target IP, NULL if tunnel should be removed
+ * @return 0 if an error happened,
+ *   if_index for successful created tunnel, 1 for successful deleted tunnel
+ */
+static int os_ip4_tunnel(const char *name, in_addr_t *target)
+{
+  struct ifreq ifr;
+  int err;
+  struct ip_tunnel_parm p;
+
+  /* only IPIP tunnel if OLSR runs with IPv6 */
+  assert (olsr_cnf->ip_version == AF_INET);
+  memset(&p, 0, sizeof(p));
+  p.iph.version = 4;
+  p.iph.ihl = 5;
+  p.iph.ttl = 64;
+  p.iph.protocol = IPPROTO_IPIP;
+  if (target) {
+    p.iph.daddr = *target;
+  }
+  strncpy(p.name, name, IFNAMSIZ);
+
+  memset(&ifr, 0, sizeof(ifr));
+  strncpy(ifr.ifr_name, target != NULL ? DEV_IPV4_TUNNEL : name, IFNAMSIZ);
+  ifr.ifr_ifru.ifru_data = (void *) &p;
+
+  if ((err = ioctl(olsr_cnf->ioctl_s, target != NULL ? SIOCADDTUNNEL : SIOCDELTUNNEL, &ifr))) {
+    char buffer[INET6_ADDRSTRLEN];
+
+    OLSR_WARN(LOG_TUNNEL, "Cannot %s a tunnel %s to %s: %s (%d)\n",
+        target != NULL ? "add" : "remove", name,
+        target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-",
+        strerror(errno), errno);
+    return 0;
+  }
+  return target != NULL ? if_nametoindex(name) : 1;
+}
+
+/**
+ * creates an ipip tunnel (for ipv6)
+ * @param name interface name
+ * @param target pointer to tunnel target IP, NULL if tunnel should be removed
+ * @return 0 if an error happened,
+ *   if_index for successful created tunnel, 1 for successful deleted tunnel
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+static int os_ip6_tunnel(const char *name, struct in6_addr *target)
+{
+  struct ifreq ifr;
+  int err;
+  struct ip6_tnl_parm p;
+
+  /* only IP6 tunnel if OLSR runs with IPv6 */
+  assert (olsr_cnf->ip_version == AF_INET6);
+  memset(&p, 0, sizeof(p));
+  p.proto = 0; /* any protocol */
+  if (target) {
+    p.raddr = *target;
+  }
+  strncpy(p.name, name, IFNAMSIZ);
+
+  memset(&ifr, 0, sizeof(ifr));
+  strncpy(ifr.ifr_name, target != NULL ? DEV_IPV6_TUNNEL : name, IFNAMSIZ);
+  ifr.ifr_ifru.ifru_data = (void *) &p;
+
+  if ((err = ioctl(olsr_cnf->ioctl_s, target != NULL ? SIOCADDTUNNEL : SIOCDELTUNNEL, &ifr))) {
+    char buffer[INET6_ADDRSTRLEN];
+
+    OLSR_WARN(LOG_TUNNEL, "Cannot %s a tunnel %s to %s: %s (%d)\n",
+        target != NULL ? "add" : "remove", name,
+        target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-",
+        strerror(errno), errno);
+    return 0;
+  }
+  return target != NULL ? if_nametoindex(name) : 1;
+}
+#endif
+
+/**
+ * Dummy for generating an interface name for an olsr ipip tunnel
+ * @param target IP destination of the tunnel
+ * @param name pointer to output buffer (length IFNAMSIZ)
+ */
+static void generate_iptunnel_name(union olsr_ip_addr *target, char *name) {
+  static char PREFIX[] = "tnl_";
+  static uint32_t counter = 0;
+
+  snprintf(name, IFNAMSIZ, "%s%08x", PREFIX,
+      olsr_cnf->ip_version == AF_INET ? target->v4.s_addr : ++counter);
+}
+
+/**
+ * demands an ipip tunnel to a certain target. If no tunnel exists it will be created
+ * @param target ip address of the target
+ * @param transportV4 true if IPv4 traffic is used, false for IPv6 traffic
+ * @return NULL if an error happened, pointer to olsr_iptunnel_entry otherwise
+ */
+struct olsr_iptunnel_entry *olsr_os_add_ipip_tunnel(union olsr_ip_addr *target, bool transportV4 __attribute__ ((unused))) {
+  struct olsr_iptunnel_entry *t;
+
+  assert(olsr_cnf->ip_version == AF_INET6 || transportV4);
+
+  t = (struct olsr_iptunnel_entry *)avl_find(&tunnel_tree, target);
+  if (t == NULL) {
+    char name[IFNAMSIZ];
+    int if_idx;
+
+    memset(name, 0, sizeof(name));
+    generate_iptunnel_name(target, name);
+
+    if (olsr_cnf->ip_version == AF_INET) {
+      if_idx = os_ip4_tunnel(name, &target->v4.s_addr);
+    }
+    else {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+      if_idx = os_ip6_tunnel(name, &target->v6);
+#else
+      if_idx = 0;
+#endif
+    }
+
+    if (if_idx == 0) {
+      // cannot create tunnel
+      OLSR_WARN(LOG_TUNNEL, "Cannot create tunnel %s\n", name);
+      return NULL;
+    }
+
+    if (olsr_if_set_state(name, true)) {
+      if (olsr_cnf->ip_version == AF_INET) {
+        os_ip4_tunnel(name, NULL);
+      }
+      else {
+  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+        os_ip6_tunnel(name, NULL);
+  #endif
+      }
+      return NULL;
+    }
+
+    /* set originator IP for tunnel */
+    olsr_os_ifip(if_idx, &olsr_cnf->main_addr, true);
+
+    t = olsr_cookie_malloc(tunnel_cookie);
+    memcpy(&t->target, target, sizeof(*target));
+    t->node.key = &t->target;
+
+    strncpy(t->if_name, name, IFNAMSIZ);
+    t->if_index = if_idx;
+
+    avl_insert(&tunnel_tree, &t->node);
+  }
+
+  t->usage++;
+  return t;
+}
+
+/**
+ * Release an olsr ipip tunnel. Tunnel will be deleted
+ * if this was the last user
+ * @param t pointer to olsr_iptunnel_entry
+ */
+static void internal_olsr_os_del_ipip_tunnel(struct olsr_iptunnel_entry *t, bool cleanup) {
+  if (!cleanup) {
+    if (t->usage == 0) {
+      return;
+    }
+    t->usage--;
+
+    if (t->usage > 0) {
+      return;
+    }
+  }
+
+  olsr_if_set_state(t->if_name, false);
+  if (olsr_cnf->ip_version == AF_INET) {
+    os_ip4_tunnel(t->if_name, NULL);
+  }
+  else {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+    os_ip6_tunnel(t->if_name, NULL);
+#endif
+  }
+
+  avl_delete(&tunnel_tree, &t->node);
+  if (!cleanup) {
+    olsr_cookie_free(tunnel_cookie, t);
+  }
+}
+
+void olsr_os_del_ipip_tunnel(struct olsr_iptunnel_entry *t) {
+  internal_olsr_os_del_ipip_tunnel(t, false);
+}
diff --git a/src/linux/linux_net.h b/src/linux/linux_net.h
new file mode 100644 (file)
index 0000000..85074de
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux_net.h
+ *
+ *  Created on: Oct 7, 2010
+ *      Author: rogge
+ */
+
+#ifndef LINUX_NET_H_
+#define LINUX_NET_H_
+
+#include "defs.h"
+#include "interfaces.h"
+
+/*
+ * these functions are used by the common unix code, but are not
+ * exported to the OLSR core
+ */
+void net_os_restore_ifoption(struct interface *ifs);
+int net_os_set_ifoptions(const char *if_name, struct interface *iface);
+
+int join_mcast(struct interface *, int);
+
+#endif /* LINUX_NET_H_ */
index a5281b6..7508329 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
+ * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  *
  */
 
-
 /*
  * Linux spesific code
  */
 
-#include "os_net.h"
-#include "os_misc.h"
 #include "ipcalc.h"
 #include "common/string.h"
 #include "olsr_protocol.h"
 #include "olsr_logging.h"
 #include "olsr.h"
+#include "os_kernel_tunnel.h"
+#include "os_net.h"
+#include "linux/linux_net.h"
 
 #include <net/if.h>
+#include <netinet/ip.h>
 
 #include <sys/ioctl.h>
+#include <sys/utsname.h>
 
 #include <fcntl.h>
 #include <string.h>
 #include <stdio.h>
 #include <syslog.h>
-#include <errno.h>
 #include <unistd.h>
-#include <assert.h>
-#include <netinet/ip.h>
+
+#define IPV6_ADDR_LOOPBACK      0x0010U
+#define IPV6_ADDR_LINKLOCAL     0x0020U
+#define IPV6_ADDR_SITELOCAL     0x0040U
+
+/* ip forwarding */
+#define PROC_IPFORWARD_V4 "/proc/sys/net/ipv4/ip_forward"
+#define PROC_IPFORWARD_V6 "/proc/sys/net/ipv6/conf/all/forwarding"
 
 /* Redirect proc entry */
-#define REDIRECT_PROC "/proc/sys/net/ipv4/conf/%s/send_redirects"
+#define PROC_IF_REDIRECT "/proc/sys/net/ipv4/conf/%s/send_redirects"
+#define PROC_ALL_REDIRECT "/proc/sys/net/ipv4/conf/all/send_redirects"
 
 /* IP spoof proc entry */
-#define SPOOF_PROC "/proc/sys/net/ipv4/conf/%s/rp_filter"
+#define PROC_IF_SPOOF "/proc/sys/net/ipv4/conf/%s/rp_filter"
+#define PROC_ALL_SPOOF "/proc/sys/net/ipv4/conf/all/rp_filter"
+
+
+/* list of IPv6 interfaces */
+#define PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
 
 /*
  *Wireless definitions for ioctl calls
 /* The original state of the IP forwarding proc entry */
 static char orig_fwd_state;
 static char orig_global_redirect_state;
+static char orig_global_rp_filter;
+static char orig_tunnel_rp_filter;
+#if 0 // should not be necessary for IPv6 */
+static char orig_tunnel6_rp_filter;
+#endif
 
-/**
- *Bind a socket to a device
- *
- *@param sock the socket to bind
- *@param dev_name name of the device
- *
- *@return negative if error
- */
-
-static int
-bind_socket_to_device(int sock, char *dev_name)
-{
-  /*
-   *Bind to device using the SO_BINDTODEVICE flag
-   */
-  OLSR_DEBUG(LOG_NETWORKING, "Binding socket %d to device %s\n", sock, dev_name);
-  return setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, dev_name, strlen(dev_name) + 1);
-}
+static int writeToProc(const char *file, char *old, char value) {
+  int fd;
+  char rv;
 
+  if ((fd = open(file, O_RDWR)) < 0) {
+    OLSR_WARN(LOG_INTERFACE, "Cannot open proc entry %s: %s (%d)\n", file, strerror(errno), errno);
+    return -1;
+  }
 
-/**
- *Enable IP forwarding.
- *Just writing "1" to the /proc/sys/net/ipv4/ip_forward
- *if using IPv4 or /proc/sys/net/ipv6/conf/all/forwarding
- *if using IPv6.
- *Could probably drop the check for
- *"0" here and write "1" anyways.
- *
- *@param version IP version.
- *
- *@return 1 on sucess 0 on failiure
- */
-int
-enable_ip_forwarding(int version)
-{
-  const char *const procfile = version == AF_INET ? "/proc/sys/net/ipv4/ip_forward" : "/proc/sys/net/ipv6/conf/all/forwarding";
-  FILE *proc_fwd = fopen(procfile, "r");
-
-  if (proc_fwd == NULL) {
-    OLSR_WARN(LOG_NETWORKING,
-              "WARNING! Could not open the %s file to check/enable IP forwarding!\n"
-              "Are you using the procfile filesystem?\nDoes your system support IPv%d?\n"
-              "I will continue(in 3 sec) - but you should manually ensure that IP forwarding is enabled!\n\n",
-              procfile, version == AF_INET ? 4 : 6);
-    sleep(3);
-    return 0;
+  if (read(fd, &rv, 1) != 1) {
+    OLSR_WARN(LOG_INTERFACE, "Cannot read proc entry %s: %s (%d)\n", file, strerror(errno), errno);
+    return -1;
   }
-  orig_fwd_state = fgetc(proc_fwd);
-  fclose(proc_fwd);
-
-  if (orig_fwd_state == '1') {
-    OLSR_INFO(LOG_NETWORKING, "\nIP forwarding is enabled on this system\n");
-  } else {
-    proc_fwd = fopen(procfile, "w");
-    if (proc_fwd == NULL) {
-      OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\n"
-                "I will continue(in 3 sec) - but you should manually ensure that IP forwarding is enabeled!\n\n", procfile);
-      sleep(3);
-      return 0;
+
+  if (rv != value) {
+    if (lseek(fd, SEEK_SET, 0) == -1) {
+      OLSR_WARN(LOG_INTERFACE, "Cannot rewind proc entry %s: %s (%d)\n", file, strerror(errno), errno);
+      return -1;
     }
-    fputs("1", proc_fwd);
-    fclose(proc_fwd);
-  }
-  return 1;
-}
 
-int
-disable_redirects_global(int version)
-{
-  FILE *proc_redirect;
-  const char *const procfile = "/proc/sys/net/ipv4/conf/all/send_redirects";
+    if (write(fd, &value, 1) != 1) {
+      OLSR_WARN(LOG_INTERFACE, "Cannot write proc entry %s: %s (%d)\n", file, strerror(errno), errno);
+      return -1;
+    }
+  }
 
-  if (version == AF_INET6) {
+  if (close(fd) != 0) {
+    OLSR_WARN(LOG_INTERFACE, "Cannot close proc entry %s: %s (%d)\n", file, strerror(errno), errno);
     return -1;
   }
-  proc_redirect = fopen(procfile, "r");
-  if (proc_redirect == NULL) {
-    OLSR_WARN(LOG_NETWORKING,
-              "WARNING! Could not open the %s file to check/disable ICMP redirects!\n"
-              "Are you using the procfile filesystem?\n"
-              "Does your system support IPv4?\n"
-              "I will continue(in 3 sec) - but you should manually ensure that ICMP redirects are disabled!\n\n", procfile);
-    sleep(3);
-    return -1;
+
+  if (old) {
+    *old = rv;
   }
-  orig_global_redirect_state = fgetc(proc_redirect);
-  fclose(proc_redirect);
+  OLSR_DEBUG(LOG_INTERFACE, "Writing '%c' (was %c) to %s", value, rv, file);
+  return 0;
+}
 
-  if (orig_global_redirect_state == '0') {
-    return 0;
+static bool is_at_least_linuxkernel_2_6_31(void) {
+  struct utsname uts;
+
+  memset(&uts, 0, sizeof(uts));
+  if (uname(&uts)) {
+    OLSR_WARN(LOG_NETWORKING, "Cannot not read kernel version: %s (%d)\n", strerror(errno), errno);
+    return false;
   }
-  proc_redirect = fopen(procfile, "w");
-  if (proc_redirect == NULL) {
-    OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\n"
-              "I will continue(in 3 sec) - but you should manually ensure that ICMP redirect is disabled!\n\n", procfile);
-    sleep(3);
-    return 0;
+
+  if (strncmp(uts.release, "2.6.",4) != 0) {
+    return false;
   }
-  fputs("0", proc_redirect);
-  fclose(proc_redirect);
-  return 1;
+  return atoi(&uts.release[4]) >= 31;
 }
 
 /**
- *
- *@return 1 on sucess 0 on failiure
+ * Setup global interface options (icmp redirect, ip forwarding, rp_filter)
+ * @return 1 on success 0 on failure
  */
-int
-disable_redirects(const char *if_name, struct interface *iface, int version)
-{
-  FILE *proc_redirect;
-  char procfile[FILENAME_MAX];
-
-  if (version == AF_INET6) {
-    return -1;
+void
+os_init_global_ifoptions(void) {
+  if (writeToProc(olsr_cnf->ip_version == AF_INET ? PROC_IPFORWARD_V4 : PROC_IPFORWARD_V6, &orig_fwd_state, '1')) {
+    OLSR_WARN(LOG_INTERFACE, "Warning, could not enable IP forwarding!\n"
+        "you should manually ensure that IP forwarding is enabled!\n\n");
+    // TODO olsr_startup_sleep(3);
   }
 
-  /* Generate the procfile name */
-  snprintf(procfile, sizeof(procfile), REDIRECT_PROC, if_name);
-
-  proc_redirect = fopen(procfile, "r");
-  if (proc_redirect == NULL) {
-    OLSR_WARN(LOG_NETWORKING,
-              "WARNING! Could not open the %s file to check/disable ICMP redirects!\n"
-              "Are you using the procfile filesystem?\n"
-              "Does your system support IPv4?\n"
-              "I will continue(in 3 sec) - but you should manually ensure that ICMP redirects are disabled!\n\n", procfile);
-    sleep(3);
-    return 0;
+  if (olsr_cnf->smart_gw_active) {
+    char procfile[FILENAME_MAX];
+
+    /* Generate the procfile name */
+    if (olsr_cnf->ip_version == AF_INET || olsr_cnf->use_niit) {
+      snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, TUNNEL_ENDPOINT_IF);
+      if (writeToProc(procfile, &orig_tunnel_rp_filter, '0')) {
+        OLSR_WARN(LOG_INTERFACE, "WARNING! Could not disable the IP spoof filter for tunnel!\n"
+            "you should mannually ensure that IP spoof filtering is disabled!\n\n");
+
+        // TODO olsr_startup_sleep(3);
+      }
+    }
   }
-  iface->nic_state.redirect = fgetc(proc_redirect);
-  fclose(proc_redirect);
 
-  proc_redirect = fopen(procfile, "w");
-  if (proc_redirect == NULL) {
-    OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\n"
-              "I will continue(in 3 sec) - but you should manually ensure that ICMP redirect is disabled!\n\n", procfile);
-    sleep(3);
-    return 0;
+  if (olsr_cnf->ip_version == AF_INET) {
+    if (writeToProc(PROC_ALL_REDIRECT, &orig_global_redirect_state, '0')) {
+      OLSR_WARN(LOG_INTERFACE, "WARNING! Could not disable ICMP redirects!\n"
+          "you should manually ensure that ICMP redirects are disabled!\n\n");
+
+      // TODO olsr_startup_sleep(3);
+    }
+
+    /* check kernel version and disable global rp_filter */
+    if (is_at_least_linuxkernel_2_6_31()) {
+      if (writeToProc(PROC_ALL_SPOOF, &orig_global_rp_filter, '0')) {
+        OLSR_WARN(LOG_INTERFACE, "WARNING! Could not disable global rp_filter (necessary for kernel 2.6.31 and higher!\n"
+            "you should manually ensure that rp_filter is disabled!\n\n");
+
+        // TODO olsr_startup_sleep(3);
+      }
+    }
   }
-  fputs("0", proc_redirect);
-  fclose(proc_redirect);
-  return 1;
+  return;
 }
 
 /**
@@ -232,118 +206,109 @@ disable_redirects(const char *if_name, struct interface *iface, int version)
  *@return 1 on sucess 0 on failiure
  */
 int
-deactivate_spoof(const char *if_name, struct interface *iface, int version)
+net_os_set_ifoptions(const char *if_name, struct interface *iface)
 {
-  FILE *proc_spoof;
   char procfile[FILENAME_MAX];
-
-  if (version == AF_INET6) {
+  if (olsr_cnf->ip_version == AF_INET6)
     return -1;
-  }
 
   /* Generate the procfile name */
-  sprintf(procfile, SPOOF_PROC, if_name);
-
-  proc_spoof = fopen(procfile, "r");
-  if (proc_spoof == NULL) {
-    OLSR_WARN(LOG_NETWORKING,
-              "WARNING! Could not open the %s file to check/disable the IP spoof filter!\n"
-              "Are you using the procfile filesystem?\n"
-              "Does your system support IPv4?\n"
-              "I will continue(in 3 sec) - but you should manually ensure that IP spoof filtering is disabled!\n\n", procfile);
-    sleep(3);
+  snprintf(procfile, sizeof(procfile), PROC_IF_REDIRECT, if_name);
+
+  if (writeToProc(procfile, &iface->nic_state.redirect, '0')) {
+    OLSR_WARN(LOG_INTERFACE, "WARNING! Could not disable ICMP redirects!\n"
+        "you should mannually ensure that ICMP redirects are disabled!\n\n");
+    // TODO olsr_startup_sleep(3);
     return 0;
   }
-  iface->nic_state.spoof = fgetc(proc_spoof);
-  fclose(proc_spoof);
 
-  proc_spoof = fopen(procfile, "w");
-  if (proc_spoof == NULL) {
-    OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\n"
-              "I will continue(in 3 sec) - but you should manually ensure that IP spoof filtering is disabled!\n\n", procfile);
-    sleep(3);
+  /* Generate the procfile name */
+  snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, if_name);
+
+  if (writeToProc(procfile, &iface->nic_state.spoof, '0')) {
+    OLSR_WARN(LOG_INTERFACE, "WARNING! Could not disable the IP spoof filter!\n"
+        "you should mannually ensure that IP spoof filtering is disabled!\n\n");
+
+    // TODO olsr_startup_sleep(3);
     return 0;
   }
-  fputs("0", proc_spoof);
-  fclose(proc_spoof);
   return 1;
 }
 
+void net_os_restore_ifoption(struct interface *ifs) {
+  char procfile[FILENAME_MAX];
+
+  /* ICMP redirects */
+  snprintf(procfile, sizeof(procfile), PROC_IF_REDIRECT, ifs->int_name);
+  if (writeToProc(procfile, NULL, ifs->nic_state.redirect)) {
+    OLSR_WARN(LOG_INTERFACE, "Could not restore icmp_redirect for interface %s\n", ifs->int_name);
+  }
+
+  /* Spoof filter */
+  sprintf(procfile, PROC_IF_SPOOF, ifs->int_name);
+  if (writeToProc(procfile, NULL, ifs->nic_state.spoof)) {
+    OLSR_WARN(LOG_INTERFACE, "Could not restore rp_filter for interface %s\n", ifs->int_name);
+  }
+}
 /**
  *Resets the spoof filter and ICMP redirect settings
  */
 int
-restore_settings(int version)
+os_cleanup_global_ifoptions(void)
 {
-  struct interface *ifs;
-  struct list_iterator iterator;
-
-  OLSR_INFO(LOG_NETWORKING, "Restoring network state\n");
+  char procfile[FILENAME_MAX];
+  OLSR_DEBUG(LOG_INTERFACE, "Restoring network state\n");
 
   /* Restore IP forwarding to "off" */
-  if (orig_fwd_state == '0') {
-    const char *const procfile = version == AF_INET ? "/proc/sys/net/ipv4/ip_forward" : "/proc/sys/net/ipv6/conf/all/forwarding";
-    FILE *proc_fd = fopen(procfile, "w");
-
-    if (proc_fd == NULL) {
-      OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\nSettings not restored!\n", procfile);
-    } else {
-      fputc(orig_fwd_state, proc_fd);
-      fclose(proc_fd);
-    }
+  if (writeToProc(olsr_cnf->ip_version == AF_INET ? PROC_IPFORWARD_V4 : PROC_IPFORWARD_V6, NULL, orig_fwd_state)) {
+    OLSR_WARN(LOG_INTERFACE, "Could not restore ip_forward settings\n");
   }
 
-  /* Restore global ICMP redirect setting */
-  if (orig_global_redirect_state != '0') {
-    if (version == AF_INET) {
-      const char *const procfile = "/proc/sys/net/ipv4/conf/all/send_redirects";
-      FILE *proc_fd = fopen(procfile, "w");
-
-      if (proc_fd == NULL) {
-        OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\nSettings not restored!\n", procfile);
-      } else {
-        fputc(orig_global_redirect_state, proc_fd);
-        fclose(proc_fd);
-      }
+  if (olsr_cnf->smart_gw_active && (olsr_cnf->ip_version == AF_INET || olsr_cnf->use_niit)) {
+    /* Generate the procfile name */
+    snprintf(procfile, sizeof(procfile), PROC_IF_SPOOF, TUNNEL_ENDPOINT_IF);
+    if (writeToProc(procfile, NULL, orig_tunnel_rp_filter)) {
+      OLSR_WARN(LOG_INTERFACE, "WARNING! Could not restore the IP spoof filter for tunnel!\n");
     }
   }
 
-  if (version == AF_INET6) {
-    return 0;
-  }
-
-  OLSR_FOR_ALL_INTERFACES(ifs, iterator) {
-    char procfile[FILENAME_MAX];
-    FILE *proc_fd;
-    /* ICMP redirects */
-
-    /* Generate the procfile name */
-    snprintf(procfile, sizeof(procfile), REDIRECT_PROC, ifs->int_name);
-    proc_fd = fopen(procfile, "w");
-    if (proc_fd == NULL) {
-      OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\nSettings not restored!\n", procfile);
-    } else {
-      fputc(ifs->nic_state.redirect, proc_fd);
-      fclose(proc_fd);
+  if (olsr_cnf->ip_version == AF_INET) {
+    /* Restore global ICMP redirect setting */
+    if (writeToProc(PROC_ALL_REDIRECT, NULL, orig_global_redirect_state)) {
+      OLSR_WARN(LOG_INTERFACE, "Could not restore global icmp_redirect setting\n");
     }
 
-    /* Spoof filter */
-
-    /* Generate the procfile name */
-    sprintf(procfile, SPOOF_PROC, ifs->int_name);
-    proc_fd = fopen(procfile, "w");
-    if (proc_fd == NULL) {
-      OLSR_WARN(LOG_NETWORKING, "Could not open %s for writing!\nSettings not restored!\n", procfile);
-    } else {
-      fputc(ifs->nic_state.spoof, proc_fd);
-      fclose(proc_fd);
+    /* Restore global rp_filter setting for linux 2.6.31+ */
+    if (is_at_least_linuxkernel_2_6_31()) {
+      if (writeToProc(PROC_ALL_SPOOF, NULL, orig_global_rp_filter)) {
+        OLSR_WARN(LOG_INTERFACE, "Could not restore global rp_filter setting\n");
+      }
     }
   }
-
   return 1;
 }
 
 /**
+ *Bind a socket to a device
+ *
+ *@param sock the socket to bind
+ *@param dev_name name of the device
+ *
+ *@return negative if error
+ */
+
+static int
+bind_socket_to_device(int sock, char *dev_name)
+{
+  /*
+   *Bind to device using the SO_BINDTODEVICE flag
+   */
+  OLSR_DEBUG(LOG_NETWORKING, "Binding socket %d to device %s\n", sock, dev_name);
+  return setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, dev_name, strlen(dev_name) + 1);
+}
+
+
+/**
  *Creates a nonblocking broadcast socket.
  *@param sa sockaddr struct. Used for bind(2).
  *@return the FD of the socket or -1 on error.
@@ -664,6 +629,56 @@ olsr_select(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, s
 {
   return select(nfds, readfds, writefds, exceptfds, timeout);
 }
+
+bool olsr_if_isup(const char * dev)
+{
+  struct ifreq ifr;
+
+  memset(&ifr, 0, sizeof(ifr));
+  strscpy(ifr.ifr_name, dev, IFNAMSIZ);
+
+  if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
+    OLSR_WARN(LOG_INTERFACE, "ioctl SIOCGIFFLAGS (get flags) error on device %s: %s (%d)\n",
+        dev, strerror(errno), errno);
+    return 1;
+  }
+  return (ifr.ifr_flags & IFF_UP) != 0;
+}
+
+int olsr_if_set_state(const char *dev, bool up) {
+  int oldflags;
+  struct ifreq ifr;
+
+  memset(&ifr, 0, sizeof(ifr));
+  strscpy(ifr.ifr_name, dev, IFNAMSIZ);
+
+  if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
+    OLSR_WARN(LOG_INTERFACE, "ioctl SIOCGIFFLAGS (get flags) error on device %s: %s (%d)\n",
+        dev, strerror(errno), errno);
+    return 1;
+  }
+
+  oldflags = ifr.ifr_flags;
+  if (up) {
+    ifr.ifr_flags |= IFF_UP;
+  }
+  else {
+    ifr.ifr_flags &= ~IFF_UP;
+  }
+
+  if (oldflags == ifr.ifr_flags) {
+    /* interface is already up/down */
+    return 0;
+  }
+
+  if (ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0) {
+    OLSR_WARN(LOG_INTERFACE, "ioctl SIOCSIFFLAGS (set flags %s) error on device %s: %s (%d)\n",
+        up ? "up" : "down", dev, strerror(errno), errno);
+    return 1;
+  }
+  return 0;
+}
+
 /*
  * Local Variables:
  * c-basic-offset: 2
index 53a39bd..b76520a 100644 (file)
@@ -55,7 +55,6 @@
 #include "plugin_loader.h"
 #include "apm.h"
 #include "net_olsr.h"
-#include "os_misc.h"
 #include "olsr_cfg_gen.h"
 #include "common/string.h"
 #include "mid_set.h"
@@ -261,10 +260,8 @@ main(int argc, char *argv[])
   /* Initialize SPF */
   olsr_init_spf();
 
-#ifndef WIN32
-  /* Disable redirects globally */
-  disable_redirects_global(olsr_cnf->ip_version);
-#endif
+  /* set global interface options */
+  os_init_global_ifoptions();
 
   /*
    * socket for ioctl calls
@@ -300,11 +297,6 @@ main(int argc, char *argv[])
   }
 #endif
 
-  /*
-   *enable ip forwarding on host
-   */
-  enable_ip_forwarding(olsr_cnf->ip_version);
-
   /* Initialize parser */
   olsr_init_parser();
 
@@ -575,7 +567,7 @@ olsr_shutdown(void)
 #endif
 
   /* Reset network settings */
-  restore_settings(olsr_cnf->ip_version);
+  os_cleanup_global_ifoptions();
 
   /* ioctl socket */
   CLOSESOCKET(olsr_cnf->ioctl_s);
index 49518ad..c148bf4 100644 (file)
 #include "olsr_spf.h"
 #include "scheduler.h"
 #include "apm.h"
-#include "os_misc.h"
 #include "neighbor_table.h"
 #include "lq_packet.h"
 #include "common/avl.h"
 #include "net_olsr.h"
 #include "lq_plugin.h"
 #include "olsr_logging.h"
+#include "os_log.h"
 
 #include <assert.h>
 #include <stdarg.h>
index 7b65ed4..0547dfe 100644 (file)
@@ -71,7 +71,10 @@ const char *LOG_SOURCE_NAMES[] = {
   "mid",
   "duplicate-set",
   "cookie",
-  "comport"
+  "comport",
+  "apm",
+  "rtnetlink",
+  "tunnel"
 };
 
 const char *LOG_SEVERITY_NAMES[] = {
index 69603cb..046be12 100644 (file)
@@ -70,6 +70,9 @@ enum log_source {
   LOG_DUPLICATE_SET,                   //!< LOG_DUPLICATE_SET
   LOG_COOKIE,                          //!< LOG_COOKIE
   LOG_COMPORT,                         //!< LOG_COMPORT
+  LOG_APM,                             //!< LOG_APM
+  LOG_RTNETLINK,                       //!< LOG_RTNETLINK
+  LOG_TUNNEL,                          //!< LOG_TUNNEL
 
   /* this one must be the last of the enums ! */
   LOG_SOURCE_COUNT                     //!< LOG_SOURCE_COUNT
diff --git a/src/os_kernel_tunnel.h b/src/os_kernel_tunnel.h
new file mode 100644 (file)
index 0000000..15d1525
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * kernel_tunnel.h
+ *
+ *  Created on: 08.02.2010
+ *      Author: henning
+ */
+
+#ifndef KERNEL_TUNNEL_H_
+#define KERNEL_TUNNEL_H_
+
+#include <net/if.h>
+#ifdef WIN32
+/* compat for win32 */
+#include <iprtrmib.h>
+#define IF_NAMESIZE MAX_INTERFACE_NAME_LEN
+#endif
+
+#include "defs.h"
+#include "olsr_types.h"
+#include "common/avl.h"
+
+#define TUNNEL_ENDPOINT_IF "tunl0"
+#define TUNNEL_ENDPOINT_IF6 "ip6tnl0"
+
+struct olsr_iptunnel_entry {
+  struct avl_node node;
+  union olsr_ip_addr target;
+
+  char if_name[IF_NAMESIZE];
+  int if_index;
+
+  int usage;
+};
+
+int olsr_os_init_iptunnel(void);
+void olsr_os_cleanup_iptunnel(void);
+
+struct olsr_iptunnel_entry *olsr_os_add_ipip_tunnel(union olsr_ip_addr *target, bool transportV4);
+void olsr_os_del_ipip_tunnel(struct olsr_iptunnel_entry *);
+
+#endif /* KERNEL_TUNNEL_H_ */
index 125e19b..9fea123 100644 (file)
@@ -50,6 +50,8 @@
 
 #include "defs.h"
 
+void clear_console(void);
+
 void olsr_open_syslog(const char *ident);
 
 void EXPORT(olsr_print_syslog) (int level, const char *format, ...) __attribute__ ((format(printf, 2, 3)));
diff --git a/src/os_misc.h b/src/os_misc.h
deleted file mode 100644 (file)
index 5617e03..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * 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
- * are met:
- *
- * * 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
- *   distribution.
- * * 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
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Visit http://www.olsr.org for more information.
- *
- * If you find this software useful feel free to make a donation
- * to the project. For more information see the website or contact
- * the copyright holders.
- *
- */
-
-#ifndef _OLSR_MISC_H
-#define _OLSR_MISC_H
-
-#include "defs.h"
-
-void clear_console(void);
-
-int EXPORT(set_nonblocking) (int fd);
-
-#endif
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
index 9a78114..a7868f0 100644 (file)
@@ -62,38 +62,32 @@ ssize_t olsr_sendto(int, const void *, size_t, int, const union olsr_sockaddr *)
 ssize_t olsr_recvfrom(int, void *, size_t, int, union olsr_sockaddr *, socklen_t *);
 int olsr_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 
-int getsocket4(int, struct interface *, bool, uint16_t);
-int getsocket6(int, struct interface *, bool, uint16_t);
+int EXPORT(getsocket4)(int, struct interface *, bool, uint16_t);
+int EXPORT(getsocket6)(int, struct interface *, bool, uint16_t);
+
+int EXPORT(set_nonblocking) (int fd);
 
 /* OS dependent interface functions */
+void os_init_global_ifoptions(void);
+int os_cleanup_global_ifoptions(void);
+
 int os_init_interface(struct interface *, struct olsr_if_config *);
+void os_cleanup_interface(struct interface *);
 
 int chk_if_changed(struct olsr_if_config *);
 
+bool EXPORT(olsr_if_isup)(const char * dev);
+int EXPORT(olsr_if_set_state)(const char *dev, bool up);
+
 #ifdef WIN32
 void CallSignalHandler(void);
 void ListInterfaces(void);
 #endif
 
-int disable_redirects(const char *, struct interface *, int);
-
-int disable_redirects_global(int);
-
-int deactivate_spoof(const char *, struct interface *, int);
-
-int restore_settings(int);
-
-int enable_ip_forwarding(int);
-
-
 void os_set_olsr_socketoptions(int socket);
 
 int get_ipv6_address(char *, struct sockaddr_in6 *, int);
 
-bool is_if_link_up(char *);
-
-int join_mcast(struct interface *, int);
-
 /* helper function for getting a socket */
 static inline int
 getsocket46(int family, int bufferSize, struct interface *interf,
index 6fb7854..597f887 100644 (file)
 #include "hna_set.h"
 #include "common/string.h"
 
+#ifdef linux
+#include "linux/linux_net.h"
+#endif
+
 #include <assert.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <netdb.h>
 #include <unistd.h>
 #include <errno.h>
+#include <fcntl.h>
 
 #define BUFSPACE  (127*1024)    /* max. input buffer size to request */
 
-#if 0
-int
-set_flag(char *ifname, short flag __attribute__ ((unused)))
-{
-  struct ifreq ifr;
-
-  /* Get flags */
-  strscpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-  if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
-    fprintf(stderr, "ioctl (get interface flags)");
-    return -1;
-  }
-
-  strscpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-  //printf("Setting flags for if \"%s\"\n", ifr.ifr_name);
-  if ((ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) == 0) {
-    /* Add UP */
-    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
-    /* Set flags + UP */
-    if (ioctl(olsr_cnf->ioctl_s, SIOCSIFFLAGS, &ifr) < 0) {
-      fprintf(stderr, "ERROR(%s): %s\n", ifr.ifr_name, strerror(errno));
-      return -1;
-    }
-  }
-  return 1;
-}
-#endif
-
 /**
  * Checks if an initialized interface is changed
  * that is if it has been set down or the address
@@ -131,7 +108,7 @@ chk_if_changed(struct olsr_if_config *iface)
   /* Get flags (and check if interface exists) */
   if (ioctl(olsr_cnf->ioctl_s, SIOCGIFFLAGS, &ifr) < 0) {
     OLSR_WARN(LOG_INTERFACE, "No such interface: %s\n", iface->name);
-    remove_interface(&iface->interf);
+    remove_interface(iface->interf);
     return 0;
   }
   int_flags = ifr.ifr_flags;
@@ -141,7 +118,7 @@ chk_if_changed(struct olsr_if_config *iface)
    */
   if ((int_flags & IFF_UP) == 0) {
     OLSR_DEBUG(LOG_INTERFACE, "\tInterface %s not up - removing it...\n", iface->name);
-    remove_interface(&iface->interf);
+    remove_interface(iface->interf);
     return 0;
   }
 
@@ -155,13 +132,13 @@ chk_if_changed(struct olsr_if_config *iface)
   if (olsr_cnf->ip_version == AF_INET && !iface->cnf->ipv4_broadcast.v4.s_addr &&       /* Skip if fixed bcast */
       ((int_flags & IFF_BROADCAST)) == 0) {
     OLSR_DEBUG(LOG_INTERFACE, "\tNo broadcast - removing\n");
-    remove_interface(&iface->interf);
+    remove_interface(iface->interf);
     return 0;
   }
 
   if (int_flags & IFF_LOOPBACK) {
     OLSR_DEBUG(LOG_INTERFACE, "\tThis is a loopback interface - removing it...\n");
-    remove_interface(&iface->interf);
+    remove_interface(iface->interf);
     return 0;
   }
 
@@ -199,7 +176,7 @@ chk_if_changed(struct olsr_if_config *iface)
         OLSR_WARN(LOG_INTERFACE, "\tCould not find global IPv6 address for %s\n", ifr.ifr_name);
       else
         OLSR_WARN(LOG_INTERFACE, "\tCould not find an IPv6 address for %s\n", ifr.ifr_name);
-      remove_interface(&iface->interf);
+      remove_interface(iface->interf);
       return 0;
     }
 
@@ -223,7 +200,7 @@ chk_if_changed(struct olsr_if_config *iface)
     /* Check interface address (IPv4) */
     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFADDR, &ifr) < 0) {
       OLSR_DEBUG(LOG_INTERFACE, "\tCould not get address of interface - removing it\n");
-      remove_interface(&iface->interf);
+      remove_interface(iface->interf);
       return 0;
     }
 
@@ -244,7 +221,7 @@ chk_if_changed(struct olsr_if_config *iface)
     /* Check netmask */
     if (ioctl(olsr_cnf->ioctl_s, SIOCGIFNETMASK, &ifr) < 0) {
       OLSR_WARN(LOG_INTERFACE, "%s: ioctl (get broadaddr) failed", ifr.ifr_name);
-      remove_interface(&iface->interf);
+      remove_interface(iface->interf);
       return 0;
     }
 
@@ -435,12 +412,6 @@ os_init_interface(struct interface *ifp, struct olsr_if_config *iface)
       ifp->int_multicast.v4 = *(struct sockaddr_in *)(ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr));
     }
 
-    /* Deactivate IP spoof filter */
-    deactivate_spoof(ifr_basename, ifp, olsr_cnf->ip_version);
-
-    /* Disable ICMP redirects */
-    disable_redirects(ifr_basename, ifp, olsr_cnf->ip_version);
-
     ifp->int_src.v4.sin_family = AF_INET;
     ifp->int_src.v4.sin_port = htons(olsr_cnf->olsr_port);
     ifp->int_multicast.v4.sin_family = AF_INET;
@@ -485,12 +456,42 @@ os_init_interface(struct interface *ifp, struct olsr_if_config *iface)
    */
   ifp->int_name = olsr_strdup(ifr_basename);
 
-#if 0
-  ifp->gen_properties = NULL;
+  if (olsr_cnf->ip_version == AF_INET6) {
+    join_mcast(ifp, ifp->olsr_socket);
+    join_mcast(ifp, ifp->send_socket);
+  }
+  /* Set interface options */
+#ifdef linux
+  net_os_set_ifoptions(ifr_basename, ifp);
 #endif
+
   return 0;
 }
 
+void
+os_cleanup_interface(struct interface *ifp) {
+#ifdef linux
+  net_os_restore_ifoption(ifp);
+#endif
+}
+
+int
+set_nonblocking(int fd)
+{
+  /* make the fd non-blocking */
+  int socket_flags = fcntl(fd, F_GETFL);
+  if (socket_flags < 0) {
+    OLSR_WARN(LOG_NETWORKING, "Cannot get the socket flags: %s", strerror(errno));
+    return -1;
+  }
+  if (fcntl(fd, F_SETFL, socket_flags | O_NONBLOCK) < 0) {
+    OLSR_WARN(LOG_NETWORKING, "Cannot set the socket flags: %s", strerror(errno));
+    return -1;
+  }
+  return 0;
+}
+
+
 /*
  * Local Variables:
  * c-basic-offset: 2
index 2a1a792..42d7111 100644 (file)
@@ -43,7 +43,9 @@
  * System logging interface for GNU/Linux systems
  */
 
+#include "olsr_logging.h"
 #include "os_log.h"
+
 #include <syslog.h>
 #include <stdarg.h>
 
@@ -90,6 +92,36 @@ olsr_print_syslog(int level, const char *format, ...)
   return;
 }
 
+void
+clear_console(void)
+{
+  static int len = -1;
+  static char clear_buff[100];
+  int i;
+
+  if (len < 0) {
+    FILE *pip = popen("clear", "r");
+    if (pip == NULL) {
+      OLSR_WARN(LOG_MAIN, "Warning, cannot access 'clear' command.\n");
+      return;
+    }
+    for (len = 0; len < (int)sizeof(clear_buff); len++) {
+      int c = fgetc(pip);
+      if (c == EOF) {
+        break;
+      }
+      clear_buff[len] = c;
+    }
+
+    pclose(pip);
+  }
+
+  for (i = 0; i < len; i++) {
+    fputc(clear_buff[i], stdout);
+  }
+  fflush(stdout);
+}
+
 /*
  * Local Variables:
  * c-basic-offset: 2
diff --git a/src/unix/misc.c b/src/unix/misc.c
deleted file mode 100644 (file)
index 2d50baf..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * 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
- * are met:
- *
- * * 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
- *   distribution.
- * * 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
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Visit http://www.olsr.org for more information.
- *
- * If you find this software useful feel free to make a donation
- * to the project. For more information see the website or contact
- * the copyright holders.
- *
- */
-
-#include "os_misc.h"
-#include "olsr_logging.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-void
-clear_console(void)
-{
-  static int len = -1;
-  static char clear_buff[100];
-  int i;
-
-  if (len < 0) {
-    FILE *pip = popen("clear", "r");
-    if (pip == NULL) {
-      OLSR_WARN(LOG_MAIN, "Warning, cannot access 'clear' command.\n");
-      return;
-    }
-    for (len = 0; len < (int)sizeof(clear_buff); len++) {
-      int c = fgetc(pip);
-      if (c == EOF) {
-        break;
-      }
-      clear_buff[len] = c;
-    }
-
-    pclose(pip);
-  }
-
-  for (i = 0; i < len; i++) {
-    fputc(clear_buff[i], stdout);
-  }
-  fflush(stdout);
-}
-
-int
-set_nonblocking(int fd)
-{
-  /* make the fd non-blocking */
-  int socket_flags = fcntl(fd, F_GETFL);
-  if (socket_flags < 0) {
-    OLSR_WARN(LOG_NETWORKING, "Cannot get the socket flags: %s", strerror(errno));
-    return -1;
-  }
-  if (fcntl(fd, F_SETFL, socket_flags | O_NONBLOCK) < 0) {
-    OLSR_WARN(LOG_NETWORKING, "Cannot set the socket flags: %s", strerror(errno));
-    return -1;
-  }
-  return 0;
-}
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */