version 1.38, 2003/09/23 20:17:11 |
version 1.38.2.2, 2005/03/10 17:15:04 |
|
|
*/ |
*/ |
|
|
static char * |
static char * |
get_remote_hostname(int socket, int use_dns) |
get_remote_hostname(int sock, int use_dns) |
{ |
{ |
struct sockaddr_storage from; |
struct sockaddr_storage from; |
int i; |
int i; |
|
|
/* Get IP address of client. */ |
/* Get IP address of client. */ |
fromlen = sizeof(from); |
fromlen = sizeof(from); |
memset(&from, 0, sizeof(from)); |
memset(&from, 0, sizeof(from)); |
if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) { |
if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { |
debug("getpeername failed: %.100s", strerror(errno)); |
debug("getpeername failed: %.100s", strerror(errno)); |
cleanup_exit(255); |
cleanup_exit(255); |
} |
} |
|
|
|
if (from.ss_family == AF_INET) |
|
check_ip_options(sock, ntop); |
|
|
if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(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"); |
fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); |
|
|
if (!use_dns) |
if (!use_dns) |
return xstrdup(ntop); |
return xstrdup(ntop); |
|
|
if (from.ss_family == AF_INET) |
|
check_ip_options(socket, ntop); |
|
|
|
debug3("Trying to reverse map address %.100s.", ntop); |
debug3("Trying to reverse map address %.100s.", ntop); |
/* Map the IP address to a host name. */ |
/* Map the IP address to a host name. */ |
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), |
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), |
|
|
*/ |
*/ |
/* IPv4 only */ |
/* IPv4 only */ |
static void |
static void |
check_ip_options(int socket, char *ipaddr) |
check_ip_options(int sock, char *ipaddr) |
{ |
{ |
u_char options[200]; |
u_char options[200]; |
char text[sizeof(options) * 3 + 1]; |
char text[sizeof(options) * 3 + 1]; |
|
|
else |
else |
ipproto = IPPROTO_IP; |
ipproto = IPPROTO_IP; |
option_size = sizeof(options); |
option_size = sizeof(options); |
if (getsockopt(socket, ipproto, IP_OPTIONS, options, |
if (getsockopt(sock, ipproto, IP_OPTIONS, options, |
&option_size) >= 0 && option_size != 0) { |
&option_size) >= 0 && option_size != 0) { |
text[0] = '\0'; |
text[0] = '\0'; |
for (i = 0; i < option_size; i++) |
for (i = 0; i < option_size; i++) |
|
|
* The returned string must be freed. |
* The returned string must be freed. |
*/ |
*/ |
static char * |
static char * |
get_socket_address(int socket, int remote, int flags) |
get_socket_address(int sock, int remote, int flags) |
{ |
{ |
struct sockaddr_storage addr; |
struct sockaddr_storage addr; |
socklen_t addrlen; |
socklen_t addrlen; |
char ntop[NI_MAXHOST]; |
char ntop[NI_MAXHOST]; |
|
int r; |
|
|
/* Get IP address of client. */ |
/* Get IP address of client. */ |
addrlen = sizeof(addr); |
addrlen = sizeof(addr); |
memset(&addr, 0, sizeof(addr)); |
memset(&addr, 0, sizeof(addr)); |
|
|
if (remote) { |
if (remote) { |
if (getpeername(socket, (struct sockaddr *)&addr, &addrlen) |
if (getpeername(sock, (struct sockaddr *)&addr, &addrlen) |
< 0) |
< 0) |
return NULL; |
return NULL; |
} else { |
} else { |
if (getsockname(socket, (struct sockaddr *)&addr, &addrlen) |
if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) |
< 0) |
< 0) |
return NULL; |
return NULL; |
} |
} |
/* Get the address in ascii. */ |
/* Get the address in ascii. */ |
if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop), |
if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, |
NULL, 0, flags) != 0) { |
sizeof(ntop), NULL, 0, flags)) != 0) { |
error("get_socket_address: getnameinfo %d failed", flags); |
error("get_socket_address: getnameinfo %d failed: %s", flags, |
|
r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); |
return NULL; |
return NULL; |
} |
} |
return xstrdup(ntop); |
return xstrdup(ntop); |
} |
} |
|
|
char * |
char * |
get_peer_ipaddr(int socket) |
get_peer_ipaddr(int sock) |
{ |
{ |
char *p; |
char *p; |
|
|
if ((p = get_socket_address(socket, 1, NI_NUMERICHOST)) != NULL) |
if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL) |
return p; |
return p; |
return xstrdup("UNKNOWN"); |
return xstrdup("UNKNOWN"); |
} |
} |
|
|
char * |
char * |
get_local_ipaddr(int socket) |
get_local_ipaddr(int sock) |
{ |
{ |
char *p; |
char *p; |
|
|
if ((p = get_socket_address(socket, 0, NI_NUMERICHOST)) != NULL) |
if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL) |
return p; |
return p; |
return xstrdup("UNKNOWN"); |
return xstrdup("UNKNOWN"); |
} |
} |
|
|
char * |
char * |
get_local_name(int socket) |
get_local_name(int sock) |
{ |
{ |
return get_socket_address(socket, 0, NI_NAMEREQD); |
return get_socket_address(sock, 0, NI_NAMEREQD); |
} |
} |
|
|
/* |
/* |
|
|
struct sockaddr_storage from; |
struct sockaddr_storage from; |
socklen_t fromlen; |
socklen_t fromlen; |
char strport[NI_MAXSERV]; |
char strport[NI_MAXSERV]; |
|
int r; |
|
|
/* Get IP address of client. */ |
/* Get IP address of client. */ |
fromlen = sizeof(from); |
fromlen = sizeof(from); |
|
|
} |
} |
} |
} |
/* Return port number. */ |
/* Return port number. */ |
if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, |
if ((r = 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"); |
fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s", |
|
r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); |
return atoi(strport); |
return atoi(strport); |
} |
} |
|
|
|
|
int |
int |
get_remote_port(void) |
get_remote_port(void) |
{ |
{ |
return get_port(0); |
static int port = -1; |
|
|
|
/* Cache to avoid getpeername() on a dead connection */ |
|
if (port == -1) |
|
port = get_port(0); |
|
|
|
return port; |
} |
} |
|
|
int |
int |