diff options
author | Colin Watson <cjwatson@debian.org> | 2004-03-01 02:25:32 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2004-03-01 02:25:32 +0000 |
commit | ea8116a11e3de70036dbc665ccb0d486cf89cac9 (patch) | |
tree | d73ccdff78d8608e156465af42e6a1b3527fb2d6 /canohost.c | |
parent | e39b311381a5609cc05acf298c42fba196dc524b (diff) | |
parent | f5bda272678ec6dccaa5f29379cf60cb855018e8 (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.c | 60 |
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" |
15 | RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $"); | 15 | RCSID("$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 | ||
22 | static void check_ip_options(int, char *); | 22 | static void check_ip_options(int, char *); |
23 | static 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 | ||
169 | static void | ||
170 | ipv64_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 | ||