resolved-dns-rr.c revision 549c1a2564b56f2bb38f1203d59c747ea15817f3
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering/***
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering This file is part of systemd.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Copyright 2014 Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is free software; you can redistribute it and/or modify it
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering under the terms of the GNU Lesser General Public License as published by
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering (at your option) any later version.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is distributed in the hope that it will be useful, but
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Lesser General Public License for more details.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering You should have received a copy of the GNU Lesser General Public License
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering***/
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <math.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "strv.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "dns-domain.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "resolved-dns-rr.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "resolved-dns-packet.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "dns-type.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering DnsResourceKey *k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering size_t l;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering l = strlen(name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k = malloc0(sizeof(DnsResourceKey) + l + 1);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!k)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->n_ref = 1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->class = class;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->type = type;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering strcpy((char*) k + sizeof(DnsResourceKey), name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering DnsResourceKey *k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k = new0(DnsResourceKey, 1);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!k)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->n_ref = 1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->class = class;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->type = type;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->_name = name;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering if (!k)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(k->n_ref > 0);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->n_ref++;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!k)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(k->n_ref > 0);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (k->n_ref == 1) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(k->_name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(k);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k->n_ref--;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r <= 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (a->class != b->class)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (a->type != b->type)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering assert(key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(rr);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering}
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poetteringint dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering assert(key);
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering assert(rr);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (rr->key->type != DNS_TYPE_CNAME)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const DnsResourceKey *k = i;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unsigned long ul;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering ul = ul * hash_key[0] + ul + k->class;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering ul = ul * hash_key[1] + ul + k->type;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return ul;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int dns_resource_key_compare_func(const void *a, const void *b) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering const DnsResourceKey *x = a, *y = b;
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering int ret;
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering if (ret != 0)
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering return ret;
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering if (x->type < y->type)
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering return -1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (x->type > y->type)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (x->class < y->class)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (x->class > y->class)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringconst struct hash_ops dns_resource_key_hash_ops = {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering .hash = dns_resource_key_hash_func,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering .compare = dns_resource_key_compare_func
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering};
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char cbuf[strlen("CLASS") + DECIMAL_STR_MAX(uint16_t)], tbuf[strlen("TYPE") + DECIMAL_STR_MAX(uint16_t)];
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering const char *c, *t;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char *s;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering c = dns_class_to_string(key->class);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!c) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering sprintf(cbuf, "CLASS%u", key->class);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering c = cbuf;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering t = dns_type_to_string(key->type);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering if (!t){
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering sprintf(tbuf, "TYPE%u", key->type);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering t = tbuf;
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering }
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering if (asprintf(&s, "%s %s %-5s", DNS_RESOURCE_KEY_NAME(key), c, t) < 0)
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering return -ENOMEM;
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering *ret = s;
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering return 0;
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering}
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering DnsResourceRecord *rr;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr = new0(DnsResourceRecord, 1);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!rr)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr->n_ref = 1;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr->key = dns_resource_key_ref(key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return rr;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering key = dns_resource_key_new(class, type, name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!key)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return dns_resource_record_new(key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!rr)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(rr->n_ref > 0);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr->n_ref++;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return rr;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringDnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering if (!rr)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(rr->n_ref > 0);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (rr->n_ref > 1) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr->n_ref--;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (rr->key) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering switch(rr->key->type) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SRV:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->srv.name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_PTR:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_NS:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_CNAME:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_DNAME:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->ptr.name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_HINFO:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->hinfo.cpu);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->hinfo.os);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_TXT:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SPF:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering strv_free(rr->txt.strings);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SOA:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->soa.mname);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->soa.rname);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_MX:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->mx.exchange);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_DS:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->ds.digest);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SSHFP:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->sshfp.fingerprint);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_DNSKEY:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->dnskey.key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_RRSIG:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->rrsig.signer);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->rrsig.signature);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_NSEC:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->nsec.next_domain_name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering bitmap_free(rr->nsec.types);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_NSEC3:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->nsec3.next_hashed_name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->nsec3.salt);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering bitmap_free(rr->nsec3.types);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_LOC:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_A:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_AAAA:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering break;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering default:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr->generic.data);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dns_resource_key_unref(rr->key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(rr);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *ptr = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(ret);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(address);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(hostname);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = dns_name_reverse(family, address, &ptr);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!key)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -ENOMEM;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering ptr = NULL;
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr = dns_resource_record_new(key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!rr)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -ENOMEM;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr->ptr.name = strdup(hostname);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!rr->ptr.name)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -ENOMEM;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering *ret = rr;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering rr = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(a);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(b);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = dns_resource_key_equal(a->key, b->key);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r <= 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (a->unparseable != b->unparseable)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SRV:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = dns_name_equal(a->srv.name, b->srv.name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r <= 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return a->srv.priority == b->srv.priority &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->srv.weight == b->srv.weight &&
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering a->srv.port == b->srv.port;
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering case DNS_TYPE_PTR:
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering case DNS_TYPE_NS:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_CNAME:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_DNAME:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return dns_name_equal(a->ptr.name, b->ptr.name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_HINFO:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return strcaseeq(a->hinfo.cpu, b->hinfo.cpu) &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering strcaseeq(a->hinfo.os, b->hinfo.os);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SPF: /* exactly the same as TXT */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_TXT:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return strv_equal(a->txt.strings, b->txt.strings);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_A:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_AAAA:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SOA:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = dns_name_equal(a->soa.mname, b->soa.mname);
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering if (r <= 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = dns_name_equal(a->soa.rname, b->soa.rname);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r <= 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return a->soa.serial == b->soa.serial &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->soa.refresh == b->soa.refresh &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->soa.retry == b->soa.retry &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->soa.expire == b->soa.expire &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->soa.minimum == b->soa.minimum;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering case DNS_TYPE_MX:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (a->mx.priority != b->mx.priority)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return dns_name_equal(a->mx.exchange, b->mx.exchange);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_LOC:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(a->loc.version == b->loc.version);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return a->loc.size == b->loc.size &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->loc.horiz_pre == b->loc.horiz_pre &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->loc.vert_pre == b->loc.vert_pre &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->loc.latitude == b->loc.latitude &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->loc.longitude == b->loc.longitude &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->loc.altitude == b->loc.altitude;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_DS:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return a->ds.key_tag == b->ds.key_tag &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->ds.algorithm == b->ds.algorithm &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->ds.digest_type == b->ds.digest_type &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->ds.digest_size == b->ds.digest_size &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering memcmp(a->ds.digest, b->ds.digest, a->ds.digest_size) == 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_SSHFP:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return a->sshfp.algorithm == b->sshfp.algorithm &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->sshfp.fptype == b->sshfp.fptype &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->sshfp.fingerprint_size == b->sshfp.fingerprint_size &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering memcmp(a->sshfp.fingerprint, b->sshfp.fingerprint, a->sshfp.fingerprint_size) == 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_DNSKEY:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return a->dnskey.zone_key_flag == b->dnskey.zone_key_flag &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->dnskey.sep_flag == b->dnskey.sep_flag &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->dnskey.algorithm == b->dnskey.algorithm &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->dnskey.key_size == b->dnskey.key_size &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering memcmp(a->dnskey.key, b->dnskey.key, a->dnskey.key_size) == 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_RRSIG:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* do the fast comparisons first */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (a->rrsig.type_covered != b->rrsig.type_covered ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->rrsig.algorithm != b->rrsig.algorithm ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->rrsig.labels != b->rrsig.labels ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->rrsig.original_ttl != b->rrsig.original_ttl ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->rrsig.expiration != b->rrsig.expiration ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->rrsig.inception != b->rrsig.inception ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->rrsig.key_tag != b->rrsig.key_tag ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering a->rrsig.signature_size != b->rrsig.signature_size ||
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering memcmp(a->rrsig.signature, b->rrsig.signature, a->rrsig.signature_size) != 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return false;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return dns_name_equal(a->rrsig.signer, b->rrsig.signer);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_NSEC:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return dns_name_equal(a->nsec.next_domain_name, b->nsec.next_domain_name) &&
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering bitmap_equal(a->nsec.types, b->nsec.types);
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering case DNS_TYPE_NSEC3:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return a->nsec3.algorithm == b->nsec3.algorithm &&
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering a->nsec3.flags == b->nsec3.flags &&
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering a->nsec3.iterations == b->nsec3.iterations &&
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering a->nsec3.salt_size == b->nsec3.salt_size &&
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering memcmp(a->nsec3.salt, b->nsec3.salt, a->nsec3.salt_size) == 0 &&
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering memcmp(a->nsec3.next_hashed_name, b->nsec3.next_hashed_name, a->nsec3.next_hashed_name_size) == 0 &&
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering bitmap_equal(a->nsec3.types, b->nsec3.types);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering default:
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return a->generic.size == b->generic.size &&
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering }
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering}
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poetteringstatic char* format_location(uint32_t latitude, uint32_t longitude, uint32_t altitude,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering uint8_t size, uint8_t horiz_pre, uint8_t vert_pre) {
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering char *s;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering char NS = latitude >= 1U<<31 ? 'N' : 'S';
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering char EW = longitude >= 1U<<31 ? 'E' : 'W';
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering int lat = latitude >= 1U<<31 ? (int) (latitude - (1U<<31)) : (int) ((1U<<31) - latitude);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering int lon = longitude >= 1U<<31 ? (int) (longitude - (1U<<31)) : (int) ((1U<<31) - longitude);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering double alt = altitude >= 10000000u ? altitude - 10000000u : -(double)(10000000u - altitude);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering double siz = (size >> 4) * exp10((double) (size & 0xF));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering double hor = (horiz_pre >> 4) * exp10((double) (horiz_pre & 0xF));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering double ver = (vert_pre >> 4) * exp10((double) (vert_pre & 0xF));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (asprintf(&s, "%d %d %.3f %c %d %d %.3f %c %.2fm %.2fm %.2fm %.2fm",
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering (lat / 60000 / 60),
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering (lat / 60000) % 60,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering (lat % 60000) / 1000.,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering NS,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering (lon / 60000 / 60),
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering (lon / 60000) % 60,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering (lon % 60000) / 1000.,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering EW,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering alt / 100.,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering siz / 100.,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering hor / 100.,
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering ver / 100.) < 0)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return NULL;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return s;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering}
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poetteringstatic int format_timestamp_dns(char *buf, size_t l, time_t sec) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering struct tm tm;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(buf);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(l > strlen("YYYYMMDDHHmmSS"));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!gmtime_r(&sec, &tm))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -EINVAL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (strftime(buf, l, "%Y%m%d%H%M%S", &tm) <= 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return -EINVAL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic char *format_types(Bitmap *types) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_strv_free_ char **strv = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *str = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Iterator i;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unsigned type;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering BITMAP_FOREACH(type, types, i) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (dns_type_to_string(type)) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = strv_extend(&strv, dns_type_to_string(type));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char *t;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = asprintf(&t, "TYPE%u", type);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = strv_consume(&strv, t);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering str = strv_join(strv, " ");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!str)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return NULL;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return strjoin("( ", str, " )", NULL);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering}
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *k = NULL, *t = NULL;
char *s;
int r;
assert(rr);
r = dns_resource_key_to_string(rr->key, &k);
if (r < 0)
return r;
switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
case DNS_TYPE_SRV:
r = asprintf(&s, "%s %u %u %u %s",
k,
rr->srv.priority,
rr->srv.weight,
rr->srv.port,
strna(rr->srv.name));
if (r < 0)
return -ENOMEM;
break;
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_DNAME:
s = strjoin(k, " ", rr->ptr.name, NULL);
if (!s)
return -ENOMEM;
break;
case DNS_TYPE_HINFO:
s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL);
if (!s)
return -ENOMEM;
break;
case DNS_TYPE_SPF: /* exactly the same as TXT */
case DNS_TYPE_TXT:
t = strv_join_quoted(rr->txt.strings);
if (!t)
return -ENOMEM;
s = strjoin(k, " ", t, NULL);
if (!s)
return -ENOMEM;
break;
case DNS_TYPE_A: {
_cleanup_free_ char *x = NULL;
r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x);
if (r < 0)
return r;
s = strjoin(k, " ", x, NULL);
if (!s)
return -ENOMEM;
break;
}
case DNS_TYPE_AAAA:
r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &t);
if (r < 0)
return r;
s = strjoin(k, " ", t, NULL);
if (!s)
return -ENOMEM;
break;
case DNS_TYPE_SOA:
r = asprintf(&s, "%s %s %s %u %u %u %u %u",
k,
strna(rr->soa.mname),
strna(rr->soa.rname),
rr->soa.serial,
rr->soa.refresh,
rr->soa.retry,
rr->soa.expire,
rr->soa.minimum);
if (r < 0)
return -ENOMEM;
break;
case DNS_TYPE_MX:
r = asprintf(&s, "%s %u %s",
k,
rr->mx.priority,
rr->mx.exchange);
if (r < 0)
return -ENOMEM;
break;
case DNS_TYPE_LOC:
assert(rr->loc.version == 0);
t = format_location(rr->loc.latitude,
rr->loc.longitude,
rr->loc.altitude,
rr->loc.size,
rr->loc.horiz_pre,
rr->loc.vert_pre);
if (!t)
return -ENOMEM;
s = strjoin(k, " ", t, NULL);
if (!s)
return -ENOMEM;
break;
case DNS_TYPE_DS:
t = hexmem(rr->ds.digest, rr->ds.digest_size);
if (!t)
return -ENOMEM;
r = asprintf(&s, "%s %u %u %u %s",
k,
rr->ds.key_tag,
rr->ds.algorithm,
rr->ds.digest_type,
t);
if (r < 0)
return -ENOMEM;
break;
case DNS_TYPE_SSHFP:
t = hexmem(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size);
if (!t)
return -ENOMEM;
r = asprintf(&s, "%s %u %u %s",
k,
rr->sshfp.algorithm,
rr->sshfp.fptype,
t);
if (r < 0)
return -ENOMEM;
break;
case DNS_TYPE_DNSKEY: {
const char *alg;
alg = dnssec_algorithm_to_string(rr->dnskey.algorithm);
t = base64mem(rr->dnskey.key, rr->dnskey.key_size);
if (!t)
return -ENOMEM;
r = asprintf(&s, "%s %u 3 %.*s%.*u %s",
k,
dnskey_to_flags(rr),
alg ? -1 : 0, alg,
alg ? 0 : 1, alg ? 0u : (unsigned) rr->dnskey.algorithm,
t);
if (r < 0)
return -ENOMEM;
break;
}
case DNS_TYPE_RRSIG: {
const char *type, *alg;
char expiration[strlen("YYYYMMDDHHmmSS") + 1], inception[strlen("YYYYMMDDHHmmSS") + 1];
type = dns_type_to_string(rr->rrsig.type_covered);
alg = dnssec_algorithm_to_string(rr->rrsig.algorithm);
t = base64mem(rr->rrsig.signature, rr->rrsig.signature_size);
if (!t)
return -ENOMEM;
r = format_timestamp_dns(expiration, sizeof(expiration), rr->rrsig.expiration);
if (r < 0)
return r;
r = format_timestamp_dns(inception, sizeof(inception), rr->rrsig.inception);
if (r < 0)
return r;
/* TYPE?? follows
* http://tools.ietf.org/html/rfc3597#section-5 */
r = asprintf(&s, "%s %s%.*u %.*s%.*u %u %u %s %s %u %s %s",
k,
type ?: "TYPE",
type ? 0 : 1, type ? 0u : (unsigned) rr->rrsig.type_covered,
alg ? -1 : 0, alg,
alg ? 0 : 1, alg ? 0u : (unsigned) rr->rrsig.algorithm,
rr->rrsig.labels,
rr->rrsig.original_ttl,
expiration,
inception,
rr->rrsig.key_tag,
rr->rrsig.signer,
t);
if (r < 0)
return -ENOMEM;
break;
}
case DNS_TYPE_NSEC:
t = format_types(rr->nsec.types);
if (!t)
return -ENOMEM;
r = asprintf(&s, "%s %s %s",
k,
rr->nsec.next_domain_name,
t);
if (r < 0)
return -ENOMEM;
break;
case DNS_TYPE_NSEC3: {
_cleanup_free_ char *salt = NULL, *hash = NULL;
if (rr->nsec3.salt_size > 0) {
salt = hexmem(rr->nsec3.salt, rr->nsec3.salt_size);
if (!salt)
return -ENOMEM;
}
hash = base32hexmem(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, false);
if (!hash)
return -ENOMEM;
t = format_types(rr->nsec3.types);
if (!t)
return -ENOMEM;
r = asprintf(&s, "%s %"PRIu8" %"PRIu8" %"PRIu16" %s %s %s",
k,
rr->nsec3.algorithm,
rr->nsec3.flags,
rr->nsec3.iterations,
rr->nsec3.salt_size > 0 ? salt : "-",
hash,
t);
if (r < 0)
return -ENOMEM;
break;
}
default:
t = hexmem(rr->generic.data, rr->generic.size);
if (!t)
return -ENOMEM;
r = asprintf(&s, "%s \\# %zu %s", k, rr->generic.size, t);
if (r < 0)
return -ENOMEM;
break;
}
*ret = s;
return 0;
}
const char *dns_class_to_string(uint16_t class) {
switch (class) {
case DNS_CLASS_IN:
return "IN";
case DNS_CLASS_ANY:
return "ANY";
}
return NULL;
}
int dns_class_from_string(const char *s, uint16_t *class) {
assert(s);
assert(class);
if (strcaseeq(s, "IN"))
*class = DNS_CLASS_IN;
else if (strcaseeq(s, "ANY"))
*class = DNS_TYPE_ANY;
else
return -EINVAL;
return 0;
}