92 lines
2.3 KiB
C
92 lines
2.3 KiB
C
#include "postgres.h"
|
|
#include "fmgr.h"
|
|
#include "utils/builtins.h"
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#include <sys/types.h>
|
|
|
|
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();
|
|
}
|