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.
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:
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: