summaryrefslogtreecommitdiff
path: root/canohost.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2004-03-01 02:25:32 +0000
committerColin Watson <cjwatson@debian.org>2004-03-01 02:25:32 +0000
commitea8116a11e3de70036dbc665ccb0d486cf89cac9 (patch)
treed73ccdff78d8608e156465af42e6a1b3527fb2d6 /canohost.c
parente39b311381a5609cc05acf298c42fba196dc524b (diff)
parentf5bda272678ec6dccaa5f29379cf60cb855018e8 (diff)
Merge 3.8p1 to the trunk. This builds and runs, but I haven't tested it
extensively yet. ProtocolKeepAlives is now just a compatibility alias for ServerAliveInterval.
Diffstat (limited to 'canohost.c')
-rw-r--r--canohost.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/canohost.c b/canohost.c
index 438175f76..f5145922e 100644
--- a/canohost.c
+++ b/canohost.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $"); 15RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $");
16 16
17#include "packet.h" 17#include "packet.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -20,6 +20,7 @@ RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $");
20#include "canohost.h" 20#include "canohost.h"
21 21
22static void check_ip_options(int, char *); 22static void check_ip_options(int, char *);
23static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
23 24
24/* 25/*
25 * Return the canonical name of the host at the other end of the socket. The 26 * Return the canonical name of the host at the other end of the socket. The
@@ -40,31 +41,11 @@ get_remote_hostname(int socket, int use_dns)
40 memset(&from, 0, sizeof(from)); 41 memset(&from, 0, sizeof(from));
41 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) { 42 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) {
42 debug("getpeername failed: %.100s", strerror(errno)); 43 debug("getpeername failed: %.100s", strerror(errno));
43 fatal_cleanup(); 44 cleanup_exit(255);
44 } 45 }
45#ifdef IPV4_IN_IPV6 46
46 if (from.ss_family == AF_INET6) { 47 ipv64_normalise_mapped(&from, &fromlen);
47 struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; 48
48
49 /* Detect IPv4 in IPv6 mapped address and convert it to */
50 /* plain (AF_INET) IPv4 address */
51 if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) {
52 struct sockaddr_in *from4 = (struct sockaddr_in *)&from;
53 struct in_addr addr;
54 u_int16_t port;
55
56 memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr));
57 port = from6->sin6_port;
58
59 memset(&from, 0, sizeof(from));
60
61 from4->sin_family = AF_INET;
62 fromlen = sizeof(*from4);
63 memcpy(&from4->sin_addr, &addr, sizeof(addr));
64 from4->sin_port = port;
65 }
66 }
67#endif
68 if (from.ss_family == AF_INET6) 49 if (from.ss_family == AF_INET6)
69 fromlen = sizeof(struct sockaddr_in6); 50 fromlen = sizeof(struct sockaddr_in6);
70 51
@@ -185,6 +166,31 @@ check_ip_options(int socket, char *ipaddr)
185#endif /* IP_OPTIONS */ 166#endif /* IP_OPTIONS */
186} 167}
187 168
169static void
170ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
171{
172 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
173 struct sockaddr_in *a4 = (struct sockaddr_in *)addr;
174 struct in_addr inaddr;
175 u_int16_t port;
176
177 if (addr->ss_family != AF_INET6 ||
178 !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
179 return;
180
181 debug3("Normalising mapped IPv4 in IPv6 address");
182
183 memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
184 port = a6->sin6_port;
185
186 memset(addr, 0, sizeof(*a4));
187
188 a4->sin_family = AF_INET;
189 *len = sizeof(*a4);
190 memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));
191 a4->sin_port = port;
192}
193
188/* 194/*
189 * Return the canonical name of the host in the other side of the current 195 * Return the canonical name of the host in the other side of the current
190 * connection. The host name is cached, so it is efficient to call this 196 * connection. The host name is cached, so it is efficient to call this
@@ -296,7 +302,7 @@ get_remote_ipaddr(void)
296 canonical_host_ip = 302 canonical_host_ip =
297 get_peer_ipaddr(packet_get_connection_in()); 303 get_peer_ipaddr(packet_get_connection_in());
298 if (canonical_host_ip == NULL) 304 if (canonical_host_ip == NULL)
299 fatal_cleanup(); 305 cleanup_exit(255);
300 } else { 306 } else {
301 /* If not on socket, return UNKNOWN. */ 307 /* If not on socket, return UNKNOWN. */
302 canonical_host_ip = xstrdup("UNKNOWN"); 308 canonical_host_ip = xstrdup("UNKNOWN");
@@ -336,7 +342,7 @@ get_sock_port(int sock, int local)
336 } else { 342 } else {
337 if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { 343 if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
338 debug("getpeername failed: %.100s", strerror(errno)); 344 debug("getpeername failed: %.100s", strerror(errno));
339 fatal_cleanup(); 345 cleanup_exit(255);
340 } 346 }
341 } 347 }
342 348