diff --git a/man/resolvectl.xml b/man/resolvectl.xml index a176fe4fa8..70400d0bca 100644 --- a/man/resolvectl.xml +++ b/man/resolvectl.xml @@ -452,11 +452,15 @@ =payload|packet - Dump the answer as binary data. If there is no argument or if the argument is - payload, the payload of the packet is exported. If the argument is - packet, the whole packet is dumped in wire format, prefixed by - length specified as a little-endian 64-bit number. This format allows multiple packets - to be dumped and unambiguously parsed. + Dump the answer records as binary data. If there is no argument or if the argument is + payload, the payload of the resource record data is exported, i.e. not the whole + "RDATA", but just primary contents. If the argument is packet, + the whole resource record is dumped in wire format, prefixed by length specified as a little-endian + 64-bit integer. This format allows multiple record to be dumped and unambiguously parsed. + + Note that payload is only supported for a small subset of resource record + types: SSHFP, TLSA, OPENPGPKEY where this dumps the key material only; and A, AAAA where + this dumps the address data. diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index bb967f8ce5..f6708cdead 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -489,10 +489,12 @@ static int output_rr_packet(const void *d, size_t l, int ifindex) { return r; } else if (arg_raw == RAW_PAYLOAD) { - void *data; + const void *data; ssize_t k; k = dns_resource_record_payload(rr, &data); + if (k == -EINVAL) + return log_error_errno(k, "Dumping of binary payload not available for RRs of this type: %s", dns_type_to_string(rr->key->type)); if (k < 0) return log_error_errno(k, "Cannot dump RR: %m"); fwrite(data, 1, k, stdout); diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 4be6dd0f23..339f9433d2 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -1355,9 +1355,9 @@ const char* dns_resource_record_to_string(DnsResourceRecord *rr) { return TAKE_PTR(s); } -ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) { +ssize_t dns_resource_record_payload(DnsResourceRecord *rr, const void **ret) { assert(rr); - assert(out); + assert(ret); switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) { case DNS_TYPE_SRV: @@ -1368,8 +1368,6 @@ ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) { case DNS_TYPE_HINFO: case DNS_TYPE_SPF: case DNS_TYPE_TXT: - case DNS_TYPE_A: - case DNS_TYPE_AAAA: case DNS_TYPE_SOA: case DNS_TYPE_MX: case DNS_TYPE_LOC: @@ -1380,17 +1378,25 @@ ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) { case DNS_TYPE_NSEC3: return -EINVAL; + case DNS_TYPE_A: + *ret = &rr->a.in_addr; + return sizeof(rr->a.in_addr); + + case DNS_TYPE_AAAA: + *ret = &rr->aaaa.in6_addr; + return sizeof(rr->aaaa.in6_addr); + case DNS_TYPE_SSHFP: - *out = rr->sshfp.fingerprint; + *ret = rr->sshfp.fingerprint; return rr->sshfp.fingerprint_size; case DNS_TYPE_TLSA: - *out = rr->tlsa.data; + *ret = rr->tlsa.data; return rr->tlsa.data_size; case DNS_TYPE_OPENPGPKEY: default: - *out = rr->generic.data; + *ret = rr->generic.data; return rr->generic.data_size; } } diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index d183d0b80f..4129cddccd 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -335,7 +335,7 @@ int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey * #define DNS_RESOURCE_KEY_STRING_MAX (_DNS_CLASS_STRING_MAX + _DNS_TYPE_STRING_MAX + DNS_HOSTNAME_MAX + 1) char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t buf_size); -ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out); +ssize_t dns_resource_record_payload(DnsResourceRecord *rr, const void **ret); #define DNS_RESOURCE_KEY_TO_STRING(key) \ dns_resource_key_to_string(key, (char[DNS_RESOURCE_KEY_STRING_MAX]) {}, DNS_RESOURCE_KEY_STRING_MAX)