resolved-dns-rr.c revision 58db254ade4fb2ef77de68f28c4f13814819f6a1
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2014 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <math.h>
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering#include "alloc-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "dns-domain.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "dns-type.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "hexdecoct.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "resolved-dns-packet.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "resolved-dns-rr.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "string-util.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "strv.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom GundersenDnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DnsResourceKey *k;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering size_t l;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek assert(name);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering l = strlen(name);
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering k = malloc0(sizeof(DnsResourceKey) + l + 1);
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering if (!k)
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->n_ref = 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->class = class;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->type = type;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering strcpy((char*) k + sizeof(DnsResourceKey), name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceKey* dns_resource_key_new_cname(const DnsResourceKey *key) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_resource_key_new(key->class, DNS_TYPE_CNAME, DNS_RESOURCE_KEY_NAME(key));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(cname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(IN_SET(cname->key->type, DNS_TYPE_CNAME, DNS_TYPE_DNAME));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (cname->key->type == DNS_TYPE_CNAME)
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering return dns_resource_key_new(key->class, key->type, cname->cname.name);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DnsResourceKey *k;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering char *destination = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_name_change_suffix(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname->key), cname->dname.name, &destination);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_resource_key_ref((DnsResourceKey*) key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k = dns_resource_key_new_consume(key->class, key->type, destination);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!k) {
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering free(destination);
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering return NULL;
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering }
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering return k;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering }
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart PoetteringDnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DnsResourceKey *k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(name);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k = new0(DnsResourceKey, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!k)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->n_ref = 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->class = class;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->type = type;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->_name = name;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!k)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering assert(k->n_ref > 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->n_ref++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!k)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(k->n_ref > 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (k->n_ref == 1) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(k->_name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(k);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k->n_ref--;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r <= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (a->class != b->class)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (a->type != b->type)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rr);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rr);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (rr->key->type == DNS_TYPE_CNAME)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_name_equal(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(rr->key));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (rr->key->type == DNS_TYPE_DNAME)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(rr->key));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void dns_resource_key_hash_func(const void *i, struct siphash *state) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const DnsResourceKey *k = i;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(k);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), state);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering siphash24_compress(&k->class, sizeof(k->class), state);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering siphash24_compress(&k->type, sizeof(k->type), state);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int dns_resource_key_compare_func(const void *a, const void *b) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const DnsResourceKey *x = a, *y = b;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt int ret;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (ret != 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return ret;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (x->type < y->type)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (x->type > y->type)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (x->class < y->class)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (x->class > y->class)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringconst struct hash_ops dns_resource_key_hash_ops = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .hash = dns_resource_key_hash_func,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .compare = dns_resource_key_compare_func
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering};
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char cbuf[strlen("CLASS") + DECIMAL_STR_MAX(uint16_t)], tbuf[strlen("TYPE") + DECIMAL_STR_MAX(uint16_t)];
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *c, *t;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *s;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c = dns_class_to_string(key->class);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!c) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen sprintf(cbuf, "CLASS%u", key->class);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c = cbuf;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t = dns_type_to_string(key->type);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!t){
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sprintf(tbuf, "TYPE%u", key->type);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t = tbuf;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (asprintf(&s, "%s %s %-5s", DNS_RESOURCE_KEY_NAME(key), c, t) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *ret = s;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DnsResourceRecord *rr;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr = new0(DnsResourceRecord, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!rr)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->n_ref = 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->key = dns_resource_key_ref(key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return rr;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering key = dns_resource_key_new(class, type, name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!key)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_resource_record_new(key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!rr)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rr->n_ref > 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->n_ref++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return rr;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!rr)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rr->n_ref > 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (rr->n_ref > 1) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->n_ref--;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (rr->key) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt switch(rr->key->type) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_SRV:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(rr->srv.name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_PTR:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_NS:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_CNAME:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_DNAME:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(rr->ptr.name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_HINFO:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(rr->hinfo.cpu);
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering free(rr->hinfo.os);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_TXT:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_SPF:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dns_txt_item_free_all(rr->txt.items);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_SOA:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(rr->soa.mname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(rr->soa.rname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_MX:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(rr->mx.exchange);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_DS:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(rr->ds.digest);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_SSHFP:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->sshfp.fingerprint);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_DNSKEY:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->dnskey.key);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_RRSIG:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->rrsig.signer);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->rrsig.signature);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_NSEC:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->nsec.next_domain_name);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering bitmap_free(rr->nsec.types);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_NSEC3:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->nsec3.next_hashed_name);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->nsec3.salt);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering bitmap_free(rr->nsec3.types);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_LOC:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_A:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering case DNS_TYPE_AAAA:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering break;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering default:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr->generic.data);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering dns_resource_key_unref(rr->key);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(rr);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringint dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_free_ char *ptr = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(ret);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(address);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(hostname);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = dns_name_reverse(family, address, &ptr);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!key)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return -ENOMEM;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering ptr = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering rr = dns_resource_record_new(key);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!rr)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return -ENOMEM;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering rr->ptr.name = strdup(hostname);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if (!rr->ptr.name)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return -ENOMEM;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering *ret = rr;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering rr = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringint dns_resource_record_new_address(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering DnsResourceRecord *rr;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(ret);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(address);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(family);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (family == AF_INET) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, name);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (!rr)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return -ENOMEM;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering rr->a.in_addr = address->in;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering } else if (family == AF_INET6) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, name);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (!rr)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return -ENOMEM;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering rr->aaaa.in6_addr = address->in6;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering } else
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return -EAFNOSUPPORT;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering *ret = rr;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return 0;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering}
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poetteringint dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering int r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(a);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(b);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = dns_resource_key_equal(a->key, b->key);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r <= 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (a->unparseable != b->unparseable)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return 0;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering case DNS_TYPE_SRV:
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering r = dns_name_equal(a->srv.name, b->srv.name);
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering if (r <= 0)
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering return r;
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering return a->srv.priority == b->srv.priority &&
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering a->srv.weight == b->srv.weight &&
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering a->srv.port == b->srv.port;
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering case DNS_TYPE_PTR:
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering case DNS_TYPE_NS:
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering case DNS_TYPE_CNAME:
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering case DNS_TYPE_DNAME:
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return dns_name_equal(a->ptr.name, b->ptr.name);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering case DNS_TYPE_HINFO:
c4147df156835513c43260a14fc9f7af177f737fLennart Poettering return strcaseeq(a->hinfo.cpu, b->hinfo.cpu) &&
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering strcaseeq(a->hinfo.os, b->hinfo.os);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering case DNS_TYPE_SPF: /* exactly the same as TXT */
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering case DNS_TYPE_TXT:
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return dns_txt_item_equal(a->txt.items, b->txt.items);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_A:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_AAAA:
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_SOA:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = dns_name_equal(a->soa.mname, b->soa.mname);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r <= 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_name_equal(a->soa.rname, b->soa.rname);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r <= 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return a->soa.serial == b->soa.serial &&
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering a->soa.refresh == b->soa.refresh &&
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering a->soa.retry == b->soa.retry &&
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen a->soa.expire == b->soa.expire &&
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering a->soa.minimum == b->soa.minimum;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_MX:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (a->mx.priority != b->mx.priority)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return dns_name_equal(a->mx.exchange, b->mx.exchange);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_LOC:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(a->loc.version == b->loc.version);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return a->loc.size == b->loc.size &&
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen a->loc.horiz_pre == b->loc.horiz_pre &&
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering a->loc.vert_pre == b->loc.vert_pre &&
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering a->loc.latitude == b->loc.latitude &&
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering a->loc.longitude == b->loc.longitude &&
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering a->loc.altitude == b->loc.altitude;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_DS:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return a->ds.key_tag == b->ds.key_tag &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->ds.algorithm == b->ds.algorithm &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->ds.digest_type == b->ds.digest_type &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->ds.digest_size == b->ds.digest_size &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcmp(a->ds.digest, b->ds.digest, a->ds.digest_size) == 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_SSHFP:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return a->sshfp.algorithm == b->sshfp.algorithm &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->sshfp.fptype == b->sshfp.fptype &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->sshfp.fingerprint_size == b->sshfp.fingerprint_size &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcmp(a->sshfp.fingerprint, b->sshfp.fingerprint, a->sshfp.fingerprint_size) == 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_DNSKEY:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return a->dnskey.zone_key_flag == b->dnskey.zone_key_flag &&
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen a->dnskey.sep_flag == b->dnskey.sep_flag &&
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen a->dnskey.algorithm == b->dnskey.algorithm &&
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen a->dnskey.key_size == b->dnskey.key_size &&
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen memcmp(a->dnskey.key, b->dnskey.key, a->dnskey.key_size) == 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_RRSIG:
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering /* do the fast comparisons first */
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (a->rrsig.type_covered != b->rrsig.type_covered ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering a->rrsig.algorithm != b->rrsig.algorithm ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering a->rrsig.labels != b->rrsig.labels ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering a->rrsig.original_ttl != b->rrsig.original_ttl ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering a->rrsig.expiration != b->rrsig.expiration ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering a->rrsig.inception != b->rrsig.inception ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering a->rrsig.key_tag != b->rrsig.key_tag ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering a->rrsig.signature_size != b->rrsig.signature_size ||
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering memcmp(a->rrsig.signature, b->rrsig.signature, a->rrsig.signature_size) != 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return false;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_name_equal(a->rrsig.signer, b->rrsig.signer);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_NSEC:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return dns_name_equal(a->nsec.next_domain_name, b->nsec.next_domain_name) &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bitmap_equal(a->nsec.types, b->nsec.types);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_NSEC3:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return a->nsec3.algorithm == b->nsec3.algorithm &&
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering a->nsec3.flags == b->nsec3.flags &&
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering a->nsec3.iterations == b->nsec3.iterations &&
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering a->nsec3.salt_size == b->nsec3.salt_size &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcmp(a->nsec3.salt, b->nsec3.salt, a->nsec3.salt_size) == 0 &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcmp(a->nsec3.next_hashed_name, b->nsec3.next_hashed_name, a->nsec3.next_hashed_name_size) == 0 &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bitmap_equal(a->nsec3.types, b->nsec3.types);
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering default:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return a->generic.size == b->generic.size &&
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering }
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering}
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poetteringstatic char* format_location(uint32_t latitude, uint32_t longitude, uint32_t altitude,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen uint8_t size, uint8_t horiz_pre, uint8_t vert_pre) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *s;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char NS = latitude >= 1U<<31 ? 'N' : 'S';
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char EW = longitude >= 1U<<31 ? 'E' : 'W';
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int lat = latitude >= 1U<<31 ? (int) (latitude - (1U<<31)) : (int) ((1U<<31) - latitude);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering int lon = longitude >= 1U<<31 ? (int) (longitude - (1U<<31)) : (int) ((1U<<31) - longitude);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering double alt = altitude >= 10000000u ? altitude - 10000000u : -(double)(10000000u - altitude);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering double siz = (size >> 4) * exp10((double) (size & 0xF));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering double hor = (horiz_pre >> 4) * exp10((double) (horiz_pre & 0xF));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering double ver = (vert_pre >> 4) * exp10((double) (vert_pre & 0xF));
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (asprintf(&s, "%d %d %.3f %c %d %d %.3f %c %.2fm %.2fm %.2fm %.2fm",
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering (lat / 60000 / 60),
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering (lat / 60000) % 60,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering (lat % 60000) / 1000.,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering NS,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering (lon / 60000 / 60),
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering (lon / 60000) % 60,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering (lon % 60000) / 1000.,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering EW,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen alt / 100.,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering siz / 100.,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hor / 100.,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen ver / 100.) < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return s;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringstatic int format_timestamp_dns(char *buf, size_t l, time_t sec) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering struct tm tm;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(buf);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(l > strlen("YYYYMMDDHHmmSS"));
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!gmtime_r(&sec, &tm))
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return -EINVAL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (strftime(buf, l, "%Y%m%d%H%M%S", &tm) <= 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return -EINVAL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return 0;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringstatic char *format_types(Bitmap *types) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering _cleanup_strv_free_ char **strv = NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering _cleanup_free_ char *str = NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering Iterator i;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering unsigned type;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering int r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering BITMAP_FOREACH(type, types, i) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (dns_type_to_string(type)) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = strv_extend(&strv, dns_type_to_string(type));
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (r < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering } else {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering char *t;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = asprintf(&t, "TYPE%u", type);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (r < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = strv_consume(&strv, t);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (r < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering str = strv_join(strv, " ");
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!str)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return strjoin("( ", str, " )", NULL);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringstatic char *format_txt(DnsTxtItem *first) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering DnsTxtItem *i;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering size_t c = 1;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering char *p, *s;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering LIST_FOREACH(items, i, first)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering c += i->length * 4 + 3;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering p = s = new(char, c);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!s)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering LIST_FOREACH(items, i, first) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering size_t j;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (i != first)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = ' ';
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = '"';
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering for (j = 0; j < i->length; j++) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (i->data[j] < ' ' || i->data[j] == '"' || i->data[j] >= 127) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = '\\';
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = '0' + (i->data[j] / 100);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = '0' + ((i->data[j] / 10) % 10);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = '0' + (i->data[j] % 10);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering } else
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = i->data[j];
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *(p++) = '"';
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *p = 0;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return s;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringint dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering _cleanup_free_ char *k = NULL, *t = NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering char *s;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering int r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(rr);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = dns_resource_key_to_string(rr->key, &k);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (r < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering case DNS_TYPE_SRV:
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = asprintf(&s, "%s %u %u %u %s",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering k,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen rr->srv.priority,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->srv.weight,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->srv.port,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen strna(rr->srv.name));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return -ENOMEM;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen break;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_PTR:
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering case DNS_TYPE_NS:
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt case DNS_TYPE_CNAME:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_DNAME:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen s = strjoin(k, " ", rr->ptr.name, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!s)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return -ENOMEM;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_HINFO:
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!s)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return -ENOMEM;
a9feff3d774eaa1cc1b59189e8f344c01e69f888Tom Gundersen break;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen case DNS_TYPE_SPF: /* exactly the same as TXT */
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen case DNS_TYPE_TXT:
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen t = format_txt(rr->txt.items);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (!t)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return -ENOMEM;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen s = strjoin(k, " ", t, NULL);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (!s)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return -ENOMEM;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen break;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen case DNS_TYPE_A: {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen _cleanup_free_ char *x = NULL;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (r < 0)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return r;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen s = strjoin(k, " ", x, NULL);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (!s)
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return -ENOMEM;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek break;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek }
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek case DNS_TYPE_AAAA:
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &t);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (r < 0)
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return r;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek s = strjoin(k, " ", t, NULL);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (!s)
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return -ENOMEM;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek break;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek case DNS_TYPE_SOA:
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek r = asprintf(&s, "%s %s %s %u %u %u %u %u",
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek k,
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek strna(rr->soa.mname),
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek strna(rr->soa.rname),
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek rr->soa.serial,
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek rr->soa.refresh,
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek rr->soa.retry,
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek rr->soa.expire,
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek rr->soa.minimum);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (r < 0)
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return -ENOMEM;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek break;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek case DNS_TYPE_MX:
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek r = asprintf(&s, "%s %u %s",
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek k,
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek rr->mx.priority,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->mx.exchange);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return -ENOMEM;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen break;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_LOC:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rr->loc.version == 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t = format_location(rr->loc.latitude,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen rr->loc.longitude,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen rr->loc.altitude,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen rr->loc.size,
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering rr->loc.horiz_pre,
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering rr->loc.vert_pre);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!t)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return -ENOMEM;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering s = strjoin(k, " ", t, NULL);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (!s)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return -ENOMEM;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt break;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen case DNS_TYPE_DS:
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen t = hexmem(rr->ds.digest, rr->ds.digest_size);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (!t)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return -ENOMEM;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering r = asprintf(&s, "%s %u %u %u %s",
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering k,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering rr->ds.key_tag,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering rr->ds.algorithm,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering rr->ds.digest_type,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering t);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (r < 0)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return -ENOMEM;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen break;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering case DNS_TYPE_SSHFP:
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering t = hexmem(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (!t)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return -ENOMEM;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering r = asprintf(&s, "%s %u %u %s",
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering k,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering rr->sshfp.algorithm,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen rr->sshfp.fptype,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen t);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (r < 0)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return -ENOMEM;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen break;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen case DNS_TYPE_DNSKEY: {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen const char *alg;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen alg = dnssec_algorithm_to_string(rr->dnskey.algorithm);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen t = base64mem(rr->dnskey.key, rr->dnskey.key_size);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (!t)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return -ENOMEM;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering r = asprintf(&s, "%s %u 3 %.*s%.*u %s",
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering k,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering dnskey_to_flags(rr),
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering alg ? -1 : 0, alg,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering alg ? 0 : 1, alg ? 0u : (unsigned) rr->dnskey.algorithm,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering t);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (r < 0)
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return -ENOMEM;
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek break;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen case DNS_TYPE_RRSIG: {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen const char *type, *alg;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen char expiration[strlen("YYYYMMDDHHmmSS") + 1], inception[strlen("YYYYMMDDHHmmSS") + 1];
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering type = dns_type_to_string(rr->rrsig.type_covered);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering alg = dnssec_algorithm_to_string(rr->rrsig.algorithm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t = base64mem(rr->rrsig.signature, rr->rrsig.signature_size);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!t)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = format_timestamp_dns(expiration, sizeof(expiration), rr->rrsig.expiration);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = format_timestamp_dns(inception, sizeof(inception), rr->rrsig.inception);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* TYPE?? follows
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering * http://tools.ietf.org/html/rfc3597#section-5 */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = asprintf(&s, "%s %s%.*u %.*s%.*u %u %u %s %s %u %s %s",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k,
40a1eebde6be7ac3f1885147fc24e06ad1da260cDavid Herrmann type ?: "TYPE",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering type ? 0 : 1, type ? 0u : (unsigned) rr->rrsig.type_covered,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering alg ? -1 : 0, alg,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering alg ? 0 : 1, alg ? 0u : (unsigned) rr->rrsig.algorithm,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering rr->rrsig.labels,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->rrsig.original_ttl,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering expiration,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering inception,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering rr->rrsig.key_tag,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->rrsig.signer,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_TYPE_NSEC:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t = format_types(rr->nsec.types);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!t)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = asprintf(&s, "%s %s %s",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering k,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->nsec.next_domain_name,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering case DNS_TYPE_NSEC3: {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *salt = NULL, *hash = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (rr->nsec3.salt_size > 0) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering salt = hexmem(rr->nsec3.salt, rr->nsec3.salt_size);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!salt)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hash = base32hexmem(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, false);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!hash)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen t = format_types(rr->nsec3.types);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!t)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = asprintf(&s, "%s %"PRIu8" %"PRIu8" %"PRIu16" %s %s %s",
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering k,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering rr->nsec3.algorithm,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rr->nsec3.flags,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen rr->nsec3.iterations,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering rr->nsec3.salt_size > 0 ? salt : "-",
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering hash,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering t);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return -ENOMEM;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering break;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering default:
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering t = hexmem(rr->generic.data, rr->generic.size);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!t)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = asprintf(&s, "%s \\# %zu %s", k, rr->generic.size, t);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering *ret = s;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringconst char *dns_class_to_string(uint16_t class) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering switch (class) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_CLASS_IN:
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return "IN";
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering case DNS_CLASS_ANY:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return "ANY";
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint dns_class_from_string(const char *s, uint16_t *class) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(s);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(class);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (strcaseeq(s, "IN"))
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering *class = DNS_CLASS_IN;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering else if (strcaseeq(s, "ANY"))
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering *class = DNS_CLASS_ANY;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering else
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -EINVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart PoetteringDnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering DnsTxtItem *n;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!i)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return NULL;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering n = i->items_next;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
a5f035960006556beab51c42e6948985635e261aLennart Poettering free(i);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return dns_txt_item_free_all(n);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringbool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!a != !b)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!a)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (a->length != b->length)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (memcmp(a->data, b->data, a->length) != 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return dns_txt_item_equal(a->items_next, b->items_next);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering