Index: releng/7.1/include/arpa/nameser.h =================================================================== --- releng/7.1/include/arpa/nameser.h (revision 186220) +++ releng/7.1/include/arpa/nameser.h (revision 186221) @@ -1,583 +1,584 @@ /* * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. 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. */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ /* - * $Id: nameser.h,v 1.7.18.1 2005/04/27 05:00:50 sra Exp $ + * $Id: nameser.h,v 1.7.18.2 2008/04/03 23:15:15 marka Exp $ * $FreeBSD$ */ #ifndef _ARPA_NAMESER_H_ #define _ARPA_NAMESER_H_ /*! \file */ #define BIND_4_COMPAT #include #include #include /*% * Revision information. This is the release date in YYYYMMDD format. * It can change every day so the right thing to do with it is use it * in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not * compare for equality; rather, use it to determine whether your libbind.a * contains a new enough lib/nameser/ to support the feature you need. */ #define __NAMESER 19991006 /*%< New interface version stamp. */ /* * Define constants based on RFC0883, RFC1034, RFC 1035 */ #define NS_PACKETSZ 512 /*%< default UDP packet size */ #define NS_MAXDNAME 1025 /*%< maximum domain name */ #define NS_MAXMSG 65535 /*%< maximum message size */ #define NS_MAXCDNAME 255 /*%< maximum compressed domain name */ #define NS_MAXLABEL 63 /*%< maximum length of domain label */ #define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ #define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ #define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ #define NS_INT32SZ 4 /*%< #/bytes of data in a u_int32_t */ #define NS_INT16SZ 2 /*%< #/bytes of data in a u_int16_t */ #define NS_INT8SZ 1 /*%< #/bytes of data in a u_int8_t */ #define NS_INADDRSZ 4 /*%< IPv4 T_A */ #define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ #define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ #define NS_DEFAULTPORT 53 /*%< For both TCP and UDP. */ /* * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() * in synch with it. */ typedef enum __ns_sect { ns_s_qd = 0, /*%< Query: Question. */ ns_s_zn = 0, /*%< Update: Zone. */ ns_s_an = 1, /*%< Query: Answer. */ ns_s_pr = 1, /*%< Update: Prerequisites. */ ns_s_ns = 2, /*%< Query: Name servers. */ ns_s_ud = 2, /*%< Update: Update. */ ns_s_ar = 3, /*%< Query|Update: Additional records. */ ns_s_max = 4 } ns_sect; /*% * This is a message handle. It is caller allocated and has no dynamic data. * This structure is intended to be opaque to all but ns_parse.c, thus the * leading _'s on the member names. Use the accessor functions, not the _'s. */ typedef struct __ns_msg { const u_char *_msg, *_eom; u_int16_t _id, _flags, _counts[ns_s_max]; const u_char *_sections[ns_s_max]; ns_sect _sect; int _rrnum; const u_char *_msg_ptr; } ns_msg; /* Private data structure - do not use from outside library. */ struct _ns_flagdata { int mask, shift; }; extern struct _ns_flagdata _ns_flagdata[]; /* Accessor macros - this is part of the public interface. */ #define ns_msg_id(handle) ((handle)._id + 0) #define ns_msg_base(handle) ((handle)._msg + 0) #define ns_msg_end(handle) ((handle)._eom + 0) #define ns_msg_size(handle) ((handle)._eom - (handle)._msg) #define ns_msg_count(handle, section) ((handle)._counts[section] + 0) /*% * This is a parsed record. It is caller allocated and has no dynamic data. */ typedef struct __ns_rr { char name[NS_MAXDNAME]; u_int16_t type; u_int16_t rr_class; u_int32_t ttl; u_int16_t rdlength; const u_char * rdata; } ns_rr; /* Accessor macros - this is part of the public interface. */ #define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") #define ns_rr_type(rr) ((ns_type)((rr).type + 0)) #define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0)) #define ns_rr_ttl(rr) ((rr).ttl + 0) #define ns_rr_rdlen(rr) ((rr).rdlength + 0) #define ns_rr_rdata(rr) ((rr).rdata + 0) /*% * These don't have to be in the same order as in the packet flags word, * and they can even overlap in some cases, but they will need to be kept * in synch with ns_parse.c:ns_flagdata[]. */ typedef enum __ns_flag { ns_f_qr, /*%< Question/Response. */ ns_f_opcode, /*%< Operation code. */ ns_f_aa, /*%< Authoritative Answer. */ ns_f_tc, /*%< Truncation occurred. */ ns_f_rd, /*%< Recursion Desired. */ ns_f_ra, /*%< Recursion Available. */ ns_f_z, /*%< MBZ. */ ns_f_ad, /*%< Authentic Data (DNSSEC). */ ns_f_cd, /*%< Checking Disabled (DNSSEC). */ ns_f_rcode, /*%< Response code. */ ns_f_max } ns_flag; /*% * Currently defined opcodes. */ typedef enum __ns_opcode { ns_o_query = 0, /*%< Standard query. */ ns_o_iquery = 1, /*%< Inverse query (deprecated/unsupported). */ ns_o_status = 2, /*%< Name server status query (unsupported). */ /* Opcode 3 is undefined/reserved. */ ns_o_notify = 4, /*%< Zone change notification. */ ns_o_update = 5, /*%< Zone update message. */ ns_o_max = 6 } ns_opcode; /*% * Currently defined response codes. */ typedef enum __ns_rcode { ns_r_noerror = 0, /*%< No error occurred. */ ns_r_formerr = 1, /*%< Format error. */ ns_r_servfail = 2, /*%< Server failure. */ ns_r_nxdomain = 3, /*%< Name error. */ ns_r_notimpl = 4, /*%< Unimplemented. */ ns_r_refused = 5, /*%< Operation refused. */ /* these are for BIND_UPDATE */ ns_r_yxdomain = 6, /*%< Name exists */ ns_r_yxrrset = 7, /*%< RRset exists */ ns_r_nxrrset = 8, /*%< RRset does not exist */ ns_r_notauth = 9, /*%< Not authoritative for zone */ ns_r_notzone = 10, /*%< Zone of record different from zone section */ ns_r_max = 11, /* The following are EDNS extended rcodes */ ns_r_badvers = 16, /* The following are TSIG errors */ ns_r_badsig = 16, ns_r_badkey = 17, ns_r_badtime = 18 } ns_rcode; /* BIND_UPDATE */ typedef enum __ns_update_operation { ns_uop_delete = 0, ns_uop_add = 1, ns_uop_max = 2 } ns_update_operation; /*% * This structure is used for TSIG authenticated messages */ struct ns_tsig_key { char name[NS_MAXDNAME], alg[NS_MAXDNAME]; unsigned char *data; int len; }; typedef struct ns_tsig_key ns_tsig_key; /*% * This structure is used for TSIG authenticated TCP messages */ struct ns_tcp_tsig_state { int counter; struct dst_key *key; void *ctx; unsigned char sig[NS_PACKETSZ]; int siglen; }; typedef struct ns_tcp_tsig_state ns_tcp_tsig_state; #define NS_TSIG_FUDGE 300 #define NS_TSIG_TCP_COUNT 100 #define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT" #define NS_TSIG_ERROR_NO_TSIG -10 #define NS_TSIG_ERROR_NO_SPACE -11 #define NS_TSIG_ERROR_FORMERR -12 /*% * Currently defined type values for resources and queries. */ typedef enum __ns_type { ns_t_invalid = 0, /*%< Cookie. */ ns_t_a = 1, /*%< Host address. */ ns_t_ns = 2, /*%< Authoritative server. */ ns_t_md = 3, /*%< Mail destination. */ ns_t_mf = 4, /*%< Mail forwarder. */ ns_t_cname = 5, /*%< Canonical name. */ ns_t_soa = 6, /*%< Start of authority zone. */ ns_t_mb = 7, /*%< Mailbox domain name. */ ns_t_mg = 8, /*%< Mail group member. */ ns_t_mr = 9, /*%< Mail rename name. */ ns_t_null = 10, /*%< Null resource record. */ ns_t_wks = 11, /*%< Well known service. */ ns_t_ptr = 12, /*%< Domain name pointer. */ ns_t_hinfo = 13, /*%< Host information. */ ns_t_minfo = 14, /*%< Mailbox information. */ ns_t_mx = 15, /*%< Mail routing information. */ ns_t_txt = 16, /*%< Text strings. */ ns_t_rp = 17, /*%< Responsible person. */ ns_t_afsdb = 18, /*%< AFS cell database. */ ns_t_x25 = 19, /*%< X_25 calling address. */ ns_t_isdn = 20, /*%< ISDN calling address. */ ns_t_rt = 21, /*%< Router. */ ns_t_nsap = 22, /*%< NSAP address. */ ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */ ns_t_sig = 24, /*%< Security signature. */ ns_t_key = 25, /*%< Security key. */ ns_t_px = 26, /*%< X.400 mail mapping. */ ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ ns_t_aaaa = 28, /*%< Ip6 Address. */ ns_t_loc = 29, /*%< Location Information. */ ns_t_nxt = 30, /*%< Next domain (security). */ ns_t_eid = 31, /*%< Endpoint identifier. */ ns_t_nimloc = 32, /*%< Nimrod Locator. */ ns_t_srv = 33, /*%< Server Selection. */ ns_t_atma = 34, /*%< ATM Address */ ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ ns_t_kx = 36, /*%< Key Exchange */ ns_t_cert = 37, /*%< Certification record */ ns_t_a6 = 38, /*%< IPv6 address (deprecates AAAA) */ ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */ ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ ns_t_tkey = 249, /*%< Transaction key */ ns_t_tsig = 250, /*%< Transaction signature. */ ns_t_ixfr = 251, /*%< Incremental zone transfer. */ ns_t_axfr = 252, /*%< Transfer zone of authority. */ ns_t_mailb = 253, /*%< Transfer mailbox records. */ ns_t_maila = 254, /*%< Transfer mail agent records. */ ns_t_any = 255, /*%< Wildcard match. */ ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ ns_t_max = 65536 } ns_type; /* Exclusively a QTYPE? (not also an RTYPE) */ #define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \ (t) == ns_t_mailb || (t) == ns_t_maila) /* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */ #define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt) /* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */ #define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t)) #define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr) #define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \ (t) == ns_t_zxfr) /*% * Values for class field */ typedef enum __ns_class { ns_c_invalid = 0, /*%< Cookie. */ ns_c_in = 1, /*%< Internet. */ ns_c_2 = 2, /*%< unallocated/unsupported. */ ns_c_chaos = 3, /*%< MIT Chaos-net. */ ns_c_hs = 4, /*%< MIT Hesiod. */ /* Query class values which do not appear in resource records */ ns_c_none = 254, /*%< for prereq. sections in update requests */ ns_c_any = 255, /*%< Wildcard match. */ ns_c_max = 65536 } ns_class; /* DNSSEC constants. */ typedef enum __ns_key_types { ns_kt_rsa = 1, /*%< key type RSA/MD5 */ ns_kt_dh = 2, /*%< Diffie Hellman */ ns_kt_dsa = 3, /*%< Digital Signature Standard (MANDATORY) */ ns_kt_private = 254 /*%< Private key type starts with OID */ } ns_key_types; typedef enum __ns_cert_types { cert_t_pkix = 1, /*%< PKIX (X.509v3) */ cert_t_spki = 2, /*%< SPKI */ cert_t_pgp = 3, /*%< PGP */ cert_t_url = 253, /*%< URL private type */ cert_t_oid = 254 /*%< OID private type */ } ns_cert_types; /* Flags field of the KEY RR rdata. */ #define NS_KEY_TYPEMASK 0xC000 /*%< Mask for "type" bits */ #define NS_KEY_TYPE_AUTH_CONF 0x0000 /*%< Key usable for both */ #define NS_KEY_TYPE_CONF_ONLY 0x8000 /*%< Key usable for confidentiality */ #define NS_KEY_TYPE_AUTH_ONLY 0x4000 /*%< Key usable for authentication */ #define NS_KEY_TYPE_NO_KEY 0xC000 /*%< No key usable for either; no key */ /* The type bits can also be interpreted independently, as single bits: */ #define NS_KEY_NO_AUTH 0x8000 /*%< Key unusable for authentication */ #define NS_KEY_NO_CONF 0x4000 /*%< Key unusable for confidentiality */ #define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */ #define NS_KEY_EXTENDED_FLAGS 0x1000 /*%< reserved - must be zero */ #define NS_KEY_RESERVED4 0x0800 /*%< reserved - must be zero */ #define NS_KEY_RESERVED5 0x0400 /*%< reserved - must be zero */ #define NS_KEY_NAME_TYPE 0x0300 /*%< these bits determine the type */ #define NS_KEY_NAME_USER 0x0000 /*%< key is assoc. with user */ #define NS_KEY_NAME_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ #define NS_KEY_NAME_ZONE 0x0100 /*%< key is zone key */ #define NS_KEY_NAME_RESERVED 0x0300 /*%< reserved meaning */ #define NS_KEY_RESERVED8 0x0080 /*%< reserved - must be zero */ #define NS_KEY_RESERVED9 0x0040 /*%< reserved - must be zero */ #define NS_KEY_RESERVED10 0x0020 /*%< reserved - must be zero */ #define NS_KEY_RESERVED11 0x0010 /*%< reserved - must be zero */ #define NS_KEY_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ #define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \ NS_KEY_RESERVED4 | \ NS_KEY_RESERVED5 | \ NS_KEY_RESERVED8 | \ NS_KEY_RESERVED9 | \ NS_KEY_RESERVED10 | \ NS_KEY_RESERVED11 ) #define NS_KEY_RESERVED_BITMASK2 0xFFFF /*%< no bits defined here */ /* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ #define NS_ALG_MD5RSA 1 /*%< MD5 with RSA */ #define NS_ALG_DH 2 /*%< Diffie Hellman KEY */ #define NS_ALG_DSA 3 /*%< DSA KEY */ #define NS_ALG_DSS NS_ALG_DSA #define NS_ALG_EXPIRE_ONLY 253 /*%< No alg, no security */ #define NS_ALG_PRIVATE_OID 254 /*%< Key begins with OID giving alg */ /* Protocol values */ /* value 0 is reserved */ #define NS_KEY_PROT_TLS 1 #define NS_KEY_PROT_EMAIL 2 #define NS_KEY_PROT_DNSSEC 3 #define NS_KEY_PROT_IPSEC 4 #define NS_KEY_PROT_ANY 255 /* Signatures */ #define NS_MD5RSA_MIN_BITS 512 /*%< Size of a mod or exp in bits */ #define NS_MD5RSA_MAX_BITS 4096 /* Total of binary mod and exp */ #define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3) /* Max length of text sig block */ #define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4) #define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8) #define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8) #define NS_DSA_SIG_SIZE 41 #define NS_DSA_MIN_SIZE 213 #define NS_DSA_MAX_BYTES 405 /* Offsets into SIG record rdata to find various values */ #define NS_SIG_TYPE 0 /*%< Type flags */ #define NS_SIG_ALG 2 /*%< Algorithm */ #define NS_SIG_LABELS 3 /*%< How many labels in name */ #define NS_SIG_OTTL 4 /*%< Original TTL */ #define NS_SIG_EXPIR 8 /*%< Expiration time */ #define NS_SIG_SIGNED 12 /*%< Signature time */ #define NS_SIG_FOOT 16 /*%< Key footprint */ #define NS_SIG_SIGNER 18 /*%< Domain name of who signed it */ /* How RR types are represented as bit-flags in NXT records */ #define NS_NXT_BITS 8 #define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS))) #define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS))) #define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS))) #define NS_NXT_MAX 127 /*% - * EDNS0 extended flags, host order. + * EDNS0 extended flags and option codes, host order. */ #define NS_OPT_DNSSEC_OK 0x8000U +#define NS_OPT_NSID 3 /*% * Inline versions of get/put short/long. Pointer is advanced. */ #define NS_GET16(s, cp) do { \ register const u_char *t_cp = (const u_char *)(cp); \ (s) = ((u_int16_t)t_cp[0] << 8) \ | ((u_int16_t)t_cp[1]) \ ; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_GET32(l, cp) do { \ register const u_char *t_cp = (const u_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) += NS_INT32SZ; \ } while (0) #define NS_PUT16(s, cp) do { \ register u_int16_t t_s = (u_int16_t)(s); \ register u_char *t_cp = (u_char *)(cp); \ *t_cp++ = t_s >> 8; \ *t_cp = t_s; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_PUT32(l, cp) do { \ register u_int32_t t_l = (u_int32_t)(l); \ register u_char *t_cp = (u_char *)(cp); \ *t_cp++ = t_l >> 24; \ *t_cp++ = t_l >> 16; \ *t_cp++ = t_l >> 8; \ *t_cp = t_l; \ (cp) += NS_INT32SZ; \ } while (0) /*% * ANSI C identifier hiding for bind's lib/nameser. */ #define ns_msg_getflag __ns_msg_getflag #define ns_get16 __ns_get16 #define ns_get32 __ns_get32 #define ns_put16 __ns_put16 #define ns_put32 __ns_put32 #define ns_initparse __ns_initparse #define ns_skiprr __ns_skiprr #define ns_parserr __ns_parserr #define ns_sprintrr __ns_sprintrr #define ns_sprintrrf __ns_sprintrrf #define ns_format_ttl __ns_format_ttl #define ns_parse_ttl __ns_parse_ttl #if 0 #define ns_datetosecs __ns_datetosecs #endif #define ns_name_ntol __ns_name_ntol #define ns_name_ntop __ns_name_ntop #define ns_name_pton __ns_name_pton #define ns_name_unpack __ns_name_unpack #define ns_name_pack __ns_name_pack #define ns_name_compress __ns_name_compress #define ns_name_uncompress __ns_name_uncompress #define ns_name_skip __ns_name_skip #define ns_name_rollback __ns_name_rollback #if 0 #define ns_sign __ns_sign #define ns_sign2 __ns_sign2 #define ns_sign_tcp __ns_sign_tcp #define ns_sign_tcp2 __ns_sign_tcp2 #define ns_sign_tcp_init __ns_sign_tcp_init #define ns_find_tsig __ns_find_tsig #define ns_verify __ns_verify #define ns_verify_tcp __ns_verify_tcp #define ns_verify_tcp_init __ns_verify_tcp_init #endif #define ns_samedomain __ns_samedomain #if 0 #define ns_subdomain __ns_subdomain #endif #define ns_makecanon __ns_makecanon #define ns_samename __ns_samename __BEGIN_DECLS int ns_msg_getflag(ns_msg, int); u_int ns_get16(const u_char *); u_long ns_get32(const u_char *); void ns_put16(u_int, u_char *); void ns_put32(u_long, u_char *); int ns_initparse(const u_char *, int, ns_msg *); int ns_skiprr(const u_char *, const u_char *, ns_sect, int); int ns_parserr(ns_msg *, ns_sect, int, ns_rr *); int ns_sprintrr(const ns_msg *, const ns_rr *, const char *, const char *, char *, size_t); int ns_sprintrrf(const u_char *, size_t, const char *, ns_class, ns_type, u_long, const u_char *, size_t, const char *, const char *, char *, size_t); int ns_format_ttl(u_long, char *, size_t); int ns_parse_ttl(const char *, u_long *); #if 0 u_int32_t ns_datetosecs(const char *cp, int *errp); #endif int ns_name_ntol(const u_char *, u_char *, size_t); int ns_name_ntop(const u_char *, char *, size_t); int ns_name_pton(const char *, u_char *, size_t); int ns_name_unpack(const u_char *, const u_char *, const u_char *, u_char *, size_t); int ns_name_pack(const u_char *, u_char *, int, const u_char **, const u_char **); int ns_name_uncompress(const u_char *, const u_char *, const u_char *, char *, size_t); int ns_name_compress(const char *, u_char *, size_t, const u_char **, const u_char **); int ns_name_skip(const u_char **, const u_char *); void ns_name_rollback(const u_char *, const u_char **, const u_char **); #if 0 int ns_sign(u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t); int ns_sign2(u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t, u_char **, u_char **); int ns_sign_tcp(u_char *, int *, int, int, ns_tcp_tsig_state *, int); int ns_sign_tcp2(u_char *, int *, int, int, ns_tcp_tsig_state *, int, u_char **, u_char **); int ns_sign_tcp_init(void *, const u_char *, int, ns_tcp_tsig_state *); u_char *ns_find_tsig(u_char *, u_char *); int ns_verify(u_char *, int *, void *, const u_char *, int, u_char *, int *, time_t *, int); int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int); int ns_verify_tcp_init(void *, const u_char *, int, ns_tcp_tsig_state *); #endif int ns_samedomain(const char *, const char *); #if 0 int ns_subdomain(const char *, const char *); #endif int ns_makecanon(const char *, char *, size_t); int ns_samename(const char *, const char *); __END_DECLS #ifdef BIND_4_COMPAT #include #endif #endif /* !_ARPA_NAMESER_H_ */ /*! \file */ Index: releng/7.1/include/resolv.h =================================================================== --- releng/7.1/include/resolv.h (revision 186220) +++ releng/7.1/include/resolv.h (revision 186221) @@ -1,498 +1,502 @@ /* * Copyright (c) 1983, 1987, 1989 * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. 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. */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ /*% * @(#)resolv.h 8.1 (Berkeley) 6/2/93 - * $Id: resolv.h,v 1.19.18.3 2005/08/25 04:43:51 marka Exp $ + * $Id: resolv.h,v 1.19.18.4 2008/04/03 23:15:15 marka Exp $ * $FreeBSD$ */ #ifndef _RESOLV_H_ #define _RESOLV_H_ #include #include #include #include #include #include /*% * Revision information. This is the release date in YYYYMMDD format. * It can change every day so the right thing to do with it is use it * in preprocessor commands such as "#if (__RES > 19931104)". Do not * compare for equality; rather, use it to determine whether your resolver * is new enough to contain a certain feature. */ #define __RES 20030124 /*% * This used to be defined in res_query.c, now it's in herror.c. * [XXX no it's not. It's in irs/irs_data.c] * It was * never extern'd by any *.h file before it was placed here. For thread * aware programs, the last h_errno value set is stored in res->h_errno. * * XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO * (and __h_errno_set) to the public via . * XXX: __h_errno_set is really part of IRS, not part of the resolver. * If somebody wants to build and use a resolver that doesn't use IRS, * what do they do? Perhaps something like * #ifdef WANT_IRS * # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x) * #else * # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x)) * #endif */ #define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x) struct __res_state; /*%< forward */ __BEGIN_DECLS void __h_errno_set(struct __res_state *, int); __END_DECLS /*% * Resolver configuration file. * Normally not present, but may contain the address of the * initial name server(s) to query and the domain search list. */ #ifndef _PATH_RESCONF #define _PATH_RESCONF "/etc/resolv.conf" #endif typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error } res_sendhookact; typedef res_sendhookact (*res_send_qhook)(struct sockaddr * const *, const u_char **, int *, u_char *, int, int *); typedef res_sendhookact (*res_send_rhook)(const struct sockaddr *, const u_char *, int, u_char *, int, int *); struct res_sym { int number; /*%< Identifying number, like T_MX */ const char * name; /*%< Its symbolic name, like "MX" */ const char * humanname; /*%< Its fun name, like "mail exchanger" */ }; /*% * Global defines and variables for resolver stub. */ #define MAXNS 3 /*%< max # name servers we'll track */ #define MAXDFLSRCH 3 /*%< # default domain levels to try */ #define MAXDNSRCH 6 /*%< max # domains in search path */ #define LOCALDOMAINPARTS 2 /*%< min levels in name that is "local" */ #define RES_TIMEOUT 5 /*%< min. seconds between retries */ #define MAXRESOLVSORT 10 /*%< number of net to sort on */ #define RES_MAXNDOTS 15 /*%< should reflect bit field size */ #define RES_MAXRETRANS 30 /*%< only for resolv.conf/RES_OPTIONS */ #define RES_MAXRETRY 5 /*%< only for resolv.conf/RES_OPTIONS */ #define RES_DFLRETRY 2 /*%< Default #/tries. */ #define RES_MAXTIME 65535 /*%< Infinity, in milliseconds. */ struct __res_state_ext; struct __res_state { int retrans; /*%< retransmission time interval */ int retry; /*%< number of times to retransmit */ /* * XXX: If `sun' is defined, `options' and `pfcode' are * defined as u_int in original BIND9 distribution. However, * it breaks binary backward compatibility against FreeBSD's * resolver. So, we changed not to see `sun'. */ #if defined(sun) && 0 u_int options; /*%< option flags - see below. */ #else u_long options; /*%< option flags - see below. */ #endif int nscount; /*%< number of name servers */ struct sockaddr_in nsaddr_list[MAXNS]; /*%< address of name server */ #define nsaddr nsaddr_list[0] /*%< for backward compatibility */ u_short id; /*%< current message id */ char *dnsrch[MAXDNSRCH+1]; /*%< components of domain to search */ char defdname[256]; /*%< default domain (deprecated) */ #if defined(sun) && 0 u_int pfcode; /*%< RES_PRF_ flags - see below. */ #else u_long pfcode; /*%< RES_PRF_ flags - see below. */ #endif unsigned ndots:4; /*%< threshold for initial abs. query */ unsigned nsort:4; /*%< number of elements in sort_list[] */ char unused[3]; struct { struct in_addr addr; u_int32_t mask; } sort_list[MAXRESOLVSORT]; res_send_qhook qhook; /*%< query hook */ res_send_rhook rhook; /*%< response hook */ int res_h_errno; /*%< last one set for this context */ int _vcsock; /*%< PRIVATE: for res_send VC i/o */ u_int _flags; /*%< PRIVATE: see below */ u_int _pad; /*%< make _u 64 bit aligned */ union { /* On an 32-bit arch this means 512b total. */ char pad[72 - 4*sizeof (int) - 2*sizeof (void *)]; struct { u_int16_t nscount; u_int16_t nstimes[MAXNS]; /*%< ms. */ int nssocks[MAXNS]; struct __res_state_ext *ext; /*%< extention for IPv6 */ } _ext; } _u; }; typedef struct __res_state *res_state; union res_sockaddr_union { struct sockaddr_in sin; #ifdef IN6ADDR_ANY_INIT struct sockaddr_in6 sin6; #endif #ifdef ISC_ALIGN64 int64_t __align64; /*%< 64bit alignment */ #else int32_t __align32; /*%< 32bit alignment */ #endif char __space[128]; /*%< max size */ }; /*% * Resolver flags (used to be discrete per-module statics ints). */ #define RES_F_VC 0x00000001 /*%< socket is TCP */ #define RES_F_CONN 0x00000002 /*%< socket is connected */ #define RES_F_EDNS0ERR 0x00000004 /*%< EDNS0 caused errors */ #define RES_F__UNUSED 0x00000008 /*%< (unused) */ #define RES_F_LASTMASK 0x000000F0 /*%< ordinal server of last res_nsend */ #define RES_F_LASTSHIFT 4 /*%< bit position of LASTMASK "flag" */ #define RES_GETLAST(res) (((res)._flags & RES_F_LASTMASK) >> RES_F_LASTSHIFT) /* res_findzonecut2() options */ #define RES_EXHAUSTIVE 0x00000001 /*%< always do all queries */ #define RES_IPV4ONLY 0x00000002 /*%< IPv4 only */ #define RES_IPV6ONLY 0x00000004 /*%< IPv6 only */ /*% * Resolver options (keep these in synch with res_debug.c, please) */ #define RES_INIT 0x00000001 /*%< address initialized */ #define RES_DEBUG 0x00000002 /*%< print debug messages */ #define RES_AAONLY 0x00000004 /*%< authoritative answers only (!IMPL)*/ #define RES_USEVC 0x00000008 /*%< use virtual circuit */ #define RES_PRIMARY 0x00000010 /*%< query primary server only (!IMPL) */ #define RES_IGNTC 0x00000020 /*%< ignore truncation errors */ #define RES_RECURSE 0x00000040 /*%< recursion desired */ #define RES_DEFNAMES 0x00000080 /*%< use default domain name */ #define RES_STAYOPEN 0x00000100 /*%< Keep TCP socket open */ #define RES_DNSRCH 0x00000200 /*%< search up local domain tree */ #define RES_INSECURE1 0x00000400 /*%< type 1 security disabled */ #define RES_INSECURE2 0x00000800 /*%< type 2 security disabled */ #define RES_NOALIASES 0x00001000 /*%< shuts off HOSTALIASES feature */ #define RES_USE_INET6 0x00002000 /*%< use/map IPv6 in gethostbyname() */ #define RES_ROTATE 0x00004000 /*%< rotate ns list after each query */ #define RES_NOCHECKNAME 0x00008000 /*%< do not check names for sanity. */ #define RES_KEEPTSIG 0x00010000 /*%< do not strip TSIG records */ #define RES_BLAST 0x00020000 /*%< blast all recursive servers */ +#define RES_NSID 0x00040000 /*%< request name server ID */ #define RES_NOTLDQUERY 0x00100000 /*%< don't unqualified name as a tld */ #define RES_USE_DNSSEC 0x00200000 /*%< use DNSSEC using OK bit in OPT */ /* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */ /* KAME extensions: use higher bit to avoid conflict with ISC use */ #define RES_USE_DNAME 0x10000000 /*%< use DNAME */ #define RES_USE_EDNS0 0x40000000 /*%< use EDNS0 if configured */ #define RES_NO_NIBBLE2 0x80000000 /*%< disable alternate nibble lookup */ #define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | \ RES_DNSRCH | RES_NO_NIBBLE2) /*% * Resolver "pfcode" values. Used by dig. */ #define RES_PRF_STATS 0x00000001 #define RES_PRF_UPDATE 0x00000002 #define RES_PRF_CLASS 0x00000004 #define RES_PRF_CMD 0x00000008 #define RES_PRF_QUES 0x00000010 #define RES_PRF_ANS 0x00000020 #define RES_PRF_AUTH 0x00000040 #define RES_PRF_ADD 0x00000080 #define RES_PRF_HEAD1 0x00000100 #define RES_PRF_HEAD2 0x00000200 #define RES_PRF_TTLID 0x00000400 #define RES_PRF_HEADX 0x00000800 #define RES_PRF_QUERY 0x00001000 #define RES_PRF_REPLY 0x00002000 #define RES_PRF_INIT 0x00004000 #define RES_PRF_TRUNC 0x00008000 /* 0x00010000 */ /* Things involving an internal (static) resolver context. */ __BEGIN_DECLS extern struct __res_state *__res_state(void); __END_DECLS #define _res (*__res_state()) #ifndef __BIND_NOSTATIC #define fp_nquery __fp_nquery #define fp_query __fp_query #define hostalias __hostalias #define p_query __p_query #define res_close __res_close #define res_init __res_init #define res_isourserver __res_isourserver #define res_mkquery __res_mkquery #define res_opt __res_opt #define res_query __res_query #define res_querydomain __res_querydomain #define res_search __res_search #define res_send __res_send #define res_sendsigned __res_sendsigned __BEGIN_DECLS void fp_nquery(const u_char *, int, FILE *); void fp_query(const u_char *, FILE *); const char * hostalias(const char *); void p_query(const u_char *); void res_close(void); int res_init(void); int res_isourserver(const struct sockaddr_in *); int res_mkquery(int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int); int res_opt(int, u_char *, int, int); int res_query(const char *, int, int, u_char *, int); int res_querydomain(const char *, const char *, int, int, u_char *, int); int res_search(const char *, int, int, u_char *, int); int res_send(const u_char *, int, u_char *, int); int res_sendsigned(const u_char *, int, ns_tsig_key *, u_char *, int); __END_DECLS #endif #if !defined(SHARED_LIBBIND) || defined(LIB) /* * If libbind is a shared object (well, DLL anyway) * these externs break the linker when resolv.h is * included by a lib client (like named) * Make them go away if a client is including this * */ extern const struct res_sym __p_key_syms[]; extern const struct res_sym __p_cert_syms[]; extern const struct res_sym __p_class_syms[]; extern const struct res_sym __p_type_syms[]; extern const struct res_sym __p_rcode_syms[]; #endif /* SHARED_LIBBIND */ #define b64_ntop __b64_ntop #define b64_pton __b64_pton #define dn_comp __dn_comp #define dn_count_labels __dn_count_labels #define dn_expand __dn_expand #define dn_skipname __dn_skipname #define fp_resstat __fp_resstat #define loc_aton __loc_aton #define loc_ntoa __loc_ntoa #define p_cdname __p_cdname #define p_cdnname __p_cdnname #define p_class __p_class #define p_fqname __p_fqname #define p_fqnname __p_fqnname #define p_option __p_option #define p_secstodate __p_secstodate #define p_section __p_section #define p_time __p_time #define p_type __p_type #define p_rcode __p_rcode #define p_sockun __p_sockun #define putlong __putlong #define putshort __putshort #define res_dnok __res_dnok #if 0 #define res_findzonecut __res_findzonecut #endif #define res_findzonecut2 __res_findzonecut2 #define res_hnok __res_hnok #define res_hostalias __res_hostalias #define res_mailok __res_mailok #define res_nameinquery __res_nameinquery #define res_nclose __res_nclose #define res_ninit __res_ninit #define res_nmkquery __res_nmkquery #define res_pquery __res_pquery #define res_nquery __res_nquery #define res_nquerydomain __res_nquerydomain #define res_nsearch __res_nsearch #define res_nsend __res_nsend #if 0 #define res_nsendsigned __res_nsendsigned #endif #define res_nisourserver __res_nisourserver #define res_ownok __res_ownok #define res_queriesmatch __res_queriesmatch #define res_randomid __res_randomid #define sym_ntop __sym_ntop #define sym_ntos __sym_ntos #define sym_ston __sym_ston #define res_nopt __res_nopt +#define res_nopt_rdata __res_nopt_rdata #define res_ndestroy __res_ndestroy #define res_nametoclass __res_nametoclass #define res_nametotype __res_nametotype #define res_setservers __res_setservers #define res_getservers __res_getservers #if 0 #define res_buildprotolist __res_buildprotolist #define res_destroyprotolist __res_destroyprotolist #define res_destroyservicelist __res_destroyservicelist #define res_get_nibblesuffix __res_get_nibblesuffix #define res_get_nibblesuffix2 __res_get_nibblesuffix2 #endif #define res_ourserver_p __res_ourserver_p #if 0 #define res_protocolname __res_protocolname #define res_protocolnumber __res_protocolnumber #endif #define res_send_setqhook __res_send_setqhook #define res_send_setrhook __res_send_setrhook #if 0 #define res_servicename __res_servicename #define res_servicenumber __res_servicenumber #endif __BEGIN_DECLS int res_hnok(const char *); int res_ownok(const char *); int res_mailok(const char *); int res_dnok(const char *); int sym_ston(const struct res_sym *, const char *, int *); const char * sym_ntos(const struct res_sym *, int, int *); const char * sym_ntop(const struct res_sym *, int, int *); int b64_ntop(u_char const *, size_t, char *, size_t); int b64_pton(char const *, u_char *, size_t); int loc_aton(const char *, u_char *); const char * loc_ntoa(const u_char *, char *); int dn_skipname(const u_char *, const u_char *); void putlong(u_int32_t, u_char *); void putshort(u_int16_t, u_char *); #ifndef __ultrix__ u_int16_t _getshort(const u_char *); u_int32_t _getlong(const u_char *); #endif const char * p_class(int); const char * p_time(u_int32_t); const char * p_type(int); const char * p_rcode(int); const char * p_sockun(union res_sockaddr_union, char *, size_t); const u_char * p_cdnname(const u_char *, const u_char *, int, FILE *); const u_char * p_cdname(const u_char *, const u_char *, FILE *); const u_char * p_fqnname(const u_char *, const u_char *, int, char *, int); const u_char * p_fqname(const u_char *, const u_char *, FILE *); const char * p_option(u_long); char * p_secstodate(u_long); int dn_count_labels(const char *); int dn_comp(const char *, u_char *, int, u_char **, u_char **); int dn_expand(const u_char *, const u_char *, const u_char *, char *, int); u_int res_randomid(void); int res_nameinquery(const char *, int, int, const u_char *, const u_char *); int res_queriesmatch(const u_char *, const u_char *, const u_char *, const u_char *); const char * p_section(int, int); /* Things involving a resolver context. */ int res_ninit(res_state); int res_nisourserver(const res_state, const struct sockaddr_in *); void fp_resstat(const res_state, FILE *); void res_pquery(const res_state, const u_char *, int, FILE *); const char * res_hostalias(const res_state, const char *, char *, size_t); int res_nquery(res_state, const char *, int, int, u_char *, int); int res_nsearch(res_state, const char *, int, int, u_char *, int); int res_nquerydomain(res_state, const char *, const char *, int, int, u_char *, int); int res_nmkquery(res_state, int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int); int res_nsend(res_state, const u_char *, int, u_char *, int); #if 0 int res_nsendsigned(res_state, const u_char *, int, ns_tsig_key *, u_char *, int); int res_findzonecut(res_state, const char *, ns_class, int, char *, size_t, struct in_addr *, int); #endif int res_findzonecut2(res_state, const char *, ns_class, int, char *, size_t, union res_sockaddr_union *, int); void res_nclose(res_state); int res_nopt(res_state, int, u_char *, int, int); +int res_nopt_rdata(res_state, int, u_char *, int, u_char *, + u_short, u_short, u_char *); void res_send_setqhook(res_send_qhook); void res_send_setrhook(res_send_rhook); int __res_vinit(res_state, int); #if 0 void res_destroyservicelist(void); const char * res_servicename(u_int16_t, const char *); const char * res_protocolname(int); void res_destroyprotolist(void); void res_buildprotolist(void); const char * res_get_nibblesuffix(res_state); const char * res_get_nibblesuffix2(res_state); #endif void res_ndestroy(res_state); u_int16_t res_nametoclass(const char *, int *); u_int16_t res_nametotype(const char *, int *); void res_setservers(res_state, const union res_sockaddr_union *, int); int res_getservers(res_state, union res_sockaddr_union *, int); __END_DECLS #endif /* !_RESOLV_H_ */ /*! \file */ Index: releng/7.1/include =================================================================== --- releng/7.1/include (revision 186220) +++ releng/7.1/include (revision 186221) Property changes on: releng/7.1/include ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/include:r186090 Index: releng/7.1/lib/libc/include/isc/eventlib.h =================================================================== --- releng/7.1/lib/libc/include/isc/eventlib.h (revision 186220) +++ releng/7.1/lib/libc/include/isc/eventlib.h (revision 186221) @@ -1,204 +1,206 @@ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-1999 by Internet Software Consortium * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ /* eventlib.h - exported interfaces for eventlib * vix 09sep95 [initial] * - * $Id: eventlib.h,v 1.3.18.2 2005/07/28 07:38:07 marka Exp $ + * $Id: eventlib.h,v 1.3.18.3 2008/01/23 02:12:01 marka Exp $ */ #ifndef _EVENTLIB_H #define _EVENTLIB_H #include #include #include #include + +#include #ifndef __P # define __EVENTLIB_P_DEFINED # ifdef __STDC__ # define __P(x) x # else # define __P(x) () # endif #endif /* In the absence of branded types... */ typedef struct { void *opaque; } evConnID; typedef struct { void *opaque; } evFileID; typedef struct { void *opaque; } evStreamID; typedef struct { void *opaque; } evTimerID; typedef struct { void *opaque; } evWaitID; typedef struct { void *opaque; } evContext; typedef struct { void *opaque; } evEvent; #define evInitID(id) ((id)->opaque = NULL) #define evTestID(id) ((id).opaque != NULL) typedef void (*evConnFunc)__P((evContext, void *, int, const void *, int, const void *, int)); typedef void (*evFileFunc)__P((evContext, void *, int, int)); typedef void (*evStreamFunc)__P((evContext, void *, int, int)); typedef void (*evTimerFunc)__P((evContext, void *, struct timespec, struct timespec)); typedef void (*evWaitFunc)__P((evContext, void *, const void *)); typedef struct { unsigned char mask[256/8]; } evByteMask; #define EV_BYTEMASK_BYTE(b) ((b) / 8) #define EV_BYTEMASK_MASK(b) (1 << ((b) % 8)) #define EV_BYTEMASK_SET(bm, b) \ ((bm).mask[EV_BYTEMASK_BYTE(b)] |= EV_BYTEMASK_MASK(b)) #define EV_BYTEMASK_CLR(bm, b) \ ((bm).mask[EV_BYTEMASK_BYTE(b)] &= ~EV_BYTEMASK_MASK(b)) #define EV_BYTEMASK_TST(bm, b) \ ((bm).mask[EV_BYTEMASK_BYTE(b)] & EV_BYTEMASK_MASK(b)) #define EV_POLL 1 #define EV_WAIT 2 #define EV_NULL 4 #define EV_READ 1 #define EV_WRITE 2 #define EV_EXCEPT 4 #define EV_WASNONBLOCKING 8 /* Internal library use. */ /* eventlib.c */ #define evCreate __evCreate #define evSetDebug __evSetDebug #define evDestroy __evDestroy #define evGetNext __evGetNext #define evDispatch __evDispatch #define evDrop __evDrop #define evMainLoop __evMainLoop #define evHighestFD __evHighestFD #define evGetOption __evGetOption #define evSetOption __evSetOption int evCreate __P((evContext *)); void evSetDebug __P((evContext, int, FILE *)); int evDestroy __P((evContext)); int evGetNext __P((evContext, evEvent *, int)); int evDispatch __P((evContext, evEvent)); void evDrop __P((evContext, evEvent)); int evMainLoop __P((evContext)); int evHighestFD __P((evContext)); int evGetOption __P((evContext *, const char *, int *)); int evSetOption __P((evContext *, const char *, int)); /* ev_connects.c */ #define evListen __evListen #define evConnect __evConnect #define evCancelConn __evCancelConn #define evHold __evHold #define evUnhold __evUnhold #define evTryAccept __evTryAccept int evListen __P((evContext, int, int, evConnFunc, void *, evConnID *)); int evConnect __P((evContext, int, const void *, int, evConnFunc, void *, evConnID *)); int evCancelConn __P((evContext, evConnID)); int evHold __P((evContext, evConnID)); int evUnhold __P((evContext, evConnID)); int evTryAccept __P((evContext, evConnID, int *)); /* ev_files.c */ #define evSelectFD __evSelectFD #define evDeselectFD __evDeselectFD int evSelectFD __P((evContext, int, int, evFileFunc, void *, evFileID *)); int evDeselectFD __P((evContext, evFileID)); /* ev_streams.c */ #define evConsIovec __evConsIovec #define evWrite __evWrite #define evRead __evRead #define evTimeRW __evTimeRW #define evUntimeRW __evUntimeRW #define evCancelRW __evCancelRW struct iovec evConsIovec __P((void *, size_t)); int evWrite __P((evContext, int, const struct iovec *, int, evStreamFunc func, void *, evStreamID *)); int evRead __P((evContext, int, const struct iovec *, int, evStreamFunc func, void *, evStreamID *)); int evTimeRW __P((evContext, evStreamID, evTimerID timer)); int evUntimeRW __P((evContext, evStreamID)); int evCancelRW __P((evContext, evStreamID)); /* ev_timers.c */ #define evConsTime __evConsTime #define evAddTime __evAddTime #define evSubTime __evSubTime #define evCmpTime __evCmpTime #define evTimeSpec __evTimeSpec #define evTimeVal __evTimeVal #define evNowTime __evNowTime #define evUTCTime __evUTCTime #define evLastEventTime __evLastEventTime #define evSetTimer __evSetTimer #define evClearTimer __evClearTimer #define evConfigTimer __evConfigTimer #define evResetTimer __evResetTimer #define evSetIdleTimer __evSetIdleTimer #define evClearIdleTimer __evClearIdleTimer #define evResetIdleTimer __evResetIdleTimer #define evTouchIdleTimer __evTouchIdleTimer struct timespec evConsTime __P((time_t sec, long nsec)); struct timespec evAddTime __P((struct timespec, struct timespec)); struct timespec evSubTime __P((struct timespec, struct timespec)); struct timespec evNowTime __P((void)); struct timespec evUTCTime __P((void)); struct timespec evLastEventTime __P((evContext)); struct timespec evTimeSpec __P((struct timeval)); struct timeval evTimeVal __P((struct timespec)); int evCmpTime __P((struct timespec, struct timespec)); int evSetTimer __P((evContext, evTimerFunc, void *, struct timespec, struct timespec, evTimerID *)); int evClearTimer __P((evContext, evTimerID)); int evConfigTimer __P((evContext, evTimerID, const char *param, int value)); int evResetTimer __P((evContext, evTimerID, evTimerFunc, void *, struct timespec, struct timespec)); int evSetIdleTimer __P((evContext, evTimerFunc, void *, struct timespec, evTimerID *)); int evClearIdleTimer __P((evContext, evTimerID)); int evResetIdleTimer __P((evContext, evTimerID, evTimerFunc, void *, struct timespec)); int evTouchIdleTimer __P((evContext, evTimerID)); /* ev_waits.c */ #define evWaitFor __evWaitFor #define evDo __evDo #define evUnwait __evUnwait #define evDefer __evDefer int evWaitFor __P((evContext, const void *, evWaitFunc, void *, evWaitID *)); int evDo __P((evContext, const void *)); int evUnwait __P((evContext, evWaitID)); int evDefer __P((evContext, evWaitFunc, void *)); #ifdef __EVENTLIB_P_DEFINED # undef __P #endif #endif /*_EVENTLIB_H*/ /*! \file */ Property changes on: releng/7.1/lib/libc/include/isc/eventlib.h ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +y \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: releng/7.1/lib/libc/include/isc/platform.h =================================================================== --- releng/7.1/lib/libc/include/isc/platform.h (nonexistent) +++ releng/7.1/lib/libc/include/isc/platform.h (revision 186221) @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/* $Id: platform.h.in,v 1.2.6.2 2008/01/23 02:15:02 tbox Exp $ */ +/* $FreeBSD$ */ + +/*! \file */ + +#ifndef ISC_PLATFORM_H +#define ISC_PLATFORM_H + +/* + * Define if the OS does not define struct timespec. + */ +#undef ISC_PLATFORM_NEEDTIMESPEC +#ifdef ISC_PLATFORM_NEEDTIMESPEC +#include /* For time_t */ +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +#endif Property changes on: releng/7.1/lib/libc/include/isc/platform.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: releng/7.1/lib/libc/inet/inet_net_pton.c =================================================================== --- releng/7.1/lib/libc/inet/inet_net_pton.c (revision 186220) +++ releng/7.1/lib/libc/inet/inet_net_pton.c (revision 186221) @@ -1,416 +1,416 @@ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.1 2005/04/27 05:00:53 sra Exp $"; +static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.2 2008/08/26 04:42:43 marka Exp $"; #endif #include __FBSDID("$FreeBSD$"); #include "port_before.h" #include #include #include #include #include #include #include #include #include #include #include #include "port_after.h" #ifdef SPRINTF_CHAR # define SPRINTF(x) strlen(sprintf/**/x) #else # define SPRINTF(x) ((size_t)sprintf x) #endif /*% * static int * inet_net_pton_ipv4(src, dst, size) * convert IPv4 network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not an IPv4 network specification. * note: * network byte order assumed. this means 192.5.5.240/28 has * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), June 1996 */ static int inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { static const char xdigits[] = "0123456789abcdef"; static const char digits[] = "0123456789"; int n, ch, tmp = 0, dirty, bits; const u_char *odst = dst; ch = *src++; if (ch == '0' && (src[0] == 'x' || src[0] == 'X') && isascii((unsigned char)(src[1])) && isxdigit((unsigned char)(src[1]))) { /* Hexadecimal: Eat nybble string. */ if (size <= 0U) goto emsgsize; dirty = 0; src++; /*%< skip x or X. */ while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) { if (isupper(ch)) ch = tolower(ch); n = strchr(xdigits, ch) - xdigits; assert(n >= 0 && n <= 15); if (dirty == 0) tmp = n; else tmp = (tmp << 4) | n; if (++dirty == 2) { if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) tmp; dirty = 0; } } if (dirty) { /*%< Odd trailing nybble? */ if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) (tmp << 4); } } else if (isascii(ch) && isdigit(ch)) { /* Decimal: eat dotted digit string. */ for (;;) { tmp = 0; do { n = strchr(digits, ch) - digits; assert(n >= 0 && n <= 9); tmp *= 10; tmp += n; if (tmp > 255) goto enoent; } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); if (size-- <= 0U) goto emsgsize; *dst++ = (u_char) tmp; if (ch == '\0' || ch == '/') break; if (ch != '.') goto enoent; ch = *src++; if (!isascii(ch) || !isdigit(ch)) goto enoent; } } else goto enoent; bits = -1; if (ch == '/' && isascii((unsigned char)(src[0])) && isdigit((unsigned char)(src[0])) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /*%< Skip over the /. */ bits = 0; do { n = strchr(digits, ch) - digits; assert(n >= 0 && n <= 9); bits *= 10; bits += n; + if (bits > 32) + goto enoent; } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); if (ch != '\0') goto enoent; - if (bits > 32) - goto emsgsize; } /* Firey death and destruction unless we prefetched EOS. */ if (ch != '\0') goto enoent; /* If nothing was written to the destination, we found no address. */ if (dst == odst) goto enoent; /* If no CIDR spec was given, infer width from net class. */ if (bits == -1) { if (*odst >= 240) /*%< Class E */ bits = 32; else if (*odst >= 224) /*%< Class D */ bits = 8; else if (*odst >= 192) /*%< Class C */ bits = 24; else if (*odst >= 128) /*%< Class B */ bits = 16; else /*%< Class A */ bits = 8; /* If imputed mask is narrower than specified octets, widen. */ if (bits < ((dst - odst) * 8)) bits = (dst - odst) * 8; /* * If there are no additional bits specified for a class D * address adjust bits to 4. */ if (bits == 8 && *odst == 224) bits = 4; } /* Extend network to cover the actual mask. */ while (bits > ((dst - odst) * 8)) { if (size-- <= 0U) goto emsgsize; *dst++ = '\0'; } return (bits); enoent: errno = ENOENT; return (-1); emsgsize: errno = EMSGSIZE; return (-1); } static int getbits(const char *src, int *bitsp) { static const char digits[] = "0123456789"; int n; int val; char ch; val = 0; n = 0; while ((ch = *src++) != '\0') { const char *pch; pch = strchr(digits, ch); if (pch != NULL) { if (n++ != 0 && val == 0) /*%< no leading zeros */ return (0); val *= 10; val += (pch - digits); if (val > 128) /*%< range */ return (0); continue; } return (0); } if (n == 0) return (0); *bitsp = val; return (1); } static int getv4(const char *src, u_char *dst, int *bitsp) { static const char digits[] = "0123456789"; u_char *odst = dst; int n; u_int val; char ch; val = 0; n = 0; while ((ch = *src++) != '\0') { const char *pch; pch = strchr(digits, ch); if (pch != NULL) { if (n++ != 0 && val == 0) /*%< no leading zeros */ return (0); val *= 10; val += (pch - digits); if (val > 255) /*%< range */ return (0); continue; } if (ch == '.' || ch == '/') { if (dst - odst > 3) /*%< too many octets? */ return (0); *dst++ = val; if (ch == '/') return (getbits(src, bitsp)); val = 0; n = 0; continue; } return (0); } if (n == 0) return (0); if (dst - odst > 3) /*%< too many octets? */ return (0); *dst++ = val; return (1); } static int inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; u_int val; int digits; int bits; size_t bytes; int words; int ipv4; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') goto enoent; curtok = src; saw_xdigit = 0; val = 0; digits = 0; bits = -1; ipv4 = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (++digits > 4) goto enoent; saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) goto enoent; colonp = tp; continue; } else if (*src == '\0') goto enoent; if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; saw_xdigit = 0; digits = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && getv4(curtok, tp, &bits) > 0) { tp += NS_INADDRSZ; saw_xdigit = 0; ipv4 = 1; break; /*%< '\\0' was seen by inet_pton4(). */ } if (ch == '/' && getbits(src, &bits) > 0) break; goto enoent; } if (saw_xdigit) { if (tp + NS_INT16SZ > endp) goto enoent; *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; } if (bits == -1) bits = 128; words = (bits + 15) / 16; if (words < 2) words = 2; if (ipv4) words = 8; endp = tmp + 2 * words; if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; if (tp == endp) goto enoent; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) goto enoent; bytes = (bits + 7) / 8; if (bytes > size) goto emsgsize; memcpy(dst, tmp, bytes); return (bits); enoent: errno = ENOENT; return (-1); emsgsize: errno = EMSGSIZE; return (-1); } /*% * int * inet_net_pton(af, src, dst, size) * convert network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not a valid network specification. * author: * Paul Vixie (ISC), June 1996 */ int inet_net_pton(int af, const char *src, void *dst, size_t size) { switch (af) { case AF_INET: return (inet_net_pton_ipv4(src, dst, size)); case AF_INET6: return (inet_net_pton_ipv6(src, dst, size)); default: errno = EAFNOSUPPORT; return (-1); } } /* * Weak aliases for applications that use certain private entry points, * and fail to include . */ #undef inet_net_pton __weak_reference(__inet_net_pton, inet_net_pton); /*! \file */ Index: releng/7.1/lib/libc/resolv/res_debug.c =================================================================== --- releng/7.1/lib/libc/resolv/res_debug.c (revision 186220) +++ releng/7.1/lib/libc/resolv/res_debug.c (revision 186221) @@ -1,1182 +1,1229 @@ /* * Copyright (c) 1985 * 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. * 4. 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 (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_debug.c,v 1.10.18.5 2005/07/28 07:38:11 marka Exp $"; +static const char rcsid[] = "$Id: res_debug.c,v 1.10.18.6 2008/04/03 23:15:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "port_before.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "port_after.h" #ifdef SPRINTF_CHAR # define SPRINTF(x) strlen(sprintf/**/x) #else # define SPRINTF(x) sprintf x #endif extern const char *_res_opcodes[]; extern const char *_res_sectioncodes[]; /*% * Print the current options. */ void fp_resstat(const res_state statp, FILE *file) { u_long mask; fprintf(file, ";; res options:"); for (mask = 1; mask != 0U; mask <<= 1) if (statp->options & mask) fprintf(file, " %s", p_option(mask)); putc('\n', file); } static void do_section(const res_state statp, ns_msg *handle, ns_sect section, int pflag, FILE *file) { int n, sflag, rrnum; static int buflen = 2048; char *buf; ns_opcode opcode; ns_rr rr; /* * Print answer records. */ sflag = (statp->pfcode & pflag); if (statp->pfcode && !sflag) return; buf = malloc(buflen); if (buf == NULL) { fprintf(file, ";; memory allocation failure\n"); return; } opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode); rrnum = 0; for (;;) { if (ns_parserr(handle, section, rrnum, &rr)) { if (errno != ENODEV) fprintf(file, ";; ns_parserr: %s\n", strerror(errno)); else if (rrnum > 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1)) putc('\n', file); goto cleanup; } if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1)) fprintf(file, ";; %s SECTION:\n", p_section(section, opcode)); if (section == ns_s_qd) fprintf(file, ";;\t%s, type = %s, class = %s\n", ns_rr_name(rr), p_type(ns_rr_type(rr)), p_class(ns_rr_class(rr))); else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) { + u_int16_t optcode, optlen, rdatalen = ns_rr_rdlen(rr); u_int32_t ttl = ns_rr_ttl(rr); + fprintf(file, "; EDNS: version: %u, udp=%u, flags=%04x\n", (ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff); + + while (rdatalen >= 4) { + const u_char *cp = ns_rr_rdata(rr); + int i; + + GETSHORT(optcode, cp); + GETSHORT(optlen, cp); + + if (optcode == NS_OPT_NSID) { + fputs("; NSID: ", file); + if (optlen == 0) { + fputs("; NSID\n", file); + } else { + fputs("; NSID: ", file); + for (i = 0; i < optlen; i++) + fprintf(file, "%02x ", + cp[i]); + fputs(" (",file); + for (i = 0; i < optlen; i++) + fprintf(file, "%c", + isprint(cp[i])? + cp[i] : '.'); + fputs(")\n", file); + } + } else { + if (optlen == 0) { + fprintf(file, "; OPT=%u\n", + optcode); + } else { + fprintf(file, "; OPT=%u: ", + optcode); + for (i = 0; i < optlen; i++) + fprintf(file, "%02x ", + cp[i]); + fputs(" (",file); + for (i = 0; i < optlen; i++) + fprintf(file, "%c", + isprint(cp[i]) ? + cp[i] : '.'); + fputs(")\n", file); + } + } + rdatalen -= 4 + optlen; + } } else { n = ns_sprintrr(handle, &rr, NULL, NULL, buf, buflen); if (n < 0) { if (errno == ENOSPC) { free(buf); buf = NULL; if (buflen < 131072) buf = malloc(buflen += 1024); if (buf == NULL) { fprintf(file, - ";; memory allocation failure\n"); + ";; memory allocation failure\n"); return; } continue; } fprintf(file, ";; ns_sprintrr: %s\n", strerror(errno)); goto cleanup; } fputs(buf, file); fputc('\n', file); } rrnum++; } cleanup: if (buf != NULL) free(buf); } /*% * Print the contents of a query. * This is intended to be primarily a debugging routine. */ void res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { ns_msg handle; int qdcount, ancount, nscount, arcount; u_int opcode, rcode, id; if (ns_initparse(msg, len, &handle) < 0) { fprintf(file, ";; ns_initparse: %s\n", strerror(errno)); return; } opcode = ns_msg_getflag(handle, ns_f_opcode); rcode = ns_msg_getflag(handle, ns_f_rcode); id = ns_msg_id(handle); qdcount = ns_msg_count(handle, ns_s_qd); ancount = ns_msg_count(handle, ns_s_an); nscount = ns_msg_count(handle, ns_s_ns); arcount = ns_msg_count(handle, ns_s_ar); /* * Print header fields. */ if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode) fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n", _res_opcodes[opcode], p_rcode(rcode), id); if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX)) putc(';', file); if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) { fprintf(file, "; flags:"); if (ns_msg_getflag(handle, ns_f_qr)) fprintf(file, " qr"); if (ns_msg_getflag(handle, ns_f_aa)) fprintf(file, " aa"); if (ns_msg_getflag(handle, ns_f_tc)) fprintf(file, " tc"); if (ns_msg_getflag(handle, ns_f_rd)) fprintf(file, " rd"); if (ns_msg_getflag(handle, ns_f_ra)) fprintf(file, " ra"); if (ns_msg_getflag(handle, ns_f_z)) fprintf(file, " ??"); if (ns_msg_getflag(handle, ns_f_ad)) fprintf(file, " ad"); if (ns_msg_getflag(handle, ns_f_cd)) fprintf(file, " cd"); } if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) { fprintf(file, "; %s: %d", p_section(ns_s_qd, opcode), qdcount); fprintf(file, ", %s: %d", p_section(ns_s_an, opcode), ancount); fprintf(file, ", %s: %d", p_section(ns_s_ns, opcode), nscount); fprintf(file, ", %s: %d", p_section(ns_s_ar, opcode), arcount); } if ((!statp->pfcode) || (statp->pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { putc('\n',file); } /* * Print the various sections. */ do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file); do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file); do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file); do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file); if (qdcount == 0 && ancount == 0 && nscount == 0 && arcount == 0) putc('\n', file); } const u_char * p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) { char name[MAXDNAME]; int n; if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0) return (NULL); if (name[0] == '\0') putc('.', file); else fputs(name, file); return (cp + n); } const u_char * p_cdname(const u_char *cp, const u_char *msg, FILE *file) { return (p_cdnname(cp, msg, PACKETSZ, file)); } /*% * Return a fully-qualified domain name from a compressed name (with length supplied). */ const u_char * p_fqnname(cp, msg, msglen, name, namelen) const u_char *cp, *msg; int msglen; char *name; int namelen; { int n, newlen; if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0) return (NULL); newlen = strlen(name); if (newlen == 0 || name[newlen - 1] != '.') { if (newlen + 1 >= namelen) /*%< Lack space for final dot */ return (NULL); else strcpy(name + newlen, "."); } return (cp + n); } /* XXX: the rest of these functions need to become length-limited, too. */ const u_char * p_fqname(const u_char *cp, const u_char *msg, FILE *file) { char name[MAXDNAME]; const u_char *n; n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name); if (n == NULL) return (NULL); fputs(name, file); return (n); } /*% * Names of RR classes and qclasses. Classes and qclasses are the same, except * that C_ANY is a qclass but not a class. (You can ask for records of class * C_ANY, but you can't have any records of that class in the database.) */ const struct res_sym __p_class_syms[] = { {C_IN, "IN", (char *)0}, {C_CHAOS, "CH", (char *)0}, {C_CHAOS, "CHAOS", (char *)0}, {C_HS, "HS", (char *)0}, {C_HS, "HESIOD", (char *)0}, {C_ANY, "ANY", (char *)0}, {C_NONE, "NONE", (char *)0}, {C_IN, (char *)0, (char *)0} }; /*% * Names of message sections. */ static const struct res_sym __p_default_section_syms[] = { {ns_s_qd, "QUERY", (char *)0}, {ns_s_an, "ANSWER", (char *)0}, {ns_s_ns, "AUTHORITY", (char *)0}, {ns_s_ar, "ADDITIONAL", (char *)0}, - {0, (char *)0, (char *)0} + {0, (char *)0, (char *)0} }; static const struct res_sym __p_update_section_syms[] = { {S_ZONE, "ZONE", (char *)0}, {S_PREREQ, "PREREQUISITE", (char *)0}, {S_UPDATE, "UPDATE", (char *)0}, {S_ADDT, "ADDITIONAL", (char *)0}, - {0, (char *)0, (char *)0} + {0, (char *)0, (char *)0} }; const struct res_sym __p_key_syms[] = { {NS_ALG_MD5RSA, "RSA", "RSA KEY with MD5 hash"}, {NS_ALG_DH, "DH", "Diffie Hellman"}, {NS_ALG_DSA, "DSA", "Digital Signature Algorithm"}, {NS_ALG_EXPIRE_ONLY, "EXPIREONLY", "No algorithm"}, {NS_ALG_PRIVATE_OID, "PRIVATE", "Algorithm obtained from OID"}, {0, NULL, NULL} }; const struct res_sym __p_cert_syms[] = { {cert_t_pkix, "PKIX", "PKIX (X.509v3) Certificate"}, {cert_t_spki, "SPKI", "SPKI certificate"}, {cert_t_pgp, "PGP", "PGP certificate"}, {cert_t_url, "URL", "URL Private"}, {cert_t_oid, "OID", "OID Private"}, {0, NULL, NULL} }; /*% * Names of RR types and qtypes. Types and qtypes are the same, except * that T_ANY is a qtype but not a type. (You can ask for records of type * T_ANY, but you can't have any records of that type in the database.) */ const struct res_sym __p_type_syms[] = { {ns_t_a, "A", "address"}, {ns_t_ns, "NS", "name server"}, {ns_t_md, "MD", "mail destination (deprecated)"}, {ns_t_mf, "MF", "mail forwarder (deprecated)"}, {ns_t_cname, "CNAME", "canonical name"}, {ns_t_soa, "SOA", "start of authority"}, {ns_t_mb, "MB", "mailbox"}, {ns_t_mg, "MG", "mail group member"}, {ns_t_mr, "MR", "mail rename"}, {ns_t_null, "NULL", "null"}, {ns_t_wks, "WKS", "well-known service (deprecated)"}, {ns_t_ptr, "PTR", "domain name pointer"}, {ns_t_hinfo, "HINFO", "host information"}, {ns_t_minfo, "MINFO", "mailbox information"}, {ns_t_mx, "MX", "mail exchanger"}, {ns_t_txt, "TXT", "text"}, {ns_t_rp, "RP", "responsible person"}, {ns_t_afsdb, "AFSDB", "DCE or AFS server"}, {ns_t_x25, "X25", "X25 address"}, {ns_t_isdn, "ISDN", "ISDN address"}, {ns_t_rt, "RT", "router"}, {ns_t_nsap, "NSAP", "nsap address"}, {ns_t_nsap_ptr, "NSAP_PTR", "domain name pointer"}, {ns_t_sig, "SIG", "signature"}, {ns_t_key, "KEY", "key"}, {ns_t_px, "PX", "mapping information"}, {ns_t_gpos, "GPOS", "geographical position (withdrawn)"}, {ns_t_aaaa, "AAAA", "IPv6 address"}, {ns_t_loc, "LOC", "location"}, {ns_t_nxt, "NXT", "next valid name (unimplemented)"}, {ns_t_eid, "EID", "endpoint identifier (unimplemented)"}, {ns_t_nimloc, "NIMLOC", "NIMROD locator (unimplemented)"}, {ns_t_srv, "SRV", "server selection"}, {ns_t_atma, "ATMA", "ATM address (unimplemented)"}, {ns_t_tkey, "TKEY", "tkey"}, {ns_t_tsig, "TSIG", "transaction signature"}, {ns_t_ixfr, "IXFR", "incremental zone transfer"}, {ns_t_axfr, "AXFR", "zone transfer"}, {ns_t_zxfr, "ZXFR", "compressed zone transfer"}, {ns_t_mailb, "MAILB", "mailbox-related data (deprecated)"}, {ns_t_maila, "MAILA", "mail agent (deprecated)"}, {ns_t_naptr, "NAPTR", "URN Naming Authority"}, {ns_t_kx, "KX", "Key Exchange"}, {ns_t_cert, "CERT", "Certificate"}, {ns_t_a6, "A6", "IPv6 Address"}, {ns_t_dname, "DNAME", "dname"}, {ns_t_sink, "SINK", "Kitchen Sink (experimental)"}, {ns_t_opt, "OPT", "EDNS Options"}, {ns_t_any, "ANY", "\"any\""}, {0, NULL, NULL} }; /*% * Names of DNS rcodes. */ const struct res_sym __p_rcode_syms[] = { {ns_r_noerror, "NOERROR", "no error"}, {ns_r_formerr, "FORMERR", "format error"}, {ns_r_servfail, "SERVFAIL", "server failed"}, {ns_r_nxdomain, "NXDOMAIN", "no such domain name"}, {ns_r_notimpl, "NOTIMP", "not implemented"}, {ns_r_refused, "REFUSED", "refused"}, {ns_r_yxdomain, "YXDOMAIN", "domain name exists"}, {ns_r_yxrrset, "YXRRSET", "rrset exists"}, {ns_r_nxrrset, "NXRRSET", "rrset doesn't exist"}, {ns_r_notauth, "NOTAUTH", "not authoritative"}, {ns_r_notzone, "NOTZONE", "Not in zone"}, {ns_r_max, "", ""}, {ns_r_badsig, "BADSIG", "bad signature"}, {ns_r_badkey, "BADKEY", "bad key"}, {ns_r_badtime, "BADTIME", "bad time"}, {0, NULL, NULL} }; int sym_ston(const struct res_sym *syms, const char *name, int *success) { for ((void)NULL; syms->name != 0; syms++) { if (strcasecmp (name, syms->name) == 0) { if (success) *success = 1; return (syms->number); } } if (success) *success = 0; return (syms->number); /*%< The default value. */ } const char * sym_ntos(const struct res_sym *syms, int number, int *success) { char *unname = sym_ntos_unname; for ((void)NULL; syms->name != 0; syms++) { if (number == syms->number) { if (success) *success = 1; return (syms->name); } } sprintf(unname, "%d", number); /*%< XXX nonreentrant */ if (success) *success = 0; return (unname); } const char * sym_ntop(const struct res_sym *syms, int number, int *success) { char *unname = sym_ntop_unname; for ((void)NULL; syms->name != 0; syms++) { if (number == syms->number) { if (success) *success = 1; return (syms->humanname); } } sprintf(unname, "%d", number); /*%< XXX nonreentrant */ if (success) *success = 0; return (unname); } /*% * Return a string for the type. */ const char * p_type(int type) { int success; const char *result; static char typebuf[20]; result = sym_ntos(__p_type_syms, type, &success); if (success) return (result); if (type < 0 || type > 0xffff) return ("BADTYPE"); sprintf(typebuf, "TYPE%d", type); return (typebuf); } /*% * Return a string for the type. */ const char * p_section(int section, int opcode) { const struct res_sym *symbols; switch (opcode) { case ns_o_update: symbols = __p_update_section_syms; break; default: symbols = __p_default_section_syms; break; } return (sym_ntos(symbols, section, (int *)0)); } /*% * Return a mnemonic for class. */ const char * p_class(int class) { int success; const char *result; static char classbuf[20]; result = sym_ntos(__p_class_syms, class, &success); if (success) return (result); if (class < 0 || class > 0xffff) return ("BADCLASS"); sprintf(classbuf, "CLASS%d", class); return (classbuf); } /*% * Return a mnemonic for an option */ const char * p_option(u_long option) { char *nbuf = p_option_nbuf; switch (option) { case RES_INIT: return "init"; case RES_DEBUG: return "debug"; case RES_AAONLY: return "aaonly(unimpl)"; case RES_USEVC: return "usevc"; case RES_PRIMARY: return "primry(unimpl)"; case RES_IGNTC: return "igntc"; case RES_RECURSE: return "recurs"; case RES_DEFNAMES: return "defnam"; case RES_STAYOPEN: return "styopn"; case RES_DNSRCH: return "dnsrch"; case RES_INSECURE1: return "insecure1"; case RES_INSECURE2: return "insecure2"; case RES_NOALIASES: return "noaliases"; case RES_USE_INET6: return "inet6"; #ifdef RES_USE_EDNS0 /*%< KAME extension */ case RES_USE_EDNS0: return "edns0"; + case RES_NSID: return "nsid"; #endif #ifdef RES_USE_DNAME case RES_USE_DNAME: return "dname"; #endif #ifdef RES_USE_DNSSEC case RES_USE_DNSSEC: return "dnssec"; #endif #ifdef RES_NOTLDQUERY case RES_NOTLDQUERY: return "no-tld-query"; #endif #ifdef RES_NO_NIBBLE2 case RES_NO_NIBBLE2: return "no-nibble2"; #endif /* XXX nonreentrant */ default: sprintf(nbuf, "?0x%lx?", (u_long)option); return (nbuf); } } /*% * Return a mnemonic for a time to live. */ const char * p_time(u_int32_t value) { char *nbuf = p_time_nbuf; if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0) sprintf(nbuf, "%u", value); return (nbuf); } /*% * Return a string for the rcode. */ const char * p_rcode(int rcode) { return (sym_ntos(__p_rcode_syms, rcode, (int *)0)); } /*% * Return a string for a res_sockaddr_union. */ const char * p_sockun(union res_sockaddr_union u, char *buf, size_t size) { char ret[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:123.123.123.123"]; switch (u.sin.sin_family) { case AF_INET: inet_ntop(AF_INET, &u.sin.sin_addr, ret, sizeof ret); break; #ifdef HAS_INET6_STRUCTS case AF_INET6: inet_ntop(AF_INET6, &u.sin6.sin6_addr, ret, sizeof ret); break; #endif default: sprintf(ret, "[af%d]", u.sin.sin_family); break; } if (size > 0U) { strncpy(buf, ret, size - 1); buf[size - 1] = '0'; } return (buf); } /*% * routines to convert between on-the-wire RR format and zone file format. * Does not contain conversion to/from decimal degrees; divide or multiply * by 60*60*1000 for that. */ static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000, 1000000,10000000,100000000,1000000000}; /*% takes an XeY precision/size value, returns a string representation. */ static const char * precsize_ntoa(prec) u_int8_t prec; { char *retbuf = precsize_ntoa_retbuf; unsigned long val; int mantissa, exponent; mantissa = (int)((prec >> 4) & 0x0f) % 10; exponent = (int)((prec >> 0) & 0x0f) % 10; val = mantissa * poweroften[exponent]; (void) sprintf(retbuf, "%lu.%.2lu", val/100, val%100); return (retbuf); } /*% converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */ static u_int8_t precsize_aton(const char **strptr) { unsigned int mval = 0, cmval = 0; u_int8_t retval = 0; const char *cp; int exponent; int mantissa; cp = *strptr; while (isdigit((unsigned char)*cp)) mval = mval * 10 + (*cp++ - '0'); if (*cp == '.') { /*%< centimeters */ cp++; if (isdigit((unsigned char)*cp)) { cmval = (*cp++ - '0') * 10; if (isdigit((unsigned char)*cp)) { cmval += (*cp++ - '0'); } } } cmval = (mval * 100) + cmval; for (exponent = 0; exponent < 9; exponent++) if (cmval < poweroften[exponent+1]) break; mantissa = cmval / poweroften[exponent]; if (mantissa > 9) mantissa = 9; retval = (mantissa << 4) | exponent; *strptr = cp; return (retval); } /*% converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */ static u_int32_t latlon2ul(const char **latlonstrptr, int *which) { const char *cp; u_int32_t retval; int deg = 0, min = 0, secs = 0, secsfrac = 0; cp = *latlonstrptr; while (isdigit((unsigned char)*cp)) deg = deg * 10 + (*cp++ - '0'); while (isspace((unsigned char)*cp)) cp++; if (!(isdigit((unsigned char)*cp))) goto fndhemi; while (isdigit((unsigned char)*cp)) min = min * 10 + (*cp++ - '0'); while (isspace((unsigned char)*cp)) cp++; if (!(isdigit((unsigned char)*cp))) goto fndhemi; while (isdigit((unsigned char)*cp)) secs = secs * 10 + (*cp++ - '0'); if (*cp == '.') { /*%< decimal seconds */ cp++; if (isdigit((unsigned char)*cp)) { secsfrac = (*cp++ - '0') * 100; if (isdigit((unsigned char)*cp)) { secsfrac += (*cp++ - '0') * 10; if (isdigit((unsigned char)*cp)) { secsfrac += (*cp++ - '0'); } } } } while (!isspace((unsigned char)*cp)) /*%< if any trailing garbage */ cp++; while (isspace((unsigned char)*cp)) cp++; fndhemi: switch (*cp) { case 'N': case 'n': case 'E': case 'e': retval = ((unsigned)1<<31) + (((((deg * 60) + min) * 60) + secs) * 1000) + secsfrac; break; case 'S': case 's': case 'W': case 'w': retval = ((unsigned)1<<31) - (((((deg * 60) + min) * 60) + secs) * 1000) - secsfrac; break; default: retval = 0; /*%< invalid value -- indicates error */ break; } switch (*cp) { case 'N': case 'n': case 'S': case 's': *which = 1; /*%< latitude */ break; case 'E': case 'e': case 'W': case 'w': *which = 2; /*%< longitude */ break; default: *which = 0; /*%< error */ break; } cp++; /*%< skip the hemisphere */ while (!isspace((unsigned char)*cp)) /*%< if any trailing garbage */ cp++; while (isspace((unsigned char)*cp)) /*%< move to next field */ cp++; *latlonstrptr = cp; return (retval); } /*% * converts a zone file representation in a string to an RDATA on-the-wire * representation. */ int loc_aton(ascii, binary) const char *ascii; u_char *binary; { const char *cp, *maxcp; u_char *bcp; u_int32_t latit = 0, longit = 0, alt = 0; u_int32_t lltemp1 = 0, lltemp2 = 0; int altmeters = 0, altfrac = 0, altsign = 1; u_int8_t hp = 0x16; /*%< default = 1e6 cm = 10000.00m = 10km */ u_int8_t vp = 0x13; /*%< default = 1e3 cm = 10.00m */ u_int8_t siz = 0x12; /*%< default = 1e2 cm = 1.00m */ int which1 = 0, which2 = 0; cp = ascii; maxcp = cp + strlen(ascii); lltemp1 = latlon2ul(&cp, &which1); lltemp2 = latlon2ul(&cp, &which2); switch (which1 + which2) { case 3: /*%< 1 + 2, the only valid combination */ if ((which1 == 1) && (which2 == 2)) { /*%< normal case */ latit = lltemp1; longit = lltemp2; } else if ((which1 == 2) && (which2 == 1)) { /*%< reversed */ longit = lltemp1; latit = lltemp2; } else { /*%< some kind of brokenness */ return (0); } break; default: /*%< we didn't get one of each */ return (0); } /* altitude */ if (*cp == '-') { altsign = -1; cp++; } if (*cp == '+') cp++; while (isdigit((unsigned char)*cp)) altmeters = altmeters * 10 + (*cp++ - '0'); if (*cp == '.') { /*%< decimal meters */ cp++; if (isdigit((unsigned char)*cp)) { altfrac = (*cp++ - '0') * 10; if (isdigit((unsigned char)*cp)) { altfrac += (*cp++ - '0'); } } } alt = (10000000 + (altsign * (altmeters * 100 + altfrac))); while (!isspace((unsigned char)*cp) && (cp < maxcp)) /*%< if trailing garbage or m */ cp++; while (isspace((unsigned char)*cp) && (cp < maxcp)) cp++; if (cp >= maxcp) goto defaults; siz = precsize_aton(&cp); while (!isspace((unsigned char)*cp) && (cp < maxcp)) /*%< if trailing garbage or m */ cp++; while (isspace((unsigned char)*cp) && (cp < maxcp)) cp++; if (cp >= maxcp) goto defaults; hp = precsize_aton(&cp); while (!isspace((unsigned char)*cp) && (cp < maxcp)) /*%< if trailing garbage or m */ cp++; while (isspace((unsigned char)*cp) && (cp < maxcp)) cp++; if (cp >= maxcp) goto defaults; vp = precsize_aton(&cp); defaults: bcp = binary; *bcp++ = (u_int8_t) 0; /*%< version byte */ *bcp++ = siz; *bcp++ = hp; *bcp++ = vp; PUTLONG(latit,bcp); PUTLONG(longit,bcp); PUTLONG(alt,bcp); return (16); /*%< size of RR in octets */ } /*% takes an on-the-wire LOC RR and formats it in a human readable format. */ const char * loc_ntoa(binary, ascii) const u_char *binary; char *ascii; { static const char *error = "?"; static char tmpbuf[sizeof "1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"]; const u_char *cp = binary; int latdeg, latmin, latsec, latsecfrac; int longdeg, longmin, longsec, longsecfrac; char northsouth, eastwest; const char *altsign; int altmeters, altfrac; const u_int32_t referencealt = 100000 * 100; int32_t latval, longval, altval; u_int32_t templ; u_int8_t sizeval, hpval, vpval, versionval; char *sizestr, *hpstr, *vpstr; versionval = *cp++; if (ascii == NULL) ascii = tmpbuf; if (versionval) { (void) sprintf(ascii, "; error: unknown LOC RR version"); return (ascii); } sizeval = *cp++; hpval = *cp++; vpval = *cp++; GETLONG(templ, cp); latval = (templ - ((unsigned)1<<31)); GETLONG(templ, cp); longval = (templ - ((unsigned)1<<31)); GETLONG(templ, cp); if (templ < referencealt) { /*%< below WGS 84 spheroid */ altval = referencealt - templ; altsign = "-"; } else { altval = templ - referencealt; altsign = ""; } if (latval < 0) { northsouth = 'S'; latval = -latval; } else northsouth = 'N'; latsecfrac = latval % 1000; latval = latval / 1000; latsec = latval % 60; latval = latval / 60; latmin = latval % 60; latval = latval / 60; latdeg = latval; if (longval < 0) { eastwest = 'W'; longval = -longval; } else eastwest = 'E'; longsecfrac = longval % 1000; longval = longval / 1000; longsec = longval % 60; longval = longval / 60; longmin = longval % 60; longval = longval / 60; longdeg = longval; altfrac = altval % 100; altmeters = (altval / 100); sizestr = strdup(precsize_ntoa(sizeval)); hpstr = strdup(precsize_ntoa(hpval)); vpstr = strdup(precsize_ntoa(vpval)); sprintf(ascii, "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm", latdeg, latmin, latsec, latsecfrac, northsouth, longdeg, longmin, longsec, longsecfrac, eastwest, altsign, altmeters, altfrac, (sizestr != NULL) ? sizestr : error, (hpstr != NULL) ? hpstr : error, (vpstr != NULL) ? vpstr : error); if (sizestr != NULL) free(sizestr); if (hpstr != NULL) free(hpstr); if (vpstr != NULL) free(vpstr); return (ascii); } /*% Return the number of DNS hierarchy levels in the name. */ int dn_count_labels(const char *name) { int i, len, count; len = strlen(name); for (i = 0, count = 0; i < len; i++) { /* XXX need to check for \. or use named's nlabels(). */ if (name[i] == '.') count++; } /* don't count initial wildcard */ if (name[0] == '*') if (count) count--; /* don't count the null label for root. */ /* if terminating '.' not found, must adjust */ /* count to include last label */ if (len > 0 && name[len-1] != '.') count++; return (count); } /*% * Make dates expressed in seconds-since-Jan-1-1970 easy to read. * SIG records are required to be printed like this, by the Secure DNS RFC. */ char * p_secstodate (u_long secs) { char *output = p_secstodate_output; time_t clock = secs; struct tm *time; #ifdef HAVE_TIME_R struct tm res; time = gmtime_r(&clock, &res); #else time = gmtime(&clock); #endif time->tm_year += 1900; time->tm_mon += 1; sprintf(output, "%04d%02d%02d%02d%02d%02d", time->tm_year, time->tm_mon, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec); return (output); } u_int16_t res_nametoclass(const char *buf, int *successp) { unsigned long result; char *endptr; int success; result = sym_ston(__p_class_syms, buf, &success); if (success) goto done; if (strncasecmp(buf, "CLASS", 5) != 0 || !isdigit((unsigned char)buf[5])) goto done; errno = 0; result = strtoul(buf + 5, &endptr, 10); if (errno == 0 && *endptr == '\0' && result <= 0xffffU) success = 1; done: if (successp) *successp = success; return (result); } u_int16_t res_nametotype(const char *buf, int *successp) { unsigned long result; char *endptr; int success; result = sym_ston(__p_type_syms, buf, &success); if (success) goto done; if (strncasecmp(buf, "type", 4) != 0 || !isdigit((unsigned char)buf[4])) goto done; errno = 0; result = strtoul(buf + 4, &endptr, 10); if (errno == 0 && *endptr == '\0' && result <= 0xffffU) success = 1; done: if (successp) *successp = success; return (result); } /* * Weak aliases for applications that use certain private entry points, * and fail to include . */ #undef fp_resstat __weak_reference(__fp_resstat, fp_resstat); #undef p_fqnname __weak_reference(__p_fqnname, p_fqnname); #undef sym_ston __weak_reference(__sym_ston, sym_ston); #undef sym_ntos __weak_reference(__sym_ntos, sym_ntos); #undef sym_ntop __weak_reference(__sym_ntop, sym_ntop); #undef dn_count_labels __weak_reference(__dn_count_labels, dn_count_labels); #undef p_secstodate __weak_reference(__p_secstodate, p_secstodate); /*! \file */ Index: releng/7.1/lib/libc/resolv/res_mkquery.c =================================================================== --- releng/7.1/lib/libc/resolv/res_mkquery.c (revision 186220) +++ releng/7.1/lib/libc/resolv/res_mkquery.c (revision 186221) @@ -1,257 +1,303 @@ /* * Copyright (c) 1985, 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. * 4. 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. */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_mkquery.c,v 1.5.18.1 2005/04/27 05:01:11 sra Exp $"; +static const char rcsid[] = "$Id: res_mkquery.c,v 1.5.18.2 2008/04/03 23:15:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "port_before.h" #include #include #include #include #include #include #include #include #include "port_after.h" /* Options. Leave them on. */ #define DEBUG extern const char *_res_opcodes[]; /*% * Form all types of queries. * Returns the size of the result or -1. */ int res_nmkquery(res_state statp, int op, /*!< opcode of query */ const char *dname, /*!< domain name */ int class, int type, /*!< class and type of query */ const u_char *data, /*!< resource record data */ int datalen, /*!< length of data */ const u_char *newrr_in, /*!< new rr for modify or append */ u_char *buf, /*!< buffer to put query */ int buflen) /*!< size of buffer */ { HEADER *hp; u_char *cp, *ep; int n; u_char *dnptrs[20], **dpp, **lastdnptr; UNUSED(newrr_in); #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_nmkquery(%s, %s, %s, %s)\n", _res_opcodes[op], dname, p_class(class), p_type(type)); #endif /* * Initialize header fields. */ if ((buf == NULL) || (buflen < HFIXEDSZ)) return (-1); memset(buf, 0, HFIXEDSZ); hp = (HEADER *) buf; hp->id = htons(++statp->id); hp->opcode = op; hp->rd = (statp->options & RES_RECURSE) != 0U; hp->rcode = NOERROR; cp = buf + HFIXEDSZ; ep = buf + buflen; dpp = dnptrs; *dpp++ = buf; *dpp++ = NULL; lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; /* * perform opcode specific processing */ switch (op) { case QUERY: /*FALLTHROUGH*/ case NS_NOTIFY_OP: if (ep - cp < QFIXEDSZ) return (-1); if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs, lastdnptr)) < 0) return (-1); cp += n; ns_put16(type, cp); cp += INT16SZ; ns_put16(class, cp); cp += INT16SZ; hp->qdcount = htons(1); if (op == QUERY || data == NULL) break; /* * Make an additional record for completion domain. */ if ((ep - cp) < RRFIXEDSZ) return (-1); n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ, dnptrs, lastdnptr); if (n < 0) return (-1); cp += n; ns_put16(T_NULL, cp); cp += INT16SZ; ns_put16(class, cp); cp += INT16SZ; ns_put32(0, cp); cp += INT32SZ; ns_put16(0, cp); cp += INT16SZ; hp->arcount = htons(1); break; case IQUERY: /* * Initialize answer section */ if (ep - cp < 1 + RRFIXEDSZ + datalen) return (-1); *cp++ = '\0'; /*%< no domain name */ ns_put16(type, cp); cp += INT16SZ; ns_put16(class, cp); cp += INT16SZ; ns_put32(0, cp); cp += INT32SZ; ns_put16(datalen, cp); cp += INT16SZ; if (datalen) { memcpy(cp, data, datalen); cp += datalen; } hp->ancount = htons(1); break; default: return (-1); } return (cp - buf); } #ifdef RES_USE_EDNS0 /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */ -#ifndef T_OPT -#define T_OPT 41 -#endif int res_nopt(res_state statp, int n0, /*%< current offset in buffer */ u_char *buf, /*%< buffer to put query */ int buflen, /*%< size of buffer */ int anslen) /*%< UDP answer buffer size */ { HEADER *hp; u_char *cp, *ep; u_int16_t flags = 0; #ifdef DEBUG if ((statp->options & RES_DEBUG) != 0U) printf(";; res_nopt()\n"); #endif hp = (HEADER *) buf; cp = buf + n0; ep = buf + buflen; if ((ep - cp) < 1 + RRFIXEDSZ) return (-1); - *cp++ = 0; /*%< "." */ - ns_put16(T_OPT, cp); /*%< TYPE */ + *cp++ = 0; /*%< "." */ + ns_put16(ns_t_opt, cp); /*%< TYPE */ cp += INT16SZ; if (anslen > 0xffff) anslen = 0xffff; /* limit to 16bit value */ - ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */ + ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */ cp += INT16SZ; - *cp++ = NOERROR; /*%< extended RCODE */ - *cp++ = 0; /*%< EDNS version */ + *cp++ = NOERROR; /*%< extended RCODE */ + *cp++ = 0; /*%< EDNS version */ + if (statp->options & RES_USE_DNSSEC) { #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_opt()... ENDS0 DNSSEC\n"); #endif flags |= NS_OPT_DNSSEC_OK; } ns_put16(flags, cp); cp += INT16SZ; - ns_put16(0, cp); /*%< RDLEN */ + + ns_put16(0U, cp); /*%< RDLEN */ cp += INT16SZ; + hp->arcount = htons(ntohs(hp->arcount) + 1); + + return (cp - buf); +} + +/* + * Construct variable data (RDATA) block for OPT psuedo-RR, append it + * to the buffer, then update the RDLEN field (previously set to zero by + * res_nopt()) with the new RDATA length. + */ +int +res_nopt_rdata(res_state statp, + int n0, /*%< current offset in buffer */ + u_char *buf, /*%< buffer to put query */ + int buflen, /*%< size of buffer */ + u_char *rdata, /*%< ptr to start of opt rdata */ + u_short code, /*%< OPTION-CODE */ + u_short len, /*%< OPTION-LENGTH */ + u_char *data) /*%< OPTION_DATA */ +{ + register u_char *cp, *ep; + +#ifdef DEBUG + if ((statp->options & RES_DEBUG) != 0U) + printf(";; res_nopt_rdata()\n"); +#endif + + cp = buf + n0; + ep = buf + buflen; + + if ((ep - cp) < (4 + len)) + return (-1); + + if (rdata < (buf + 2) || rdata >= ep) + return (-1); + + ns_put16(code, cp); + cp += INT16SZ; + + ns_put16(len, cp); + cp += INT16SZ; + + memcpy(cp, data, len); + cp += len; + + len = cp - rdata; + ns_put16(len, rdata - 2); /* Update RDLEN field */ return (cp - buf); } #endif /*! \file */ Index: releng/7.1/lib/libc/resolv/res_query.c =================================================================== --- releng/7.1/lib/libc/resolv/res_query.c (revision 186220) +++ releng/7.1/lib/libc/resolv/res_query.c (revision 186221) @@ -1,481 +1,489 @@ /* * Copyright (c) 1988, 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. * 4. 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. */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_query.c,v 1.7.18.1 2005/04/27 05:01:11 sra Exp $"; +static const char rcsid[] = "$Id: res_query.c,v 1.7.18.2 2008/04/03 23:15:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "port_before.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "port_after.h" /* Options. Leave them on. */ #define DEBUG #if PACKETSZ > 1024 #define MAXPACKET PACKETSZ #else #define MAXPACKET 1024 #endif /*% * Formulate a normal query, send, and await answer. * Returned answer is placed in supplied buffer "answer". * Perform preliminary check of answer, returning success only * if no error is indicated and the answer count is nonzero. * Return the size of the response on success, -1 on error. * Error number is left in H_ERRNO. * * Caller must parse answer and determine whether it answers the question. */ int res_nquery(res_state statp, const char *name, /*%< domain name */ int class, int type, /*%< class and type of query */ u_char *answer, /*%< buffer to put answer */ int anslen) /*%< size of answer buffer */ { u_char buf[MAXPACKET]; HEADER *hp = (HEADER *) answer; - int n; u_int oflags; + u_char *rdata; + int n; oflags = statp->_flags; again: hp->rcode = NOERROR; /*%< default */ #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query(%s, %d, %d)\n", name, class, type); #endif n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, buf, sizeof(buf)); #ifdef RES_USE_EDNS0 if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 && - (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U) + (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC|RES_NSID))) { n = res_nopt(statp, n, buf, sizeof(buf), anslen); + rdata = &buf[n]; + if (n > 0 && (statp->options & RES_NSID) != 0U) { + n = res_nopt_rdata(statp, n, buf, sizeof(buf), rdata, + NS_OPT_NSID, 0, NULL); + } + } #endif if (n <= 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query: mkquery failed\n"); #endif RES_SET_H_ERRNO(statp, NO_RECOVERY); return (n); } + n = res_nsend(statp, buf, n, answer, anslen); if (n < 0) { #ifdef RES_USE_EDNS0 /* if the query choked with EDNS0, retry without EDNS0 */ if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U && ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) { statp->_flags |= RES_F_EDNS0ERR; if (statp->options & RES_DEBUG) printf(";; res_nquery: retry without EDNS0\n"); goto again; } #endif #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query: send error\n"); #endif RES_SET_H_ERRNO(statp, TRY_AGAIN); return (n); } if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; rcode = (%s), counts = an:%d ns:%d ar:%d\n", p_rcode(hp->rcode), ntohs(hp->ancount), ntohs(hp->nscount), ntohs(hp->arcount)); #endif switch (hp->rcode) { case NXDOMAIN: RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); break; case SERVFAIL: RES_SET_H_ERRNO(statp, TRY_AGAIN); break; case NOERROR: RES_SET_H_ERRNO(statp, NO_DATA); break; case FORMERR: case NOTIMP: case REFUSED: default: RES_SET_H_ERRNO(statp, NO_RECOVERY); break; } return (-1); } return (n); } /*% * Formulate a normal query, send, and retrieve answer in supplied buffer. * Return the size of the response on success, -1 on error. * If enabled, implement search rules until answer or unrecoverable failure * is detected. Error code, if any, is left in H_ERRNO. */ int res_nsearch(res_state statp, const char *name, /*%< domain name */ int class, int type, /*%< class and type of query */ u_char *answer, /*%< buffer to put answer */ int anslen) /*%< size of answer */ { const char *cp, * const *domain; HEADER *hp = (HEADER *) answer; char tmp[NS_MAXDNAME]; u_int dots; int trailing_dot, ret, saved_herrno; int got_nodata = 0, got_servfail = 0, root_on_list = 0; int tried_as_is = 0; int searched = 0; errno = 0; RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); /*%< True if we never query. */ dots = 0; for (cp = name; *cp != '\0'; cp++) dots += (*cp == '.'); trailing_dot = 0; if (cp > name && *--cp == '.') trailing_dot++; /* If there aren't any dots, it could be a user-level alias. */ if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL) return (res_nquery(statp, cp, class, type, answer, anslen)); /* * If there are enough dots in the name, let's just give it a * try 'as is'. The threshold can be set with the "ndots" option. * Also, query 'as is', if there is a trailing dot in the name. */ saved_herrno = -1; if (dots >= statp->ndots || trailing_dot) { ret = res_nquerydomain(statp, name, NULL, class, type, answer, anslen); if (ret > 0 || trailing_dot) return (ret); if (errno == ECONNREFUSED) { RES_SET_H_ERRNO(statp, TRY_AGAIN); return (-1); } switch (statp->res_h_errno) { case NO_DATA: case HOST_NOT_FOUND: break; case TRY_AGAIN: if (hp->rcode == SERVFAIL) break; /* FALLTHROUGH */ default: return (-1); } saved_herrno = statp->res_h_errno; tried_as_is++; } /* * We do at least one level of search if * - there is no dot and RES_DEFNAME is set, or * - there is at least one dot, there is no trailing dot, * and RES_DNSRCH is set. */ if ((!dots && (statp->options & RES_DEFNAMES) != 0U) || (dots && !trailing_dot && (statp->options & RES_DNSRCH) != 0U)) { int done = 0; for (domain = (const char * const *)statp->dnsrch; *domain && !done; domain++) { searched = 1; if (domain[0][0] == '\0' || (domain[0][0] == '.' && domain[0][1] == '\0')) root_on_list++; if (root_on_list && tried_as_is) continue; ret = res_nquerydomain(statp, name, *domain, class, type, answer, anslen); if (ret > 0) return (ret); /* * If no server present, give up. * If name isn't found in this domain, * keep trying higher domains in the search list * (if that's enabled). * On a NO_DATA error, keep trying, otherwise * a wildcard entry of another type could keep us * from finding this entry higher in the domain. * If we get some other error (negative answer or * server failure), then stop searching up, * but try the input name below in case it's * fully-qualified. */ if (errno == ECONNREFUSED) { RES_SET_H_ERRNO(statp, TRY_AGAIN); return (-1); } switch (statp->res_h_errno) { case NO_DATA: got_nodata++; /* FALLTHROUGH */ case HOST_NOT_FOUND: /* keep trying */ break; case TRY_AGAIN: /* * This can occur due to a server failure * (that is, all listed servers have failed), * or all listed servers have timed out. * ((HEADER *)answer)->rcode may not be set * to SERVFAIL in the case of a timeout. * * Either way we must return TRY_AGAIN in * order to avoid non-deterministic * return codes. * For example, loaded name servers or races * against network startup/validation (dhcp, * ppp, etc) can cause the search to timeout * on one search element, e.g. 'fu.bar.com', * and return a definitive failure on the * next search element, e.g. 'fu.'. */ got_servfail++; if (hp->rcode == SERVFAIL) { /* try next search element, if any */ break; } /* FALLTHROUGH */ default: /* anything else implies that we're done */ done++; } /* if we got here for some reason other than DNSRCH, * we only wanted one iteration of the loop, so stop. */ if ((statp->options & RES_DNSRCH) == 0U) done++; } } switch (statp->res_h_errno) { case NO_DATA: case HOST_NOT_FOUND: break; case TRY_AGAIN: if (hp->rcode == SERVFAIL) break; /* FALLTHROUGH */ default: goto giveup; } /* * If the query has not already been tried as is then try it * unless RES_NOTLDQUERY is set and there were no dots. */ if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0U) && !(tried_as_is || root_on_list)) { ret = res_nquerydomain(statp, name, NULL, class, type, answer, anslen); if (ret > 0) return (ret); } /* if we got here, we didn't satisfy the search. * if we did an initial full query, return that query's H_ERRNO * (note that we wouldn't be here if that query had succeeded). * else if we ever got a nodata, send that back as the reason. * else send back meaningless H_ERRNO, that being the one from * the last DNSRCH we did. */ giveup: if (saved_herrno != -1) RES_SET_H_ERRNO(statp, saved_herrno); else if (got_nodata) RES_SET_H_ERRNO(statp, NO_DATA); else if (got_servfail) RES_SET_H_ERRNO(statp, TRY_AGAIN); return (-1); } /*% * Perform a call on res_query on the concatenation of name and domain, * removing a trailing dot from name if domain is NULL. */ int res_nquerydomain(res_state statp, const char *name, const char *domain, int class, int type, /*%< class and type of query */ u_char *answer, /*%< buffer to put answer */ int anslen) /*%< size of answer */ { char nbuf[MAXDNAME]; const char *longname = nbuf; int n, d; #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_nquerydomain(%s, %s, %d, %d)\n", name, domain?domain:"", class, type); #endif if (domain == NULL) { /* * Check for trailing '.'; * copy without '.' if present. */ n = strlen(name); if (n >= MAXDNAME) { RES_SET_H_ERRNO(statp, NO_RECOVERY); return (-1); } n--; if (n >= 0 && name[n] == '.') { strncpy(nbuf, name, n); nbuf[n] = '\0'; } else longname = name; } else { n = strlen(name); d = strlen(domain); if (n + d + 1 >= MAXDNAME) { RES_SET_H_ERRNO(statp, NO_RECOVERY); return (-1); } sprintf(nbuf, "%s.%s", name, domain); } return (res_nquery(statp, longname, class, type, answer, anslen)); } const char * res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) { char *file, *cp1, *cp2; char buf[BUFSIZ]; FILE *fp; if (statp->options & RES_NOALIASES) return (NULL); if (issetugid()) return (NULL); file = getenv("HOSTALIASES"); if (file == NULL || (fp = fopen(file, "r")) == NULL) return (NULL); setbuf(fp, NULL); buf[sizeof(buf) - 1] = '\0'; while (fgets(buf, sizeof(buf), fp)) { for (cp1 = buf; *cp1 && !isspace((unsigned char)*cp1); ++cp1) ; if (!*cp1) break; *cp1 = '\0'; if (ns_samename(buf, name) == 1) { while (isspace((unsigned char)*++cp1)) ; if (!*cp1) break; for (cp2 = cp1 + 1; *cp2 && !isspace((unsigned char)*cp2); ++cp2) ; *cp2 = '\0'; strncpy(dst, cp1, siz - 1); dst[siz - 1] = '\0'; fclose(fp); return (dst); } } fclose(fp); return (NULL); } /*! \file */ Index: releng/7.1/lib/libc/resolv/res_send.c =================================================================== --- releng/7.1/lib/libc/resolv/res_send.c (revision 186220) +++ releng/7.1/lib/libc/resolv/res_send.c (revision 186221) @@ -1,1167 +1,1181 @@ /* * Copyright (c) 1985, 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. * 4. 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. */ /* * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * 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. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. */ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_send.c,v 1.9.18.8 2006/10/16 23:00:58 marka Exp $"; +static const char rcsid[] = "$Id: res_send.c,v 1.9.18.10 2008/01/27 02:06:26 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /*! \file * \brief * Send query to name server and wait for reply. */ #include "port_before.h" #ifndef USE_KQUEUE #include "fd_setsize.h" #endif #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "port_after.h" #ifdef USE_KQUEUE #include #else #ifdef USE_POLL #ifdef HAVE_STROPTS_H #include #endif #include #endif /* USE_POLL */ #endif #include "un-namespace.h" /* Options. Leave them on. */ #define DEBUG #include "res_debug.h" #include "res_private.h" #define EXT(res) ((res)->_u._ext) #if !defined(USE_POLL) && !defined(USE_KQUEUE) static const int highestFD = FD_SETSIZE - 1; #endif /* Forward. */ static int get_salen(const struct sockaddr *); static struct sockaddr * get_nsaddr(res_state, size_t); static int send_vc(res_state, const u_char *, int, u_char *, int, int *, int); static int send_dg(res_state, #ifdef USE_KQUEUE int kq, #endif const u_char *, int, u_char *, int, int *, int, int, int *, int *); static void Aerror(const res_state, FILE *, const char *, int, const struct sockaddr *, int); static void Perror(const res_state, FILE *, const char *, int); static int sock_eq(struct sockaddr *, struct sockaddr *); #if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE) static int pselect(int, void *, void *, void *, struct timespec *, const sigset_t *); #endif void res_pquery(const res_state, const u_char *, int, FILE *); static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; /* Public. */ /*% * looks up "ina" in _res.ns_addr_list[] * * returns: *\li 0 : not found *\li >0 : found * * author: *\li paul vixie, 29may94 */ int res_ourserver_p(const res_state statp, const struct sockaddr *sa) { const struct sockaddr_in *inp, *srv; const struct sockaddr_in6 *in6p, *srv6; int ns; switch (sa->sa_family) { case AF_INET: inp = (const struct sockaddr_in *)sa; for (ns = 0; ns < statp->nscount; ns++) { srv = (struct sockaddr_in *)get_nsaddr(statp, ns); if (srv->sin_family == inp->sin_family && srv->sin_port == inp->sin_port && (srv->sin_addr.s_addr == INADDR_ANY || srv->sin_addr.s_addr == inp->sin_addr.s_addr)) return (1); } break; case AF_INET6: if (EXT(statp).ext == NULL) break; in6p = (const struct sockaddr_in6 *)sa; for (ns = 0; ns < statp->nscount; ns++) { srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns); if (srv6->sin6_family == in6p->sin6_family && srv6->sin6_port == in6p->sin6_port && #ifdef HAVE_SIN6_SCOPE_ID (srv6->sin6_scope_id == 0 || srv6->sin6_scope_id == in6p->sin6_scope_id) && #endif (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) || IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr))) return (1); } break; default: break; } return (0); } /*% * look for (name,type,class) in the query section of packet (buf,eom) * * requires: *\li buf + HFIXEDSZ <= eom * * returns: *\li -1 : format error *\li 0 : not found *\li >0 : found * * author: *\li paul vixie, 29may94 */ int res_nameinquery(const char *name, int type, int class, const u_char *buf, const u_char *eom) { const u_char *cp = buf + HFIXEDSZ; int qdcount = ntohs(((const HEADER*)buf)->qdcount); while (qdcount-- > 0) { char tname[MAXDNAME+1]; int n, ttype, tclass; n = dn_expand(buf, eom, cp, tname, sizeof tname); if (n < 0) return (-1); cp += n; if (cp + 2 * INT16SZ > eom) return (-1); ttype = ns_get16(cp); cp += INT16SZ; tclass = ns_get16(cp); cp += INT16SZ; if (ttype == type && tclass == class && ns_samename(tname, name) == 1) return (1); } return (0); } /*% * is there a 1:1 mapping of (name,type,class) * in (buf1,eom1) and (buf2,eom2)? * * returns: *\li -1 : format error *\li 0 : not a 1:1 mapping *\li >0 : is a 1:1 mapping * * author: *\li paul vixie, 29may94 */ int res_queriesmatch(const u_char *buf1, const u_char *eom1, const u_char *buf2, const u_char *eom2) { const u_char *cp = buf1 + HFIXEDSZ; int qdcount = ntohs(((const HEADER*)buf1)->qdcount); if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1); /* * Only header section present in replies to * dynamic update packets. */ if ((((const HEADER *)buf1)->opcode == ns_o_update) && (((const HEADER *)buf2)->opcode == ns_o_update)) return (1); if (qdcount != ntohs(((const HEADER*)buf2)->qdcount)) return (0); while (qdcount-- > 0) { char tname[MAXDNAME+1]; int n, ttype, tclass; n = dn_expand(buf1, eom1, cp, tname, sizeof tname); if (n < 0) return (-1); cp += n; if (cp + 2 * INT16SZ > eom1) return (-1); ttype = ns_get16(cp); cp += INT16SZ; tclass = ns_get16(cp); cp += INT16SZ; if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) return (0); } return (1); } int res_nsend(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz) { - int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; + int gotsomewhere, terrno, tries, v_circuit, resplen, ns, n; #ifdef USE_KQUEUE int kq; #endif char abuf[NI_MAXHOST]; /* No name servers or res_init() failure */ if (statp->nscount == 0 || EXT(statp).ext == NULL) { errno = ESRCH; return (-1); } if (anssiz < HFIXEDSZ) { errno = EINVAL; return (-1); } DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), (stdout, ";; res_send()\n"), buf, buflen); v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; gotsomewhere = 0; terrno = ETIMEDOUT; #ifdef USE_KQUEUE if ((kq = kqueue()) < 0) { Perror(statp, stderr, "kqueue", errno); return (-1); } #endif /* * If the ns_addr_list in the resolver context has changed, then * invalidate our cached copy and the associated timing data. */ if (EXT(statp).nscount != 0) { int needclose = 0; struct sockaddr_storage peer; ISC_SOCKLEN_T peerlen; if (EXT(statp).nscount != statp->nscount) needclose++; else for (ns = 0; ns < statp->nscount; ns++) { if (statp->nsaddr_list[ns].sin_family && !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns], (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) { needclose++; break; } if (EXT(statp).nssocks[ns] == -1) continue; peerlen = sizeof(peer); if (_getsockname(EXT(statp).nssocks[ns], (struct sockaddr *)&peer, &peerlen) < 0) { needclose++; break; } if (!sock_eq((struct sockaddr *)&peer, get_nsaddr(statp, ns))) { needclose++; break; } } if (needclose) { res_nclose(statp); EXT(statp).nscount = 0; } } /* * Maybe initialize our private copy of the ns_addr_list. */ if (EXT(statp).nscount == 0) { for (ns = 0; ns < statp->nscount; ns++) { EXT(statp).nstimes[ns] = RES_MAXTIME; EXT(statp).nssocks[ns] = -1; if (!statp->nsaddr_list[ns].sin_family) continue; EXT(statp).ext->nsaddrs[ns].sin = statp->nsaddr_list[ns]; } EXT(statp).nscount = statp->nscount; } /* * Some resolvers want to even out the load on their nameservers. * Note that RES_BLAST overrides RES_ROTATE. */ if ((statp->options & RES_ROTATE) != 0U && (statp->options & RES_BLAST) == 0U) { union res_sockaddr_union inu; struct sockaddr_in ina; int lastns = statp->nscount - 1; int fd; u_int16_t nstime; if (EXT(statp).ext != NULL) inu = EXT(statp).ext->nsaddrs[0]; ina = statp->nsaddr_list[0]; fd = EXT(statp).nssocks[0]; nstime = EXT(statp).nstimes[0]; for (ns = 0; ns < lastns; ns++) { if (EXT(statp).ext != NULL) EXT(statp).ext->nsaddrs[ns] = EXT(statp).ext->nsaddrs[ns + 1]; statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1]; } if (EXT(statp).ext != NULL) EXT(statp).ext->nsaddrs[lastns] = inu; statp->nsaddr_list[lastns] = ina; EXT(statp).nssocks[lastns] = fd; EXT(statp).nstimes[lastns] = nstime; } /* * Send request, RETRY times, or until successful. */ - for (try = 0; try < statp->retry; try++) { + for (tries = 0; tries < statp->retry; tries++) { for (ns = 0; ns < statp->nscount; ns++) { struct sockaddr *nsap; int nsaplen; nsap = get_nsaddr(statp, ns); nsaplen = get_salen(nsap); statp->_flags &= ~RES_F_LASTMASK; statp->_flags |= (ns << RES_F_LASTSHIFT); same_ns: if (statp->qhook) { int done = 0, loops = 0; do { res_sendhookact act; act = (*statp->qhook)(&nsap, &buf, &buflen, ans, anssiz, &resplen); switch (act) { case res_goahead: done = 1; break; case res_nextns: res_nclose(statp); goto next_ns; case res_done: #ifdef USE_KQUEUE _close(kq); #endif return (resplen); case res_modified: /* give the hook another try */ if (++loops < 42) /*doug adams*/ break; /*FALLTHROUGH*/ case res_error: /*FALLTHROUGH*/ default: goto fail; } } while (!done); } Dprint(((statp->options & RES_DEBUG) && getnameinfo(nsap, nsaplen, abuf, sizeof(abuf), NULL, 0, niflags) == 0), (stdout, ";; Querying server (# %d) address = %s\n", ns + 1, abuf)); if (v_circuit) { /* Use VC; at most one attempt per server. */ - try = statp->retry; + tries = statp->retry; n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, ns); if (n < 0) goto fail; if (n == 0) goto next_ns; resplen = n; } else { /* Use datagrams. */ n = send_dg(statp, #ifdef USE_KQUEUE kq, #endif buf, buflen, ans, anssiz, &terrno, - ns, try, &v_circuit, &gotsomewhere); + ns, tries, &v_circuit, &gotsomewhere); if (n < 0) goto fail; if (n == 0) goto next_ns; if (v_circuit) goto same_ns; resplen = n; } Dprint((statp->options & RES_DEBUG) || ((statp->pfcode & RES_PRF_REPLY) && (statp->pfcode & RES_PRF_HEAD1)), (stdout, ";; got answer:\n")); DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, "%s", ""), ans, (resplen > anssiz) ? anssiz : resplen); /* * If we have temporarily opened a virtual circuit, * or if we haven't been asked to keep a socket open, * close the socket. */ if ((v_circuit && (statp->options & RES_USEVC) == 0U) || (statp->options & RES_STAYOPEN) == 0U) { res_nclose(statp); } if (statp->rhook) { int done = 0, loops = 0; do { res_sendhookact act; act = (*statp->rhook)(nsap, buf, buflen, ans, anssiz, &resplen); switch (act) { case res_goahead: case res_done: done = 1; break; case res_nextns: res_nclose(statp); goto next_ns; case res_modified: /* give the hook another try */ if (++loops < 42) /*doug adams*/ break; /*FALLTHROUGH*/ case res_error: /*FALLTHROUGH*/ default: goto fail; } } while (!done); } #ifdef USE_KQUEUE _close(kq); #endif return (resplen); next_ns: ; } /*foreach ns*/ } /*foreach retry*/ res_nclose(statp); #ifdef USE_KQUEUE _close(kq); #endif if (!v_circuit) { if (!gotsomewhere) errno = ECONNREFUSED; /*%< no nameservers found */ else errno = ETIMEDOUT; /*%< no answer obtained */ } else errno = terrno; return (-1); fail: res_nclose(statp); #ifdef USE_KQUEUE _close(kq); #endif return (-1); } /* Private */ static int get_salen(sa) const struct sockaddr *sa; { #ifdef HAVE_SA_LEN /* There are people do not set sa_len. Be forgiving to them. */ if (sa->sa_len) return (sa->sa_len); #endif if (sa->sa_family == AF_INET) return (sizeof(struct sockaddr_in)); else if (sa->sa_family == AF_INET6) return (sizeof(struct sockaddr_in6)); else return (0); /*%< unknown, die on connect */ } /*% * pick appropriate nsaddr_list for use. see res_init() for initialization. */ static struct sockaddr * get_nsaddr(statp, n) res_state statp; size_t n; { if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { /* * - EXT(statp).ext->nsaddrs[n] holds an address that is larger * than struct sockaddr, and * - user code did not update statp->nsaddr_list[n]. */ return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n]; } else { /* * - user code updated statp->nsaddr_list[n], or * - statp->nsaddr_list[n] has the same content as * EXT(statp).ext->nsaddrs[n]. */ return (struct sockaddr *)(void *)&statp->nsaddr_list[n]; } } static int send_vc(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz, int *terrno, int ns) { const HEADER *hp = (const HEADER *) buf; HEADER *anhp = (HEADER *) ans; struct sockaddr *nsap; int nsaplen; int truncating, connreset, resplen, n; struct iovec iov[2]; u_short len; u_char *cp; void *tmp; +#ifdef SO_NOSIGPIPE + int on = 1; +#endif nsap = get_nsaddr(statp, ns); nsaplen = get_salen(nsap); connreset = 0; same_ns: truncating = 0; /* Are we still talking to whom we want to talk to? */ if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { struct sockaddr_storage peer; ISC_SOCKLEN_T size = sizeof peer; if (_getpeername(statp->_vcsock, (struct sockaddr *)&peer, &size) < 0 || !sock_eq((struct sockaddr *)&peer, nsap)) { res_nclose(statp); statp->_flags &= ~RES_F_VC; } } if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { if (statp->_vcsock >= 0) res_nclose(statp); statp->_vcsock = _socket(nsap->sa_family, SOCK_STREAM, 0); #if !defined(USE_POLL) && !defined(USE_KQUEUE) if (statp->_vcsock > highestFD) { res_nclose(statp); errno = ENOTSOCK; } #endif if (statp->_vcsock < 0) { switch (errno) { case EPROTONOSUPPORT: #ifdef EPFNOSUPPORT case EPFNOSUPPORT: #endif case EAFNOSUPPORT: Perror(statp, stderr, "socket(vc)", errno); return (0); default: *terrno = errno; Perror(statp, stderr, "socket(vc)", errno); return (-1); } } +#ifdef SO_NOSIGPIPE + /* + * Disable generation of SIGPIPE when writing to a closed + * socket. Write should return -1 and set errno to EPIPE + * instead. + * + * Push on even if setsockopt(SO_NOSIGPIPE) fails. + */ + (void)_setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on, + sizeof(on)); +#endif errno = 0; if (_connect(statp->_vcsock, nsap, nsaplen) < 0) { *terrno = errno; Aerror(statp, stderr, "connect/vc", errno, nsap, nsaplen); res_nclose(statp); return (0); } statp->_flags |= RES_F_VC; } /* * Send length & message */ ns_put16((u_short)buflen, (u_char*)&len); iov[0] = evConsIovec(&len, INT16SZ); DE_CONST(buf, tmp); iov[1] = evConsIovec(tmp, buflen); if (_writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { *terrno = errno; Perror(statp, stderr, "write failed", errno); res_nclose(statp); return (0); } /* * Receive length & response */ read_len: cp = ans; len = INT16SZ; while ((n = _read(statp->_vcsock, (char *)cp, (int)len)) > 0) { cp += n; if ((len -= n) == 0) break; } if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read failed", errno); res_nclose(statp); /* * A long running process might get its TCP * connection reset if the remote server was * restarted. Requery the server instead of * trying a new one. When there is only one * server, this means that a query might work * instead of failing. We only allow one reset * per query to prevent looping. */ if (*terrno == ECONNRESET && !connreset) { connreset = 1; res_nclose(statp); goto same_ns; } res_nclose(statp); return (0); } resplen = ns_get16(ans); if (resplen > anssiz) { Dprint(statp->options & RES_DEBUG, (stdout, ";; response truncated\n") ); truncating = 1; len = anssiz; } else len = resplen; if (len < HFIXEDSZ) { /* * Undersized message. */ Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", len)); *terrno = EMSGSIZE; res_nclose(statp); return (0); } cp = ans; while (len != 0 && (n = _read(statp->_vcsock, (char *)cp, (int)len)) > 0) { cp += n; len -= n; } if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read(vc)", errno); res_nclose(statp); return (0); } if (truncating) { /* * Flush rest of answer so connection stays in synch. */ anhp->tc = 1; len = resplen - anssiz; while (len != 0) { char junk[PACKETSZ]; n = _read(statp->_vcsock, junk, (len > sizeof junk) ? sizeof junk : len); if (n > 0) len -= n; else break; } } /* * If the calling applicating has bailed out of * a previous call and failed to arrange to have * the circuit closed or the server has got * itself confused, then drop the packet and * wait for the correct one. */ if (hp->id != anhp->id) { DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, ";; old answer (unexpected):\n"), ans, (resplen > anssiz) ? anssiz: resplen); goto read_len; } /* * All is well, or the error is fatal. Signal that the * next nameserver ought not be tried. */ return (resplen); } static int send_dg(res_state statp, #ifdef USE_KQUEUE int kq, #endif const u_char *buf, int buflen, u_char *ans, - int anssiz, int *terrno, int ns, int try, int *v_circuit, + int anssiz, int *terrno, int ns, int tries, int *v_circuit, int *gotsomewhere) { const HEADER *hp = (const HEADER *) buf; HEADER *anhp = (HEADER *) ans; const struct sockaddr *nsap; int nsaplen; struct timespec now, timeout, finish; struct sockaddr_storage from; ISC_SOCKLEN_T fromlen; int resplen, seconds, n, s; #ifdef USE_KQUEUE struct kevent kv; #else #ifdef USE_POLL int polltimeout; struct pollfd pollfd; #else fd_set dsmask; #endif #endif nsap = get_nsaddr(statp, ns); nsaplen = get_salen(nsap); if (EXT(statp).nssocks[ns] == -1) { EXT(statp).nssocks[ns] = _socket(nsap->sa_family, SOCK_DGRAM, 0); #if !defined(USE_POLL) && !defined(USE_KQUEUE) if (EXT(statp).nssocks[ns] > highestFD) { res_nclose(statp); errno = ENOTSOCK; } #endif if (EXT(statp).nssocks[ns] < 0) { switch (errno) { case EPROTONOSUPPORT: #ifdef EPFNOSUPPORT case EPFNOSUPPORT: #endif case EAFNOSUPPORT: Perror(statp, stderr, "socket(dg)", errno); return (0); default: *terrno = errno; Perror(statp, stderr, "socket(dg)", errno); return (-1); } } #ifndef CANNOT_CONNECT_DGRAM /* * On a 4.3BSD+ machine (client and server, * actually), sending to a nameserver datagram * port with no nameserver will cause an * ICMP port unreachable message to be returned. * If our datagram socket is "connected" to the * server, we get an ECONNREFUSED error on the next * socket operation, and select returns if the * error message is received. We can thus detect * the absence of a nameserver without timing out. * * When the option "insecure1" is specified, we'd * rather expect to see responses from an "unknown" * address. In order to let the kernel accept such * responses, do not connect the socket here. * XXX: or do we need an explicit option to disable * connecting? */ if (!(statp->options & RES_INSECURE1) && _connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) { Aerror(statp, stderr, "connect(dg)", errno, nsap, nsaplen); res_nclose(statp); return (0); } #endif /* !CANNOT_CONNECT_DGRAM */ Dprint(statp->options & RES_DEBUG, (stdout, ";; new DG socket\n")) } s = EXT(statp).nssocks[ns]; #ifndef CANNOT_CONNECT_DGRAM if (statp->options & RES_INSECURE1) { if (_sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) { Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); res_nclose(statp); return (0); } } else if (send(s, (const char*)buf, buflen, 0) != buflen) { Perror(statp, stderr, "send", errno); res_nclose(statp); return (0); } #else /* !CANNOT_CONNECT_DGRAM */ if (_sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) { Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); res_nclose(statp); return (0); } #endif /* !CANNOT_CONNECT_DGRAM */ /* * Wait for reply. */ - seconds = (statp->retrans << try); + seconds = (statp->retrans << tries); if (ns > 0) seconds /= statp->nscount; if (seconds <= 0) seconds = 1; now = evNowTime(); timeout = evConsTime(seconds, 0); finish = evAddTime(now, timeout); goto nonow; wait: now = evNowTime(); nonow: #ifndef USE_POLL if (evCmpTime(finish, now) > 0) timeout = evSubTime(finish, now); else timeout = evConsTime(0, 0); #ifdef USE_KQUEUE EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, 0); n = _kevent(kq, &kv, 1, &kv, 1, &timeout); #else FD_ZERO(&dsmask); FD_SET(s, &dsmask); n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL); #endif #else timeout = evSubTime(finish, now); if (timeout.tv_sec < 0) timeout = evConsTime(0, 0); polltimeout = 1000*timeout.tv_sec + timeout.tv_nsec/1000000; pollfd.fd = s; pollfd.events = POLLRDNORM; n = poll(&pollfd, 1, polltimeout); #endif /* USE_POLL */ if (n == 0) { Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); *gotsomewhere = 1; return (0); } if (n < 0) { if (errno == EINTR) goto wait; #ifdef USE_KQUEUE Perror(statp, stderr, "kevent", errno); #else #ifndef USE_POLL Perror(statp, stderr, "select", errno); #else Perror(statp, stderr, "poll", errno); #endif /* USE_POLL */ #endif res_nclose(statp); return (0); } #ifdef USE_KQUEUE if (kv.ident != s) goto wait; #endif errno = 0; fromlen = sizeof(from); resplen = _recvfrom(s, (char*)ans, anssiz,0, (struct sockaddr *)&from, &fromlen); if (resplen <= 0) { Perror(statp, stderr, "recvfrom", errno); res_nclose(statp); return (0); } *gotsomewhere = 1; if (resplen < HFIXEDSZ) { /* * Undersized message. */ Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", resplen)); *terrno = EMSGSIZE; res_nclose(statp); return (0); } if (hp->id != anhp->id) { /* * response from old query, ignore it. * XXX - potential security hazard could * be detected here. */ DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, ";; old answer:\n"), ans, (resplen > anssiz) ? anssiz : resplen); goto wait; } if (!(statp->options & RES_INSECURE1) && !res_ourserver_p(statp, (struct sockaddr *)&from)) { /* * response from wrong server? ignore it. * XXX - potential security hazard could * be detected here. */ DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, ";; not our server:\n"), ans, (resplen > anssiz) ? anssiz : resplen); goto wait; } #ifdef RES_USE_EDNS0 if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) { /* * Do not retry if the server do not understand EDNS0. * The case has to be captured here, as FORMERR packet do not * carry query section, hence res_queriesmatch() returns 0. */ DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query with EDNS0:\n"), ans, (resplen > anssiz) ? anssiz : resplen); /* record the error */ statp->_flags |= RES_F_EDNS0ERR; res_nclose(statp); return (0); } #endif if (!(statp->options & RES_INSECURE2) && !res_queriesmatch(buf, buf + buflen, ans, ans + anssiz)) { /* * response contains wrong query? ignore it. * XXX - potential security hazard could * be detected here. */ DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, ";; wrong query name:\n"), ans, (resplen > anssiz) ? anssiz : resplen); goto wait; } if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || anhp->rcode == REFUSED) { DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query:\n"), ans, (resplen > anssiz) ? anssiz : resplen); res_nclose(statp); /* don't retry if called from dig */ if (!statp->pfcode) return (0); } if (!(statp->options & RES_IGNTC) && anhp->tc) { /* * To get the rest of answer, * use TCP with same server. */ Dprint(statp->options & RES_DEBUG, (stdout, ";; truncated answer\n")); *v_circuit = 1; res_nclose(statp); return (1); } /* * All is well, or the error is fatal. Signal that the * next nameserver ought not be tried. */ return (resplen); } static void Aerror(const res_state statp, FILE *file, const char *string, int error, const struct sockaddr *address, int alen) { int save = errno; char hbuf[NI_MAXHOST]; char sbuf[NI_MAXSERV]; alen = alen; if ((statp->options & RES_DEBUG) != 0U) { if (getnameinfo(address, alen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), niflags)) { strncpy(hbuf, "?", sizeof(hbuf) - 1); hbuf[sizeof(hbuf) - 1] = '\0'; strncpy(sbuf, "?", sizeof(sbuf) - 1); sbuf[sizeof(sbuf) - 1] = '\0'; } fprintf(file, "res_send: %s ([%s].%s): %s\n", string, hbuf, sbuf, strerror(error)); } errno = save; } static void Perror(const res_state statp, FILE *file, const char *string, int error) { int save = errno; if ((statp->options & RES_DEBUG) != 0U) fprintf(file, "res_send: %s: %s\n", string, strerror(error)); errno = save; } static int sock_eq(struct sockaddr *a, struct sockaddr *b) { struct sockaddr_in *a4, *b4; struct sockaddr_in6 *a6, *b6; if (a->sa_family != b->sa_family) return 0; switch (a->sa_family) { case AF_INET: a4 = (struct sockaddr_in *)a; b4 = (struct sockaddr_in *)b; return a4->sin_port == b4->sin_port && a4->sin_addr.s_addr == b4->sin_addr.s_addr; case AF_INET6: a6 = (struct sockaddr_in6 *)a; b6 = (struct sockaddr_in6 *)b; return a6->sin6_port == b6->sin6_port && #ifdef HAVE_SIN6_SCOPE_ID a6->sin6_scope_id == b6->sin6_scope_id && #endif IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr); default: return 0; } } #if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE) /* XXX needs to move to the porting library. */ static int pselect(int nfds, void *rfds, void *wfds, void *efds, struct timespec *tsp, const sigset_t *sigmask) { struct timeval tv, *tvp; sigset_t sigs; int n; if (tsp) { tvp = &tv; tv = evTimeVal(*tsp); } else tvp = NULL; if (sigmask) sigprocmask(SIG_SETMASK, sigmask, &sigs); n = select(nfds, rfds, wfds, efds, tvp); if (sigmask) sigprocmask(SIG_SETMASK, &sigs, NULL); if (tsp) *tsp = evTimeSpec(tv); return (n); } #endif Index: releng/7.1/lib/libc =================================================================== --- releng/7.1/lib/libc (revision 186220) +++ releng/7.1/lib/libc (revision 186221) Property changes on: releng/7.1/lib/libc ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/lib/libc:r186090