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