[Babel-users] OpenBSD porting efforts

dermiste dermiste at screwball-coders.net
Mon May 17 20:02:43 UTC 2010


Hi folks,

here is the result of my efforts to port babel on OpenBSD. Everything seems to
be working fine, but I still have a problem with the linux node that does not
seem to receive the hello sent from the OpenBSD node.

here is the darcs patch


Sun May 16 20:47:58 CEST 2010  dermiste at screwball-coders.net
  * add missing headers required for OpenBSD

Sun May 16 20:49:18 CEST 2010  dermiste at screwball-coders.net
  * portability fixes

Sun May 16 20:56:02 CEST 2010  dermiste at screwball-coders.net
  * adding IPv4 support in kernel_socket.c

Sun May 16 20:57:49 CEST 2010  dermiste at screwball-coders.net
  * fixing null pointer dereferencing

Sun May 16 21:30:08 CEST 2010  dermiste at screwball-coders.net
  * portability enhancements for kernel_setup

Sun May 16 21:32:12 CEST 2010  dermiste at screwball-coders.net
  * implementing kernel_interface_wireless in kernel_socket.c

New patches:

[add missing headers required for OpenBSD
dermiste at screwball-coders.net**20100516184758
 Ignore-this: 913f62f9ec2968b89b056171678c3a80
] hunk ./kernel.c 24
 */
 
 #include <sys/time.h>
+#include <sys/param.h>
 #include <time.h>
 
 #include "babeld.h"
hunk ./kernel_socket.c 35
 
 #include <strings.h>
 #include <netinet/in.h>
+#include <netinet/icmp6.h>
 #include <arpa/inet.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
hunk ./kernel_socket.c 44
 #include <ifaddrs.h>
 #include <net/if.h>
 #include <net/if_dl.h>
+#include <net/if_media.h>
 #include <net/route.h>
 
 #include "babeld.h"
hunk ./net.c 28
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
+#include <sys/uio.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
hunk ./util.c 33
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <netinet/in.h>
 #include <arpa/inet.h>
 
 #include "babeld.h"
[portability fixes
dermiste at screwball-coders.net**20100516184918
 Ignore-this: c679725fd1af343e62262eb9a52f9936
] hunk ./babeld.c 114
 
     gettime(&now);
 
-    rfd = open("/dev/urandom", O_RDONLY);
+    rfd = open(RND_DEV, O_RDONLY);
     if(rfd < 0) {
         perror("open(random)");
     } else {
hunk ./babeld.h 83
 #endif
 #endif
 
+#if defined(__linux)
+#define RND_DEV "/dev/urandom"
+#elif defined(__OpenBSD__)
+#define RND_DEV "/dev/arandom"
+#else
+#error "don't know which random device to use"
+#endif
+
 extern struct timeval now;
 extern int debug;
 extern time_t reboot_time;
hunk ./config.c 27
 #include <string.h>
 #include <stdio.h>
 
-#ifndef __APPLE__
+#ifdef __linux
 /* Defining it rather than including <linux/rtnetlink.h> because this
  * implies <asm/types.h> on Linux 2.4 */
 #define RTPROT_BOOT 3 /* Route installed during boot */
hunk ./config.c 649
             return 0;
     } else if(proto == RTPROT_BABEL_LOCAL) {
         return 0;
-#ifndef __APPLE__
+#ifdef __linux
     } else if(proto == RTPROT_BOOT) {
         return 0;
 #endif
hunk ./kernel.c 29
 
 #include "babeld.h"
 
-#ifdef __APPLE__
-#include "kernel_socket.c"
-#else
+#ifdef __linux
 #include "kernel_netlink.c"
hunk ./kernel.c 31
+#else
+#include "kernel_socket.c"
 #endif
 
 /* Like gettimeofday, but returns monotonic time.  If POSIX clocks are not
[adding IPv4 support in kernel_socket.c
dermiste at screwball-coders.net**20100516185602
 Ignore-this: 71f88e0489e6a0cb2390060c5801f11f
] hunk ./kernel_socket.c 209
     int zero = 0;
     if(setup) {
         if(kernel_socket < 0) {
-            kernel_socket = socket(PF_ROUTE, SOCK_RAW, AF_INET6);
+            kernel_socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
             if(kernel_socket < 0)
                 return -1;
         }
hunk ./kernel_socket.c 321
     unsigned char msg[512];
     struct rt_msghdr *rtm;
     struct sockaddr_in6 *sin6;
-    int rc, len;
+    struct sockaddr_in *sin4;
+    int rc, len, ipv4;
 
hunk ./kernel_socket.c 324
-    char local[1][1][16] = IN6ADDR_LOOPBACK_INIT;
+    char local6[1][1][16] = IN6ADDR_LOOPBACK_INIT;
+    char local4[1][1][16] =
+	{{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	    0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01 }}};
 
     /* Check that the protocol family is consistent. */
     if(plen >= 96 && v4mapped(dest)) {
hunk ./kernel_socket.c 335
             errno = EINVAL;
             return -1;
         }
+        ipv4 = 1;
     } else {
         if(v4mapped(gate)) {
             errno = EINVAL;
hunk ./kernel_socket.c 341
             return -1;
         }
-    }
-
-    if(v4mapped(gate)) {
-        /* Not implemented yet. */
-        errno = ENOSYS;
-        return -1;
+        ipv4 = 0;
     }
 
     if(operation == ROUTE_MODIFY && newmetric == metric && 
hunk ./kernel_socket.c 399
         rtm->rtm_addrs |= RTA_NETMASK;
     }
 
