]> andersk Git - openssh.git/blobdiff - canohost.c
- (djm) [canohost.c] Move IPv4inV6 mapped address normalisation to its own
[openssh.git] / canohost.c
index fca7134f9e0c906749a2a47f0d0aafbbe0a93651..f5145922e6c8050003e9e40d8eebe3d216ece2a8 100644 (file)
@@ -20,6 +20,7 @@ RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $");
 #include "canohost.h"
 
 static void check_ip_options(int, char *);
+static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
 
 /*
  * Return the canonical name of the host at the other end of the socket. The
@@ -42,29 +43,9 @@ get_remote_hostname(int socket, int use_dns)
                debug("getpeername failed: %.100s", strerror(errno));
                cleanup_exit(255);
        }
-#ifdef IPV4_IN_IPV6
-       if (from.ss_family == AF_INET6) {
-               struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from;
-
-               /* Detect IPv4 in IPv6 mapped address and convert it to */
-               /* plain (AF_INET) IPv4 address */
-               if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) {
-                       struct sockaddr_in *from4 = (struct sockaddr_in *)&from;
-                       struct in_addr addr;
-                       u_int16_t port;
-
-                       memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr));
-                       port = from6->sin6_port;
-
-                       memset(&from, 0, sizeof(from));
-
-                       from4->sin_family = AF_INET;
-                       fromlen = sizeof(*from4);
-                       memcpy(&from4->sin_addr, &addr, sizeof(addr));
-                       from4->sin_port = port;
-               }
-       }
-#endif
+
+       ipv64_normalise_mapped(&from, &fromlen);
+
        if (from.ss_family == AF_INET6)
                fromlen = sizeof(struct sockaddr_in6);
 
@@ -185,6 +166,31 @@ check_ip_options(int socket, char *ipaddr)
 #endif /* IP_OPTIONS */
 }
 
+static void
+ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
+{
+       struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
+       struct sockaddr_in *a4 = (struct sockaddr_in *)addr;
+       struct in_addr inaddr;
+       u_int16_t port;
+
+       if (addr->ss_family != AF_INET6 || 
+           !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
+               return;
+
+       debug3("Normalising mapped IPv4 in IPv6 address");
+
+       memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
+       port = a6->sin6_port;
+
+       memset(addr, 0, sizeof(*a4));
+
+       a4->sin_family = AF_INET;
+       *len = sizeof(*a4);
+       memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));
+       a4->sin_port = port;
+}
+
 /*
  * Return the canonical name of the host in the other side of the current
  * connection.  The host name is cached, so it is efficient to call this
This page took 1.157461 seconds and 4 git commands to generate.