xref: /netbsd-src/external/ibm-public/postfix/dist/src/dns/dns.h (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: dns.h,v 1.2 2017/02/14 01:16:44 christos Exp $	*/
2 
3 #ifndef _DNS_H_INCLUDED_
4 #define _DNS_H_INCLUDED_
5 
6 /*++
7 /* NAME
8 /*	dns 3h
9 /* SUMMARY
10 /*	domain name service lookup
11 /* SYNOPSIS
12 /*	#include <dns.h>
13 /* DESCRIPTION
14 /* .nf
15 
16  /*
17   * System library.
18   */
19 #include <netinet/in.h>
20 #include <arpa/nameser.h>
21 #ifdef RESOLVE_H_NEEDS_STDIO_H
22 #include <stdio.h>
23 #endif
24 #ifdef RESOLVE_H_NEEDS_NAMESER8_COMPAT_H
25 #include <nameser8_compat.h>
26 #endif
27 #ifdef RESOLVE_H_NEEDS_ARPA_NAMESER_COMPAT_H
28 #include <arpa/nameser_compat.h>
29 #endif
30 #include <resolv.h>
31 
32  /*
33   * Name server compatibility. These undocumented macros appear in the file
34   * <arpa/nameser.h>, but since they are undocumented we should not count on
35   * their presence, and so they are included here just in case.
36   */
37 #ifndef GETSHORT
38 
39 #define GETSHORT(s, cp) { \
40 	unsigned char *t_cp = (u_char *)(cp); \
41 	(s) = ((unsigned)t_cp[0] << 8) \
42 	    | ((unsigned)t_cp[1]) \
43 	    ; \
44 	(cp) += 2; \
45 }
46 
47 #define GETLONG(l, cp) { \
48 	unsigned char *t_cp = (u_char *)(cp); \
49 	(l) = ((unsigned)t_cp[0] << 24) \
50 	    | ((unsigned)t_cp[1] << 16) \
51 	    | ((unsigned)t_cp[2] << 8) \
52 	    | ((unsigned)t_cp[3]) \
53 	    ; \
54 	(cp) += 4; \
55 }
56 
57 #endif
58 
59 /*
60  * Disable DNSSEC at compile-time even if RES_USE_DNSSEC is available
61  */
62 #ifdef NO_DNSSEC
63 #undef RES_USE_DNSSEC
64 #endif
65 
66  /*
67   * Compatibility with systems that lack RES_USE_DNSSEC and RES_USE_EDNS0
68   */
69 #ifndef RES_USE_DNSSEC
70 #define RES_USE_DNSSEC	0
71 #endif
72 #ifndef RES_USE_EDNS0
73 #define RES_USE_EDNS0	0
74 #endif
75 
76  /*-
77   * TLSA: https://tools.ietf.org/html/rfc6698#section-7.1
78   * RRSIG: http://tools.ietf.org/html/rfc4034#section-3
79   *
80   * We don't request RRSIG, but we get it "for free" when we send the DO-bit.
81   */
82 #ifndef T_TLSA
83 #define T_TLSA		52
84 #endif
85 #ifndef T_RRSIG
86 #define T_RRSIG		46		/* Avoid unknown RR in logs */
87 #endif
88 #ifndef T_DNAME
89 #define T_DNAME		39		/* [RFC6672] */
90 #endif
91 
92  /*
93   * https://tools.ietf.org/html/rfc6698#section-7.2
94   */
95 #define DNS_TLSA_USAGE_CA_CONSTRAINT			0
96 #define DNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT	1
97 #define DNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION		2
98 #define DNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE	3
99 
100  /*
101   * https://tools.ietf.org/html/rfc6698#section-7.3
102   */
103 #define DNS_TLSA_SELECTOR_FULL_CERTIFICATE	0
104 #define DNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO	1
105 
106  /*
107   * https://tools.ietf.org/html/rfc6698#section-7.4
108   */
109 #define DNS_TLSA_MATCHING_TYPE_NO_HASH_USED	0
110 #define DNS_TLSA_MATCHING_TYPE_SHA256		1
111 #define DNS_TLSA_MATCHING_TYPE_SHA512		2
112 
113  /*
114   * SunOS 4 needs this.
115   */
116 #ifndef T_TXT
117 #define T_TXT	16
118 #endif
119 
120  /*
121   * Utility library.
122   */
123 #include <vstring.h>
124 #include <sock_addr.h>
125 #include <myaddrinfo.h>
126 
127  /*
128   * Structure for fixed resource record data.
129   */
130 typedef struct DNS_FIXED {
131     unsigned short type;		/* T_A, T_CNAME, etc. */
132     unsigned short class;		/* C_IN, etc. */
133     unsigned int ttl;			/* always */
134     unsigned length;			/* record length */
135 } DNS_FIXED;
136 
137  /*
138   * Structure of a DNS resource record after expansion. The components are
139   * named after the things one can expect to find in a DNS resource record.
140   */
141 typedef struct DNS_RR {
142     char   *qname;			/* query name, mystrdup()ed */
143     char   *rname;			/* reply name, mystrdup()ed */
144     unsigned short type;		/* T_A, T_CNAME, etc. */
145     unsigned short class;		/* C_IN, etc. */
146     unsigned int ttl;			/* always */
147     unsigned int dnssec_valid;		/* DNSSEC validated */
148     unsigned short pref;		/* T_MX only */
149     struct DNS_RR *next;		/* linkage */
150     size_t  data_len;			/* actual data size */
151     char    data[1];			/* actually a bunch of data */
152 } DNS_RR;
153 
154  /*
155   * dns_strerror.c
156   */
157 extern const char *dns_strerror(unsigned);
158 
159  /*
160   * dns_strtype.c
161   */
162 extern const char *dns_strtype(unsigned);
163 extern unsigned dns_type(const char *);
164 
165  /*
166   * dns_strrecord.c
167   */
168 extern char *dns_strrecord(VSTRING *, DNS_RR *);
169 
170  /*
171   * dns_rr.c
172   */
173 extern DNS_RR *dns_rr_create(const char *, const char *,
174 			             ushort, ushort,
175 			             unsigned, unsigned,
176 			             const char *, size_t);
177 extern void dns_rr_free(DNS_RR *);
178 extern DNS_RR *dns_rr_copy(DNS_RR *);
179 extern DNS_RR *dns_rr_append(DNS_RR *, DNS_RR *);
180 extern DNS_RR *dns_rr_sort(DNS_RR *, int (*) (DNS_RR *, DNS_RR *));
181 extern int dns_rr_compare_pref_ipv6(DNS_RR *, DNS_RR *);
182 extern int dns_rr_compare_pref_ipv4(DNS_RR *, DNS_RR *);
183 extern int dns_rr_compare_pref_any(DNS_RR *, DNS_RR *);
184 extern int dns_rr_compare_pref(DNS_RR *, DNS_RR *);
185 extern DNS_RR *dns_rr_shuffle(DNS_RR *);
186 extern DNS_RR *dns_rr_remove(DNS_RR *, DNS_RR *);
187 
188  /*
189   * dns_rr_to_pa.c
190   */
191 extern const char *dns_rr_to_pa(DNS_RR *, MAI_HOSTADDR_STR *);
192 
193  /*
194   * dns_sa_to_rr.c
195   */
196 extern DNS_RR *dns_sa_to_rr(const char *, unsigned, struct sockaddr *);
197 
198  /*
199   * dns_rr_to_sa.c
200   */
201 extern int dns_rr_to_sa(DNS_RR *, unsigned, struct sockaddr *, SOCKADDR_SIZE *);
202 
203  /*
204   * dns_rr_eq_sa.c
205   */
206 extern int dns_rr_eq_sa(DNS_RR *, struct sockaddr *);
207 
208 #ifdef HAS_IPV6
209 #define DNS_RR_EQ_SA(rr, sa) \
210     ((SOCK_ADDR_IN_FAMILY(sa) == AF_INET && (rr)->type == T_A \
211      && SOCK_ADDR_IN_ADDR(sa).s_addr == IN_ADDR((rr)->data).s_addr) \
212     || (SOCK_ADDR_IN_FAMILY(sa) == AF_INET6 && (rr)->type == T_AAAA \
213 	&& memcmp((char *) &(SOCK_ADDR_IN6_ADDR(sa)), \
214 		  (rr)->data, (rr)->data_len) == 0))
215 #else
216 #define DNS_RR_EQ_SA(rr, sa) \
217     (SOCK_ADDR_IN_FAMILY(sa) == AF_INET && (rr)->type == T_A \
218      && SOCK_ADDR_IN_ADDR(sa).s_addr == IN_ADDR((rr)->data).s_addr)
219 #endif
220 
221  /*
222   * dns_lookup.c
223   */
224 extern int dns_lookup_x(const char *, unsigned, unsigned, DNS_RR **,
225 			        VSTRING *, VSTRING *, int *, unsigned);
226 extern int dns_lookup_rl(const char *, unsigned, DNS_RR **, VSTRING *,
227 			         VSTRING *, int *, int,...);
228 extern int dns_lookup_rv(const char *, unsigned, DNS_RR **, VSTRING *,
229 			         VSTRING *, int *, int, unsigned *);
230 
231 #define dns_lookup(name, type, rflags, list, fqdn, why) \
232     dns_lookup_x((name), (type), (rflags), (list), (fqdn), (why), (int *) 0, \
233 	(unsigned) 0)
234 #define dns_lookup_r(name, type, rflags, list, fqdn, why, rcode) \
235     dns_lookup_x((name), (type), (rflags), (list), (fqdn), (why), (rcode), \
236 	(unsigned) 0)
237 #define dns_lookup_l(name, rflags, list, fqdn, why, lflags, ...) \
238     dns_lookup_rl((name), (rflags), (list), (fqdn), (why), (int *) 0, \
239 	(lflags), __VA_ARGS__)
240 #define dns_lookup_v(name, rflags, list, fqdn, why, lflags, ltype) \
241     dns_lookup_rv((name), (rflags), (list), (fqdn), (why), (int *) 0, \
242 	(lflags), (ltype))
243 
244  /*
245   * Request flags.
246   */
247 #define DNS_REQ_FLAG_STOP_OK	(1<<0)
248 #define DNS_REQ_FLAG_STOP_INVAL	(1<<1)
249 #define DNS_REQ_FLAG_STOP_NULLMX (1<<2)
250 #define DNS_REQ_FLAG_STOP_MX_POLICY (1<<3)
251 #define DNS_REQ_FLAG_NCACHE_TTL	(1<<4)
252 #define DNS_REQ_FLAG_NONE	(0)
253 
254  /*
255   * Status codes. Failures must have negative codes so they will not collide
256   * with valid counts of answer records etc.
257   *
258   * When a function queries multiple record types for one name, it issues one
259   * query for each query record type. Each query returns a (status, rcode,
260   * text). Only one of these (status, rcode, text) will be returned to the
261   * caller. The selection is based on the status code precedence.
262   *
263   * - Return DNS_OK (and the corresponding rcode) as long as any query returned
264   * DNS_OK. If this is changed, then code needs to be added to prevent memory
265   * leaks.
266   *
267   * - Return DNS_RETRY (and the corresponding rcode and text) instead of any
268   * hard negative result.
269   *
270   * - Return DNS_NOTFOUND (and the corresponding rcode and text) only when all
271   * queries returned DNS_NOTFOUND.
272   *
273   * DNS_POLICY ranks higher than DNS_RETRY because there was a DNS_OK result,
274   * but the reply filter dropped it. This is a very soft error.
275   *
276   * Below is the precedence order. The order between DNS_RETRY and DNS_NOTFOUND
277   * is arbitrary.
278   */
279 #define DNS_RECURSE	(-7)		/* internal only: recursion needed */
280 #define DNS_NOTFOUND	(-6)		/* query ok, data not found */
281 #define DNS_NULLMX	(-5)		/* query ok, service unavailable */
282 #define DNS_FAIL	(-4)		/* query failed, don't retry */
283 #define DNS_INVAL	(-3)		/* query ok, malformed reply */
284 #define DNS_RETRY	(-2)		/* query failed, try again */
285 #define DNS_POLICY	(-1)		/* query ok, all records dropped */
286 #define DNS_OK		0		/* query succeeded */
287 
288  /*
289   * How long can a DNS name or single text value be?
290   */
291 #define DNS_NAME_LEN	1024
292 
293  /*
294   * dns_rr_filter.c.
295   */
296 extern void dns_rr_filter_compile(const char *, const char *);
297 
298 #ifdef LIBDNS_INTERNAL
299 #include <maps.h>
300 extern MAPS *dns_rr_filter_maps;
301 extern int dns_rr_filter_execute(DNS_RR **);
302 
303 #endif
304 
305 /* LICENSE
306 /* .ad
307 /* .fi
308 /*	The Secure Mailer license must be distributed with this software.
309 /* AUTHOR(S)
310 /*	Wietse Venema
311 /*	IBM T.J. Watson Research
312 /*	P.O. Box 704
313 /*	Yorktown Heights, NY 10598, USA
314 /*--*/
315 
316 #endif
317