*/
#include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.21 2001/02/08 19:30:51 itojun Exp $");
+RCSID("$OpenBSD: canohost.c,v 1.31 2002/02/27 21:23:13 stevesk Exp $");
#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "canohost.h"
-void check_ip_options(int socket, char *ipaddr);
+static void check_ip_options(int, char *);
/*
* Return the canonical name of the host at the other end of the socket. The
* caller should free the returned string with xfree.
*/
-char *
-get_remote_hostname(int socket, int reverse_mapping_check)
+static char *
+get_remote_hostname(int socket, int verify_reverse_mapping)
{
struct sockaddr_storage from;
int i;
check_ip_options(socket, ntop);
if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
- NULL, 0, NI_NUMERICHOST) != 0)
+ NULL, 0, NI_NUMERICHOST) != 0)
fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
+ 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),
- NULL, 0, NI_NAMEREQD) != 0) {
+ NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
log("Could not reverse map address %.100s.", ntop);
return xstrdup(ntop);
if (isupper(name[i]))
name[i] = tolower(name[i]);
- if (!reverse_mapping_check)
+ if (!verify_reverse_mapping)
return xstrdup(name);
/*
* Map it back to an IP address and check that the given
* exit here if we detect any IP options.
*/
/* IPv4 only */
-void
+static void
check_ip_options(int socket, char *ipaddr)
{
- u_char options[200], *ucp;
- char text[1024], *cp;
+ u_char options[200];
+ char text[sizeof(options) * 3 + 1];
socklen_t option_size;
- int ipproto;
+ int i, ipproto;
struct protoent *ip;
if ((ip = getprotobyname("ip")) != NULL)
else
ipproto = IPPROTO_IP;
option_size = sizeof(options);
- if (getsockopt(socket, ipproto, IP_OPTIONS, (void *)options,
+ if (getsockopt(socket, ipproto, IP_OPTIONS, options,
&option_size) >= 0 && option_size != 0) {
- cp = text;
- /* Note: "text" buffer must be at least 3x as big as options. */
- for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3)
- sprintf(cp, " %2.2x", *ucp);
+ text[0] = '\0';
+ for (i = 0; i < option_size; i++)
+ snprintf(text + i*3, sizeof(text) - i*3,
+ " %2.2x", options[i]);
log("Connection from %.100s with IP options:%.800s",
ipaddr, text);
packet_disconnect("Connection from %.100s with IP options:%.800s",
*/
const char *
-get_canonical_hostname(int reverse_mapping_check)
+get_canonical_hostname(int verify_reverse_mapping)
{
static char *canonical_host_name = NULL;
- static int reverse_mapping_checked = 0;
+ static int verify_reverse_mapping_done = 0;
/* Check if we have previously retrieved name with same option. */
if (canonical_host_name != NULL) {
- if (reverse_mapping_checked != reverse_mapping_check)
+ if (verify_reverse_mapping_done != verify_reverse_mapping)
xfree(canonical_host_name);
else
return canonical_host_name;
/* Get the real hostname if socket; otherwise return UNKNOWN. */
if (packet_connection_is_on_socket())
canonical_host_name = get_remote_hostname(
- packet_get_connection_in(), reverse_mapping_check);
+ packet_get_connection_in(), verify_reverse_mapping);
else
canonical_host_name = xstrdup("UNKNOWN");
- reverse_mapping_checked = reverse_mapping_check;
+ verify_reverse_mapping_done = verify_reverse_mapping;
return canonical_host_name;
}
* Returns the remote IP-address of socket as a string. The returned
* string must be freed.
*/
-
-char *
-get_peer_ipaddr(int socket)
+static char *
+get_socket_address(int socket, int remote, int flags)
{
- struct sockaddr_storage from;
- socklen_t fromlen;
+ struct sockaddr_storage addr;
+ socklen_t addrlen;
char ntop[NI_MAXHOST];
/* Get IP address of client. */
- fromlen = sizeof(from);
- memset(&from, 0, sizeof(from));
- if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) {
- debug("get_peer_ipaddr: getpeername failed: %.100s", strerror(errno));
- return NULL;
+ addrlen = sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+
+ if (remote) {
+ if (getpeername(socket, (struct sockaddr *)&addr, &addrlen)
+ < 0) {
+ debug("get_socket_ipaddr: getpeername failed: %.100s",
+ strerror(errno));
+ return NULL;
+ }
+ } else {
+ if (getsockname(socket, (struct sockaddr *)&addr, &addrlen)
+ < 0) {
+ debug("get_socket_ipaddr: getsockname failed: %.100s",
+ strerror(errno));
+ return NULL;
+ }
}
- /* Get the IP address in ascii. */
- if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
- NULL, 0, NI_NUMERICHOST) != 0) {
- error("get_peer_ipaddr: getnameinfo NI_NUMERICHOST failed");
+ /* Get the address in ascii. */
+ if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop),
+ NULL, 0, flags) != 0) {
+ error("get_socket_ipaddr: getnameinfo %d failed", flags);
return NULL;
}
return xstrdup(ntop);
}
+char *
+get_peer_ipaddr(int socket)
+{
+ return get_socket_address(socket, 1, NI_NUMERICHOST);
+}
+
+char *
+get_local_ipaddr(int socket)
+{
+ return get_socket_address(socket, 0, NI_NUMERICHOST);
+}
+
+char *
+get_local_name(int socket)
+{
+ return get_socket_address(socket, 0, NI_NAMEREQD);
+}
+
/*
* Returns the IP-address of the remote host as a string. The returned
* string must not be freed.
*/
const char *
-get_remote_ipaddr()
+get_remote_ipaddr(void)
{
static char *canonical_host_ip = NULL;
return canonical_host_ip;
}
+const char *
+get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping)
+{
+ static const char *remote = "";
+ if (utmp_len > 0)
+ remote = get_canonical_hostname(verify_reverse_mapping);
+ if (utmp_len == 0 || strlen(remote) > utmp_len)
+ remote = get_remote_ipaddr();
+ return remote;
+}
+
/* Returns the local/remote port for the socket. */
-int
+static int
get_sock_port(int sock, int local)
{
struct sockaddr_storage from;
}
/* Return port number. */
if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
- strport, sizeof(strport), NI_NUMERICSERV) != 0)
+ strport, sizeof(strport), NI_NUMERICSERV) != 0)
fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed");
return atoi(strport);
}
/* Returns remote/local port number for the current connection. */
-int
+static int
get_port(int local)
{
/*
}
int
-get_remote_port()
+get_remote_port(void)
{
return get_port(0);
}
int
-get_local_port()
+get_local_port(void)
{
return get_port(1);
}