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