Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement _nss_resolver_gethostbyaddr_r() for reverse resolving #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ so = env.SharedLibrary("%s/libnss_resolver" % build_dir, Glob("src/*c"),
install_dirs = {
'pack' : ARGUMENTS.get('pack_prefix', '%s/libnss/usr/lib' % build_dir),
'local': ARGUMENTS.get('prefix', '/usr/lib'),
'azk' : '/azk/lib'
'azk' : './azk/lib'
}

for k,v in install_dirs.items():
Expand Down Expand Up @@ -109,5 +109,5 @@ env.Alias('cares' , cares)
env.Alias('cmocka' , cmocka)
env.Alias('test' , cares + cmocka + test_app)
env.Alias('pack' , cares + so_pack)
env.Alias('install', cares + ['/azk/lib'])
env.Alias('install', cares + ['./azk/lib'])
env.Alias('local-install', cares + [install_dirs['local']])
69 changes: 53 additions & 16 deletions src/nssrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@

#define ALIGN(a) (((a+sizeof(void*)-1)/sizeof(void*))*sizeof(void*))

static void
static int
pack_hostent(struct hostent *result,
char *buffer,
size_t buflen,
const char *name,
const void *addr)
const struct hostent *hent)
{
char *aliases, *r_addr, *addrlist;
size_t l, idx;
const char *name = hent->h_name;
const void *addr = hent->h_addr_list[0];
char **aliases, *r_addr, *addrlist;
size_t l, idx, aidx;

/* we can't allocate any memory, the buffer is where we need to
* return things we want to use
Expand All @@ -38,12 +39,23 @@ pack_hostent(struct hostent *result,

idx = ALIGN (l+1);

/* 2nd, the empty aliases array */
aliases = buffer + idx;
*(char **) aliases = NULL;
idx += sizeof (char*);
/* 2nd, the aliases array */
aliases = (char **)buffer + idx;
int alias_cnt = 0;
for(char** alias = hent->h_aliases; hent->h_aliases != NULL && *alias != NULL; alias++) alias_cnt++;
idx += (alias_cnt+1) * sizeof(void*);
for(alias_cnt = 0; hent->h_aliases != NULL && hent->h_aliases[alias_cnt] != NULL; alias_cnt++)
{
if(idx >= buflen)
return NSS_STATUS_TRYAGAIN;
aliases[alias_cnt] = buffer + idx;
l = strlen(hent->h_aliases[alias_cnt]) + 1;
memcpy(aliases[alias_cnt], hent->h_aliases[alias_cnt], l);
idx += l;
}
aliases[alias_cnt] = NULL;
result->h_aliases = aliases;

result->h_aliases = (char **) aliases;

result->h_addrtype = AF_INET;
result->h_length = sizeof (struct in_addr);
Expand All @@ -55,10 +67,12 @@ pack_hostent(struct hostent *result,

/* 4th, the addresses ptr array */
addrlist = buffer + idx;
//FIXME
((char **) addrlist)[0] = r_addr;
((char **) addrlist)[1] = NULL;

result->h_addr_list = (char **) addrlist;
return NSS_STATUS_SUCCESS;
}

enum nss_status
Expand Down Expand Up @@ -89,10 +103,10 @@ _nss_resolver_gethostbyname2_r (const char *name,
return NSS_STATUS_NOTFOUND;
}

pack_hostent(result, buffer, buflen, name, hosts->h_addr_list[0]);
int ok = pack_hostent(result, buffer, buflen, hosts);
ares_free_hostent(hosts);

return NSS_STATUS_SUCCESS;
return ok;
}

enum nss_status
Expand Down Expand Up @@ -122,7 +136,6 @@ _nss_resolver_gethostbyaddr_r (const void *addr,
int *errnop,
int *h_errnop)
{

if (af != AF_INET) {
*errnop = EAFNOSUPPORT;
*h_errnop = NO_DATA;
Expand All @@ -135,7 +148,31 @@ _nss_resolver_gethostbyaddr_r (const void *addr,
return NSS_STATUS_UNAVAIL;
}

*errnop = EAFNOSUPPORT;
*h_errnop = NO_DATA;
return NSS_STATUS_UNAVAIL;
const struct in_addr *address = addr;
char addrstr[INET6_ADDRSTRLEN];

sprintf(addrstr, "%s", inet_ntoa(*address));
debug("Query libnss-resolver: %s - %s", NSSRS_DEFAULT_FOLDER, addrstr);

struct hostent *hosts = nssrs_resolve(NSSRS_DEFAULT_FOLDER, addrstr);

if (!hosts || hosts->h_name == NULL) {
*errnop = ENOENT;
*h_errnop = HOST_NOT_FOUND;
if (hosts) {
ares_free_hostent(hosts);
}
debug("Host not found");
return NSS_STATUS_NOTFOUND;
}

int ok = pack_hostent(result, buffer, buflen, hosts);
ares_free_hostent(hosts);

if(ok == NSS_STATUS_TRYAGAIN)
{
*errnop = ERANGE;
*h_errnop = TRY_AGAIN;
}
return ok;
}
65 changes: 59 additions & 6 deletions src/resolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static char **copy_list(char **list) {
count++;
}

debug("list size: %d\n", count);
debug("list size: %d", count);
new_list = malloc((count+1) * sizeof(char *));
for (p = list; *p; p++) {
new_list[index] = malloc(sizeof(struct in_addr));
Expand All @@ -53,12 +53,24 @@ static char **copy_list(char **list) {
return new_list;
}

static char ** copy_string_list(char ** list)
{
char ** new_list = NULL;
int count = 0;
for(char** s = list; list != NULL && *s != NULL; s++) count++;
new_list = malloc((count+1) * sizeof(char*));
for(count = 0; list != NULL && list[count] != NULL; count++)
new_list[count] = strdup(list[count]);
new_list[count] = NULL;
return new_list;
}

void nssrs_copy_hostent(struct hostent *from, struct hostent *to) {
if (from->h_name != NULL) {
to->h_name = strdup(from->h_name);
to->h_addrtype = from->h_addrtype;
to->h_length = from->h_length;
to->h_aliases = copy_list(from->h_aliases);
to->h_aliases = copy_string_list(from->h_aliases);
to->h_addr_list = copy_list(from->h_addr_list);
}
}
Expand Down Expand Up @@ -88,16 +100,20 @@ struct hostent *nssrs_resolver_by_servers(char *name, char *nameserver) {
int status, optmask = 0;
struct ares_options options;
struct hostent *results;
struct in_addr inet_address;

status = ares_library_init(ARES_LIB_INIT_ALL);
if (status != ARES_SUCCESS) {
debug("ares_library_init: %s\n", ares_strerror(status));
return NULL;
}

optmask = ARES_OPT_SERVERS | ARES_OPT_UDP_PORT;
optmask = ARES_OPT_SERVERS | ARES_OPT_UDP_PORT | ARES_OPT_TCP_PORT;
memset(&options, 0, sizeof(options));
options.servers = NULL;
options.nservers = 0;
options.tcp_port = 53;
options.udp_port = 53;
options.flags = ARES_FLAG_NOCHECKRESP;

status = ares_init_options(&channel, &options, optmask);
Expand All @@ -117,11 +133,22 @@ struct hostent *nssrs_resolver_by_servers(char *name, char *nameserver) {
// Wait resolver
results = malloc(sizeof(struct hostent));
nssrs_init_hostent(results);
ares_gethostbyname(channel, name, AF_INET, &callback, results);
if(inet_aton(name, &inet_address) != 0)
{
ares_gethostbyaddr(channel, &inet_address, sizeof(inet_address), AF_INET, &callback, results);
}
else
{
ares_gethostbyname(channel, name, AF_INET, &callback, results);
}
wait_ares(channel);
ares_destroy(channel);
ares_library_cleanup();

debug("h_name: %s", results->h_name);
for(char** alias = results->h_aliases; results->h_aliases != NULL && *alias != NULL; alias++)
debug("h_alias: %s", *alias);

if (results->h_name != NULL) {
return results;
}
Expand All @@ -132,7 +159,33 @@ struct hostent *nssrs_resolver_by_servers(char *name, char *nameserver) {

struct hostent *nssrs_resolve(char *folder, char *domain) {
struct hostent *results = NULL;
char *file = nssrs_getfile_by_sufix(folder, domain);
char *file;
struct in_addr inet_address;

if(inet_aton(domain, &inet_address))
{
/* Make PTR address from IPv4 */
char ptraddr[29];
memset(ptraddr, 0, sizeof(ptraddr));
char *dot = domain + strlen(domain);
while(dot >= domain)
{
if(dot[0] == '.' || dot == domain)
{
char *octet = dot + 1;
if(dot == domain) octet = domain;
int len = (char*)strchrnul(octet, '.') - octet + 2;
snprintf(ptraddr + strlen(ptraddr), len, "%s.", octet);
}
dot--;
}
strcat(ptraddr, "in-addr.arpa");
file = nssrs_getfile_by_sufix(folder, ptraddr);
}
else
{
file = nssrs_getfile_by_sufix(folder, domain);
}

if (file) {
debug("resolver file: %s", file);
Expand All @@ -150,7 +203,7 @@ struct hostent *nssrs_resolve(char *folder, char *domain) {

for (i = 0; results->h_addr_list[i]; ++i) {
inet_ntop(results->h_addrtype, results->h_addr_list[i], ip, sizeof(ip));
debug("ip: %s\n", ip);
debug("ip: %s", ip);
}
}
#endif
Expand Down