-    sin6 = (struct sockaddr_in6 *)&msg[sizeof(struct rt_msghdr)];
-    /* Destination */
-    sin6->sin6_len = sizeof(struct sockaddr_in6);
-    sin6->sin6_family = AF_INET6;
-    sin6->sin6_addr = *((struct in6_addr *)dest);
-    sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
-    /* Gateway */
-    sin6->sin6_len = sizeof(struct sockaddr_in6);
-    sin6->sin6_family = AF_INET6;
-    if (metric == KERNEL_INFINITY) 
-        sin6->sin6_addr = *((struct in6_addr *)*local);
-    else
-        sin6->sin6_addr = *((struct in6_addr *)gate);
-    if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr))
-        SET_IN6_LINKLOCAL_IFINDEX (sin6->sin6_addr, ifindex);
-    sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
-    /* Netmask */
-    if((rtm->rtm_addrs | RTA_NETMASK) != 0) {
-        sin6->sin6_len = sizeof(struct sockaddr_in6);
-        sin6->sin6_family = AF_INET6;
-        plen2mask(plen, &sin6->sin6_addr);
-        sin6 = (struct sockaddr_in6 *)((char *)sin6 + ROUNDUP(sin6->sin6_len));
+#define push_sockaddr_in(ptr, offset) \
+	do { (ptr) = (struct sockaddr_in *)((char *)(ptr) + (offset)); \
+	     (ptr)->sin_len = sizeof(struct sockaddr_in); \
+	     (ptr)->sin_family = AF_INET; } while (0)
+
+#define get_sin_addr(dst,src) \
+	do { memcpy((dst), (src) + 12, 4); } while (0)
+
+#define push_sockaddr_in6(ptr, offset) \
+	do { (ptr) = (struct sockaddr_in6 *)((char *)(ptr) + (offset)); \
+	     (ptr)->sin6_len = sizeof(struct sockaddr_in6); \
+             (ptr)->sin6_family = AF_INET6; } while (0)
+
+#define get_sin6_addr(dst,src) \
+	do { memcpy((dst), (src), 16); } while (0)
+
+    /* KAME ipv6 stack does not support IPv4 mapped IPv6, so we have to */
+    if(ipv4) {
+	sin4 = (struct sockaddr_in *)msg;
+	/* destination */
+        push_sockaddr_in(sin4, sizeof(*rtm));
+        get_sin_addr(&(sin4->sin_addr), dest);
+	/* gateway */
+	push_sockaddr_in(sin4, ROUNDUP(sin4->sin_len));
+        if (metric == KERNEL_INFINITY)
+            get_sin_addr(&(sin4->sin_addr),**local4);
+        else
+            get_sin_addr(&(sin4->sin_addr),gate);
+	/* netmask */
+        if((rtm->rtm_addrs | RTA_NETMASK) != 0) {
+	    struct in6_addr tmp_sin6_addr;
+	    push_sockaddr_in(sin4, ROUNDUP(sin4->sin_len));
+            plen2mask(plen, &tmp_sin6_addr);
+	    get_sin_addr(&(sin4->sin_addr), (char *)&tmp_sin6_addr);
+        }
+        len = (char *)sin4 + ROUNDUP(sin4->sin_len) - (char *)msg;
+    } else {
+	sin6 = (struct sockaddr_in6 *)msg;
+	/* destination */
+	push_sockaddr_in6(sin6, sizeof(*rtm));
+        get_sin6_addr(&(sin6->sin6_addr), dest);
+	/* gateway */
+	push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len));
+        if (metric == KERNEL_INFINITY)
+            get_sin6_addr(&(sin6->sin6_addr),**local6);
+        else
+            get_sin6_addr(&(sin6->sin6_addr),gate);
+        if(IN6_IS_ADDR_LINKLOCAL (&sin6->sin6_addr))
+            SET_IN6_LINKLOCAL_IFINDEX (sin6->sin6_addr, ifindex);
+	/* netmask */
+        if((rtm->rtm_addrs | RTA_NETMASK) != 0) {
+	    push_sockaddr_in6(sin6, ROUNDUP(sin6->sin6_len));
+            plen2mask(plen, &sin6->sin6_addr);
+        }
+        len = (char *)sin6 + ROUNDUP(sin6->sin6_len) - (char *)msg;
     }
