resolvectl: --raw improvements (#37743)

Fixes: #37737
This commit is contained in:
Lennart Poettering
2025-06-05 14:02:00 +02:00
committed by GitHub
4 changed files with 26 additions and 14 deletions

View File

@@ -452,11 +452,15 @@
<varlistentry>
<term><option>--raw</option><optional>=payload|packet</optional></term>
<listitem><para>Dump the answer as binary data. If there is no argument or if the argument is
<literal>payload</literal>, the payload of the packet is exported. If the argument is
<literal>packet</literal>, 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.</para>
<listitem><para>Dump the answer records as binary data. If there is no argument or if the argument is
<literal>payload</literal>, the payload of the resource record data is exported, i.e. not the whole
"RDATA", but just primary contents. If the argument is <literal>packet</literal>,
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.</para>
<para>Note that <literal>payload</literal> 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.</para>
<xi:include href="version-info.xml" xpointer="v239"/></listitem>
</varlistentry>

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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)