1 /* $OpenBSD: asr_private.h,v 1.26 2014/04/17 15:28:26 guenther Exp $ */ 2 /* 3 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <stdio.h> 19 20 #define QR_MASK (0x1 << 15) 21 #define OPCODE_MASK (0xf << 11) 22 #define AA_MASK (0x1 << 10) 23 #define TC_MASK (0x1 << 9) 24 #define RD_MASK (0x1 << 8) 25 #define RA_MASK (0x1 << 7) 26 #define Z_MASK (0x7 << 4) 27 #define RCODE_MASK (0xf) 28 29 #define OPCODE(v) ((v) & OPCODE_MASK) 30 #define RCODE(v) ((v) & RCODE_MASK) 31 32 33 struct asr_pack { 34 char *buf; 35 size_t len; 36 size_t offset; 37 const char *err; 38 }; 39 40 struct asr_unpack { 41 const char *buf; 42 size_t len; 43 size_t offset; 44 const char *err; 45 }; 46 47 struct asr_dns_header { 48 uint16_t id; 49 uint16_t flags; 50 uint16_t qdcount; 51 uint16_t ancount; 52 uint16_t nscount; 53 uint16_t arcount; 54 }; 55 56 struct asr_dns_query { 57 char q_dname[MAXDNAME]; 58 uint16_t q_type; 59 uint16_t q_class; 60 }; 61 62 struct asr_dns_rr { 63 char rr_dname[MAXDNAME]; 64 uint16_t rr_type; 65 uint16_t rr_class; 66 uint32_t rr_ttl; 67 union { 68 struct { 69 char cname[MAXDNAME]; 70 } cname; 71 struct { 72 uint16_t preference; 73 char exchange[MAXDNAME]; 74 } mx; 75 struct { 76 char nsname[MAXDNAME]; 77 } ns; 78 struct { 79 char ptrname[MAXDNAME]; 80 } ptr; 81 struct { 82 char mname[MAXDNAME]; 83 char rname[MAXDNAME]; 84 uint32_t serial; 85 uint32_t refresh; 86 uint32_t retry; 87 uint32_t expire; 88 uint32_t minimum; 89 } soa; 90 struct { 91 struct in_addr addr; 92 } in_a; 93 struct { 94 struct in6_addr addr6; 95 } in_aaaa; 96 struct { 97 uint16_t rdlen; 98 const void *rdata; 99 } other; 100 } rr; 101 }; 102 103 104 #define ASR_MAXNS 5 105 #define ASR_MAXDB 3 106 #define ASR_MAXDOM 10 107 108 enum async_type { 109 ASR_SEND, 110 ASR_SEARCH, 111 ASR_GETRRSETBYNAME, 112 ASR_GETHOSTBYNAME, 113 ASR_GETHOSTBYADDR, 114 ASR_GETNETBYNAME, 115 ASR_GETNETBYADDR, 116 ASR_GETADDRINFO, 117 ASR_GETNAMEINFO, 118 }; 119 120 #define ASR_DB_FILE 'f' 121 #define ASR_DB_DNS 'b' 122 #define ASR_DB_YP 'y' 123 124 struct asr_ctx { 125 int ac_refcount; 126 int ac_options; 127 int ac_ndots; 128 char *ac_domain; 129 int ac_domcount; 130 char *ac_dom[ASR_MAXDOM]; 131 int ac_dbcount; 132 char ac_db[ASR_MAXDB + 1]; 133 int ac_family[3]; 134 135 char *ac_hostfile; 136 137 int ac_nscount; 138 int ac_nstimeout; 139 int ac_nsretries; 140 struct sockaddr *ac_ns[ASR_MAXNS]; 141 142 }; 143 144 struct asr { 145 char *a_path; 146 time_t a_mtime; 147 time_t a_rtime; 148 struct asr_ctx *a_ctx; 149 }; 150 151 #define ASYNC_COND 0 152 #define ASYNC_DONE 1 153 154 #define ASYNC_DOM_FQDN 0x00000001 155 #define ASYNC_DOM_NDOTS 0x00000002 156 #define ASYNC_DOM_DOMAIN 0x00000004 157 #define ASYNC_DOM_ASIS 0x00000008 158 159 #define ASYNC_NODATA 0x00000100 160 #define ASYNC_AGAIN 0x00000200 161 162 #define ASYNC_EXTOBUF 0x00002000 163 164 165 struct asr_query { 166 int (*as_run)(struct asr_query *, struct asr_result *); 167 struct asr_ctx *as_ctx; 168 int as_type; 169 int as_state; 170 171 /* cond */ 172 int as_timeout; 173 int as_fd; 174 175 /* loop indices in ctx */ 176 int as_dom_step; 177 int as_dom_idx; 178 int as_dom_flags; 179 int as_family_idx; 180 int as_db_idx; 181 182 int as_count; 183 184 union { 185 struct { 186 int flags; 187 uint16_t reqid; 188 int class; 189 int type; 190 char *dname; /* not fqdn! */ 191 int rcode; /* response code */ 192 int ancount; /* answer count */ 193 194 int nsidx; 195 int nsloop; 196 197 /* io buffers for query/response */ 198 unsigned char *obuf; 199 size_t obuflen; 200 size_t obufsize; 201 unsigned char *ibuf; 202 size_t ibuflen; 203 size_t ibufsize; 204 size_t datalen; /* for tcp io */ 205 uint16_t pktlen; 206 } dns; 207 208 struct { 209 int flags; 210 int class; 211 int type; 212 char *name; 213 struct asr_query *subq; 214 int saved_h_errno; 215 } search; 216 217 struct { 218 int flags; 219 int class; 220 int type; 221 char *name; 222 struct asr_query *subq; 223 } rrset; 224 225 struct { 226 char *name; 227 int family; 228 struct asr_query *subq; 229 char addr[16]; 230 int addrlen; 231 int subq_h_errno; 232 } hostnamadr; 233 234 struct { 235 char *name; 236 int family; 237 struct asr_query *subq; 238 in_addr_t addr; 239 } netnamadr; 240 241 struct { 242 char *hostname; 243 char *servname; 244 int port_tcp; 245 int port_udp; 246 union { 247 struct sockaddr sa; 248 struct sockaddr_in sain; 249 struct sockaddr_in6 sain6; 250 } sa; 251 252 struct addrinfo hints; 253 char *fqdn; 254 struct addrinfo *aifirst; 255 struct addrinfo *ailast; 256 struct asr_query *subq; 257 int flags; 258 } ai; 259 260 struct { 261 char *hostname; 262 char *servname; 263 size_t hostnamelen; 264 size_t servnamelen; 265 union { 266 struct sockaddr sa; 267 struct sockaddr_in sain; 268 struct sockaddr_in6 sain6; 269 } sa; 270 int flags; 271 struct asr_query *subq; 272 } ni; 273 #define MAXTOKEN 10 274 } as; 275 276 }; 277 278 #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1]) 279 #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx]) 280 281 enum asr_state { 282 ASR_STATE_INIT, 283 ASR_STATE_NEXT_DOMAIN, 284 ASR_STATE_NEXT_DB, 285 ASR_STATE_SAME_DB, 286 ASR_STATE_NEXT_FAMILY, 287 ASR_STATE_NEXT_NS, 288 ASR_STATE_UDP_SEND, 289 ASR_STATE_UDP_RECV, 290 ASR_STATE_TCP_WRITE, 291 ASR_STATE_TCP_READ, 292 ASR_STATE_PACKET, 293 ASR_STATE_SUBQUERY, 294 ASR_STATE_NOT_FOUND, 295 ASR_STATE_HALT, 296 }; 297 298 299 /* asr_utils.c */ 300 void asr_pack_init(struct asr_pack *, char *, size_t); 301 int asr_pack_header(struct asr_pack *, const struct asr_dns_header *); 302 int asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *); 303 void asr_unpack_init(struct asr_unpack *, const char *, size_t); 304 int asr_unpack_header(struct asr_unpack *, struct asr_dns_header *); 305 int asr_unpack_query(struct asr_unpack *, struct asr_dns_query *); 306 int asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *); 307 int asr_sockaddr_from_str(struct sockaddr *, int, const char *); 308 ssize_t asr_dname_from_fqdn(const char *, char *, size_t); 309 ssize_t asr_addr_as_fqdn(const char *, int, char *, size_t); 310 311 /* asr.c */ 312 void *asr_resolver(const char *); 313 void asr_resolver_done(void *); 314 struct asr_ctx *asr_use_resolver(void *); 315 void asr_ctx_unref(struct asr_ctx *); 316 struct asr_query *asr_async_new(struct asr_ctx *, int); 317 void asr_async_free(struct asr_query *); 318 size_t asr_make_fqdn(const char *, const char *, char *, size_t); 319 char *asr_strdname(const char *, char *, size_t); 320 int asr_iter_db(struct asr_query *); 321 int asr_parse_namedb_line(FILE *, char **, int); 322 char *asr_hostalias(struct asr_ctx *, const char *, char *, size_t); 323 324 /* *_async.c */ 325 struct asr_query *res_query_async_ctx(const char *, int, int, struct asr_ctx *); 326 struct asr_query *res_search_async_ctx(const char *, int, int, struct asr_ctx *); 327 struct asr_query *gethostbyaddr_async_ctx(const void *, socklen_t, int, 328 struct asr_ctx *); 329 330 #ifdef DEBUG 331 332 #define DPRINT(...) do { if(asr_debug) { \ 333 fprintf(asr_debug, __VA_ARGS__); \ 334 } } while (0) 335 #define DPRINT_PACKET(n, p, s) do { if(asr_debug) { \ 336 fprintf(asr_debug, "----- %s -----\n", n); \ 337 asr_dump_packet(asr_debug, (p), (s)); \ 338 fprintf(asr_debug, "--------------\n"); \ 339 } } while (0) 340 341 const char *asr_querystr(int); 342 const char *asr_statestr(int); 343 const char *asr_transitionstr(int); 344 const char *print_sockaddr(const struct sockaddr *, char *, size_t); 345 void asr_dump_config(FILE *, struct asr *); 346 void asr_dump_packet(FILE *, const void *, size_t); 347 348 extern FILE * asr_debug; 349 350 #else /* DEBUG */ 351 352 #define DPRINT(...) 353 #define DPRINT_PACKET(...) 354 355 #endif /* DEBUG */ 356 357 #define async_set_state(a, s) do { \ 358 DPRINT("asr: [%s@%p] %s -> %s\n", \ 359 asr_querystr((a)->as_type), \ 360 as, \ 361 asr_statestr((a)->as_state), \ 362 asr_statestr((s))); \ 363 (a)->as_state = (s); } while (0) 364