1 /* $OpenBSD: asr_private.h,v 1.3 2012/07/07 20:41:52 eric 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 #include <stdio.h> 18 19 #define DEBUG 20 21 #define QR_MASK (0x1 << 15) 22 #define OPCODE_MASK (0xf << 11) 23 #define AA_MASK (0x1 << 10) 24 #define TC_MASK (0x1 << 9) 25 #define RD_MASK (0x1 << 8) 26 #define RA_MASK (0x1 << 7) 27 #define Z_MASK (0x7 << 4) 28 #define RCODE_MASK (0xf) 29 30 #define OPCODE(v) ((v) & OPCODE_MASK) 31 #define RCODE(v) ((v) & RCODE_MASK) 32 33 34 struct packed { 35 char *data; 36 size_t len; 37 size_t offset; 38 const char *err; 39 }; 40 41 struct header { 42 uint16_t id; 43 uint16_t flags; 44 uint16_t qdcount; 45 uint16_t ancount; 46 uint16_t nscount; 47 uint16_t arcount; 48 }; 49 50 struct query { 51 char q_dname[MAXDNAME]; 52 uint16_t q_type; 53 uint16_t q_class; 54 }; 55 56 struct rr { 57 char rr_dname[MAXDNAME]; 58 uint16_t rr_type; 59 uint16_t rr_class; 60 uint32_t rr_ttl; 61 union { 62 struct { 63 char cname[MAXDNAME]; 64 } cname; 65 struct { 66 uint16_t preference; 67 char exchange[MAXDNAME]; 68 } mx; 69 struct { 70 char nsname[MAXDNAME]; 71 } ns; 72 struct { 73 char ptrname[MAXDNAME]; 74 } ptr; 75 struct { 76 char mname[MAXDNAME]; 77 char rname[MAXDNAME]; 78 uint32_t serial; 79 uint32_t refresh; 80 uint32_t retry; 81 uint32_t expire; 82 uint32_t minimum; 83 } soa; 84 struct { 85 struct in_addr addr; 86 } in_a; 87 struct { 88 struct in6_addr addr6; 89 } in_aaaa; 90 struct { 91 uint16_t rdlen; 92 const void *rdata; 93 } other; 94 } rr; 95 }; 96 97 98 #define ASR_MAXNS 5 99 #define ASR_MAXDB 3 100 #define ASR_MAXDOM 10 101 102 enum async_type { 103 ASR_SEND, 104 ASR_SEARCH, 105 ASR_GETRRSETBYNAME, 106 ASR_GETHOSTBYNAME, 107 ASR_GETHOSTBYADDR, 108 ASR_GETNETBYNAME, 109 ASR_GETNETBYADDR, 110 ASR_GETADDRINFO, 111 ASR_GETNAMEINFO, 112 ASR_HOSTADDR, 113 }; 114 115 enum asr_db_type { 116 ASR_DB_FILE, 117 ASR_DB_DNS, 118 ASR_DB_YP, 119 }; 120 121 struct asr_ctx { 122 int ac_refcount; 123 int ac_options; 124 int ac_ndots; 125 char *ac_domain; 126 int ac_domcount; 127 char *ac_dom[ASR_MAXDOM]; 128 int ac_dbcount; 129 int ac_db[ASR_MAXDB]; 130 int ac_family[3]; 131 132 char *ac_hostfile; 133 134 int ac_nscount; 135 int ac_nstimeout; 136 int ac_nsretries; 137 struct sockaddr *ac_ns[ASR_MAXNS]; 138 139 }; 140 141 struct asr { 142 char *a_path; 143 time_t a_mtime; 144 time_t a_rtime; 145 struct asr_ctx *a_ctx; 146 }; 147 148 149 #define ASYNC_DOM_FQDN 0x00000001 150 #define ASYNC_DOM_NDOTS 0x00000002 151 #define ASYNC_DOM_HOSTALIAS 0x00000004 152 #define ASYNC_DOM_DOMAIN 0x00000008 153 #define ASYNC_DOM_ASIS 0x00000010 154 155 #define ASYNC_NODATA 0x00000100 156 #define ASYNC_AGAIN 0x00000200 157 158 #define ASYNC_EXTIBUF 0x00001000 159 #define ASYNC_EXTOBUF 0x00002000 160 161 162 struct async { 163 int (*as_run)(struct async *, struct async_res *); 164 struct asr_ctx *as_ctx; 165 int as_type; 166 int as_state; 167 168 /* cond */ 169 int as_timeout; 170 int as_fd; 171 172 /* loop indices in ctx */ 173 int as_dom_step; 174 int as_dom_idx; 175 int as_dom_flags; 176 int as_family_idx; 177 int as_db_idx; 178 int as_ns_idx; 179 int as_ns_cycles; 180 181 int as_count; 182 183 union { 184 struct { 185 int flags; 186 uint16_t reqid; 187 int class; 188 int type; 189 char *dname; /* not fqdn! */ 190 int rcode; /* response code */ 191 int ancount; /* answer count */ 192 193 /* io buffers for query/response */ 194 unsigned char *obuf; 195 size_t obuflen; 196 size_t obufsize; 197 unsigned char *ibuf; 198 size_t ibuflen; 199 size_t ibufsize; 200 size_t bufpos; 201 size_t datalen; /* for tcp io */ 202 } dns; 203 204 struct { 205 int flags; 206 int class; 207 int type; 208 char *name; 209 struct async *subq; 210 int saved_h_errno; 211 unsigned char *ibuf; 212 size_t ibuflen; 213 size_t ibufsize; 214 } search; 215 216 struct { 217 int flags; 218 int class; 219 int type; 220 char *name; 221 struct async *subq; 222 } rrset; 223 224 struct { 225 char *name; 226 int family; 227 char *dname; 228 struct async *subq; 229 char addr[16]; 230 int addrlen; 231 } hostnamadr; 232 233 struct { 234 char *name; 235 int family; 236 struct async *subq; 237 in_addr_t addr; 238 } netnamadr; 239 240 struct { 241 char *hostname; 242 char *servname; 243 int port_tcp; 244 int port_udp; 245 union { 246 struct sockaddr sa; 247 struct sockaddr_in sain; 248 struct sockaddr_in6 sain6; 249 } sa; 250 251 struct addrinfo hints; 252 struct addrinfo *aifirst; 253 struct addrinfo *ailast; 254 struct async *subq; 255 int flags; 256 } ai; 257 258 struct { 259 char *hostname; 260 char *servname; 261 size_t hostnamelen; 262 size_t servnamelen; 263 union { 264 struct sockaddr sa; 265 struct sockaddr_in sain; 266 struct sockaddr_in6 sain6; 267 } sa; 268 int flags; 269 struct async *subq; 270 } ni; 271 272 struct { 273 char *name; 274 int family; 275 int aiflags; 276 union { 277 struct sockaddr sa; 278 struct sockaddr_in sain; 279 struct sockaddr_in6 sain6; 280 } sa; 281 282 struct async *subq; 283 int class; 284 int type; 285 int ancount; 286 unsigned char *pkt; 287 size_t pktlen; 288 size_t pktpos; 289 FILE *file; 290 #define MAXTOKEN 10 291 char *tokens[MAXTOKEN]; 292 int token_count; 293 int token_idx; 294 } host; 295 } as; 296 297 }; 298 299 #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1]) 300 #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx]) 301 302 enum asr_state { 303 ASR_STATE_INIT, 304 ASR_STATE_SEARCH_DOMAIN, 305 ASR_STATE_LOOKUP_DOMAIN, 306 ASR_STATE_NEXT_DOMAIN, 307 ASR_STATE_NEXT_DB, 308 ASR_STATE_SAME_DB, 309 ASR_STATE_NEXT_FAMILY, 310 ASR_STATE_LOOKUP_FAMILY, 311 ASR_STATE_NEXT_NS, 312 ASR_STATE_READ_RR, 313 ASR_STATE_READ_FILE, 314 ASR_STATE_UDP_SEND, 315 ASR_STATE_UDP_RECV, 316 ASR_STATE_TCP_WRITE, 317 ASR_STATE_TCP_READ, 318 ASR_STATE_PACKET, 319 ASR_STATE_SUBQUERY, 320 ASR_STATE_NOT_FOUND, 321 ASR_STATE_HALT, 322 }; 323 324 325 /* asr_utils.c */ 326 void packed_init(struct packed*, char*, size_t); 327 int pack_header(struct packed*, const struct header*); 328 int pack_query(struct packed*, uint16_t, uint16_t, const char*); 329 int unpack_header(struct packed*, struct header*); 330 int unpack_query(struct packed*, struct query*); 331 int unpack_rr(struct packed*, struct rr*); 332 int sockaddr_from_str(struct sockaddr *, int, const char *); 333 ssize_t dname_from_fqdn(const char*, char*, size_t); 334 335 /* asr.c */ 336 struct asr_ctx *asr_use_resolver(struct asr *); 337 void asr_ctx_unref(struct asr_ctx *); 338 struct async *async_new(struct asr_ctx *, int); 339 void async_free(struct async *); 340 size_t asr_make_fqdn(const char *, const char *, char *, size_t); 341 size_t asr_domcat(const char *, const char *, char *, size_t); 342 char *asr_strdname(const char *, char *, size_t); 343 int asr_iter_db(struct async *); 344 int asr_iter_ns(struct async *); 345 int asr_iter_domain(struct async *, const char *, char *, size_t); 346 int asr_parse_namedb_line(FILE *, char **, int); 347 348 /* <*>_async.h */ 349 struct async *res_query_async_ctx(const char *, int, int, unsigned char *, int, 350 struct asr_ctx *); 351 struct async *res_search_async_ctx(const char *, int, int, unsigned char *, int, 352 struct asr_ctx *); 353 struct async *gethostbyaddr_async_ctx(const void *, socklen_t, int, 354 struct asr_ctx *); 355 struct async *hostaddr_async_ctx(const char *, int, int, struct asr_ctx *); 356 357 #ifdef DEBUG 358 359 extern int asr_debug; 360 361 /* asr_debug.h */ 362 const char *asr_querystr(int); 363 const char *asr_transitionstr(int); 364 void asr_dump(struct asr *); 365 void asr_dump_async(struct async *); 366 void asr_dump_packet(FILE *, const void *, size_t, int); 367 void asr_printf(const char *fmt, ...); 368 void async_set_state(struct async *, int); 369 char *asr_print_addr(const struct sockaddr *, char *, size_t); 370 371 #else /* DEBUG */ 372 373 #define async_set_state(a, s) do { (a)->as_state = (s); } while (0) 374 375 #endif /* DEBUG */ 376