On 03/18/2013 09:43 AM, Bussi Andrea wrote:
On 03/16/2013 09:30 AM, Raj Kishore1/CHN/TCS wrote:
Hi Joe,

Thanks for the previous replies.

We have modified the pound 1.9 socket structures to listen IPV4/ipv6
address.

However when IPV4 request comes,it is mapped to IPV6 address as
::ffff:<X.X.X.X>
In case of IPV6 client, it is fetching the IPV6 address only.

Is it the right mechansim to handle ipv4 client in ipv4 mapped ipv6
address mode in pound?

Do we need to handele explicitly  the IPV4-6 mapped address in dual
stack?

I had the same problem with Pound 2.6; it seems to be an
issue in the inet_ntop function, if I'm not mistaken.

I don't believe my patch (attached below) is the right way
to solve it; the proper way should be a patched inet_ntop.

But this solved my troubles; maybe somebody else will find
it useful too.


The patch I previously posted didn't initialize
the port variable for IPv4 addresses, so the
addr2str function would print an uninitialized
stack value as the port number.

This is the right patch.

Sorry for the mistake,
                                Bussi Andrea


Best regards,
                     Bussi Andrea



If an IPv4 connection is made to an IPv6 socket then the local and
remote network addresses will be represented as IPv4-mapped addresses.
We try to print the IPv4 addresses in the usual format.

From inet_ntop man page:

BUGS
       AF_INET6 converts IPv4-mapped IPv6 addresses into an IPv6 format.

So this patch can be considered as a workaround for an inet_ntop bug.

--- Pound-2.6/svc.c.orig        2011-12-28 14:57:45.000000000 +0100
+++ Pound-2.6/svc.c     2012-10-11 11:56:15.342374373 +0200
@@ -280,10 +280,27 @@
             strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
         break;
     case AF_INET6:
-        src = (void *)&((struct sockaddr_in6 
*)addr->ai_addr)->sin6_addr.s6_addr;
-        port = ntohs(((struct sockaddr_in6 *)addr->ai_addr)->sin6_port);
-        if(inet_ntop(AF_INET6, src, buf, MAXBUF - 1) == NULL)
-            strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
+   {
+        struct sockaddr_in6* addr6=(struct sockaddr_in6 *)addr->ai_addr;
+        if( IN6_IS_ADDR_V4MAPPED( &(addr6->sin6_addr) ) ) {
+            struct sockaddr_in addr4;
+            memset(&addr4,0,sizeof(addr4));
+            addr4.sin_family=AF_INET;
+            addr4.sin_port=addr6->sin6_port;
+            port = ntohs(addr6->sin6_port);
+            memcpy(&addr4.sin_addr.s_addr,addr6->sin6_addr.s6_addr+12,
+                sizeof(addr4.sin_addr.s_addr));
+            if(inet_ntop(AF_INET, &(addr4.sin_addr.s_addr), buf,
+                MAXBUF - 1) == NULL) {
+                strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
+            }
+        } else {
+            src = (void *)&((struct sockaddr_in6 
*)addr->ai_addr)->sin6_addr.s6_addr;
+            port = ntohs(((struct sockaddr_in6 *)addr->ai_addr)->sin6_port);
+            if(inet_ntop(AF_INET6, src, buf, MAXBUF - 1) == NULL)
+                strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
+        }
+   }
         break;
     case AF_UNIX:
         strncpy(buf, (char *)addr->ai_addr, MAXBUF - 1);

Reply via email to