You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Edward Rudd <ed...@omegaware.com> on 2005/03/18 03:39:57 UTC

why are ipv4 address being mapped as ipv6?

I have an ftpd protocol module for apache
(http://www.outoforder.cc/projects/apache/mod_ftpd) and have been tracking
down a bug that a user is having and have finally tracked down the cause
of the issue.. I

mod_ftpd is running on a (linux in this case 2.4 or 2.6 kernel) system w/
IPV4 and IPV6 support enabled. (in apache 2.0.48 or 2.0.53)

client logs into the ftp server and issues a PASV command.  The docs and
*current practive* specify that the ftp server should bind to a port under
the same IP family as the original connection came in on. IF the client
uses the newer EPSV command they can specify the family
  'EPSV 1' for IPV4
  'EPSV 2' for IPV6
  'EPSV' then use the same family that the connection came in on.

The issue is, when you have IPV6 enabled the r->connection->local_addr
socket structure has a ->family member of APR_INET6 even if the connection
came in under an IPV4 connection.  and apr_sockaddr_ip_get(&ipaddr,
r->connection->local_addr) will set ip_addr to the IPV4 ip address.

Why is the family set to APR_INET6 for an IPV4 incoming connection, and is
there a way for me to *truly* figure out how the connection really came in
originally.



Re: why are ipv4 address being mapped as ipv6?

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Thu, Mar 17, 2005 at 09:39:57PM -0500, Edward Rudd wrote:
> Why is the family set to APR_INET6 for an IPV4 incoming connection, and is
> there a way for me to *truly* figure out how the connection really came in
> originally.

whenOn Linux, the default is to use IPv4 mapped IPv6 addresses, see the
recently released RFC4038 for more details, but in summary; Apache binds
to :: and IPv4 packets are accepted on this socket - they get addresses
that look like; ::ffff:192.0.2.0, APR generally hides this as much as it
can, but the family will be set to APR_INET6 because after all - it is
an IPv6 socket.

A block like:

#if APR_HAVE_IPV6
    if (sockaddr->family == AF_INET6 &&
        IN6_IS_ADDR_V4MAPPED((struct in6_addr *)sockaddr->ipaddr_ptr)) {
		/* Address is IPv4-mapped-IPv6 */
    }
#endif	    

... will let you determine it's mapped nature. But it might be easier
to bind to the local sockaddr from the existing connected socket, it
should also be mapped, and even if you bind to say ::ffff:192.0.2.1
with family = INET6 the OS will translate that into a plain old
IPv4 bind on 192.0.2.1.

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net

Re: why are ipv4 address being mapped as ipv6?

Posted by Edward Rudd <ed...@omegaware.com>.
On Fri, 18 Mar 2005 09:24:16 +0000, Colm MacCarthaigh wrote:


> A block like:
> 
> #if APR_HAVE_IPV6
>     if (sockaddr->family == AF_INET6 &&
>         IN6_IS_ADDR_V4MAPPED((struct in6_addr *)sockaddr->ipaddr_ptr)) {
> 		/* Address is IPv4-mapped-IPv6 */
>     }
> #endif	    
> 

Thanks, that worked perfectly.