>From 0b5e8e199229569e5ba1446fac844140f83a57eb Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 30 Apr 2013 16:40:00 +0200 Subject: [PATCH 2/5] resolver: Return PTR record as string This is a requirement to update the PTR records. Includes a unit test. --- src/resolv/async_resolv.c | 36 ++++++++++++++++ src/resolv/async_resolv.h | 4 ++ src/tests/resolv-tests.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c index 60d9e05bfa61f1490263a3defa21cab1c709c5ac..3a1dd533f5062399a5b449f3f6e0f351f5892624 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_asprintf(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 3a02558866a078a0f52774a3fd84f21a0709f3a1..d759a82f37fa8bebc5d6b4b6d9a65e935e4cbb52 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 dd212c055f6c25c9add3c49a701df19c2e802faf..49fe2a5f6c21988cfd1a98aac096a7f94461ce45 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) { -- 1.8.2.1