resolved-dns-rr.c revision fd0b4602f6332c3f1660eb208c8f5c719709a009
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt This file is part of systemd.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Copyright 2014 Lennart Poettering
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt systemd is free software; you can redistribute it and/or modify it
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt under the terms of the GNU Lesser General Public License as published by
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt the Free Software Foundation; either version 2.1 of the License, or
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (at your option) any later version.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt systemd is distributed in the hope that it will be useful, but
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt WITHOUT ANY WARRANTY; without even the implied warranty of
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Lesser General Public License for more details.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt You should have received a copy of the GNU Lesser General Public License
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt along with systemd; If not, see <http://www.gnu.org/licenses/>.
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt strcpy((char*) k + sizeof(DnsResourceKey), name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtunsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt unsigned long ul;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_compare_func(const void *a, const void *b) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const DnsResourceKey *x = a, *y = b;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt char cbuf[DECIMAL_STR_MAX(uint16_t)], tbuf[DECIMAL_STR_MAX(uint16_t)];
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *c, *t;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt s = strjoin(DNS_RESOURCE_KEY_NAME(key), " ", c, " ", t, NULL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal SchmidtDnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal SchmidtDnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt key = dns_resource_key_new(class, type, name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtint dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtint dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_name_equal(a->srv.name, b->srv.name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return dns_name_equal(a->ptr.name, b->ptr.name);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return strcaseeq(a->hinfo.cpu, b->hinfo.cpu) &&
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SPF: /* exactly the same as TXT */
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt for (i = 0; a->txt.strings[i] || b->txt.strings[i]; i++)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!streq_ptr(a->txt.strings[i], b->txt.strings[i]))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return false;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_name_equal(a->soa.mname, b->soa.mname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_name_equal(a->soa.rname, b->soa.rname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return dns_name_equal(a->mx.exchange, b->mx.exchange);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return a->sshfp.algorithm == b->sshfp.algorithm &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt memcmp(a->sshfp.key, b->sshfp.key, a->sshfp.key_size) == 0;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidtstatic char* format_location(uint32_t latitude, uint32_t longitude, uint32_t altitude,
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt uint8_t size, uint8_t horiz_pre, uint8_t vert_pre) {
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt int lat = latitude >= 1U<<31 ? (int) (latitude - (1U<<31)) : (int) ((1U<<31) - latitude);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt int lon = longitude >= 1U<<31 ? (int) (longitude - (1U<<31)) : (int) ((1U<<31) - longitude);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt double alt = altitude >= 10000000u ? altitude - 10000000u : -(double)(10000000u - altitude);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt double siz = (size >> 4) * exp10((double) (size & 0xF));
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt double hor = (horiz_pre >> 4) * exp10((double) (horiz_pre & 0xF));
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt double ver = (vert_pre >> 4) * exp10((double) (vert_pre & 0xF));
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt if (asprintf(&s, "%d %d %.3f %c %d %d %.3f %c %.2fm %.2fm %.2fm %.2fm",
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SPF: /* exactly the same as TXT */
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &x);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt x = hexmem(rr->sshfp.key, rr->sshfp.key_size);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt x = hexmem(rr->generic.data, rr->generic.size);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtconst char *dns_class_to_string(uint16_t class) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return "ANY";
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_class_from_string(const char *s, uint16_t *class) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic const struct {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtconst char *dns_type_to_string(uint16_t type) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtint dns_type_from_string(const char *s, uint16_t *type) {