libs6dns
s6-dns
Software
skarnet.org
The following functions are declared in the s6-dns/s6dns-message.h header, and implemented in the libs6dns.a or libs6dns.so library.
s6dns_message provides functions to read and parse DNS messages sent by servers and caches and containing answers to queries.
A s6dns_message_header_t is a structure containing the header of a received DNS packet, broken down for easy access to the bits.
A s6dns_message_rr_t is a structure containing the information about a resource record given by an answer packet - all of it, except the value of the answer itself, which is rtype-specific and has to be decoded by rtype-specific functions.
A s6dns_message_rr_func_t is the type of such a function. The
prototype is
int f (s6dns_message_rr_t const *rr, char const *packet, unsigned int packetlen, unsigned int pos, unsigned int section, void *data)
Various structures designed to store specific resource record types are also provided. The list includes:
void s6dns_message_header_pack (char *s, s6dns_message_header_t const *h)
Packs the header *h into the 12 bytes pointed to by s.
void s6dns_message_header_unpack (char const *s, s6dns_message_header_t *h)
Unpacks the 12 bytes pointed to by s into the structure *h.
The following primitives are used in the implementation of s6dns_message_rr_func_t-typed functions, to read and decode information stored in a DNS packet. Their arguments are:
int s6dns_message_get_string (s6dns_domain_t *d, char const *packet, unsigned int packetlen, unsigned int *pos)
Reads a character-string and stores it into *d. Returns 1 on success
and 0 on failure. Note that *d does not contain a domain, but the
s6dns_domain_t structure is adapted to store strings that do not
exceed 255 characters. d→s can be used to access the string,
and d→len its length.
int s6dns_message_get_strings (char *s, unsigned int rdlength, char const *packet, unsigned int packetlen, unsigned int *pos
This function takes an additional parameter rdlength. It reads a series of
character-strings and stores their concatenation into the string s, which
must be preallocated; it can never store more than rdlength bytes. It returns
-1 if it fails; on success, it returns the number of bytes written. The
rdlength parameter must be the length of the resource record containing
the series of character-strings.
size_t s6dns_message_get_domain_nodecode (char *out, size_t outmax, char const *packet, unsigned int packetlen, unsigned int *pos)
Reads a domain and stores it, in packet form, into *out, which is a character
array that must have been preallocated by the user; outmax is the maximum
number of characters that can be stored in out. As a special
case, out can be NULL, in which case nothing will be written, but
the domain will still be parsed and pos will still be updated.
The function returns the number of characters written to out
(or that would have been). If 0, it denotes a failure, and errno is set:
unsigned int s6dns_message_get_domain (s6dns_domain_t *d, char const *packet, unsigned int packetlen, unsigned int *pos)
Reads a domain and stores it, in string form, into *d.
Returns 1 on success and 0 on failure, and sets errno just like the
function above.
int s6dns_message_get_hinfo (s6dns_message_rr_hinfo_t *p, char const *packet, unsigned int packetlen, unsigned int *pos)
Reads a HINFO RR and stores it into *p. Returns 1 on success or 0
on failure.
int s6dns_message_get_mx (s6dns_message_rr_mx_t *p, char const *packet, unsigned int packetlen, unsigned int *pos)
Reads a MX RR and stores it into *p. Returns 1 on success or 0 on failure.
int s6dns_message_get_soa (s6dns_message_rr_soa_t *p, char const *packet, unsigned int packetlen, unsigned int *pos)
Reads a SOA RR and stores it into *p. Returns 1 on success or 0 on failure.
int s6dns_message_get_srv (s6dns_message_rr_srv_t *p, char const *packet, unsigned int packetlen, unsigned int *pos)
Reads a SRV RR and stores it into *p. Returns 1 on success or 0 on failure.
int s6dns_message_get_caa (s6dns_message_rr_caa_t *p, char const *packet, unsigned int packetlen, unsigned int *pos, uint16_t rdlength)
Reads a CAA RR and stores it into *p. Returns 1 on success or 0 on failure.
rdlength is the length of the RDATA field of the record; this value is
needed to properly parse a CAA record.
s6dns_message_func_t s6dns_message_parse_answer_strings
Parses character-strings located in the answer section of the packet. The
data argument is interpreted as a pointer to a s6dns_mpag_t,
which is a structure defined in the s6-dns/s6dns-message.h header
and used to store multiple character-strings.
s6dns_message_func_t s6dns_message_parse_answer_domain
Parses domains located in the answer section of the packet. The
data argument is interpreted as a pointer to a s6dns_dpag_t,
which is a structure defined in the s6-dns/s6dns-message.h header
and used to store multiple domains.
s6dns_message_func_t s6dns_message_parse_answer_a
Parses A RRs located in the answer section of the packet. The
data argument is interpreted as a pointer to a
stralloc,
and 4 bytes are appended to this stralloc for every IPv4 address found.
s6dns_message_func_t s6dns_message_parse_answer_aaaa
Parses AAAA RRs located in the answer section of the packet. The
data argument is interpreted as a pointer to a
stralloc,
and 16 bytes are appended to this stralloc for every IPv6 address found.
s6dns_message_func_t s6dns_message_parse_answer_hinfo
Parses HINFO RRs located in the answer section of the packet. The
data argument is interpreted as a pointer to a
genalloc
containing s6dns_message_rr_hinfo_t structures.
s6dns_message_func_t s6dns_message_parse_answer_mx
Parses MX RRs located in the answer section of the packet. The
data argument is interpreted as a pointer to a
genalloc
containing s6dns_message_rr_mx_t structures.
s6dns_message_func_t s6dns_message_parse_answer_soa
Parses SOA RRs located in the answer section of the packet. The
data argument is interpreted as a pointer to a
genalloc
containing s6dns_message_rr_soa_t structures.
s6dns_message_func_t s6dns_message_parse_answer_srv
Parses SRV RRs located in the answer section of the packet. The
data argument is interpreted as a pointer to a
genalloc
containing s6dns_message_rr_srv_t structures.
s6dns_message_func_t s6dns_message_parse_answer_caa
Parses CAA RRs located in the answer section of the packet. The
data argument is interpreted as a pointer to a
genalloc
containing s6dns_message_rr_caa_t structures.
int s6dns_message_parse (s6dns_message_header_t *h, char const *packet, unsigned int packetlen, s6dns_message_rr_func_t *f, void *data)
This function parses the DNS packet packet of length packetlen.
It stores the packet header into *h. Then, for every RR in the answer,
authority or additional section of the packet, it calls f with the
relevant parameters. data is the extra pointer given to f to
store information. If the parsing succeeds, the function returns 2 if the packet
contains an answer section and 1 if it does not. Otherwise, it
returns -1 if there is a local error unrelated to the packet, or 0 if no
appropriate answer can be decoded from the packet. errno then contains one
of the following values: