/* * Copyright 2005 Niels Provos * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Niels Provos. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ++Copyright++ 1983, 1989, 1993 * - * Copyright (c) 1983, 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. * --Copyright-- */ #ifndef _DNSRES_INTERNAL_H_ #define _DNSRES_INTERNAL_H_ /* * Define constants based on rfc883 */ #define DNSRES_PACKETSZ 512 /* maximum packet size */ #define DNSRES_MAXDNAME 1025 /* maximum presentation domain name */ #define DNSRES_MAXCDNAME 255 /* maximum compressed domain name */ #define DNSRES_MAXLABEL 63 /* maximum length of domain label */ #define DNSRES_HFIXEDSZ 12 /* #/bytes of fixed data in header */ #define DNSRES_QFIXEDSZ 4 /* #/bytes of fixed data in query */ #define DNSRES_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ #define DNSRES_INT32SZ 4 /* for systems without 32-bit ints */ #define DNSRES_INT16SZ 2 /* for systems without 16-bit ints */ #define DNSRES_INADDRSZ 4 /* IPv4 T_A */ #define DNSRES_IN6ADDRSZ 16 /* IPv6 T_AAAA */ #define MAXPACKET (64*1024) /* * Structure for query header. The order of the fields is machine- and * compiler-dependent, depending on the byte/bit order and the layout * of bit fields. We use bit fields only in int variables, as this * is all ANSI requires. This requires a somewhat confusing rearrangement. */ typedef struct { unsigned id :16; /* query identification number */ #ifdef HAVE_BIG_ENDIAN /* fields in third byte */ unsigned qr: 1; /* response flag */ unsigned opcode: 4; /* purpose of message */ unsigned aa: 1; /* authoritive answer */ unsigned tc: 1; /* truncated message */ unsigned rd: 1; /* recursion desired */ /* fields in fourth byte */ unsigned ra: 1; /* recursion available */ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ unsigned ad: 1; /* authentic data from named */ unsigned cd: 1; /* checking disabled by resolver */ unsigned rcode :4; /* response code */ #else /* !HAVE_BIG_ENDIAN - for our little endians */ /* fields in third byte */ unsigned rd :1; /* recursion desired */ unsigned tc :1; /* truncated message */ unsigned aa :1; /* authoritive answer */ unsigned opcode :4; /* purpose of message */ unsigned qr :1; /* response flag */ /* fields in fourth byte */ unsigned rcode :4; /* response code */ unsigned cd: 1; /* checking disabled by resolver */ unsigned ad: 1; /* authentic data from named */ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ unsigned ra :1; /* recursion available */ #endif /* remaining bytes */ unsigned qdcount :16; /* number of question entries */ unsigned ancount :16; /* number of answer entries */ unsigned nscount :16; /* number of authority entries */ unsigned arcount :16; /* number of resource entries */ } DNSRES_HEADER; typedef union { DNSRES_HEADER hdr; u_char buf[MAXPACKET]; } querybuf; struct dnsres_socket { struct event ev; struct sockaddr *nsap; socklen_t salen; int s; /* socket used for communications */ int connected; /* is the socket connected */ int vc; /* is the socket a virtual ciruit? */ int af; /* address family of socket */ }; struct dnsres_target { struct dnsres_target *next; const char *name; /* domain name */ int qclass, qtype; /* class and type of query */ u_char *answer; /* buffer to put answer */ int anslen; /* size of answer buffer */ int n; /* result length */ }; #define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */ #define MAXALIASES 35 #define MAXADDRS 35 /* state used by all the gethostby* functions */ struct dnsres_cbstate { void (*cb)(struct dnsres_hostent *hp, int dr_errno, void *arg); void *cb_arg; struct dnsres_hostent *hp; char *name; /* the name we are trying to resolve */ size_t name_len; int af; struct dnsres *_resp; char lookups[MAXDNSLUS]; int lookup_index; struct dnsres_target q; int size; querybuf *buf; char qbuf[MAXDNAME+1]; void (*internal_cb)(struct dnsres_hostent *, struct dnsres_cbstate *); /* More resolver state to carry around */ char *h_addr_ptrs[MAXADDRS + 1]; struct dnsres_hostent host; char *host_aliases[MAXALIASES]; char hostbuf[BUFSIZ+1]; union { struct in_addr _host_in_addr; u_char _host_addr[16]; /* IPv4 or IPv6 */ } _host_addr_u; #define host_addr _host_addr_u._host_addr }; /* state used by all the res functions */ #if PACKETSZ > 1024 #define UDP_MAXPACKET PACKETSZ #else #define UDP_MAXPACKET 1024 #endif struct res_search_state { struct dnsres *_resp; const char *name; struct dnsres_target *target; int ancount; /* used when we have multiple queries */ void (*cb)(int, void *); void *cb_arg; void (*res_conditional_cb)(struct res_search_state *); int trailing_dot; u_int dots; int tried_as_is; int saved_herrno; int dont_save_errno; int done; int got_nodata; int got_servfail; const char * const *domain; /* res_query state */ u_char buf[UDP_MAXPACKET]; /* res_send state */ struct dnsres_socket ds; /* XXX - move away */ void (*send_cb)(int, struct res_search_state *); const u_char *send_buf; int resplen; int send_buflen; int gotsomewhere; int terrno; int v_circuit; int try; int connreset; u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ int ns; int ret; int read_len; /* used by res_send_vcircuit magic */ int truncated; u_char *cp; }; /* * Encapsulates the query state, so that it can be passed around between * functions. */ struct dnsres_cbstate *dnsres_cbstate_new( struct dnsres *_resp, const char *name, size_t len, void (*cb)(struct dnsres_hostent *, int, void *), void *arg); /* * Defines for handling compressed domain names */ #define DNSRES_INDIR_MASK 0xc0 /* * Inline versions of get/put short/long. Pointer is advanced. * * These macros demonstrate the property of C whereby it can be * portable or it can be elegant but rarely both. */ #define DNSRES_GETSHORT(s, cp) { \ unsigned char *t_cp = (unsigned char *)(cp); \ (s) = ((u_int16_t)t_cp[0] << 8) \ | ((u_int16_t)t_cp[1]) \ ; \ (cp) += INT16SZ; \ } #define DNSRES_GETLONG(l, cp) { \ unsigned char *t_cp = (unsigned char *)(cp); \ (l) = ((u_int32_t)t_cp[0] << 24) \ | ((u_int32_t)t_cp[1] << 16) \ | ((u_int32_t)t_cp[2] << 8) \ | ((u_int32_t)t_cp[3]) \ ; \ (cp) += INT32SZ; \ } #define DNSRES_PUTSHORT(s, cp) { \ u_int16_t t_s = (u_int16_t)(s); \ unsigned char *t_cp = (unsigned char *)(cp); \ *t_cp++ = t_s >> 8; \ *t_cp = t_s; \ (cp) += INT16SZ; \ } #define DNSRES_PUTLONG(l, cp) { \ u_int32_t t_l = (u_int32_t)(l); \ unsigned char *t_cp = (unsigned char *)(cp); \ *t_cp++ = t_l >> 24; \ *t_cp++ = t_l >> 16; \ *t_cp++ = t_l >> 8; \ *t_cp = t_l; \ (cp) += INT32SZ; \ } #endif /* _DNSRES_INTERNAL_H_ */