resolved-dns-rr.c revision 4ad7f2761da661853dcc29d542efb4727abb1101
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2014 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart PoetteringDnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering k = malloc0(sizeof(DnsResourceKey) + l + 1);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering strcpy((char*) k + sizeof(DnsResourceKey), name);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart PoetteringDnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart PoetteringDnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart PoetteringDnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringint dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringint dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringint dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poetteringstatic unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering unsigned long ul;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic int dns_resource_key_compare_func(const void *a, const void *b) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering const DnsResourceKey *x = a, *y = b;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poetteringconst struct hash_ops dns_resource_key_hash_ops = {
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poetteringint dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering char cbuf[DECIMAL_STR_MAX(uint16_t)], tbuf[DECIMAL_STR_MAX(uint16_t)];
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering const char *c, *t;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (asprintf(&s, "%s %s %-5s", DNS_RESOURCE_KEY_NAME(key), c, t) < 0)
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart PoetteringDnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart PoetteringDnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering key = dns_resource_key_new(class, type, name);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart PoetteringDnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart PoetteringDnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poetteringint dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = dns_name_reverse(family, address, &ptr);
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poettering key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringint dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering r = dns_resource_key_equal(a->key, b->key);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering r = dns_name_equal(a->srv.name, b->srv.name);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return a->srv.priority == b->srv.priority &&
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return dns_name_equal(a->ptr.name, b->ptr.name);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return strcaseeq(a->hinfo.cpu, b->hinfo.cpu) &&
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering case DNS_TYPE_SPF: /* exactly the same as TXT */
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return strv_equal(a->txt.strings, b->txt.strings);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_name_equal(a->soa.mname, b->soa.mname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_name_equal(a->soa.rname, b->soa.rname);
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering return dns_name_equal(a->mx.exchange, b->mx.exchange);
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering assert(a->loc.version == b->loc.version);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return a->sshfp.algorithm == b->sshfp.algorithm &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->sshfp.key_size == b->sshfp.key_size &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcmp(a->sshfp.key, b->sshfp.key, a->sshfp.key_size) == 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return a->dnskey.zone_key_flag == b->dnskey.zone_key_flag &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->dnskey.sep_flag == b->dnskey.sep_flag &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->dnskey.algorithm == b->dnskey.algorithm &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->dnskey.key_size == b->dnskey.key_size &&
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcmp(a->dnskey.key, b->dnskey.key, a->dnskey.key_size) == 0;
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek /* do the fast comparisons first */
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering if (a->rrsig.type_covered != b->rrsig.type_covered ||
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering a->rrsig.algorithm != b->rrsig.algorithm ||
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering a->rrsig.original_ttl != b->rrsig.original_ttl ||
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering a->rrsig.expiration != b->rrsig.expiration ||
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek a->rrsig.inception != b->rrsig.inception ||
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek a->rrsig.key_tag != b->rrsig.key_tag ||
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek a->rrsig.signature_size != b->rrsig.signature_size ||
8ac4e9e1e54397f6d1745c2a7a806132418c7da2Lennart Poettering memcmp(a->rrsig.signature, b->rrsig.signature, a->rrsig.signature_size) != 0)
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering return dns_name_equal(a->rrsig.signer, b->rrsig.signer);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return a->generic.size == b->generic.size &&
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poetteringstatic char* format_location(uint32_t latitude, uint32_t longitude, uint32_t altitude,
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek uint8_t size, uint8_t horiz_pre, uint8_t vert_pre) {
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek char NS = latitude >= 1U<<31 ? 'N' : 'S';
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering char EW = longitude >= 1U<<31 ? 'E' : 'W';
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek int lat = latitude >= 1U<<31 ? (int) (latitude - (1U<<31)) : (int) ((1U<<31) - latitude);
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering int lon = longitude >= 1U<<31 ? (int) (longitude - (1U<<31)) : (int) ((1U<<31) - longitude);
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek double alt = altitude >= 10000000u ? altitude - 10000000u : -(double)(10000000u - altitude);
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek double siz = (size >> 4) * exp10((double) (size & 0xF));
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek double hor = (horiz_pre >> 4) * exp10((double) (horiz_pre & 0xF));
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering double ver = (vert_pre >> 4) * exp10((double) (vert_pre & 0xF));
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen if (asprintf(&s, "%d %d %.3f %c %d %d %.3f %c %.2fm %.2fm %.2fm %.2fm",
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersenint dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
48d45d2b49d2adb870cd5f1bc7cb389b33655f1cZbigniew Jędrzejewski-Szmek r = asprintf(&s, "%s %u %u %u %s",
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering case DNS_TYPE_SPF: /* exactly the same as TXT */
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &t);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = asprintf(&s, "%s %s %s %u %u %u %u %u",
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering t = hexmem(rr->sshfp.key, rr->sshfp.key_size);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering alg = dnssec_algorithm_to_string(rr->dnskey.algorithm);
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek t = hexmem(rr->dnskey.key, rr->dnskey.key_size);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering alg ? 0 : 1, alg ? 0u : (unsigned) rr->dnskey.algorithm,
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering type = dns_type_to_string(rr->rrsig.type_covered);
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering alg = dnssec_algorithm_to_string(rr->rrsig.algorithm);
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering t = hexmem(rr->rrsig.signature, rr->rrsig.signature_size);
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek /* TYPE?? follows
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek * http://tools.ietf.org/html/rfc3597#section-5 */
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek r = asprintf(&s, "%s %s%.*u %.*s%.*u %u %u %u %u %u %s %s",
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek type ? 0 : 1, type ? 0u : (unsigned) rr->rrsig.type_covered,
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek alg ? 0 : 1, alg ? 0u : (unsigned) rr->rrsig.algorithm,
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering t = hexmem(rr->generic.data, rr->generic.size);
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmekconst char *dns_class_to_string(uint16_t class) {
03664a62914782dbd8f069bbcf8a0c8ca1df7010Lukas Nykryn return "IN";
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersenint dns_class_from_string(const char *s, uint16_t *class) {