1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
.TH qlibs: dnsresolv
.SH NAME
dns \- dns resolver routines
.SH SYNTAX
.B #include \(dqdnsresolv.h\(dq
int \fBdns_ip4_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR);
.br
int \fBdns_ip4\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR);
int \fBdns_ip6_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR);
.br
int \fBdns_ip6\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR);
int \fBdns_mx\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR);
.br
int \fBdns_mx_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR);
void \fBdns_name4_domain\fP(char \fIq\fR[DNS_NAME4_DOMAIN],const char *\fIip\fR[4]);
.br
int \fBdns_name4\fP(stralloc *\fIout\fR,const char *\fIip\fR[4]);
void \fBdns_name6_domain\fP(char \fIq\fR[DNS_NAME6_DOMAIN],const char *\fIip\fR[16]);
.br
int \fBdns_name6\fP(stralloc *\fIout\fR,const char *\fIip\fR[16]);
int \fBdns_name\fP(stralloc *\fIout\fR,const char *\fIip\fR[16]);
.br
int \fBdns_name_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR);
int \fBdns_txt\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR);
.br
int \fBdns_txt_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR);
int \fBdns_cname\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR);
.br
int \fBdns_cname_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR);
int \fBdns_ip4_qualify\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR,const stralloc *\fIudn\fR);
.br
int \fBdns_ip6_qualify\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR,const stralloc *\fIudn\fR);
.br
int \fBdns_ip_qualify\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR,const stralloc *\fIudn\fR);
.SH DESCRIPTION
.B dns_ip[4|6]_packet
is a low-level component of
.BR dns_ip[4|6] ,
designed to support asynchronous DNS lookups.
It reads a DNS packet of length \fIlen\fR from
\fIbuf\fR, extracts the IP(4|6) addresses from the answer section of the packet and
puts the addresses into \fIout\fR.
.B dns_ip[4|6]
looks up 4/16-byte IPv6 addresses for the fully qualified domain name of
\fIfqdn\fR. It puts the concatenation of the IPv[4|6] addresses into \fIout\fR and
returns the number of received answers for \fIfqdn\fR or \fI0\fR if none are replied.
If the domain does not exist in DNS, or has no IP addresses,
\fIout\fR will be empty. More generally, if \fIfqdn\fR is considered by
.B dns_ip4
to be a dotted-decimal IPv4 address, it is provissioned as \fIout\fR
without checking the DNS while returning \fI1\fR.
Brackets may enclose the dotted-decimal IP address; they are ignored.
.B dns_name[4|6]_packet
is a low-level component of
.B dns_name[4|6]
designed to support asynchronous DNS lookups.
It reads a DNS packet of length \fIlen\fR from \fIbuf\fR,
.B dns_name[4|6]_domain
is a low-level component of
.BR dns_name[4|6] .
It converts an IP address such as
.I 1.2.3.4
or
.I 4321:0:1:2:3:4:567:89ab
into a domain name such as
.I 4.3.2.1.in-addr.arpa
or
.I b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa
and places the packet-encoded domain name into \fIq\fR.
.I q
is zero terminated.
.I q
must have space for DNS_NAME[4|6]_DOMAIN bytes.
.B dns_mx_packet
is a low-level component of
.BR dns_mx ,
designed to support asynchronous DNS lookups.
It reads a DNS packet of length \fIlen\fR from \fIbuf\fR,
extracts the MX records from the answer section of the packet, puts the
result into \fIout\fR, and returns the number of replies received
or \fI-1\fR the same way as
.BR dns_mx .
.B dns_mx
looks up MX records for the fully-qualified domain name in
\fIfqdn\fR. It puts the MX records into \fIout\fR and returns the number of
received records or \fI0\fR.
Each MX record is a two-byte MX distance (big endian) followed by a
\\0-terminated dot-encoded domain name. If the domain does not exist in
DNS, or has no MX records, \fIout\fR will be empty.
.B dns_txt_packet
is a low-level component of
.BR dns_txt ,
designed to support
asynchronous DNS lookups. It reads a DNS packet of length \fIlen\fR from \fIbuf\fR,
extracts the TXT records from the answer section of the packet, puts the
result into \fIout\fR, and returns the number of replies
or \fI-1\fR the same way as \fBdns_txt\fR.
.B dns_txt
looks up TXT records for the fully-qualified domain name in
\fIfqdn\fR. It puts the concatenation of the TXT records into \fIout\fR
and returns the number of replies received.
If the domain does not exist in DNS, or has no TXT records, \fIout\fR will be empty.
.B dns_cname_packet
is a low-level component of
.BR dns_cname ,
designed to support
asynchronous DNS lookups. It reads a DNS packet of length \fIlen\fR from \fIbuf\fR,
extracts the TXT records from the answer section of the packet, puts the
result into \fIout\fR, and returns the number of replies received or
\fI-1\fR the same way as \fBdns_cname\fR.
.B dns_cname
looks up the canonical name for a given
.IR fqdn .
.B dns_ip[4|6]_qualify
feeds the name \fIudn\fR through qualification and looks up their
4-byte/16-byte IP addresses. It puts the fully qualified domain name
into \fIfqdn\fR and the concatenation of the IP addresses into \fIout\fR,
while returning the number of encountered IP addresses.
.B dns_ip[4|6]_qualify
evaluates the environment variables
.I $DNSREWRITEFILE
pointing to
.I /etc/dnsrewrite
and
.I $LOCALDOMAIN
and finally reading
.I /etc/resolv.conf
to build the
.I Full Qualified Domain Name (FQDN)
using the
.I domain suffix
for
.IR hostname .
.B dns_ip_qualify
returns
.I out
as
.I IP[4|6]
and
.IR FQDN .
If the domain does not exist in DNS, or has no IP addresses,
\fIout\fR will be empty and the return code is \fI0\fR.
In case
.B dns_ip[4|6]_qualify
is fed with an
.I IP[4|6]
addresses instead of domain names,
it recognizes those not to be subject of
.IR qualification .
The particular names
.IR localhost ,
.I ip4-loopback
and
.I ip6-loopback
are treated locally and mapped to
the respective
.I IP[4|6]
addresses (and vice versa)
without facilitating a DNS lookup.
.SH "INPUT"
For the high-level routines
.BR dns_ip[4|6] ,
.BR dns_ip_qualify[4|6] ,
.BR dns_name[4|6] ,
.BR dns_mx ,
.BR dns_name ,
.BR dns_txt
and
.BR dns_cname
the provided input variable
.I stralloc \*\fqdn
needs to be un-terminated, thus the given
string length is identitical to the number of
.I fqdn
characters.
.SH "OUTPUT"
The returned IP addresses are given as character (byte) strings
with 4 or 16 bytes:
.B dns_ip4
and
.B dns_ip4_qualifiy
return 4 byte IPv4 addresses, where as
.B dns_ip6
and
.B dns_ip
as well as
.B dns_ip6_qualify
and
.B dns_ip_qualify
return sets of 16 byte IPv6 addresses, where
the potential IPv4 addresses are given in their
IPv6-mapped-IPv4 representation.
.SH "RETURN CODES"
The dns routines
.BR dns_cname* ,
.BR dns_ip* ,
.BR dns_mx* ,
.B dns_name*
and
.BR dns_txt*
return the number of answers received, which may be
.I 0
and potentially
.I -1
in case of a memory failure. The full set of return codes:
.EX
Value | Macro | Explaination
------+----------+-------------------------------------
n>0 | | n = number of answers reeceived
0 | DNS_NXD | either NXDOMAIN or NODATA
-1 | DNS_MEM | out of memory (fatal)
-2 | DNS_ERR | parsing errors
-3 | DNS_COM | socket communicaton errror; SERVFAIL
-4 | DNS_INT | internal error
-5 | DNS_SOFT | DNS_ERR or DNS_COM
-6 | DNS_HARD | DNS loop problem (CNAME)
.EE
.I errno
is set appropriately.
In case of a failure, the respective output variables like
\fIout\fR and \fIfqdn\fR may or may not change.
Since a received reply may be empty, always check the length of the
received output additionally.
.SH "SEE ALSO"
ip4(3),
ip6(3),
dnsstub(3)
|