- (djm) [canohost.c] Move IPv4inV6 mapped address normalisation to its own

function and call it unconditionally
This commit is contained in:
Damien Miller 2003-11-24 12:57:25 +11:00
parent 5924ceb22d
commit 927f52783e
2 changed files with 32 additions and 22 deletions

View File

@ -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 $

View 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;
ipv64_normalise_mapped(&from, &fromlen);
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_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