aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/address.c14
-rw-r--r--src/test/test_addr.c49
2 files changed, 58 insertions, 5 deletions
diff --git a/src/common/address.c b/src/common/address.c
index 54ea5df86..00d2d100b 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -476,13 +476,17 @@ tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
return 0;
}
-/** Convert <b>addr</b> to an in-addr.arpa name or a .ip6.arpa name, and store
- * the result in the <b>outlen</b>-byte buffer at <b>out</b>. Return 0 on
- * success, -1 on failure. */
+/** Convert <b>addr</b> to an in-addr.arpa name or a .ip6.arpa name,
+ * and store the result in the <b>outlen</b>-byte buffer at
+ * <b>out</b>. Return the number of chars written to <b>out</b>, not
+ * including the trailing \0, on success. Returns -1 on failure. */
int
tor_addr_to_PTR_name(char *out, size_t outlen,
- const tor_addr_t *addr)
+ const tor_addr_t *addr)
{
+ tor_assert(out);
+ tor_assert(addr);
+
if (addr->family == AF_INET) {
uint32_t a = tor_addr_to_ipv4h(addr);
@@ -505,7 +509,7 @@ tor_addr_to_PTR_name(char *out, size_t outlen,
*cp++ = '.';
}
memcpy(cp, "ip6.arpa", 9); /* 8 characters plus NUL */
- return 0;
+ return 32 * 2 + 8;
}
return -1;
}
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index b879efd41..b14ddb3d7 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -175,6 +175,7 @@ static void
test_addr_ip6_helpers(void)
{
char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN];
+ char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN];
struct in6_addr a1, a2;
tor_addr_t t1, t2;
int r, i;
@@ -500,6 +501,54 @@ test_addr_ip6_helpers(void)
AF_INET, 0);
test_eq(i, -1);
+ /* === Test tor_addr_to_PTR_name */
+
+ /* Stage IPv4 addr */
+ memset(&sa_storage, 0, sizeof(sa_storage));
+ sin = (struct sockaddr_in *)&sa_storage;
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = htonl(0x7f010203); /* 127.1.2.3 */
+ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL);
+
+ /* Check IPv4 PTR - too short buffer */
+ test_eq(tor_addr_to_PTR_name(rbuf, 1, &t1), -1);
+ test_eq(tor_addr_to_PTR_name(rbuf,
+ strlen("3.2.1.127.in-addr.arpa") - 1,
+ &t1), -1);
+
+ /* Check IPv4 PTR - valid addr */
+ test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),
+ strlen("3.2.1.127.in-addr.arpa"));
+ test_streq(rbuf, "3.2.1.127.in-addr.arpa");
+
+ /* Invalid addr family */
+ t1.family = AF_UNSPEC;
+ test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), -1);
+
+ /* Stage IPv6 addr */
+ memset(&sa_storage, 0, sizeof(sa_storage));
+ sin6 = (struct sockaddr_in6 *)&sa_storage;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_addr.s6_addr[0] = 0x80; /* 8000::abcd */
+ sin6->sin6_addr.s6_addr[14] = 0xab;
+ sin6->sin6_addr.s6_addr[15] = 0xcd;
+
+ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL);
+
+ {
+ const char* addr_PTR = "d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0."
+ "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa";
+
+ /* Check IPv6 PTR - too short buffer */
+ test_eq(tor_addr_to_PTR_name(rbuf, 0, &t1), -1);
+ test_eq(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1), -1);
+
+ /* Check IPv6 PTR - valid addr */
+ test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),
+ strlen(addr_PTR));
+ test_streq(rbuf, addr_PTR);
+ }
+
/* test tor_addr_parse_mask_ports */
test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
0, 0, 0, 0x0000000f, 17, 47, 95);