resolved-dns-rr.c revision fd0b4602f6332c3f1660eb208c8f5c719709a009
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt/***
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt This file is part of systemd.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Copyright 2014 Lennart Poettering
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
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
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
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 Schmidt***/
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include <math.h>
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "strv.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "resolved-dns-domain.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "resolved-dns-rr.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt DnsResourceKey *k;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt size_t l;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt l = strlen(name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k = malloc0(sizeof(DnsResourceKey) + l + 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!k)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->n_ref = 1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->class = class;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->type = type;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt strcpy((char*) k + sizeof(DnsResourceKey), name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return k;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt DnsResourceKey *k;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k = new0(DnsResourceKey, 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!k)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->n_ref = 1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->class = class;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->type = type;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->_name = name;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return k;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!k)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(k->n_ref > 0);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->n_ref++;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return k;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!k)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(k->n_ref > 0);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (k->n_ref == 1) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt free(k->_name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt free(k);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt } else
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k->n_ref--;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r <= 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (a->class != b->class)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (a->type != b->type)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(key);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(rr);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(key);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(rr);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->key->type != DNS_TYPE_CNAME)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtunsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const DnsResourceKey *k = i;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt unsigned long ul;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt ul = ul * hash_key[0] + ul + k->class;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt ul = ul * hash_key[1] + ul + k->type;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return ul;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_key_compare_func(const void *a, const void *b) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const DnsResourceKey *x = a, *y = b;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int ret;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (ret != 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return ret;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (x->type < y->type)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (x->type > y->type)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (x->class < y->class)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (x->class > y->class)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
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 char *s;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt c = dns_class_to_string(key->class);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!c) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt sprintf(cbuf, "%i", key->class);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt c = cbuf;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt t = dns_type_to_string(key->type);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!t){
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt sprintf(tbuf, "%i", key->type);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt t = tbuf;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt s = strjoin(DNS_RESOURCE_KEY_NAME(key), " ", c, " ", t, NULL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!s)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -ENOMEM;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt *ret = s;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal SchmidtDnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt DnsResourceRecord *rr;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt rr = new0(DnsResourceRecord, 1);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!rr)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
e80afdb3e4a1239ce0bffa4215d6a227caf3d833Michal Schmidt
e80afdb3e4a1239ce0bffa4215d6a227caf3d833Michal Schmidt rr->n_ref = 1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt rr->key = dns_resource_key_ref(key);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return rr;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
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
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt key = dns_resource_key_new(class, type, name);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!key)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return dns_resource_record_new(key);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!rr)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(rr->n_ref > 0);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->n_ref++;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return rr;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal SchmidtDnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!rr)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(rr->n_ref > 0);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (rr->n_ref > 1) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt rr->n_ref--;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (rr->key) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt switch(rr->key->type) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SRV:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt free(rr->srv.name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_PTR:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_NS:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_CNAME:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_DNAME:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt free(rr->ptr.name);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_HINFO:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt free(rr->hinfo.cpu);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt free(rr->hinfo.os);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_TXT:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_SPF:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt strv_free(rr->txt.strings);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SOA:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt free(rr->soa.mname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt free(rr->soa.rname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_MX:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt free(rr->mx.exchange);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_SSHFP:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt free(rr->sshfp.key);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_LOC:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_A:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_AAAA:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt default:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt free(rr->generic.data);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt dns_resource_key_unref(rr->key);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt free(rr);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
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 _cleanup_free_ char *ptr = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt int r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(ret);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(address);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(hostname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_name_reverse(family, address, &ptr);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!key)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -ENOMEM;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt ptr = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt rr = dns_resource_record_new(key);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!rr)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -ENOMEM;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt rr->ptr.name = strdup(hostname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!rr->ptr.name)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -ENOMEM;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt *ret = rr;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt rr = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtint dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt int r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(a);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(b);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_resource_key_equal(a->key, b->key);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r <= 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (a->unparseable != b->unparseable)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_SRV:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_name_equal(a->srv.name, b->srv.name);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r <= 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return a->srv.priority == b->srv.priority &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->srv.weight == b->srv.weight &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->srv.port == b->srv.port;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_PTR:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_NS:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_CNAME:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_DNAME:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return dns_name_equal(a->ptr.name, b->ptr.name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_HINFO:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return strcaseeq(a->hinfo.cpu, b->hinfo.cpu) &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt strcaseeq(a->hinfo.os, b->hinfo.os);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SPF: /* exactly the same as TXT */
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_TXT: {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt int i;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
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 true;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_A:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_AAAA:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_SOA:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_name_equal(a->soa.mname, b->soa.mname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r <= 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = dns_name_equal(a->soa.rname, b->soa.rname);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r <= 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return a->soa.serial == b->soa.serial &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->soa.refresh == b->soa.refresh &&
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt a->soa.retry == b->soa.retry &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->soa.expire == b->soa.expire &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->soa.minimum == b->soa.minimum;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_MX:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (a->mx.priority != b->mx.priority)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return dns_name_equal(a->mx.exchange, b->mx.exchange);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_LOC:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(a->loc.version == b->loc.version);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return a->loc.size == b->loc.size &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->loc.horiz_pre == b->loc.horiz_pre &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->loc.vert_pre == b->loc.vert_pre &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->loc.latitude == b->loc.latitude &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->loc.longitude == b->loc.longitude &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->loc.altitude == b->loc.altitude;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_SSHFP:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return a->sshfp.algorithm == b->sshfp.algorithm &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->sshfp.fptype == b->sshfp.fptype &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt a->sshfp.key_size == b->sshfp.key_size &&
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt memcmp(a->sshfp.key, b->sshfp.key, a->sshfp.key_size) == 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt default:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return a->generic.size == b->generic.size &&
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt }
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt}
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt
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 char *s;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt char NS = latitude >= 1U<<31 ? 'N' : 'S';
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt char EW = longitude >= 1U<<31 ? 'E' : 'W';
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt
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
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt if (asprintf(&s, "%d %d %.3f %c %d %d %.3f %c %.2fm %.2fm %.2fm %.2fm",
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt (lat / 60000 / 60),
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (lat / 60000) % 60,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (lat % 60000) / 1000.,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt NS,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (lon / 60000 / 60),
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (lon / 60000) % 60,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (lon % 60000) / 1000.,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt EW,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt alt / 100.,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt siz / 100.,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt hor / 100.,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt ver / 100.) < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return s;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char *k = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt char *s;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(rr);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = dns_resource_key_to_string(rr->key, &k);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SRV:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = asprintf(&s, "%s %u %u %u %s",
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->srv.priority,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->srv.weight,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->srv.port,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt strna(rr->srv.name));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_PTR:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_NS:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_CNAME:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_DNAME:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt s = strjoin(k, " ", rr->ptr.name, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!s)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_HINFO:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!s)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SPF: /* exactly the same as TXT */
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_TXT: {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char *t;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt t = strv_join_quoted(rr->txt.strings);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!t)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt s = strjoin(k, " ", t, NULL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!s)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -ENOMEM;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt break;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt case DNS_TYPE_A: {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char *x = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt s = strjoin(k, " ", x, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!s)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_AAAA: {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char *x = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &x);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt s = strjoin(k, " ", x, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!s)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SOA:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = asprintf(&s, "%s %s %s %u %u %u %u %u",
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt strna(rr->soa.mname),
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt strna(rr->soa.rname),
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->soa.serial,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->soa.refresh,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->soa.retry,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->soa.expire,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->soa.minimum);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_MX:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = asprintf(&s, "%s %u %s",
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->mx.priority,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->mx.exchange);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_LOC: {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char *loc;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(rr->loc.version == 0);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt loc = format_location(rr->loc.latitude,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->loc.longitude,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->loc.altitude,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->loc.size,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->loc.horiz_pre,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->loc.vert_pre);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!loc)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt s = strjoin(k, " ", loc, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!s)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_TYPE_SSHFP: {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char *x = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt x = hexmem(rr->sshfp.key, rr->sshfp.key_size);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!x)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = asprintf(&s, "%s %u %u %s",
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt k,
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt rr->sshfp.algorithm,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt rr->sshfp.fptype,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt x);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt default: {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char *x = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt x = hexmem(rr->generic.data, rr->generic.size);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!x)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt s = strjoin(k, " ", x, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!s)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt break;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt *ret = s;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtconst char *dns_class_to_string(uint16_t class) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt switch (class) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_CLASS_IN:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return "IN";
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt case DNS_CLASS_ANY:
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return "ANY";
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint dns_class_from_string(const char *s, uint16_t *class) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(s);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(class);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (strcaseeq(s, "IN"))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt *class = DNS_CLASS_IN;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt else if (strcaseeq(s, "ANY"))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt *class = DNS_TYPE_ANY;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt else
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -EINVAL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic const struct {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt uint16_t type;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *name;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt} dns_types[] = {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_A, "A" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_NS, "NS" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_CNAME, "CNAME" },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt { DNS_TYPE_SOA, "SOA" },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt { DNS_TYPE_PTR, "PTR" },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt { DNS_TYPE_HINFO, "HINFO" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_MX, "MX" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_TXT, "TXT" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_AAAA, "AAAA" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_LOC, "LOC" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_SRV, "SRV" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_SSHFP, "SSHFP" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_SPF, "SPF" },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt { DNS_TYPE_DNAME, "DNAME" },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt { DNS_TYPE_ANY, "ANY" },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt { DNS_TYPE_OPT, "OPT" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_TKEY, "TKEY" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_TSIG, "TSIG" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_IXFR, "IXFR" },
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt { DNS_TYPE_AXFR, "AXFR" },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt};
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtconst char *dns_type_to_string(uint16_t type) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt unsigned i;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt for (i = 0; i < ELEMENTSOF(dns_types); i++)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (dns_types[i].type == type)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return dns_types[i].name;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtint dns_type_from_string(const char *s, uint16_t *type) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt unsigned i;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(s);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(type);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt for (i = 0; i < ELEMENTSOF(dns_types); i++)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (strcaseeq(dns_types[i].name, s)) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt *type = dns_types[i].type;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -EINVAL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt