diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2013-04-30 16:40:00 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-05-03 20:25:46 +0200 |
commit | a398adc5b40381fc567a2aee1841b26af78aea17 (patch) | |
tree | 4de66827028e07dd9faf66f605c83050ad23afd6 | |
parent | 5a4239490c7fb7d732180a9d40f27f0247c56631 (diff) | |
download | sssd-a398adc5b40381fc567a2aee1841b26af78aea17.tar.gz sssd-a398adc5b40381fc567a2aee1841b26af78aea17.tar.xz sssd-a398adc5b40381fc567a2aee1841b26af78aea17.zip |
resolver: Return PTR record as string
This is a requirement to update the PTR records.
Includes a unit test.
-rw-r--r-- | src/resolv/async_resolv.c | 36 | ||||
-rw-r--r-- | src/resolv/async_resolv.h | 4 | ||||
-rw-r--r-- | src/tests/resolv-tests.c | 104 |
3 files changed, 144 insertions, 0 deletions
diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c index 60d9e05bf..f673a25c3 100644 --- a/src/resolv/async_resolv.c +++ b/src/resolv/async_resolv.c @@ -1416,6 +1416,42 @@ resolv_get_string_address_index(TALLOC_CTX *mem_ctx, return address; } +char * +resolv_get_string_ptr_address(TALLOC_CTX *mem_ctx, + int family, uint8_t *address) +{ + char *straddr; + + if (family == AF_INET6) { + int i; + char hexbyte[3]; + + straddr = talloc_strdup(mem_ctx, "\0"); + if (!straddr) { + return NULL; + } + + for (i = 15; i >= 0; i--) { + snprintf(hexbyte, 3, "%02x", address[i]); + straddr = talloc_asprintf_append(straddr, "%c.%c.", + hexbyte[1], hexbyte[0]); + } + straddr = talloc_asprintf_append(straddr, "ip6.arpa."); + } else if (family == AF_INET) { + straddr = talloc_asprintf(mem_ctx, + "%u.%u.%u.%u.in-addr.arpa.", + (address[3]), + (address[2]), + (address[1]), + (address[0])); + } else { + DEBUG(SSSDBG_CRIT_FAILURE, ("Unknown address family\n")); + return NULL; + } + + return straddr; +} + struct sockaddr_storage * resolv_get_sockaddr_address(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, int port) diff --git a/src/resolv/async_resolv.h b/src/resolv/async_resolv.h index 3a0255886..d759a82f3 100644 --- a/src/resolv/async_resolv.h +++ b/src/resolv/async_resolv.h @@ -121,6 +121,10 @@ resolv_get_string_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, unsigned int addrindex); +char * +resolv_get_string_ptr_address(TALLOC_CTX *mem_ctx, + int family, uint8_t *address); + #define resolv_get_string_address(mem_ctx, hostent) \ resolv_get_string_address_index(mem_ctx, hostent, 0) diff --git a/src/tests/resolv-tests.c b/src/tests/resolv-tests.c index dd212c055..49fe2a5f6 100644 --- a/src/tests/resolv-tests.c +++ b/src/tests/resolv-tests.c @@ -95,6 +95,62 @@ static int test_loop(struct resolv_test_ctx *data) return data->error; } +struct resolv_hostent * +test_create_rhostent(TALLOC_CTX *mem_ctx, + const char *hostname, const char *address) +{ + struct resolv_hostent *rhostent; + int ret; + int family; + + rhostent = talloc_zero(mem_ctx, struct resolv_hostent); + if (!rhostent) { + return NULL; + } + + rhostent->name = talloc_strdup(rhostent, hostname); + rhostent->addr_list = talloc_array(rhostent, struct resolv_addr *, 2); + if (!rhostent->name || + !rhostent->addr_list) { + goto fail; + } + + rhostent->addr_list[0] = talloc_zero(rhostent->addr_list, + struct resolv_addr); + if (!rhostent->addr_list[0]) { + goto fail; + } + rhostent->addr_list[0]->ipaddr = talloc_array(rhostent->addr_list[0], + uint8_t, + sizeof(struct in6_addr)); + if (!rhostent->addr_list[0]->ipaddr) { + goto fail; + } + + family = AF_INET; + ret = inet_pton(family, address, + rhostent->addr_list[0]->ipaddr); + if (ret != 1) { + family = AF_INET6; + ret = inet_pton(family, address, + rhostent->addr_list[0]->ipaddr); + if (ret != 1) { + goto fail; + } + } + + rhostent->addr_list[0]->ttl = RESOLV_DEFAULT_TTL; + rhostent->addr_list[1] = NULL; + rhostent->family = family; + rhostent->aliases = NULL; + + return rhostent; + +fail: + talloc_free(rhostent); + return NULL; +} + START_TEST(test_copy_hostent) { void *ctx; @@ -155,6 +211,53 @@ START_TEST(test_copy_hostent) } END_TEST +START_TEST(test_address_to_string) +{ + void *ctx; + struct resolv_hostent *rhe; + char *str_addr; + char *ptr_addr; + + ctx = talloc_new(global_talloc_context); + fail_if(ctx == NULL); + ck_leaks_push(ctx); + + rhe = test_create_rhostent(ctx, "www.example.com", "1.2.3.4"); + fail_if(rhe == NULL); + + str_addr = resolv_get_string_address_index(ctx, rhe, 0); + fail_if(str_addr == NULL); + fail_unless(strcmp(str_addr, "1.2.3.4") == 0, "Unexpected address\n"); + talloc_free(str_addr); + + ptr_addr = resolv_get_string_ptr_address(ctx, rhe->family, + rhe->addr_list[0]->ipaddr); + fail_if(ptr_addr == NULL); + fail_unless(strcmp(ptr_addr, "4.3.2.1.in-addr.arpa.") == 0, "Unexpected PTR address\n"); + talloc_free(ptr_addr); + + talloc_free(rhe); + + rhe = test_create_rhostent(ctx, "www6.example.com", "2607:f8b0:400c:c03::6a"); + fail_if(rhe == NULL); + + str_addr = resolv_get_string_address_index(ctx, rhe, 0); + fail_if(str_addr == NULL); + fail_unless(strcmp(str_addr, "2607:f8b0:400c:c03::6a") == 0, "Unexpected address\n"); + talloc_free(str_addr); + + ptr_addr = resolv_get_string_ptr_address(ctx, rhe->family, + rhe->addr_list[0]->ipaddr); + fail_if(ptr_addr == NULL); + fail_unless(strcmp(ptr_addr, + "a.6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.c.0.c.0.0.4.0.b.8.f.7.0.6.2.ip6.arpa.") == 0, "Unexpected PTR address\n"); + talloc_free(ptr_addr); + + talloc_free(rhe); + ck_leaks_pop(ctx); +} +END_TEST + static void test_ip_addr(struct tevent_req *req) { int recv_status; @@ -791,6 +894,7 @@ Suite *create_resolv_suite(void) tcase_add_checked_fixture(tc_resolv, ck_leak_check_setup, ck_leak_check_teardown); /* Do some testing */ tcase_add_test(tc_resolv, test_copy_hostent); + tcase_add_test(tc_resolv, test_address_to_string); tcase_add_test(tc_resolv, test_resolv_ip_addr); tcase_add_test(tc_resolv, test_resolv_sort_srv_reply); if (use_net_test) { |