1*373da8abSflorian /* $OpenBSD: asr_private.h,v 1.49 2023/11/20 12:15:16 florian Exp $ */ 2b44da627Seric /* 3b44da627Seric * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> 4b44da627Seric * 5b44da627Seric * Permission to use, copy, modify, and distribute this software for any 6b44da627Seric * purpose with or without fee is hereby granted, provided that the above 7b44da627Seric * copyright notice and this permission notice appear in all copies. 8b44da627Seric * 9b44da627Seric * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10b44da627Seric * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11b44da627Seric * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12b44da627Seric * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13b44da627Seric * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14b44da627Seric * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15b44da627Seric * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16b44da627Seric */ 1780f48568Seric 18b44da627Seric #include <stdio.h> 19b44da627Seric 20b44da627Seric #define QR_MASK (0x1 << 15) 21b44da627Seric #define OPCODE_MASK (0xf << 11) 22b44da627Seric #define AA_MASK (0x1 << 10) 23b44da627Seric #define TC_MASK (0x1 << 9) 24b44da627Seric #define RD_MASK (0x1 << 8) 25b44da627Seric #define RA_MASK (0x1 << 7) 263aff1a83Sjca #define Z_MASK (0x1 << 6) 273aff1a83Sjca #define AD_MASK (0x1 << 5) 283aff1a83Sjca #define CD_MASK (0x1 << 4) 29b44da627Seric #define RCODE_MASK (0xf) 30b44da627Seric 31b44da627Seric #define OPCODE(v) ((v) & OPCODE_MASK) 32b44da627Seric #define RCODE(v) ((v) & RCODE_MASK) 33b44da627Seric 34b44da627Seric 35f90bf415Seric struct asr_pack { 36975956b6Seric char *buf; 37975956b6Seric size_t len; 38975956b6Seric size_t offset; 3992f75510Seric int err; 40975956b6Seric }; 41975956b6Seric 42f90bf415Seric struct asr_unpack { 43975956b6Seric const char *buf; 44b44da627Seric size_t len; 45b44da627Seric size_t offset; 4692f75510Seric int err; 47b44da627Seric }; 48b44da627Seric 49f90bf415Seric struct asr_dns_header { 50b44da627Seric uint16_t id; 51b44da627Seric uint16_t flags; 52b44da627Seric uint16_t qdcount; 53b44da627Seric uint16_t ancount; 54b44da627Seric uint16_t nscount; 55b44da627Seric uint16_t arcount; 56b44da627Seric }; 57b44da627Seric 58f90bf415Seric struct asr_dns_query { 59b44da627Seric char q_dname[MAXDNAME]; 60b44da627Seric uint16_t q_type; 61b44da627Seric uint16_t q_class; 62b44da627Seric }; 63b44da627Seric 64f90bf415Seric struct asr_dns_rr { 65b44da627Seric char rr_dname[MAXDNAME]; 66b44da627Seric uint16_t rr_type; 67b44da627Seric uint16_t rr_class; 68b44da627Seric uint32_t rr_ttl; 69b44da627Seric union { 70b44da627Seric struct { 71b44da627Seric char cname[MAXDNAME]; 72b44da627Seric } cname; 73b44da627Seric struct { 74b44da627Seric uint16_t preference; 75b44da627Seric char exchange[MAXDNAME]; 76b44da627Seric } mx; 77b44da627Seric struct { 78b44da627Seric char nsname[MAXDNAME]; 79b44da627Seric } ns; 80b44da627Seric struct { 81b44da627Seric char ptrname[MAXDNAME]; 82b44da627Seric } ptr; 83b44da627Seric struct { 84b44da627Seric char mname[MAXDNAME]; 85b44da627Seric char rname[MAXDNAME]; 86b44da627Seric uint32_t serial; 87b44da627Seric uint32_t refresh; 88b44da627Seric uint32_t retry; 89b44da627Seric uint32_t expire; 90b44da627Seric uint32_t minimum; 91b44da627Seric } soa; 92b44da627Seric struct { 93b44da627Seric struct in_addr addr; 94b44da627Seric } in_a; 95b44da627Seric struct { 96b44da627Seric struct in6_addr addr6; 97b44da627Seric } in_aaaa; 98b44da627Seric struct { 99b44da627Seric uint16_t rdlen; 100b44da627Seric const void *rdata; 101b44da627Seric } other; 102b44da627Seric } rr; 103b44da627Seric }; 104b44da627Seric 105b44da627Seric 106b44da627Seric #define ASR_MAXNS 5 107b44da627Seric #define ASR_MAXDB 3 108b44da627Seric #define ASR_MAXDOM 10 109b44da627Seric 110b44da627Seric enum async_type { 111b44da627Seric ASR_SEND, 112b44da627Seric ASR_SEARCH, 113b44da627Seric ASR_GETRRSETBYNAME, 114b44da627Seric ASR_GETHOSTBYNAME, 115b44da627Seric ASR_GETHOSTBYADDR, 116b44da627Seric ASR_GETADDRINFO, 117b44da627Seric ASR_GETNAMEINFO, 118b44da627Seric }; 119b44da627Seric 1201ed934d0Seric #define ASR_DB_FILE 'f' 1211ed934d0Seric #define ASR_DB_DNS 'b' 122b44da627Seric 123b44da627Seric struct asr_ctx { 124b44da627Seric int ac_refcount; 125b44da627Seric int ac_options; 126b44da627Seric int ac_ndots; 127b44da627Seric char *ac_domain; 128b44da627Seric int ac_domcount; 129b44da627Seric char *ac_dom[ASR_MAXDOM]; 130b44da627Seric int ac_dbcount; 1311ed934d0Seric char ac_db[ASR_MAXDB + 1]; 132b44da627Seric int ac_family[3]; 133b44da627Seric 134b44da627Seric int ac_nscount; 135b44da627Seric int ac_nstimeout; 136b44da627Seric int ac_nsretries; 137b44da627Seric struct sockaddr *ac_ns[ASR_MAXNS]; 138b44da627Seric 139b44da627Seric }; 140b44da627Seric 141b44da627Seric struct asr { 1425aaab171Seric pid_t a_pid; 143b44da627Seric time_t a_mtime; 144b44da627Seric time_t a_rtime; 145b44da627Seric struct asr_ctx *a_ctx; 146b44da627Seric }; 147b44da627Seric 1485be03f8fSeric #define ASYNC_COND 0 1495be03f8fSeric #define ASYNC_DONE 1 150b44da627Seric 151b44da627Seric #define ASYNC_DOM_FQDN 0x00000001 152b44da627Seric #define ASYNC_DOM_NDOTS 0x00000002 1536a7a3d64Seric #define ASYNC_DOM_DOMAIN 0x00000004 1546a7a3d64Seric #define ASYNC_DOM_ASIS 0x00000008 155b44da627Seric 156b44da627Seric #define ASYNC_NODATA 0x00000100 157b44da627Seric #define ASYNC_AGAIN 0x00000200 158b44da627Seric 159b5afe704Sschwarze #define ASYNC_GETNET 0x00001000 160b44da627Seric #define ASYNC_EXTOBUF 0x00002000 161b44da627Seric 1628b59b78cSjca #define ASYNC_NO_INET 0x00010000 1638b59b78cSjca #define ASYNC_NO_INET6 0x00020000 164b44da627Seric 1655be03f8fSeric struct asr_query { 1665be03f8fSeric int (*as_run)(struct asr_query *, struct asr_result *); 167b44da627Seric struct asr_ctx *as_ctx; 168b44da627Seric int as_type; 169abe78e02Sjca int as_flags; 170b44da627Seric int as_state; 171b44da627Seric 172b44da627Seric /* cond */ 173b44da627Seric int as_timeout; 174b44da627Seric int as_fd; 175f6f51dadSeric struct asr_query *as_subq; 176b44da627Seric 177b44da627Seric /* loop indices in ctx */ 178b44da627Seric int as_dom_step; 179b44da627Seric int as_dom_idx; 180b44da627Seric int as_dom_flags; 181b44da627Seric int as_family_idx; 182b44da627Seric int as_db_idx; 183b44da627Seric 184b44da627Seric int as_count; 185b44da627Seric 186b44da627Seric union { 187b44da627Seric struct { 188b44da627Seric uint16_t reqid; 189b44da627Seric int class; 190b44da627Seric int type; 191b44da627Seric char *dname; /* not fqdn! */ 192b44da627Seric int rcode; /* response code */ 193b44da627Seric int ancount; /* answer count */ 194b44da627Seric 195d3064b1fSeric int nsidx; 196d3064b1fSeric int nsloop; 197d3064b1fSeric 198b44da627Seric /* io buffers for query/response */ 199b44da627Seric unsigned char *obuf; 200b44da627Seric size_t obuflen; 201b44da627Seric size_t obufsize; 202b44da627Seric unsigned char *ibuf; 203b44da627Seric size_t ibuflen; 204b44da627Seric size_t ibufsize; 205b44da627Seric size_t datalen; /* for tcp io */ 2067856d263Seric uint16_t pktlen; 207b44da627Seric } dns; 208b44da627Seric 209b44da627Seric struct { 210b44da627Seric int class; 211b44da627Seric int type; 212b44da627Seric char *name; 213b44da627Seric int saved_h_errno; 214b44da627Seric } search; 215b44da627Seric 216b44da627Seric struct { 217b44da627Seric int flags; 218b44da627Seric int class; 219b44da627Seric int type; 220b44da627Seric char *name; 221b44da627Seric } rrset; 222b44da627Seric 223b44da627Seric struct { 224b44da627Seric char *name; 225b44da627Seric int family; 226b44da627Seric char addr[16]; 227b44da627Seric int addrlen; 2287ffb6b35Seric int subq_h_errno; 229b44da627Seric } hostnamadr; 230b44da627Seric 231b44da627Seric struct { 232b44da627Seric char *hostname; 233b44da627Seric char *servname; 234b44da627Seric int port_tcp; 235b44da627Seric int port_udp; 236b44da627Seric union { 237b44da627Seric struct sockaddr sa; 238b44da627Seric struct sockaddr_in sain; 239b44da627Seric struct sockaddr_in6 sain6; 240b44da627Seric } sa; 241b44da627Seric 242b44da627Seric struct addrinfo hints; 243c5c8c49bSeric char *fqdn; 244b44da627Seric struct addrinfo *aifirst; 245b44da627Seric struct addrinfo *ailast; 246b44da627Seric } ai; 247b44da627Seric 248b44da627Seric struct { 249b44da627Seric char *hostname; 250b44da627Seric char *servname; 251b44da627Seric size_t hostnamelen; 252b44da627Seric size_t servnamelen; 253b44da627Seric union { 254b44da627Seric struct sockaddr sa; 255b44da627Seric struct sockaddr_in sain; 256b44da627Seric struct sockaddr_in6 sain6; 257b44da627Seric } sa; 258b44da627Seric int flags; 259b44da627Seric } ni; 260b44da627Seric #define MAXTOKEN 10 261b44da627Seric } as; 262b44da627Seric 263b44da627Seric }; 264b44da627Seric 265b44da627Seric #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1]) 266b44da627Seric #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx]) 267b44da627Seric 268b44da627Seric enum asr_state { 269b44da627Seric ASR_STATE_INIT, 270b44da627Seric ASR_STATE_NEXT_DOMAIN, 271b44da627Seric ASR_STATE_NEXT_DB, 272b44da627Seric ASR_STATE_SAME_DB, 273b44da627Seric ASR_STATE_NEXT_FAMILY, 274b44da627Seric ASR_STATE_NEXT_NS, 275b44da627Seric ASR_STATE_UDP_SEND, 276b44da627Seric ASR_STATE_UDP_RECV, 277b44da627Seric ASR_STATE_TCP_WRITE, 278b44da627Seric ASR_STATE_TCP_READ, 279b44da627Seric ASR_STATE_PACKET, 280b44da627Seric ASR_STATE_SUBQUERY, 281b44da627Seric ASR_STATE_NOT_FOUND, 282b44da627Seric ASR_STATE_HALT, 283b44da627Seric }; 284b44da627Seric 2852aa4cd21Sjca #define MAXPACKETSZ 4096 286b44da627Seric 287253ef892Sderaadt __BEGIN_HIDDEN_DECLS 288253ef892Sderaadt 289b44da627Seric /* asr_utils.c */ 290253ef892Sderaadt void _asr_pack_init(struct asr_pack *, char *, size_t); 291253ef892Sderaadt int _asr_pack_header(struct asr_pack *, const struct asr_dns_header *); 292253ef892Sderaadt int _asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *); 293d4d39a6fSjca int _asr_pack_edns0(struct asr_pack *, uint16_t, int); 294253ef892Sderaadt void _asr_unpack_init(struct asr_unpack *, const char *, size_t); 295253ef892Sderaadt int _asr_unpack_header(struct asr_unpack *, struct asr_dns_header *); 296253ef892Sderaadt int _asr_unpack_query(struct asr_unpack *, struct asr_dns_query *); 297253ef892Sderaadt int _asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *); 298253ef892Sderaadt int _asr_sockaddr_from_str(struct sockaddr *, int, const char *); 299253ef892Sderaadt ssize_t _asr_dname_from_fqdn(const char *, char *, size_t); 300253ef892Sderaadt ssize_t _asr_addr_as_fqdn(const char *, int, char *, size_t); 3011b04c78cSflorian int hnok_lenient(const char *); 302*373da8abSflorian int _asr_is_localhost(const char*); 303b44da627Seric 304b44da627Seric /* asr.c */ 305253ef892Sderaadt void _asr_resolver_done(void *); 306253ef892Sderaadt struct asr_ctx *_asr_use_resolver(void *); 307656b8d51Sderaadt struct asr_ctx *_asr_no_resolver(void); 308253ef892Sderaadt void _asr_ctx_unref(struct asr_ctx *); 309253ef892Sderaadt struct asr_query *_asr_async_new(struct asr_ctx *, int); 310253ef892Sderaadt void _asr_async_free(struct asr_query *); 311253ef892Sderaadt size_t _asr_make_fqdn(const char *, const char *, char *, size_t); 312253ef892Sderaadt char *_asr_strdname(const char *, char *, size_t); 313253ef892Sderaadt int _asr_iter_db(struct asr_query *); 314253ef892Sderaadt int _asr_parse_namedb_line(FILE *, char **, int, char *, size_t); 315b44da627Seric 316f90bf415Seric /* *_async.c */ 317253ef892Sderaadt struct asr_query *_res_query_async_ctx(const char *, int, int, struct asr_ctx *); 318253ef892Sderaadt struct asr_query *_res_search_async_ctx(const char *, int, int, struct asr_ctx *); 319253ef892Sderaadt struct asr_query *_gethostbyaddr_async_ctx(const void *, socklen_t, int, 320b44da627Seric struct asr_ctx *); 321b44da627Seric 322253ef892Sderaadt int _asr_iter_domain(struct asr_query *, const char *, char *, size_t); 323253ef892Sderaadt 324b44da627Seric #ifdef DEBUG 325b44da627Seric 32655f55055Seric #define DPRINT(...) do { if(_asr_debug) { \ 32755f55055Seric fprintf(_asr_debug, __VA_ARGS__); \ 32846ab4803Seric } } while (0) 32955f55055Seric #define DPRINT_PACKET(n, p, s) do { if(_asr_debug) { \ 33055f55055Seric fprintf(_asr_debug, "----- %s -----\n", n); \ 33155f55055Seric _asr_dump_packet(_asr_debug, (p), (s)); \ 33255f55055Seric fprintf(_asr_debug, "--------------\n"); \ 33346ab4803Seric } } while (0) 334b44da627Seric 3358031c0b5Sjca #else /* DEBUG */ 3368031c0b5Sjca 3378031c0b5Sjca #define DPRINT(...) 3388031c0b5Sjca #define DPRINT_PACKET(...) 3398031c0b5Sjca 3408031c0b5Sjca #endif /* DEBUG */ 3418031c0b5Sjca 342253ef892Sderaadt const char *_asr_querystr(int); 343253ef892Sderaadt const char *_asr_statestr(int); 344253ef892Sderaadt const char *_asr_transitionstr(int); 345253ef892Sderaadt const char *_asr_print_sockaddr(const struct sockaddr *, char *, size_t); 346253ef892Sderaadt void _asr_dump_config(FILE *, struct asr *); 347253ef892Sderaadt void _asr_dump_packet(FILE *, const void *, size_t); 348d4cf23afSeric 349253ef892Sderaadt extern FILE *_asr_debug; 350b44da627Seric 351d4cf23afSeric #define async_set_state(a, s) do { \ 352d4cf23afSeric DPRINT("asr: [%s@%p] %s -> %s\n", \ 35355f55055Seric _asr_querystr((a)->as_type), \ 354d4cf23afSeric as, \ 35555f55055Seric _asr_statestr((a)->as_state), \ 35655f55055Seric _asr_statestr((s))); \ 357d4cf23afSeric (a)->as_state = (s); } while (0) 358253ef892Sderaadt 359253ef892Sderaadt __END_HIDDEN_DECLS 360