hunk ./kernel_socket.c 455
-    len = (char *)sin6 - (char *)msg;
     rtm->rtm_msglen = len;
 
     rc = write(kernel_socket, msg, rtm->rtm_msglen);
[fixing null pointer dereferencing
dermiste at screwball-coders.net**20100516185749
 Ignore-this: d2ad970be74c8719fd2d3679578efa48
] hunk ./kernel_socket.c 662
     i = 0;
 
     while(ifap && i < maxroutes) {
-        if(ifap->ifa_name == NULL || strcmp(ifap->ifa_name, ifname) != 0)
+        if(ifap->ifa_name == NULL || ifname == NULL || strcmp(ifap->ifa_name, ifname) != 0)
             goto next;
         if(ifap->ifa_addr->sa_family == AF_INET6) {
             struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ifap->ifa_addr;
[portability enhancements for kernel_setup
dermiste at screwball-coders.net**20100516193008
 Ignore-this: 243e557947eda9e5d4ffb552eb3af8ea
] hunk ./kernel_socket.c 83
 static int ifindex_lo = -1;
 static int seq;
 
-static int get_sysctl_int(char *name)
-{
-  int old;
-  size_t len = sizeof (old);
-
-  if (sysctlbyname(name, &old, &len, NULL, 0) < 0)
-    return -1;
-
-  return old;
-}
-
-static int set_sysctl_int(char *name, int new)
-{
-  int old;
-  size_t len = sizeof (old);
-
-  if (sysctlbyname(name, &old, &len, &new, sizeof (new)) < 0)
-    return -1;
-
-  return old;
-}
-
 int
 mask2len(const struct in6_addr *addr)
 {
hunk ./kernel_socket.c 137
 kernel_setup(int setup)
 {
     int rc;
-    if(setup) {
-        seq = time(NULL);
-        old_forwarding = get_sysctl_int("net.inet6.ip6.forwarding");
-        if(old_forwarding < 0) {
+    int forwarding = 1;
+    int accept_redirects = 0;
+    int mib[4];
+    size_t datasize;
+
+    mib[0] = CTL_NET;
+    mib[1] = AF_INET6;
+    seq = time(NULL);
+
+    mib[2] = IPPROTO_IPV6;
+    mib[3] = IPV6CTL_FORWARDING;
+    datasize = sizeof(old_forwarding);
+    if (setup)
+        rc = sysctl(mib, 4, &old_forwarding, &datasize,
+		    &forwarding, datasize);
+    else if (0 <= old_forwarding)
+        rc = sysctl(mib, 4, NULL, NULL,
+		    &old_forwarding, datasize);
+    if (rc == -1) {
+	if(errno == ENOMEM)
             perror("Couldn't read forwarding knob.");
hunk ./kernel_socket.c 158
-            return -1;
-        }
-        rc = set_sysctl_int("net.inet6.ip6.forwarding",1);
-        if(rc < 0) {
-            perror("Couldn't write forwarding knob.");
-            return -1;
-        }
-        old_accept_redirects = get_sysctl_int("net.inet6.icmp6.rediraccept");
-        if(old_accept_redirects < 0) {
+	else
+	    perror("Couldn't write forwarding knob.");
+        return -1;
+    }
+
+    mib[2] = IPPROTO_ICMPV6;
+    mib[3] = ICMPV6CTL_REDIRACCEPT;
+    datasize = sizeof(old_accept_redirects);
+    if (setup)
+        rc = sysctl(mib, 4, &old_accept_redirects, &datasize,
+		    &accept_redirects, datasize);
+    else if (0 <= old_accept_redirects)
+        rc = sysctl(mib, 4, NULL, NULL,
+		    &old_accept_redirects, datasize);
+    if (rc == -1) {
+	if(errno == ENOMEM)
             perror("Couldn't read accept_redirects knob.");
hunk ./kernel_socket.c 175
-            return -1;
-        }
-        rc = set_sysctl_int("net.inet6.icmp6.rediraccept",0);
-        if(rc < 0) {
-            perror("Couldn't write accept_redirects knob.");
-            return -1;
-        }
-        return 1;
-    } else {
-        if(old_forwarding >= 0) {
-            rc = set_sysctl_int("net.inet6.ip6.forwarding",old_forwarding);
-            if(rc < 0) {
-                perror("Couldn't write accept_redirects knob.\n");
-                return -1;
-            }
-        }
-        if(old_accept_redirects >= 0) {
-            rc = set_sysctl_int("net.inet6.icmp6.rediraccept",
-				old_accept_redirects);
-            if(rc < 0) {
-                perror("Couldn't write accept_redirects knob.\n");
-                return -1;
-            }
-        }
-        return 1;
+	else
+	    perror("Couldn't write accept_redirects knob.");
+        return -1;
     }
hunk ./kernel_socket.c 179
+    return 1;
 }
 
 int
[implementing kernel_interface_wireless in kernel_socket.c
dermiste at screwball-coders.net**20100516193212
 Ignore-this: 5f3dd6cf769eba0daecca1a32c58708a
] hunk ./kernel_socket.c 288
 int
 kernel_interface_wireless(const char *ifname, int ifindex)
 {
-    return -1;
+    struct ifmediareq ifmr;
+    int s, rc;
+
+    s = socket(PF_INET6, SOCK_DGRAM, 0);
+    memset(&ifmr, 0, sizeof(ifmr));
+    strncpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
+    rc = ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr);
+    close(s);
+    if (rc < 0)
+	return rc;
+    if ((ifmr.ifm_active & IFM_NMASK) == IFM_IEEE80211)
+	return 1;
+    else
+	return 0;
 }
 
 int

Context:

[Tweak retract_neighbour_routes.
Juliusz Chroboczek <jch at pps.jussieu.fr>**20100502010110] 
[Use retract_route in sundry places.
Juliusz Chroboczek <jch at pps.jussieu.fr>**20100502005047] 
[Implement retract_route.
Juliusz Chroboczek <jch at pps.jussieu.fr>**20100502004904] 
[Make change_route_metric private.
Juliusz Chroboczek <jch at pps.jussieu.fr>**20100501234222] 
[TAG babeld-1.0.1
Juliusz Chroboczek <jch at pps.jussieu.fr>**20100502011632] 
Patch bundle hash:
367277f9cbd8ea65853c76cb2ce97743c602b4be
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/babel-users/attachments/20100517/cbb35411/attachment-0001.pgp>


More information about the Babel-users mailing list