]> andersk Git - openssh.git/blobdiff - canohost.c
- (tim) [contrib/cygwin/README] add minires-devel requirement. Patch from
[openssh.git] / canohost.c
index fca7134f9e0c906749a2a47f0d0aafbbe0a93651..057f061b6aa51b5d31108974fedcfecd63cbfc04 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $");
+RCSID("$OpenBSD: canohost.c,v 1.40 2004/06/21 17:36:31 avsm Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -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
@@ -27,7 +28,7 @@ static void check_ip_options(int, char *);
  */
 
 static char *
-get_remote_hostname(int socket, int use_dns)
+get_remote_hostname(int sock, int use_dns)
 {
        struct sockaddr_storage from;
        int i;
@@ -38,33 +39,16 @@ get_remote_hostname(int socket, int use_dns)
        /* Get IP address of client. */
        fromlen = sizeof(from);
        memset(&from, 0, sizeof(from));
-       if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) {
+       if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
                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
+
+       if (from.ss_family == AF_INET)
+               check_ip_options(sock, ntop);
+
+       ipv64_normalise_mapped(&from, &fromlen);
+
        if (from.ss_family == AF_INET6)
                fromlen = sizeof(struct sockaddr_in6);
 
@@ -75,9 +59,6 @@ get_remote_hostname(int socket, int use_dns)
        if (!use_dns)
                return xstrdup(ntop);
 
-       if (from.ss_family == AF_INET)
-               check_ip_options(socket, ntop);
-
        debug3("Trying to reverse map address %.100s.", ntop);
        /* Map the IP address to a host name. */
        if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
@@ -157,7 +138,7 @@ get_remote_hostname(int socket, int use_dns)
  */
 /* IPv4 only */
 static void
-check_ip_options(int socket, char *ipaddr)
+check_ip_options(int sock, char *ipaddr)
 {
 #ifdef IP_OPTIONS
        u_char options[200];
@@ -171,7 +152,7 @@ check_ip_options(int socket, char *ipaddr)
        else
                ipproto = IPPROTO_IP;
        option_size = sizeof(options);
-       if (getsockopt(socket, ipproto, IP_OPTIONS, options,
+       if (getsockopt(sock, ipproto, IP_OPTIONS, options,
            &option_size) >= 0 && option_size != 0) {
                text[0] = '\0';
                for (i = 0; i < option_size; i++)
@@ -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
@@ -221,7 +227,7 @@ get_canonical_hostname(int use_dns)
  * The returned string must be freed.
  */
 static char *
-get_socket_address(int socket, int remote, int flags)
+get_socket_address(int sock, int remote, int flags)
 {
        struct sockaddr_storage addr;
        socklen_t addrlen;
@@ -232,11 +238,11 @@ get_socket_address(int socket, int remote, int flags)
        memset(&addr, 0, sizeof(addr));
 
        if (remote) {
-               if (getpeername(socket, (struct sockaddr *)&addr, &addrlen)
+               if (getpeername(sock, (struct sockaddr *)&addr, &addrlen)
                    < 0)
                        return NULL;
        } else {
-               if (getsockname(socket, (struct sockaddr *)&addr, &addrlen)
+               if (getsockname(sock, (struct sockaddr *)&addr, &addrlen)
                    < 0)
                        return NULL;
        }
@@ -255,29 +261,29 @@ get_socket_address(int socket, int remote, int flags)
 }
 
 char *
-get_peer_ipaddr(int socket)
+get_peer_ipaddr(int sock)
 {
        char *p;
 
-       if ((p = get_socket_address(socket, 1, NI_NUMERICHOST)) != NULL)
+       if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
                return p;
        return xstrdup("UNKNOWN");
 }
 
 char *
-get_local_ipaddr(int socket)
+get_local_ipaddr(int sock)
 {
        char *p;
 
-       if ((p = get_socket_address(socket, 0, NI_NUMERICHOST)) != NULL)
+       if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
                return p;
        return xstrdup("UNKNOWN");
 }
 
 char *
-get_local_name(int socket)
+get_local_name(int sock)
 {
-       return get_socket_address(socket, 0, NI_NAMEREQD);
+       return get_socket_address(sock, 0, NI_NAMEREQD);
 }
 
 /*
This page took 0.046867 seconds and 4 git commands to generate.