/** * Fill `p_addr' with socket's remote address/port information. */ int socket_addr_getpeername(socket_addr_t *p_addr, int fd) { socklen_t addr_len; g_return_val_if_fail(p_addr, -1); g_return_val_if_fail(fd >= 0, -1); errno = 0; addr_len = socket_addr_init(p_addr, NET_TYPE_IPV4); if ( -1 != getpeername(fd, socket_addr_get_sockaddr(p_addr), &addr_len) && AF_INET == socket_addr_get_family(p_addr) ) { return 0; } #ifdef HAS_IPV6 errno = 0; addr_len = socket_addr_init(p_addr, NET_TYPE_IPV6); if ( -1 != getpeername(fd, socket_addr_get_sockaddr(p_addr), &addr_len) && AF_INET6 == socket_addr_get_family(p_addr) ) { return 0; } #endif /* HAS_IPV6 */ return -1; }
/** * Resolves an IP address to a hostname per DNS. * * @param ha The host address to resolve. * @return On success, the hostname is returned. Otherwise, NULL is * returned. The resulting string points to a static buffer. */ const char * host_addr_to_name(host_addr_t addr) { socket_addr_t sa; if (host_addr_can_convert(addr, NET_TYPE_IPV4)) { (void) host_addr_convert(addr, &addr, NET_TYPE_IPV4); } if (0 == socket_addr_set(&sa, addr, 0)) { return NULL; } #ifdef HAS_GETNAMEINFO { static char host[1025]; int error; error = getnameinfo(socket_addr_get_const_sockaddr(&sa), socket_addr_get_len(&sa), host, sizeof host, NULL, 0, 0); if (error) { char buf[HOST_ADDR_BUFLEN]; host_addr_to_string_buf(addr, buf, sizeof buf); g_message("getnameinfo() failed for \"%s\": %s", buf, gai_strerror(error)); return NULL; } return host; } #else /* !HAS_GETNAMEINFO */ { const struct hostent *he; socklen_t len = 0; const char *ptr = NULL; switch (host_addr_net(addr)) { case NET_TYPE_IPV4: ptr = cast_to_gchar_ptr(&sa.inet4.sin_addr); len = sizeof sa.inet4.sin_addr; break; case NET_TYPE_IPV6: #ifdef HAS_IPV6 ptr = cast_to_gchar_ptr(&sa.inet6.sin6_addr); len = sizeof sa.inet6.sin6_addr; break; #endif /* HAS_IPV6 */ case NET_TYPE_LOCAL: case NET_TYPE_NONE: return NULL; } g_return_val_if_fail(ptr, NULL); g_return_val_if_fail(0 != len, NULL); he = gethostbyaddr(ptr, len, socket_addr_get_family(&sa)); if (!he) { char buf[HOST_ADDR_BUFLEN]; host_addr_to_string_buf(addr, buf, sizeof buf); gethostbyname_error(buf); return NULL; } return he->h_name; } #endif /* HAS_GETNAMEINFO */ }