#include "postgres.h" #include "fmgr.h" #include "utils/builtins.h" #include #include #include #include PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(rdns_lookup); Datum rdns_lookup(PG_FUNCTION_ARGS) { struct in_addr iaddr; char host[512]; struct sockaddr_in sa; int r; char* ip = text_to_cstring(PG_GETARG_TEXT_PP(0)); memset(&iaddr, 0, sizeof(struct in_addr)); memset(&sa, 0, sizeof(struct sockaddr_in)); memset(host, 0, 512); inet_aton(ip, &iaddr); sa.sin_family = AF_INET; sa.sin_addr = iaddr; r = getnameinfo((struct sockaddr*)(&sa), sizeof(struct sockaddr_in), host, 512, 0, 0, NI_NAMEREQD); if (r == EAI_NONAME) PG_RETURN_NULL(); if (r) { ereport(ERROR, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("getnameinfo failed! %s", gai_strerror(r)))); } PG_RETURN_TEXT_P(cstring_to_text(host)); } PG_FUNCTION_INFO_V1(circular_rdns_lookup); Datum circular_rdns_lookup(PG_FUNCTION_ARGS) { struct in_addr iaddr; char host[512]; struct sockaddr_in sa; int r; struct addrinfo hint; struct addrinfo* results; char* ip = text_to_cstring(PG_GETARG_TEXT_PP(0)); struct addrinfo* c; memset(&iaddr, 0, sizeof(struct in_addr)); memset(&sa, 0, sizeof(struct sockaddr_in)); memset(host, 0, 512); memset(&hint, 0, sizeof(struct addrinfo)); inet_aton(ip, &iaddr); sa.sin_family = AF_INET; sa.sin_addr = iaddr; r = getnameinfo((struct sockaddr*)(&sa), sizeof(struct sockaddr_in), host, 512, 0, 0, NI_NAMEREQD); if (r == EAI_NONAME) PG_RETURN_NULL(); if (r) { ereport(NOTICE, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("getnameinfo failed for IP `%s`, %s", ip, gai_strerror(r)))); PG_RETURN_NULL(); } hint.ai_family = AF_INET; r = getaddrinfo(host, 0, &hint, &results); if (r) { ereport(NOTICE, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("getaddrinfo failed for host `%s`, %s", host, gai_strerror(r)))); PG_RETURN_NULL(); } c = results; while (c) { struct addrinfo* current = c; c = current->ai_next; if (current->ai_family != AF_INET) continue; if (((struct sockaddr_in*)current->ai_addr)->sin_addr.s_addr == iaddr.s_addr) { freeaddrinfo(results); PG_RETURN_TEXT_P(cstring_to_text(host)); } } freeaddrinfo(results); PG_RETURN_NULL(); }