summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--canohost.c52
2 files changed, 34 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f4a1f8d..4aa9e1d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+20031123
+ - (djm) [canohost.c] Move IPv4inV6 mapped address normalisation to its own
+ function and call it unconditionally
+
20031122
- (dtucker) [channels.c] Make AIX write limit code clearer. Suggested by djm@
- (dtucker) [auth-passwd.c openbsd-compat/port-aix.c openbsd-compat/port-aix.h]
@@ -1510,4 +1514,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
-$Id: ChangeLog,v 1.3125 2003/11/22 04:02:42 djm Exp $
+$Id: ChangeLog,v 1.3126 2003/11/24 01:57:25 djm Exp $
diff --git a/canohost.c b/canohost.c
index fca7134f..f5145922 100644
--- a/canohost.c
+++ b/canohost.c
@@ -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