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