[Olsr-dev] ipv6 patch for txtinfo plugin

John Hay (spam-protected)
Sun Oct 14 11:58:28 CEST 2007


On Sat, Oct 13, 2007 at 03:18:25PM +0200, Bernd Petrovitsch wrote:
> On Fri, 2007-10-12 at 08:54 +0200, John Hay wrote:
> [...]
> > Here is a patch that make the txtinfo plugin work when olsr is used in
> > ipv6 "mode". Its output side seems ok, I only had to tweak the parts
> 
> Very good.
> 
> > that opened the socket and did the access control.
> 
> Hmm, on Fedora-7 I get 
> ----  snip  ----
> /usr/bin/ccache gcc -Wall -Wextra -Wold-style-definition -Wdeclaration-after-statement -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wsign-compare -Waggregate-return -Wmissing-noreturn -Wmissing-format-attribute -Wno-multichar -Wno-deprecated-declarations -Wnested-externs -Winline -Wdisabled-optimization -Werror -Os -g  -finline-functions-called-once -fearly-inlining -finline-limit=50 -fPIC -Isrc -I../../src -pthread -DOLSR_PLUGIN -DSUPPORT_OLD_PLUGIN_VERSIONS=1 -Dlinux    -c -o src/olsrd_txtinfo.o src/olsrd_txtinfo.c
> src/olsrd_txtinfo.c: In function ???plugin_ipc_init???:
> src/olsrd_txtinfo.c:178: error: ???struct sockaddr_in??? has no member named ???sin_len???
> src/olsrd_txtinfo.c:184: error: ???struct sockaddr_in6??? has no member named ???sin6_len???
> src/olsrd_txtinfo.c:190: error: ???struct sockaddr_storage??? has no member named ???ss_len???
> make[2]: *** [src/olsrd_txtinfo.o] Error 1
> ----  snip  ----
> Apparently there are no *_len fields there (and I didn't find one in the
> header files).
> Since it doesn't compile on the most recent F-7, I wonder if the *_len
> fields are a FreeBSD-only thing or what's the story behind.

Ah, I forgot (maybe just conveniently :-)) that only late BSD4.3 and
BSD4.4 derived stacks have the sin*_len elements in their sockaddr*
structures.

According to rfc 3493 that defines the "Basic Socket Interface Extensions
for IPv6" they should then also define SIN6_LEN, so it is probably best
to check for that. bind() do need the different lengths, so I came up
with this new patch. You can try that.
 
> BTW no need to send an updated patch. If it's OK, I put it into #ifdef
> and what else takes (as it is trivial to fix anyways).

Or just use yours. :-)

John
-- 
John Hay -- (spam-protected) / (spam-protected)


--- lib/txtinfo/src/olsrd_txtinfo.c.orig	2007-09-18 10:55:50.000000000 +0200
+++ lib/txtinfo/src/olsrd_txtinfo.c	2007-10-14 11:54:04.000000000 +0200
@@ -143,11 +143,14 @@
 static int
 plugin_ipc_init(void)
 {
-    struct sockaddr_in sin;
+    struct sockaddr_storage sst;
+    struct sockaddr_in *sin;
+    struct sockaddr_in6 *sin6;
     olsr_u32_t yes = 1;
+    socklen_t addrlen;
 
     /* Init ipc socket */
-    if ((ipc_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+    if ((ipc_socket = socket(olsr_cnf->ip_version, SOCK_STREAM, 0)) == -1) {
 #ifndef NODEBUG
         olsr_printf(1, "(TXTINFO) socket()=%s\n", strerror(errno));
 #endif
@@ -169,13 +172,29 @@
         /* Bind the socket */
 
         /* complete the socket structure */
-        memset(&sin, 0, sizeof(sin));
-        sin.sin_family = AF_INET;
-        sin.sin_addr.s_addr = INADDR_ANY;
-        sin.sin_port = htons(ipc_port);
+        memset(&sst, 0, sizeof(sst));
+        if (olsr_cnf->ip_version == AF_INET) {
+	    sin = (struct sockaddr_in *)&sst;
+	    sin->sin_family = AF_INET;
+	    addrlen = sizeof(struct sockaddr_in);
+#ifdef SIN6_LEN
+	    sin->sin_len = addrlen;
+#endif
+	    sin->sin_addr.s_addr = INADDR_ANY;
+	    sin->sin_port = htons(ipc_port);
+        } else {
+	    sin6 = (struct sockaddr_in6 *)&sst;
+	    sin6->sin6_family = AF_INET6;
+	    addrlen = sizeof(struct sockaddr_in6);
+#ifdef SIN6_LEN
+	    sin6->sin6_len = addrlen;
+#endif
+	    sin6->sin6_addr = in6addr_any;
+	    sin6->sin6_port = htons(ipc_port);
+        }
       
         /* bind the socket to the port number */
-        if (bind(ipc_socket, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
+        if (bind(ipc_socket, (struct sockaddr *) &sst, addrlen) == -1) {
 #ifndef NODEBUG
             olsr_printf(1, "(TXTINFO) bind()=%s\n", strerror(errno));
 #endif
@@ -204,13 +223,15 @@
 
 static void ipc_action(int fd)
 {
-    struct sockaddr_in pin;
-    char *addr;  
+    struct sockaddr_storage pin;
+    struct sockaddr_in *sin4;
+    struct sockaddr_in6 *sin6;
+    char addr[INET6_ADDRSTRLEN];
     fd_set rfds;
     struct timeval tv;
     int neighonly = 0;
 
-    socklen_t addrlen = sizeof(struct sockaddr_in);
+    socklen_t addrlen = sizeof(struct sockaddr_storage);
 
     if(ipc_open)
         return;
@@ -223,11 +244,28 @@
     }
 
     tv.tv_sec = tv.tv_usec = 0;
-    addr = inet_ntoa(pin.sin_addr);
-    if (ntohl(pin.sin_addr.s_addr) != ntohl(ipc_accept_ip.v4)) {
-        olsr_printf(1, "(TXTINFO) From host(%s) not allowed!\n", addr);
-        close(ipc_connection);
-        return;
+    if (olsr_cnf->ip_version == AF_INET) {
+        sin4 = (struct sockaddr_in *)&pin;
+        if (inet_ntop(olsr_cnf->ip_version, &sin4->sin_addr, addr,
+	    INET6_ADDRSTRLEN) == NULL)
+	      addr[0] = '\0';
+        if (!COMP_IP(&sin4->sin_addr, &ipc_accept_ip.v4)) {
+            olsr_printf(1, "(TXTINFO) From host(%s) not allowed!\n", addr);
+            close(ipc_connection);
+            return;
+        }
+    } else {
+        sin6 = (struct sockaddr_in6 *)&pin;
+        if (inet_ntop(olsr_cnf->ip_version, &sin6->sin6_addr, addr,
+	    INET6_ADDRSTRLEN) == NULL)
+	      addr[0] = '\0';
+	/* Use in6addr_any (::) in olsr.conf to allow anybody. */
+        if (!COMP_IP(&in6addr_any, &ipc_accept_ip.v6) &&
+	    !COMP_IP(&sin6->sin6_addr, &ipc_accept_ip.v6)) {
+            olsr_printf(1, "(TXTINFO) From host(%s) not allowed!\n", addr);
+            close(ipc_connection);
+            return;
+        }
     }
     ipc_open = 1;
 #ifndef NODEBUG




More information about the Olsr-dev mailing list