X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fresolve%2Fresolved-dns-domain.c;h=1bb011d9e72297197c2886d1ccb493644d0d29b2;hp=27739c1e57342ea654c214973c29643b81bbbb70;hb=7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cd;hpb=1fa65c593c6d2fbafe9d0f7caa6eb1c8034da2e0 diff --git a/src/resolve/resolved-dns-domain.c b/src/resolve/resolved-dns-domain.c index 27739c1e5..1bb011d9e 100644 --- a/src/resolve/resolved-dns-domain.c +++ b/src/resolve/resolved-dns-domain.c @@ -88,7 +88,7 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) { } else return -EINVAL; - } else if (*n >= ' ' && *n != 127) { + } else if ((uint8_t) *n >= (uint8_t) ' ' && *n != 127) { /* Normal character */ *(d++) = *(n++); @@ -141,13 +141,13 @@ int dns_label_escape(const char *p, size_t l, char **ret) { /* Proper character */ *(q++) = *p; - } else if (*p >= ' ' && *p != 127) { + } else if ((uint8_t) *p >= (uint8_t) ' ' && *p != 127) { /* Everything else */ *(q++) = '\\'; - *(q++) = '0' + (char) ((unsigned) *p / 100); - *(q++) = '0' + (char) (((unsigned) *p / 10) % 10); - *(q++) = '0' + (char) ((unsigned) *p % 10); + *(q++) = '0' + (char) ((uint8_t) *p / 100); + *(q++) = '0' + (char) (((uint8_t) *p / 10) % 10); + *(q++) = '0' + (char) ((uint8_t) *p % 10); } else return -EINVAL; @@ -172,7 +172,6 @@ int dns_name_normalize(const char *s, char **_ret) { int r; assert(s); - assert(_ret); for (;;) { _cleanup_free_ char *t = NULL; @@ -203,19 +202,25 @@ int dns_name_normalize(const char *s, char **_ret) { n += r; } + if (n > DNS_NAME_MAX) + return -EINVAL; + if (!GREEDY_REALLOC(ret, allocated, n + 1)) return -ENOMEM; ret[n] = 0; - *_ret = ret; - ret = NULL; + + if (_ret) { + *_ret = ret; + ret = NULL; + } return 0; } unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_SIZE]) { const char *p = s; - unsigned long ul = 0; + unsigned long ul = hash_key[0]; int r; assert(p); @@ -230,7 +235,7 @@ unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_ label[r] = 0; ascii_strlower(label); - ul = hash_key[0] * ul + ul + string_hash_func(label, hash_key); + ul = ul * hash_key[1] + ul + string_hash_func(label, hash_key); } return ul; @@ -357,6 +362,93 @@ int dns_name_reverse(int family, const union in_addr_union *a, char **ret) { return 0; } +int dns_name_address(const char *p, int *family, union in_addr_union *address) { + int r; + + assert(p); + assert(family); + assert(address); + + r = dns_name_endswith(p, "in-addr.arpa"); + if (r < 0) + return r; + if (r > 0) { + uint8_t a[4]; + unsigned i; + + for (i = 0; i < ELEMENTSOF(a); i++) { + char label[DNS_LABEL_MAX+1]; + + r = dns_label_unescape(&p, label, sizeof(label)); + if (r < 0) + return r; + if (r == 0) + return -EINVAL; + if (r > 3) + return -EINVAL; + + r = safe_atou8(label, &a[i]); + if (r < 0) + return r; + } + + r = dns_name_equal(p, "in-addr.arpa"); + if (r <= 0) + return r; + + *family = AF_INET; + address->in.s_addr = htobe32(((uint32_t) a[3] << 24) | + ((uint32_t) a[2] << 16) | + ((uint32_t) a[1] << 8) | + (uint32_t) a[0]); + + return 1; + } + + r = dns_name_endswith(p, "ip6.arpa"); + if (r < 0) + return r; + if (r > 0) { + struct in6_addr a; + unsigned i; + + for (i = 0; i < ELEMENTSOF(a.s6_addr); i++) { + char label[DNS_LABEL_MAX+1]; + int x, y; + + r = dns_label_unescape(&p, label, sizeof(label)); + if (r <= 0) + return r; + if (r != 1) + return -EINVAL; + x = unhexchar(label[0]); + if (x < 0) + return -EINVAL; + + r = dns_label_unescape(&p, label, sizeof(label)); + if (r <= 0) + return r; + if (r != 1) + return -EINVAL; + y = unhexchar(label[0]); + if (y < 0) + return -EINVAL; + + a.s6_addr[ELEMENTSOF(a.s6_addr) - i - 1] = (uint8_t) y << 4 | (uint8_t) x; + } + + r = dns_name_equal(p, "ip6.arpa"); + if (r <= 0) + return r; + + *family = AF_INET6; + address->in6 = a; + return 1; + } + + return 0; +} + int dns_name_root(const char *name) { char label[DNS_LABEL_MAX+1]; int r; @@ -379,7 +471,6 @@ int dns_name_single_label(const char *name) { r = dns_label_unescape(&name, label, sizeof(label)); if (r < 0) return r; - if (r == 0) return 0;