Hello,
I'm trying to use libunbound (and possibly libldns) to pull out SRV
records. I am not certain how to proceed, based on the documentation
that I could found in the form of man pages, tutorials and doxygen.
Am I correct that libunbound returns RDATA unmodified, and is basically
concerned with the security chain but not the RDATA contents? And so,
that I have to turn to another tool?
I therefore looked at LDNS, but that does not seem to help either. I
don't mind following the RFC (though in the case of SRV it is not
explicit on the wire format) to pull out data, but I would be surprised
if I was to make assumptions about the structure of hosts, especially
because it may point back into a DNS packet. Is this really how it is
done though? Then, should I assume the data[i]/len[i] to be pointers
into the frame, and compute offsets manually?
I can hardly believe that this hasn't been tried before
but as I
said, I can't find the documentation that answers this with clarity. So
any help is welcome, including pointers to documentation that I've
overlooked!
Thanks,
-Rick
Rick,
You can parse the packet returned by ub_result.answer_packet with
ldns_wire2pkt(). For example when res is of type ub_result *, then
if ((s = ldns_wire2pkt(&pkt, res->answer_packet, res->answer_len)))
/* handle error */
else if (!(rrs = ldns_pkt_answer(pkt)))
/* handle error */
else for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
ldns_rr *rr = ldns_rr_list_rr(rrs, i);
if (!rr || ldns_rr_get_type(rr) != LDNS_RR_TYPE_SRV)
continue;
uint16_t priority = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
uint16_t weight = ldns_rdf2native_int16(ldns_rr_rdf(rr, 1));
uint16_t port = ldns_rdf2native_int16(ldns_rr_rdf(rr, 2));
ldns_rdf *target = ldns_rr_rdf(rr, 3);
/* Do stuff */
}
Not that it is not safe to use ldns_rdf2native_int16 directly on what
ldns_rr_rdf returns. You should test for NULL first. I just wrote it
so for clarity.
Cheers,
-- Willem
Hi Rick,
Hello,
I'm trying to use libunbound (and possibly libldns) to pull out SRV
records. I am not certain how to proceed, based on the documentation
that I could found in the form of man pages, tutorials and doxygen.
Am I correct that libunbound returns RDATA unmodified, and is basically
concerned with the security chain but not the RDATA contents? And so,
that I have to turn to another tool?
I therefore looked at LDNS, but that does not seem to help either. I
don't mind following the RFC (though in the case of SRV it is not
explicit on the wire format) to pull out data, but I would be surprised
if I was to make assumptions about the structure of hosts, especially
because it may point back into a DNS packet. Is this really how it is
done though? Then, should I assume the data[i]/len[i] to be pointers
into the frame, and compute offsets manually?
The data[i] elements contain self-contained, uncompressed, rdata
elements that do not point to a packet somewhere.
For SRV that means there is an uncompressed domainname in there. In
wireformat. LDNS can parse the rdata in data[i].
Best regards, Wouter
The data[i] elements contain self-contained, uncompressed, rdata
elements that do not point to a packet somewhere.
For SRV that means there is an uncompressed domainname in there. In
wireformat. LDNS can parse the rdata in data[i].
Ah yes.. that is much better, so rewriting the example:
char **data;
int *len;
for (data = res->data, len = res->len; *data; data++, len++) {
if (*len < 7) {
/* Handle error */
continue;
}
uint16_t priority = ((*data)[0] << 8) | (*data)[1];
uint16_t weight = ((*data)[2] << 8) | (*data)[3];
uint16_t port = ((*data)[4] << 8) | (*data)[5];
ldns_rdf *target_rdf =
ldns_dname_new_frm_data(*len - 6, *data + 6);
char *target = ldns_rdf2str(target_rdf);
ldns_rdf_free(target_rdf);
}
I haven't tested, so there might be errors...
wrapsrv, which is linked from the page below, is an open source tool capable of extracting (and utilizing) SRV records.
https://www.farsightsecurity.com/Blog/20160328-stsauver-magic-of-srv/
vixie
Ah!
Thanks a lot guys! Even with code 
Looks like I was on the right track after all, but struggled to find the vital routines ldns_dname_new_frm_data() and ldns_rdf2str() -- and their pragmatically short names made it difficult for me / newbee to find them. The uncompressed names are vital information too, though!
Cheers,
-Rick