Update the resolver in libc to BIND9's one.
Since, res_sendsigned(3) and the friends use MD5 functions, it is hard to include them without having MD5 functions in libc. So, res_sendsigned(3) is not merged into libc. Since, res_update(3) in BIND9 is not binary compatible with our res_update(3), res_update(3) is leaved as is, except some necessary modifications. The res_update(3) and the friends are not essential part of the resolver. They are not defined in resolv.h but defined in res_update.h separately in BIND9. Further, they are not called from our tree. So, I hide them from our resolv.h, but leave them only for binary backward compatibility (perhaps, no one calls them). Since, struct __res_state_ext is not exposed in BIND9, I hide it from our resolv.h. And, global variable _res_ext is removed. It breaks binary backward compatibility. But, since it is not used from outside of our libc, I think it is safe. Reviewed by: arch@ (no objection)
This commit is contained in:
parent
cbfec51a4b
commit
5342d17f09
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=156960
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* ++Copyright++ 1983, 1993
|
||||
* -
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -47,9 +49,13 @@
|
||||
* 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--
|
||||
*/
|
||||
|
||||
/*
|
||||
* @(#)inet.h 8.1 (Berkeley) 6/2/93
|
||||
* From: Id: inet.h,v 8.5 1997/01/29 08:48:09 vixie Exp $
|
||||
* $Id: inet.h,v 1.1.206.1 2004/03/09 08:33:30 marka Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -121,6 +127,8 @@ struct in_addr {
|
||||
#define inet_network __inet_network
|
||||
#define inet_net_ntop __inet_net_ntop
|
||||
#define inet_net_pton __inet_net_pton
|
||||
#define inet_cidr_ntop __inet_cidr_ntop
|
||||
#define inet_cidr_pton __inet_cidr_pton
|
||||
#define inet_ntoa __inet_ntoa
|
||||
#define inet_pton __inet_pton
|
||||
#define inet_ntop __inet_ntop
|
||||
@ -138,7 +146,7 @@ uint16_t ntohs(uint16_t);
|
||||
#endif
|
||||
|
||||
in_addr_t inet_addr(const char *);
|
||||
char *inet_ntoa(struct in_addr);
|
||||
/*const*/ char *inet_ntoa(struct in_addr);
|
||||
const char *inet_ntop(int, const void * __restrict, char * __restrict,
|
||||
socklen_t);
|
||||
int inet_pton(int, const char * __restrict, void * __restrict);
|
||||
@ -154,6 +162,8 @@ in_addr_t inet_netof(struct in_addr);
|
||||
in_addr_t inet_network(const char *);
|
||||
char *inet_net_ntop(int, const void *, int, char *, size_t);
|
||||
int inet_net_pton(int, const char *, void *, size_t);
|
||||
char *inet_cidr_ntop(int, const void *, int, char *, size_t);
|
||||
int inet_cidr_pton(int, const char *, void *, int *);
|
||||
unsigned inet_nsap_addr(const char *, unsigned char *, int);
|
||||
char *inet_nsap_ntoa(int, const unsigned char *, char *);
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
@ -32,24 +32,24 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* From: Id: nameser.h,v 8.16 1998/02/06 00:35:58 halley Exp
|
||||
* $Id: nameser.h,v 1.2.2.4.4.1 2004/03/09 08:33:30 marka Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -58,25 +58,26 @@
|
||||
|
||||
#define BIND_4_COMPAT
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* 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 libnameser.a
|
||||
* is new enough to contain a certain feature.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* XXXRTH I made this bigger than __BIND in 4.9.5 T6B */
|
||||
#define __NAMESER 19961001 /* New interface version stamp. */
|
||||
#define __NAMESER 19991006 /* New interface version stamp. */
|
||||
|
||||
/*
|
||||
* Define constants based on RFC 883, RFC 1034, RFC 1035
|
||||
*/
|
||||
#define NS_PACKETSZ 512 /* maximum packet size */
|
||||
#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 */
|
||||
@ -116,7 +117,7 @@ typedef struct __ns_msg {
|
||||
const u_char *_sections[ns_s_max];
|
||||
ns_sect _sect;
|
||||
int _rrnum;
|
||||
const u_char *_ptr;
|
||||
const u_char *_msg_ptr;
|
||||
} ns_msg;
|
||||
|
||||
/* Private data structure - do not use from outside library. */
|
||||
@ -124,10 +125,7 @@ struct _ns_flagdata { int mask, shift; };
|
||||
extern struct _ns_flagdata _ns_flagdata[];
|
||||
|
||||
/* Accessor macros - this is part of the public interface. */
|
||||
#define ns_msg_getflag(handle, flag) ( \
|
||||
((handle)._flags & _ns_flagdata[flag].mask) \
|
||||
>> _ns_flagdata[flag].shift \
|
||||
)
|
||||
|
||||
#define ns_msg_id(handle) ((handle)._id + 0)
|
||||
#define ns_msg_base(handle) ((handle)._msg + 0)
|
||||
#define ns_msg_end(handle) ((handle)._eom + 0)
|
||||
@ -138,7 +136,7 @@ extern struct _ns_flagdata _ns_flagdata[];
|
||||
* This is a parsed record. It is caller allocated and has no dynamic data.
|
||||
*/
|
||||
typedef struct __ns_rr {
|
||||
char name[NS_MAXDNAME]; /* XXX need to malloc */
|
||||
char name[NS_MAXDNAME];
|
||||
u_int16_t type;
|
||||
u_int16_t rr_class;
|
||||
u_int32_t ttl;
|
||||
@ -148,8 +146,8 @@ typedef struct __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) ((rr).type + 0)
|
||||
#define ns_rr_class(rr) ((rr).rr_class + 0)
|
||||
#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)
|
||||
@ -202,7 +200,13 @@ typedef enum __ns_rcode {
|
||||
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
|
||||
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 */
|
||||
@ -213,31 +217,40 @@ typedef enum __ns_update_operation {
|
||||
} ns_update_operation;
|
||||
|
||||
/*
|
||||
* This RR-like structure is particular to UPDATE.
|
||||
* This structure is used for TSIG authenticated messages
|
||||
*/
|
||||
struct ns_updrec {
|
||||
struct ns_updrec *r_prev; /* prev record */
|
||||
struct ns_updrec *r_next; /* next record */
|
||||
u_int8_t r_section; /* ZONE/PREREQUISITE/UPDATE */
|
||||
char * r_dname; /* owner of the RR */
|
||||
u_int16_t r_class; /* class number */
|
||||
u_int16_t r_type; /* type number */
|
||||
u_int32_t r_ttl; /* time to live */
|
||||
u_char * r_data; /* rdata fields as text string */
|
||||
u_int16_t r_size; /* size of r_data field */
|
||||
int r_opcode; /* type of operation */
|
||||
/* following fields for private use by the resolver/server routines */
|
||||
struct ns_updrec *r_grpnext; /* next record when grouped */
|
||||
struct databuf *r_dp; /* databuf to process */
|
||||
struct databuf *r_deldp; /* databuf's deleted/overwritten */
|
||||
u_int16_t r_zone; /* zone number on server */
|
||||
struct ns_tsig_key {
|
||||
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
|
||||
unsigned char *data;
|
||||
int len;
|
||||
};
|
||||
typedef struct ns_updrec ns_updrec;
|
||||
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. */
|
||||
@ -273,22 +286,42 @@ typedef enum __ns_type {
|
||||
ns_t_srv = 33, /* Server Selection. */
|
||||
ns_t_atma = 34, /* ATM Address */
|
||||
ns_t_naptr = 35, /* Naming Authority PoinTeR */
|
||||
ns_t_opt = 41, /* OPT pseudo-RR, RFC2761 */
|
||||
/* Query type values which do not appear in resource records. */
|
||||
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 (RFC 3123) */
|
||||
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. */
|
||||
/* Class 2 unallocated/unsupported. */
|
||||
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 */
|
||||
@ -297,9 +330,24 @@ typedef enum __ns_class {
|
||||
ns_c_max = 65536
|
||||
} ns_class;
|
||||
|
||||
/*
|
||||
* Flags field of the KEY RR rdata
|
||||
*/
|
||||
/* 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 */
|
||||
@ -308,35 +356,58 @@ typedef enum __ns_class {
|
||||
/* 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_EXPERIMENTAL 0x2000 /* Security is *mandatory* if bit=0 */
|
||||
#define NS_KEY_RESERVED3 0x1000 /* reserved - must be zero */
|
||||
#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_USERACCOUNT 0x0400 /* key is assoc. with a user acct */
|
||||
#define NS_KEY_ENTITY 0x0200 /* key is assoc. with entity eg host */
|
||||
#define NS_KEY_ZONEKEY 0x0100 /* key is zone key */
|
||||
#define NS_KEY_IPSEC 0x0080 /* key is for IPSEC (host or user)*/
|
||||
#define NS_KEY_EMAIL 0x0040 /* key is for email (MIME security) */
|
||||
#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_RESERVED3 | \
|
||||
#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 2552
|
||||
#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 */
|
||||
@ -353,38 +424,43 @@ typedef enum __ns_class {
|
||||
#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.
|
||||
*/
|
||||
#define NS_OPT_DNSSEC_OK 0x8000U
|
||||
|
||||
/*
|
||||
* Inline versions of get/put short/long. Pointer is advanced.
|
||||
*/
|
||||
#define NS_GET16(s, cp) { \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
#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) { \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
#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) { \
|
||||
#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) { \
|
||||
#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; \
|
||||
@ -392,21 +468,27 @@ typedef enum __ns_class {
|
||||
*t_cp++ = t_l >> 8; \
|
||||
*t_cp = t_l; \
|
||||
(cp) += NS_INT32SZ; \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* ANSI C identifier hiding.
|
||||
* 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
|
||||
@ -414,13 +496,31 @@ typedef enum __ns_class {
|
||||
#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
|
||||
#define ns_samedomain __ns_samedomain
|
||||
#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);
|
||||
@ -430,6 +530,10 @@ int ns_sprintrrf(const u_char *, size_t, 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 *,
|
||||
@ -441,6 +545,33 @@ int ns_name_uncompress(const u_char *, const u_char *,
|
||||
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 *);
|
||||
int ns_samedomain(const char *, const char *);
|
||||
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
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
/*
|
||||
* from nameser.h 8.1 (Berkeley) 6/2/93
|
||||
* From: Id: nameser_compat.h,v 8.9 1998/03/20 23:25:10 halley Exp
|
||||
* $Id: nameser_compat.h,v 1.1.2.3.4.2 2004/07/01 04:43:41 marka Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -107,6 +107,7 @@ typedef struct {
|
||||
#define RRFIXEDSZ NS_RRFIXEDSZ
|
||||
#define INT32SZ NS_INT32SZ
|
||||
#define INT16SZ NS_INT16SZ
|
||||
#define INT8SZ NS_INT8SZ
|
||||
#define INADDRSZ NS_INADDRSZ
|
||||
#define IN6ADDRSZ NS_IN6ADDRSZ
|
||||
#define INDIR_MASK NS_CMPRSFLGS
|
||||
@ -134,6 +135,10 @@ typedef struct {
|
||||
#define NXRRSET ns_r_nxrrset
|
||||
#define NOTAUTH ns_r_notauth
|
||||
#define NOTZONE ns_r_notzone
|
||||
/*#define BADSIG ns_r_badsig*/
|
||||
/*#define BADKEY ns_r_badkey*/
|
||||
/*#define BADTIME ns_r_badtime*/
|
||||
|
||||
|
||||
#define DELETE ns_uop_delete
|
||||
#define ADD ns_uop_add
|
||||
@ -173,7 +178,9 @@ typedef struct {
|
||||
#define T_SRV ns_t_srv
|
||||
#define T_ATMA ns_t_atma
|
||||
#define T_NAPTR ns_t_naptr
|
||||
#define T_A6 ns_t_a6
|
||||
#define T_OPT ns_t_opt
|
||||
#define T_TSIG ns_t_tsig
|
||||
#define T_IXFR ns_t_ixfr
|
||||
#define T_AXFR ns_t_axfr
|
||||
#define T_MAILB ns_t_mailb
|
||||
|
@ -87,7 +87,7 @@ typedef __uint32_t uint32_t;
|
||||
#define _PATH_PROTOCOLS "/etc/protocols"
|
||||
#define _PATH_SERVICES "/etc/services"
|
||||
|
||||
#define h_errno (*__h_error())
|
||||
#define h_errno (*__h_errno())
|
||||
|
||||
/*
|
||||
* Structures returned by network data base library. All addresses are
|
||||
@ -257,7 +257,7 @@ void setservent(int);
|
||||
*/
|
||||
|
||||
/* DO NOT USE THESE, THEY ARE SUBJECT TO CHANGE AND ARE NOT PORTABLE!!! */
|
||||
int * __h_error(void);
|
||||
int * __h_errno(void);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_NETDB_H_ */
|
||||
|
428
include/resolv.h
428
include/resolv.h
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1987, 1989, 1993
|
||||
/*
|
||||
* 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
|
||||
@ -32,25 +32,25 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
* 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
|
||||
* From Id: resolv.h,v 8.12 1998/04/28 19:36:46 halley Exp $
|
||||
* $Id: resolv.h,v 1.7.2.11.4.3 2005/08/25 04:44:13 marka Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -62,6 +62,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
/*
|
||||
* Revision information. This is the release date in YYYYMMDD format.
|
||||
@ -71,18 +72,60 @@
|
||||
* is new enough to contain a certain feature.
|
||||
*/
|
||||
|
||||
#define __RES 19960801
|
||||
#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 <resolv.h>.
|
||||
* 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
|
||||
* inital name server(s) to query and the domain search list.
|
||||
* 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.
|
||||
*/
|
||||
@ -92,16 +135,29 @@
|
||||
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
|
||||
|
||||
#define RES_TIMEOUT 5 /* min. seconds between retries */
|
||||
#define RES_DFLRETRY 2 /* retries per each name server */
|
||||
#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; /* retransmition time interval */
|
||||
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 */
|
||||
@ -109,7 +165,11 @@ struct __res_state {
|
||||
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];
|
||||
@ -117,24 +177,55 @@ struct __res_state {
|
||||
struct in_addr addr;
|
||||
u_int32_t mask;
|
||||
} sort_list[MAXRESOLVSORT];
|
||||
char pad[72]; /* on an i386 this means 512b total */
|
||||
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;
|
||||
};
|
||||
|
||||
/* for INET6 */
|
||||
/*
|
||||
* replacement of __res_state, separated to keep binary compatibility.
|
||||
*/
|
||||
struct __res_state_ext {
|
||||
struct sockaddr_storage nsaddr_list[MAXNS];
|
||||
struct {
|
||||
int af; /* address family for addr, mask */
|
||||
union {
|
||||
struct in_addr ina;
|
||||
struct in6_addr in6a;
|
||||
} addr, mask;
|
||||
} sort_list[MAXRESOLVSORT];
|
||||
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)
|
||||
*/
|
||||
@ -152,11 +243,20 @@ struct __res_state_ext {
|
||||
#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_NOTLDQUERY 0x00004000 /* Don't query TLD names */
|
||||
#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_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_EDNS0 0x40000000 /* use EDNS0 */
|
||||
#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)
|
||||
#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | \
|
||||
RES_DNSRCH | RES_NO_NIBBLE2)
|
||||
|
||||
/*
|
||||
* Resolver "pfcode" values. Used by dig.
|
||||
@ -176,93 +276,137 @@ struct __res_state_ext {
|
||||
#define RES_PRF_QUERY 0x00001000
|
||||
#define RES_PRF_REPLY 0x00002000
|
||||
#define RES_PRF_INIT 0x00004000
|
||||
/* 0x00008000 */
|
||||
#define RES_PRF_TRUNC 0x00008000
|
||||
/* 0x00010000 */
|
||||
|
||||
typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
|
||||
res_sendhookact;
|
||||
/* Things involving an internal (static) resolver context. */
|
||||
__BEGIN_DECLS
|
||||
extern struct __res_state *__res_state(void);
|
||||
__END_DECLS
|
||||
#define _res (*__res_state())
|
||||
|
||||
typedef res_sendhookact (*res_send_qhook)(struct sockaddr * const *ns,
|
||||
const u_char **query,
|
||||
int *querylen,
|
||||
u_char *ans,
|
||||
int anssiz,
|
||||
int *resplen);
|
||||
|
||||
typedef res_sendhookact (*res_send_rhook)(const struct sockaddr *ns,
|
||||
const u_char *query,
|
||||
int querylen,
|
||||
u_char *ans,
|
||||
int anssiz,
|
||||
int *resplen);
|
||||
|
||||
struct res_sym {
|
||||
int number; /* Identifying number, like T_MX */
|
||||
char * name; /* Its symbolic name, like "MX" */
|
||||
char * humanname; /* Its fun name, like "mail exchanger" */
|
||||
};
|
||||
#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
|
||||
extern struct __res_state *___res(void);
|
||||
extern struct __res_state_ext *___res_ext(void);
|
||||
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
|
||||
#define _res (*___res())
|
||||
/* for INET6 */
|
||||
#define _res_ext (*___res_ext())
|
||||
#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 */
|
||||
|
||||
/* Private routines shared between libc/net, named, nslookup and others. */
|
||||
#define res_hnok __res_hnok
|
||||
#define res_ownok __res_ownok
|
||||
#define res_mailok __res_mailok
|
||||
#define res_dnok __res_dnok
|
||||
#define sym_ston __sym_ston
|
||||
#define sym_ntos __sym_ntos
|
||||
#define sym_ntop __sym_ntop
|
||||
#define b64_ntop __b64_ntop
|
||||
#define b64_pton __b64_pton
|
||||
#define loc_ntoa __loc_ntoa
|
||||
#define loc_aton __loc_aton
|
||||
#define fp_resstat __fp_resstat
|
||||
#define p_query __p_query
|
||||
#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 fp_query __fp_query
|
||||
#define fp_nquery __fp_nquery
|
||||
#define hostalias __hostalias
|
||||
#define putlong __putlong
|
||||
#define putshort __putshort
|
||||
#define p_class __p_class
|
||||
#define p_time __p_time
|
||||
#define p_type __p_type
|
||||
#define p_query __p_query
|
||||
#define p_cdnname __p_cdnname
|
||||
#define p_section __p_section
|
||||
#define loc_aton __loc_aton
|
||||
#define loc_ntoa __loc_ntoa
|
||||
#define p_cdname __p_cdname
|
||||
#define p_fqnname __p_fqnname
|
||||
#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 dn_count_labels __dn_count_labels
|
||||
#define dn_comp __dn_comp
|
||||
#define dn_expand __dn_expand
|
||||
#define res_init __res_init
|
||||
#define res_randomid __res_randomid
|
||||
#define res_query __res_query
|
||||
#define res_search __res_search
|
||||
#define res_querydomain __res_querydomain
|
||||
#define res_mkquery __res_mkquery
|
||||
#define res_send __res_send
|
||||
#define res_isourserver __res_isourserver
|
||||
#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
|
||||
#define res_findzonecut2 __res_findzonecut2
|
||||
#endif
|
||||
#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_close __res_close
|
||||
#define res_opt __res_opt
|
||||
#define res_mkupdate __res_mkupdate
|
||||
#define res_mkupdrec __res_mkupdrec
|
||||
#define res_freeupdrec __res_freeupdrec
|
||||
|
||||
#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_ndestroy __res_ndestroy
|
||||
#define res_nametoclass __res_nametoclass
|
||||
#define res_nametotype __res_nametotype
|
||||
#define res_setservers __res_setservers
|
||||
#define res_getservers __res_getservers
|
||||
#define res_buildprotolist __res_buildprotolist
|
||||
#define res_destroyprotolist __res_destroyprotolist
|
||||
#define res_destroyservicelist __res_destroyservicelist
|
||||
#if 0
|
||||
#define res_get_nibblesuffix __res_get_nibblesuffix
|
||||
#define res_get_nibblesuffix2 __res_get_nibblesuffix2
|
||||
#endif
|
||||
#define res_ourserver_p __res_ourserver_p
|
||||
#define res_protocolname __res_protocolname
|
||||
#define res_protocolnumber __res_protocolnumber
|
||||
#define res_send_setqhook __res_send_setqhook
|
||||
#define res_send_setrhook __res_send_setrhook
|
||||
#define res_servicename __res_servicename
|
||||
#define res_servicenumber __res_servicenumber
|
||||
__BEGIN_DECLS
|
||||
int res_hnok(const char *);
|
||||
int res_ownok(const char *);
|
||||
@ -276,20 +420,20 @@ 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 fp_resstat(struct __res_state *, FILE *);
|
||||
void fp_query(const u_char *, FILE *);
|
||||
void fp_nquery(const u_char *, int, FILE *);
|
||||
const char * hostalias(const 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);
|
||||
void p_query(const u_char *);
|
||||
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_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);
|
||||
@ -297,35 +441,55 @@ 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);
|
||||
int res_init(void);
|
||||
u_int res_randomid(void);
|
||||
int res_query(const char *, int, int, u_char *, int);
|
||||
int res_search(const char *, int, int, u_char *, int);
|
||||
int res_querydomain(const char *, const char *, int, int,
|
||||
u_char *, int);
|
||||
int res_mkquery(int, const char *, int, int, const u_char *,
|
||||
int, const u_char *, u_char *, int);
|
||||
int res_send(const u_char *, int, u_char *, int);
|
||||
int res_isourserver(const struct sockaddr_in *);
|
||||
int res_nameinquery(const char *, int, int,
|
||||
const u_char *, const u_char *);
|
||||
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 *);
|
||||
void res_close(void);
|
||||
int res_opt(int, u_char *, int, int);
|
||||
const char * p_section(int, int);
|
||||
/* XXX These must be exported for BIND4 compatibility. */
|
||||
void __putlong(u_int32_t, u_char *);
|
||||
void __putshort(u_int16_t, u_char *);
|
||||
u_int32_t _getlong(const u_char *);
|
||||
u_int16_t _getshort(const u_char *);
|
||||
/* XXX The following depend on the ns_updrec typedef in arpa/nameser.h */
|
||||
#ifdef _ARPA_NAMESER_H_
|
||||
int res_update(ns_updrec *);
|
||||
int res_mkupdate(ns_updrec *, u_char *, int);
|
||||
ns_updrec * res_mkupdrec(int, const char *, u_int, u_int, u_long);
|
||||
void res_freeupdrec(ns_updrec *);
|
||||
/* 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);
|
||||
int res_findzonecut2(res_state, const char *, ns_class, int,
|
||||
char *, size_t,
|
||||
union res_sockaddr_union *, int);
|
||||
#endif
|
||||
void res_nclose(res_state);
|
||||
int res_nopt(res_state, int, u_char *, int, int);
|
||||
void res_send_setqhook(res_send_qhook);
|
||||
void res_send_setrhook(res_send_rhook);
|
||||
int __res_vinit(res_state, int);
|
||||
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);
|
||||
#if 0
|
||||
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_ */
|
||||
|
@ -36,7 +36,10 @@ NOASM=
|
||||
.include "${.CURDIR}/gdtoa/Makefile.inc"
|
||||
.include "${.CURDIR}/gen/Makefile.inc"
|
||||
.include "${.CURDIR}/gmon/Makefile.inc"
|
||||
.include "${.CURDIR}/inet/Makefile.inc"
|
||||
.include "${.CURDIR}/isc/Makefile.inc"
|
||||
.include "${.CURDIR}/locale/Makefile.inc"
|
||||
.include "${.CURDIR}/nameser/Makefile.inc"
|
||||
.include "${.CURDIR}/net/Makefile.inc"
|
||||
.include "${.CURDIR}/nls/Makefile.inc"
|
||||
.include "${.CURDIR}/posix1e/Makefile.inc"
|
||||
@ -47,6 +50,7 @@ NOASM=
|
||||
.include "${.CURDIR}/quad/Makefile.inc"
|
||||
.endif
|
||||
.include "${.CURDIR}/regex/Makefile.inc"
|
||||
.include "${.CURDIR}/resolv/Makefile.inc"
|
||||
.include "${.CURDIR}/stdio/Makefile.inc"
|
||||
.include "${.CURDIR}/stdlib/Makefile.inc"
|
||||
.include "${.CURDIR}/stdtime/Makefile.inc"
|
||||
|
@ -10,21 +10,22 @@ SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c eui64.c \
|
||||
getifaddrs.c getifmaddrs.c getnameinfo.c \
|
||||
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
|
||||
getproto.c getprotoent.c getprotoname.c getservbyname.c \
|
||||
getservbyport.c getservent.c herror.c inet_addr.c \
|
||||
if_indextoname.c if_nameindex.c if_nametoindex.c inet_lnaof.c \
|
||||
inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \
|
||||
inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
|
||||
inet_pton.c ip6opt.c linkaddr.c map_v4v6.c name6.c \
|
||||
ns_name.c ns_netint.c ns_parse.c ns_print.c ns_ttl.c \
|
||||
getservbyport.c getservent.c \
|
||||
if_indextoname.c if_nameindex.c if_nametoindex.c \
|
||||
ip6opt.c linkaddr.c map_v4v6.c name6.c \
|
||||
nsdispatch.c nslexer.c nsparser.c nss_compat.c \
|
||||
nsap_addr.c rcmd.c rcmdsh.c recv.c res_comp.c res_data.c res_debug.c \
|
||||
res_init.c res_mkquery.c res_mkupdate.c res_query.c res_send.c \
|
||||
res_update.c rthdr.c send.c sockatmark.c vars.c
|
||||
rcmd.c rcmdsh.c recv.c rthdr.c send.c sockatmark.c vars.c
|
||||
|
||||
# for binary backward compatibility against FreeBSD 6.X and earlier
|
||||
SRCS+= res_mkupdate.c res_update.c
|
||||
|
||||
SYM_MAPS+=${.CURDIR}/net/Symbol.map
|
||||
|
||||
CFLAGS+=-DINET6 -I${.OBJDIR}
|
||||
|
||||
# name6.c refers res_private.h
|
||||
CFLAGS+=-I${.CURDIR}/resolv
|
||||
|
||||
YFLAGS+=-p_nsyy
|
||||
LFLAGS+=-P_nsyy
|
||||
|
||||
|
@ -44,10 +44,6 @@ FBSD_1.0 {
|
||||
setservent;
|
||||
endservent;
|
||||
getservent;
|
||||
#h_nerr; # Why is this not staticized in net/herror.c?
|
||||
h_errlist;
|
||||
herror;
|
||||
hstrerror;
|
||||
hesiod_init;
|
||||
hesiod_end;
|
||||
hesiod_to_bind;
|
||||
@ -62,30 +58,6 @@ FBSD_1.0 {
|
||||
if_nameindex;
|
||||
if_freenameindex;
|
||||
if_nametoindex;
|
||||
__inet_addr;
|
||||
__inet_aton;
|
||||
inet_addr;
|
||||
inet_aton;
|
||||
__inet_lnaof;
|
||||
inet_lnaof;
|
||||
__inet_makeaddr;
|
||||
inet_makeaddr;
|
||||
__inet_net_ntop;
|
||||
inet_net_ntop;
|
||||
__inet_net_pton;
|
||||
inet_net_pton;
|
||||
__inet_neta;
|
||||
inet_neta;
|
||||
__inet_netof;
|
||||
inet_netof;
|
||||
__inet_network;
|
||||
inet_network;
|
||||
__inet_ntoa;
|
||||
inet_ntoa;
|
||||
__inet_ntop;
|
||||
inet_ntop;
|
||||
__inet_pton;
|
||||
inet_pton;
|
||||
inet6_option_space;
|
||||
inet6_option_init;
|
||||
inet6_option_append;
|
||||
@ -104,28 +76,6 @@ FBSD_1.0 {
|
||||
getipnodebyname;
|
||||
getipnodebyaddr;
|
||||
freehostent;
|
||||
__ns_name_ntop;
|
||||
__ns_name_pton;
|
||||
__ns_name_unpack;
|
||||
__ns_name_pack;
|
||||
__ns_name_uncompress;
|
||||
__ns_name_compress;
|
||||
__ns_name_skip;
|
||||
__ns_get16;
|
||||
__ns_get32;
|
||||
__ns_put16;
|
||||
__ns_put32;
|
||||
__ns_initparse;
|
||||
__ns_parserr;
|
||||
_ns_flagdata;
|
||||
__ns_sprintrr;
|
||||
__ns_sprintrrf;
|
||||
__ns_format_ttl;
|
||||
__ns_parse_ttl;
|
||||
__inet_nsap_addr;
|
||||
__inet_nsap_ntoa;
|
||||
inet_nsap_addr;
|
||||
inet_nsap_ntoa;
|
||||
__nsdefaultsrc;
|
||||
_nsdbtaddsrc;
|
||||
_nsdbtdump;
|
||||
@ -140,77 +90,10 @@ FBSD_1.0 {
|
||||
iruserok_sa;
|
||||
rcmdsh;
|
||||
recv;
|
||||
__dn_expand;
|
||||
__dn_comp;
|
||||
__dn_skipname;
|
||||
__res_hnok;
|
||||
__res_ownok;
|
||||
__res_mailok;
|
||||
__res_dnok;
|
||||
__putlong;
|
||||
__putshort;
|
||||
_getlong;
|
||||
_getshort;
|
||||
dn_comp;
|
||||
dn_expand;
|
||||
__fp_resstat;
|
||||
__p_query;
|
||||
__fp_query;
|
||||
__fp_nquery;
|
||||
__p_cdnname;
|
||||
__p_cdname;
|
||||
__p_fqnname;
|
||||
__p_fqname;
|
||||
__p_class_syms;
|
||||
__p_type_syms;
|
||||
__sym_ston;
|
||||
__sym_ntos;
|
||||
__sym_ntop;
|
||||
__p_type;
|
||||
__p_section;
|
||||
__p_class;
|
||||
__p_option;
|
||||
__p_time;
|
||||
__loc_aton;
|
||||
__loc_ntoa;
|
||||
__dn_count_labels;
|
||||
__p_secstodate;
|
||||
fp_resstat;
|
||||
p_query;
|
||||
p_fqnname;
|
||||
sym_ston;
|
||||
sym_ntos;
|
||||
sym_ntop;
|
||||
dn_count_labels;
|
||||
p_secstodate;
|
||||
__res_init;
|
||||
__res_randomid;
|
||||
___res;
|
||||
___res_ext;
|
||||
__h_error;
|
||||
h_errno;
|
||||
res_init;
|
||||
__res_mkquery;
|
||||
res_mkquery;
|
||||
__res_opt;
|
||||
__res_mkupdate;
|
||||
__res_mkupdrec;
|
||||
__res_freeupdrec;
|
||||
__res_query;
|
||||
__res_search;
|
||||
__res_querydomain;
|
||||
__hostalias;
|
||||
res_query;
|
||||
res_search;
|
||||
res_querydomain;
|
||||
__res_isourserver;
|
||||
__res_nameinquery;
|
||||
__res_queriesmatch;
|
||||
__res_send;
|
||||
__res_close;
|
||||
_res_close;
|
||||
res_send;
|
||||
res_update; # Why is this not __res_update?
|
||||
#__res_mkupdate; # Obsoleted
|
||||
#__res_mkupdrec; # Obsoleted
|
||||
#__res_freeupdrec; # Obsoleted
|
||||
#res_update; # Obsoleted Why is this not __res_update?
|
||||
inet6_rthdr_space;
|
||||
inet6_rthdr_init;
|
||||
inet6_rthdr_add;
|
||||
|
@ -265,9 +265,9 @@ static struct policyqueue *match_addrselectpolicy(struct sockaddr *,
|
||||
static int matchlen(struct sockaddr *, struct sockaddr *);
|
||||
|
||||
static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
|
||||
const struct addrinfo *);
|
||||
const struct addrinfo *, res_state);
|
||||
#if defined(RESOLVSORT)
|
||||
static int addr4sort(struct addrinfo *);
|
||||
static int addr4sort(struct addrinfo *, res_state);
|
||||
#endif
|
||||
static int _dns_getaddrinfo(void *, void *, va_list);
|
||||
static void _sethtent(FILE **);
|
||||
@ -280,10 +280,10 @@ static struct addrinfo *_yphostent(char *, const struct addrinfo *);
|
||||
static int _yp_getaddrinfo(void *, void *, va_list);
|
||||
#endif
|
||||
|
||||
static int res_queryN(const char *, struct res_target *);
|
||||
static int res_searchN(const char *, struct res_target *);
|
||||
static int res_queryN(const char *, struct res_target *, res_state);
|
||||
static int res_searchN(const char *, struct res_target *, res_state);
|
||||
static int res_querydomainN(const char *, const char *,
|
||||
struct res_target *);
|
||||
struct res_target *, res_state);
|
||||
|
||||
/* XXX macros that make external reference is BAD. */
|
||||
|
||||
@ -1628,12 +1628,13 @@ static const char AskedForGot[] =
|
||||
#endif
|
||||
|
||||
static struct addrinfo *
|
||||
getanswer(answer, anslen, qname, qtype, pai)
|
||||
getanswer(answer, anslen, qname, qtype, pai, res)
|
||||
const querybuf *answer;
|
||||
int anslen;
|
||||
const char *qname;
|
||||
int qtype;
|
||||
const struct addrinfo *pai;
|
||||
res_state res;
|
||||
{
|
||||
struct addrinfo sentinel, *cur;
|
||||
struct addrinfo ai;
|
||||
@ -1674,12 +1675,12 @@ getanswer(answer, anslen, qname, qtype, pai)
|
||||
ep = hostbuf + sizeof hostbuf;
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (qdcount != 1) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
cp += n + QFIXEDSZ;
|
||||
@ -1690,7 +1691,7 @@ getanswer(answer, anslen, qname, qtype, pai)
|
||||
*/
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
canonname = bp;
|
||||
@ -1817,10 +1818,10 @@ getanswer(answer, anslen, qname, qtype, pai)
|
||||
* We support only IPv4 address for backward
|
||||
* compatibility against gethostbyname(3).
|
||||
*/
|
||||
if (_res.nsort && qtype == T_A) {
|
||||
if (addr4sort(&sentinel) < 0) {
|
||||
if (res->nsort && qtype == T_A) {
|
||||
if (addr4sort(&sentinel, res) < 0) {
|
||||
freeaddrinfo(sentinel.ai_next);
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1829,11 +1830,11 @@ getanswer(answer, anslen, qname, qtype, pai)
|
||||
(void)get_canonname(pai, sentinel.ai_next, qname);
|
||||
else
|
||||
(void)get_canonname(pai, sentinel.ai_next, canonname);
|
||||
h_errno = NETDB_SUCCESS;
|
||||
RES_SET_H_ERRNO(res, NETDB_SUCCESS);
|
||||
return sentinel.ai_next;
|
||||
}
|
||||
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1844,7 +1845,7 @@ struct addr_ptr {
|
||||
};
|
||||
|
||||
static int
|
||||
addr4sort(struct addrinfo *sentinel)
|
||||
addr4sort(struct addrinfo *sentinel, res_state res)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
struct addr_ptr *addrs, addr;
|
||||
@ -1864,9 +1865,9 @@ addr4sort(struct addrinfo *sentinel)
|
||||
i = 0;
|
||||
for (ai = sentinel->ai_next; ai; ai = ai->ai_next) {
|
||||
sin = (struct sockaddr_in *)ai->ai_addr;
|
||||
for (j = 0; (unsigned)j < _res.nsort; j++) {
|
||||
if (_res.sort_list[j].addr.s_addr ==
|
||||
(sin->sin_addr.s_addr & _res.sort_list[j].mask))
|
||||
for (j = 0; (unsigned)j < res->nsort; j++) {
|
||||
if (res->sort_list[j].addr.s_addr ==
|
||||
(sin->sin_addr.s_addr & res->sort_list[j].mask))
|
||||
break;
|
||||
}
|
||||
addrs[i].ai = ai;
|
||||
@ -1916,6 +1917,7 @@ _dns_getaddrinfo(rv, cb_data, ap)
|
||||
const struct addrinfo *pai;
|
||||
struct addrinfo sentinel, *cur;
|
||||
struct res_target q, q2;
|
||||
res_state res;
|
||||
|
||||
hostname = va_arg(ap, char *);
|
||||
pai = va_arg(ap, const struct addrinfo *);
|
||||
@ -1927,13 +1929,13 @@ _dns_getaddrinfo(rv, cb_data, ap)
|
||||
|
||||
buf = malloc(sizeof(*buf));
|
||||
if (!buf) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(res, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
buf2 = malloc(sizeof(*buf2));
|
||||
if (!buf2) {
|
||||
free(buf);
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(res, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
|
||||
@ -1970,27 +1972,36 @@ _dns_getaddrinfo(rv, cb_data, ap)
|
||||
free(buf2);
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
if (res_searchN(hostname, &q) < 0) {
|
||||
|
||||
res = __res_state();
|
||||
if ((res->options & RES_INIT) == 0 && res_ninit(res) == -1) {
|
||||
RES_SET_H_ERRNO(res, NETDB_INTERNAL);
|
||||
free(buf);
|
||||
free(buf2);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
|
||||
if (res_searchN(hostname, &q, res) < 0) {
|
||||
free(buf);
|
||||
free(buf2);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
/* prefer IPv6 */
|
||||
if (q.next) {
|
||||
ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
|
||||
ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai, res);
|
||||
if (ai) {
|
||||
cur->ai_next = ai;
|
||||
while (cur && cur->ai_next)
|
||||
cur = cur->ai_next;
|
||||
}
|
||||
}
|
||||
ai = getanswer(buf, q.n, q.name, q.qtype, pai);
|
||||
ai = getanswer(buf, q.n, q.name, q.qtype, pai, res);
|
||||
if (ai)
|
||||
cur->ai_next = ai;
|
||||
free(buf);
|
||||
free(buf2);
|
||||
if (sentinel.ai_next == NULL)
|
||||
switch (h_errno) {
|
||||
switch (res->res_h_errno) {
|
||||
case HOST_NOT_FOUND:
|
||||
return NS_NOTFOUND;
|
||||
case TRY_AGAIN:
|
||||
@ -2261,7 +2272,7 @@ _yp_getaddrinfo(rv, cb_data, ap)
|
||||
}
|
||||
|
||||
if (sentinel.ai_next == NULL) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(__res_state(), HOST_NOT_FOUND);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
*((struct addrinfo **)rv) = sentinel.ai_next;
|
||||
@ -2271,8 +2282,6 @@ _yp_getaddrinfo(rv, cb_data, ap)
|
||||
|
||||
/* resolver logic */
|
||||
|
||||
extern const char *_res_hostalias(const char *, char *, size_t);
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and await answer.
|
||||
* Returned answer is placed in supplied buffer "answer".
|
||||
@ -2284,9 +2293,10 @@ extern const char *_res_hostalias(const char *, char *, size_t);
|
||||
* Caller must parse answer and determine whether it answers the question.
|
||||
*/
|
||||
static int
|
||||
res_queryN(name, target)
|
||||
res_queryN(name, target, res)
|
||||
const char *name; /* domain name */
|
||||
struct res_target *target;
|
||||
res_state res;
|
||||
{
|
||||
u_char *buf;
|
||||
HEADER *hp;
|
||||
@ -2300,7 +2310,7 @@ res_queryN(name, target)
|
||||
|
||||
buf = malloc(MAXPACKET);
|
||||
if (!buf) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2318,32 +2328,32 @@ res_queryN(name, target)
|
||||
answer = t->answer;
|
||||
anslen = t->anslen;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
if (res->options & RES_DEBUG)
|
||||
printf(";; res_query(%s, %d, %d)\n", name, class, type);
|
||||
#endif
|
||||
|
||||
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
|
||||
n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL,
|
||||
buf, MAXPACKET);
|
||||
if (n > 0 && (_res.options & RES_USE_EDNS0) != 0)
|
||||
n = res_opt(n, buf, MAXPACKET, anslen);
|
||||
if (n > 0 && (res->options & RES_USE_EDNS0) != 0)
|
||||
n = res_nopt(res, n, buf, MAXPACKET, anslen);
|
||||
if (n <= 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
if (res->options & RES_DEBUG)
|
||||
printf(";; res_query: mkquery failed\n");
|
||||
#endif
|
||||
free(buf);
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return (n);
|
||||
}
|
||||
n = res_send(buf, n, answer, anslen);
|
||||
n = res_nsend(res, buf, n, answer, anslen);
|
||||
#if 0
|
||||
if (n < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
if (res->options & RES_DEBUG)
|
||||
printf(";; res_query: send error\n");
|
||||
#endif
|
||||
free(buf);
|
||||
h_errno = TRY_AGAIN;
|
||||
RES_SET_H_ERRNO(res, TRY_AGAIN);
|
||||
return (n);
|
||||
}
|
||||
#endif
|
||||
@ -2353,7 +2363,7 @@ res_queryN(name, target)
|
||||
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
|
||||
rcode = hp->rcode; /* record most recent error */
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
if (res->options & RES_DEBUG)
|
||||
printf(";; rcode = %u, ancount=%u\n", hp->rcode,
|
||||
ntohs(hp->ancount));
|
||||
#endif
|
||||
@ -2370,19 +2380,19 @@ res_queryN(name, target)
|
||||
if (ancount == 0) {
|
||||
switch (rcode) {
|
||||
case NXDOMAIN:
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(res, HOST_NOT_FOUND);
|
||||
break;
|
||||
case SERVFAIL:
|
||||
h_errno = TRY_AGAIN;
|
||||
RES_SET_H_ERRNO(res, TRY_AGAIN);
|
||||
break;
|
||||
case NOERROR:
|
||||
h_errno = NO_DATA;
|
||||
RES_SET_H_ERRNO(res, NO_DATA);
|
||||
break;
|
||||
case FORMERR:
|
||||
case NOTIMP:
|
||||
case REFUSED:
|
||||
default:
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
break;
|
||||
}
|
||||
return (-1);
|
||||
@ -2397,9 +2407,10 @@ res_queryN(name, target)
|
||||
* is detected. Error code, if any, is left in h_errno.
|
||||
*/
|
||||
static int
|
||||
res_searchN(name, target)
|
||||
res_searchN(name, target, res)
|
||||
const char *name; /* domain name */
|
||||
struct res_target *target;
|
||||
res_state res;
|
||||
{
|
||||
const char *cp, * const *domain;
|
||||
HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/
|
||||
@ -2410,13 +2421,8 @@ res_searchN(name, target)
|
||||
int searched = 0;
|
||||
char abuf[MAXDNAME];
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
h_errno = HOST_NOT_FOUND; /* default, if we never query */
|
||||
RES_SET_H_ERRNO(res, HOST_NOT_FOUND); /* default, if we never query */
|
||||
dots = 0;
|
||||
for (cp = name; *cp; cp++)
|
||||
dots += (*cp == '.');
|
||||
@ -2427,8 +2433,9 @@ res_searchN(name, target)
|
||||
/*
|
||||
* if there aren't any dots, it could be a user-level alias
|
||||
*/
|
||||
if (!dots && (cp = _res_hostalias(name, abuf, sizeof(abuf))) != NULL)
|
||||
return (res_queryN(cp, target));
|
||||
if (!dots &&
|
||||
(cp = res_hostalias(res, name, abuf, sizeof(abuf))) != NULL)
|
||||
return (res_queryN(cp, target, res));
|
||||
|
||||
/*
|
||||
* If there are enough dots in the name, let's just give it a
|
||||
@ -2436,22 +2443,22 @@ res_searchN(name, target)
|
||||
* Also, query 'as is', if there is a trailing dot in the name.
|
||||
*/
|
||||
saved_herrno = -1;
|
||||
if (dots >= _res.ndots || trailing_dot) {
|
||||
ret = res_querydomainN(name, NULL, target);
|
||||
if (dots >= res->ndots || trailing_dot) {
|
||||
ret = res_querydomainN(name, NULL, target, res);
|
||||
if (ret > 0 || trailing_dot)
|
||||
return (ret);
|
||||
if (errno == ECONNREFUSED) {
|
||||
h_errno = TRY_AGAIN;
|
||||
RES_SET_H_ERRNO(res, TRY_AGAIN);
|
||||
return (-1);
|
||||
}
|
||||
switch (h_errno) {
|
||||
switch (res->res_h_errno) {
|
||||
case NO_DATA:
|
||||
case HOST_NOT_FOUND:
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
saved_herrno = h_errno;
|
||||
saved_herrno = res->res_h_errno;
|
||||
tried_as_is++;
|
||||
}
|
||||
|
||||
@ -2461,11 +2468,11 @@ res_searchN(name, target)
|
||||
* - there is at least one dot, there is no trailing dot,
|
||||
* and RES_DNSRCH is set.
|
||||
*/
|
||||
if ((!dots && (_res.options & RES_DEFNAMES)) ||
|
||||
(dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
|
||||
if ((!dots && (res->options & RES_DEFNAMES)) ||
|
||||
(dots && !trailing_dot && (res->options & RES_DNSRCH))) {
|
||||
int done = 0;
|
||||
|
||||
for (domain = (const char * const *)_res.dnsrch;
|
||||
for (domain = (const char * const *)res->dnsrch;
|
||||
*domain && !done;
|
||||
domain++) {
|
||||
searched = 1;
|
||||
@ -2477,7 +2484,7 @@ res_searchN(name, target)
|
||||
if (root_on_list && tried_as_is)
|
||||
continue;
|
||||
|
||||
ret = res_querydomainN(name, *domain, target);
|
||||
ret = res_querydomainN(name, *domain, target, res);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
|
||||
@ -2495,11 +2502,11 @@ res_searchN(name, target)
|
||||
* fully-qualified.
|
||||
*/
|
||||
if (errno == ECONNREFUSED) {
|
||||
h_errno = TRY_AGAIN;
|
||||
RES_SET_H_ERRNO(res, TRY_AGAIN);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
switch (h_errno) {
|
||||
switch (res->res_h_errno) {
|
||||
case NO_DATA:
|
||||
got_nodata++;
|
||||
/* FALLTHROUGH */
|
||||
@ -2521,12 +2528,12 @@ res_searchN(name, target)
|
||||
* if we got here for some reason other than DNSRCH,
|
||||
* we only wanted one iteration of the loop, so stop.
|
||||
*/
|
||||
if (!(_res.options & RES_DNSRCH))
|
||||
if (!(res->options & RES_DNSRCH))
|
||||
done++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (h_errno) {
|
||||
switch (res->res_h_errno) {
|
||||
case NO_DATA:
|
||||
case HOST_NOT_FOUND:
|
||||
break;
|
||||
@ -2538,9 +2545,9 @@ res_searchN(name, target)
|
||||
* 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 || !(_res.options & RES_NOTLDQUERY)) &&
|
||||
if ((dots || !searched || !(res->options & RES_NOTLDQUERY)) &&
|
||||
!(tried_as_is || root_on_list)) {
|
||||
ret = res_querydomainN(name, NULL, target);
|
||||
ret = res_querydomainN(name, NULL, target, res);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
}
|
||||
@ -2555,11 +2562,11 @@ res_searchN(name, target)
|
||||
*/
|
||||
giveup:
|
||||
if (saved_herrno != -1)
|
||||
h_errno = saved_herrno;
|
||||
RES_SET_H_ERRNO(res, saved_herrno);
|
||||
else if (got_nodata)
|
||||
h_errno = NO_DATA;
|
||||
RES_SET_H_ERRNO(res, NO_DATA);
|
||||
else if (got_servfail)
|
||||
h_errno = TRY_AGAIN;
|
||||
RES_SET_H_ERRNO(res, TRY_AGAIN);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -2568,16 +2575,17 @@ res_searchN(name, target)
|
||||
* removing a trailing dot from name if domain is NULL.
|
||||
*/
|
||||
static int
|
||||
res_querydomainN(name, domain, target)
|
||||
res_querydomainN(name, domain, target, res)
|
||||
const char *name, *domain;
|
||||
struct res_target *target;
|
||||
res_state res;
|
||||
{
|
||||
char nbuf[MAXDNAME];
|
||||
const char *longname = nbuf;
|
||||
size_t n, d;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
if (res->options & RES_DEBUG)
|
||||
printf(";; res_querydomain(%s, %s)\n",
|
||||
name, domain?domain:"<Nil>");
|
||||
#endif
|
||||
@ -2588,7 +2596,7 @@ res_querydomainN(name, domain, target)
|
||||
*/
|
||||
n = strlen(name);
|
||||
if (n >= MAXDNAME) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
if (n > 0 && name[--n] == '.') {
|
||||
@ -2600,10 +2608,10 @@ res_querydomainN(name, domain, target)
|
||||
n = strlen(name);
|
||||
d = strlen(domain);
|
||||
if (n + d + 1 >= MAXDNAME) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(res, NO_RECOVERY);
|
||||
return (-1);
|
||||
}
|
||||
snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
|
||||
}
|
||||
return (res_queryN(longname, target));
|
||||
return (res_queryN(longname, target, res));
|
||||
}
|
||||
|
@ -88,11 +88,11 @@ static const char AskedForGot[] =
|
||||
"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
static void addrsort(char **, int);
|
||||
static void addrsort(char **, int, res_state);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void dprintf(char *, int) __printflike(1, 0);
|
||||
static void dprintf(char *, int, res_state) __printflike(1, 0);
|
||||
#endif
|
||||
|
||||
#define MAXPACKET (64*1024)
|
||||
@ -111,11 +111,12 @@ int _dns_ttl_;
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
dprintf(msg, num)
|
||||
dprintf(msg, num, res)
|
||||
char *msg;
|
||||
int num;
|
||||
res_state res;
|
||||
{
|
||||
if (_res.options & RES_DEBUG) {
|
||||
if (res->options & RES_DEBUG) {
|
||||
int save = errno;
|
||||
|
||||
printf(msg, num);
|
||||
@ -123,14 +124,14 @@ dprintf(msg, num)
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define dprintf(msg, num) /*nada*/
|
||||
# define dprintf(msg, num, res) /*nada*/
|
||||
#endif
|
||||
|
||||
#define BOUNDED_INCR(x) \
|
||||
do { \
|
||||
cp += x; \
|
||||
if (cp > eom) { \
|
||||
h_errno = NO_RECOVERY; \
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
@ -138,7 +139,7 @@ dprintf(msg, num)
|
||||
#define BOUNDS_CHECK(ptr, count) \
|
||||
do { \
|
||||
if ((ptr) + (count) > eom) { \
|
||||
h_errno = NO_RECOVERY; \
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
@ -171,7 +172,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
name_ok = res_dnok;
|
||||
break;
|
||||
default:
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1; /* XXX should be abort(); */
|
||||
}
|
||||
/*
|
||||
@ -185,12 +186,12 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
cp = answer->buf;
|
||||
BOUNDED_INCR(HFIXEDSZ);
|
||||
if (qdcount != 1) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
BOUNDED_INCR(n + QFIXEDSZ);
|
||||
@ -201,7 +202,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
*/
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
he->h_name = bp;
|
||||
@ -252,7 +253,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
}
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
/* Store alias. */
|
||||
@ -282,7 +283,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
}
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
/* Get canonical name. */
|
||||
@ -321,7 +322,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
#if MULTI_PTRS_ARE_ALIASES
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
if (!haveanswer)
|
||||
@ -341,7 +342,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
break;
|
||||
#else
|
||||
he->h_name = bp;
|
||||
if (_res.options & RES_USE_INET6) {
|
||||
if (hed->res->options & RES_USE_INET6) {
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
@ -350,7 +351,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
bp += n;
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
}
|
||||
h_errno = NETDB_SUCCESS;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
#endif
|
||||
case T_A:
|
||||
@ -376,14 +377,14 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
bp += sizeof(align) - ((u_long)bp % sizeof(align));
|
||||
|
||||
if (bp + n >= ep) {
|
||||
dprintf("size (%d) too big\n", n);
|
||||
dprintf("size (%d) too big\n", n, hed->res);
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
if (hap >= &hed->h_addr_ptrs[_MAXADDRS-1]) {
|
||||
if (!toobig++)
|
||||
dprintf("Too many addresses (%d)\n",
|
||||
_MAXADDRS);
|
||||
_MAXADDRS, hed->res);
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
@ -391,13 +392,14 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
bp += n;
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dprintf("Impossible condition (type=%d)\n", type);
|
||||
h_errno = NO_RECOVERY;
|
||||
dprintf("Impossible condition (type=%d)\n", type,
|
||||
hed->res);
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
/* BIND has abort() here, too risky on bad data */
|
||||
}
|
||||
@ -413,8 +415,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
* in its return structures - should give it the "best"
|
||||
* address in that case, not some random one
|
||||
*/
|
||||
if (_res.nsort && haveanswer > 1 && qtype == T_A)
|
||||
addrsort(hed->h_addr_ptrs, haveanswer);
|
||||
if (hed->res->nsort && haveanswer > 1 && qtype == T_A)
|
||||
addrsort(hed->h_addr_ptrs, haveanswer, hed->res);
|
||||
# endif /*RESOLVSORT*/
|
||||
if (!he->h_name) {
|
||||
n = strlen(qname) + 1; /* for the \0 */
|
||||
@ -424,13 +426,13 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
he->h_name = bp;
|
||||
bp += n;
|
||||
}
|
||||
if (_res.options & RES_USE_INET6)
|
||||
if (hed->res->options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
h_errno = NETDB_SUCCESS;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
no_recovery:
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -440,11 +442,14 @@ __dns_getanswer(const char *answer, int anslen, const char *qname, int qtype)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NULL;
|
||||
}
|
||||
hd->data.res = statp;
|
||||
switch (qtype) {
|
||||
case T_AAAA:
|
||||
hd->host.h_addrtype = AF_INET6;
|
||||
@ -487,7 +492,7 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
type = T_AAAA;
|
||||
break;
|
||||
default:
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
@ -496,17 +501,17 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
he->h_length = size;
|
||||
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
n = res_search(name, C_IN, type, buf->buf, sizeof(buf->buf));
|
||||
n = res_nsearch(hed->res, name, C_IN, type, buf->buf, sizeof(buf->buf));
|
||||
if (n < 0) {
|
||||
free(buf);
|
||||
dprintf("res_search failed (%d)\n", n);
|
||||
dprintf("res_nsearch failed (%d)\n", n, hed->res);
|
||||
return (0);
|
||||
} else if (n > sizeof(buf->buf)) {
|
||||
free(buf);
|
||||
dprintf("static buffer is too small (%d)\n", n);
|
||||
dprintf("static buffer is too small (%d)\n", n, hed->res);
|
||||
return (0);
|
||||
}
|
||||
error = gethostanswer(buf, n, name, type, he, hed);
|
||||
@ -538,10 +543,6 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
(void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
|
||||
@ -563,18 +564,19 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
abort();
|
||||
}
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf->buf, sizeof buf->buf);
|
||||
n = res_nquery(hed->res, qbuf, C_IN, T_PTR, (u_char *)buf->buf,
|
||||
sizeof buf->buf);
|
||||
if (n < 0) {
|
||||
free(buf);
|
||||
dprintf("res_query failed (%d)\n", n);
|
||||
dprintf("res_nquery failed (%d)\n", n, hed->res);
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
if (n > sizeof buf->buf) {
|
||||
free(buf);
|
||||
dprintf("static buffer is too small (%d)\n", n);
|
||||
dprintf("static buffer is too small (%d)\n", n, hed->res);
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
if ((error = gethostanswer(buf, n, qbuf, T_PTR, he, hed)) != 0) {
|
||||
@ -590,9 +592,9 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
*/
|
||||
strncpy(hname2, he->h_name, MAXDNAME);
|
||||
hname2[MAXDNAME] = '\0';
|
||||
old_options = _res.options;
|
||||
_res.options &= ~RES_DNSRCH;
|
||||
_res.options |= RES_DEFNAMES;
|
||||
old_options = hed->res->options;
|
||||
hed->res->options &= ~RES_DNSRCH;
|
||||
hed->res->options |= RES_DEFNAMES;
|
||||
memset(&rhd, 0, sizeof rhd);
|
||||
if (!(rhe = gethostbyname_r(hname2, &rhd.host, &rhd.data))) {
|
||||
if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
|
||||
@ -600,11 +602,11 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostbyaddr: No A record for %s (verifying [%s])",
|
||||
hname2, numaddr);
|
||||
_res.options = old_options;
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
hed->res->options = old_options;
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
_res.options = old_options;
|
||||
hed->res->options = old_options;
|
||||
for (haddr = rhe->h_addr_list; *haddr; haddr++)
|
||||
if (!memcmp(*haddr, addr, INADDRSZ))
|
||||
break;
|
||||
@ -614,7 +616,7 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostbyaddr: A record of %s != PTR record [%s]",
|
||||
hname2, numaddr);
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
@ -624,20 +626,21 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
memcpy(hed->host_addr, uaddr, len);
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
if (af == AF_INET && (_res.options & RES_USE_INET6)) {
|
||||
if (af == AF_INET && (hed->res->options & RES_USE_INET6)) {
|
||||
_map_v4v6_address((char*)hed->host_addr, (char*)hed->host_addr);
|
||||
he->h_addrtype = AF_INET6;
|
||||
he->h_length = IN6ADDRSZ;
|
||||
}
|
||||
h_errno = NETDB_SUCCESS;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
}
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
static void
|
||||
addrsort(ap, num)
|
||||
addrsort(ap, num, res)
|
||||
char **ap;
|
||||
int num;
|
||||
res_state res;
|
||||
{
|
||||
int i, j;
|
||||
char **p;
|
||||
@ -646,9 +649,9 @@ addrsort(ap, num)
|
||||
|
||||
p = ap;
|
||||
for (i = 0; i < num; i++, p++) {
|
||||
for (j = 0 ; (unsigned)j < _res.nsort; j++)
|
||||
if (_res.sort_list[j].addr.s_addr ==
|
||||
(((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
|
||||
for (j = 0 ; (unsigned)j < res->nsort; j++)
|
||||
if (res->sort_list[j].addr.s_addr ==
|
||||
(((struct in_addr *)(*p))->s_addr & res->sort_list[j].mask))
|
||||
break;
|
||||
aval[i] = j;
|
||||
if (needsort == 0 && i > 0 && j < aval[i-1])
|
||||
@ -677,19 +680,26 @@ addrsort(ap, num)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_sethostdnsent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1)
|
||||
return;
|
||||
if (stayopen)
|
||||
_res.options |= RES_STAYOPEN | RES_USEVC;
|
||||
statp->options |= RES_STAYOPEN | RES_USEVC;
|
||||
}
|
||||
|
||||
void
|
||||
_endhostdnsent()
|
||||
{
|
||||
_res.options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_close();
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
statp->options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_nclose(statp);
|
||||
}
|
||||
|
@ -99,12 +99,12 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped)
|
||||
char hostbuf[BUFSIZ + 1];
|
||||
|
||||
if (!hed->hostf && !(hed->hostf = fopen(_PATH_HOSTS, "r"))) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
again:
|
||||
if (!(p = fgets(hostbuf, sizeof hostbuf, hed->hostf))) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
if (*p == '#')
|
||||
@ -146,7 +146,7 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped)
|
||||
*p++ = '\0';
|
||||
len = strlen(cp) + 1;
|
||||
if (ep - bp < len) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
@ -170,14 +170,19 @@ gethostent_p(struct hostent *he, struct hostent_data *hed, int mapped)
|
||||
cp = p;
|
||||
}
|
||||
*q = NULL;
|
||||
h_errno = NETDB_SUCCESS;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gethostent_r(struct hostent *he, struct hostent_data *hed)
|
||||
{
|
||||
return gethostent_p(he, hed, _res.options & RES_USE_INET6);
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
return gethostent_p(he, hed, hed->res->options & RES_USE_INET6);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
@ -212,7 +217,7 @@ _ht_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
if (he->h_addrtype != af)
|
||||
continue;
|
||||
if (he->h_addrtype == AF_INET &&
|
||||
_res.options & RES_USE_INET6) {
|
||||
hed->res->options & RES_USE_INET6) {
|
||||
_map_v4v6_address(he->h_addr, he->h_addr);
|
||||
he->h_length = IN6ADDRSZ;
|
||||
he->h_addrtype = AF_INET6;
|
||||
@ -248,7 +253,7 @@ _ht_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
while ((error = gethostent_p(he, hed, 0)) == 0)
|
||||
if (he->h_addrtype == af && !bcmp(he->h_addr, addr, len)) {
|
||||
if (he->h_addrtype == AF_INET &&
|
||||
_res.options & RES_USE_INET6) {
|
||||
hed->res->options & RES_USE_INET6) {
|
||||
_map_v4v6_address(he->h_addr, he->h_addr);
|
||||
he->h_length = IN6ADDRSZ;
|
||||
he->h_addrtype = AF_INET6;
|
||||
|
@ -67,19 +67,19 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hed->yp_domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&hed->yp_domain)) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
|
||||
&resultlen)) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
|
||||
if (addrok != 1)
|
||||
break;
|
||||
if (_res.options & RES_USE_INET6) {
|
||||
if (hed->res->options & RES_USE_INET6) {
|
||||
_map_v4v6_address((char *)hed->host_addr,
|
||||
(char *)hed->host_addr);
|
||||
af = AF_INET6;
|
||||
@ -113,7 +113,7 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
break;
|
||||
}
|
||||
if (addrok != 1) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
he->h_addr_list[1] = NULL;
|
||||
@ -130,7 +130,7 @@ _gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
*p++ = '\0';
|
||||
size = strlen(cp) + 1;
|
||||
if (ep - bp < size) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(hed->res, NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
@ -204,15 +204,18 @@ _gethostbynisname(const char *name, int af)
|
||||
struct hostdata *hd;
|
||||
u_long oresopt;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NULL;
|
||||
}
|
||||
oresopt = _res.options;
|
||||
_res.options &= ~RES_USE_INET6;
|
||||
hd->data.res = statp;
|
||||
oresopt = statp->options;
|
||||
statp->options &= ~RES_USE_INET6;
|
||||
error = _gethostbynisname_r(name, af, &hd->host, &hd->data);
|
||||
_res.options = oresopt;
|
||||
statp->options = oresopt;
|
||||
return (error == 0) ? &hd->host : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
@ -226,15 +229,18 @@ _gethostbynisaddr(const char *addr, int len, int af)
|
||||
struct hostdata *hd;
|
||||
u_long oresopt;
|
||||
int error;
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NULL;
|
||||
}
|
||||
oresopt = _res.options;
|
||||
_res.options &= ~RES_USE_INET6;
|
||||
hd->data.res = statp;
|
||||
oresopt = statp->options;
|
||||
statp->options &= ~RES_USE_INET6;
|
||||
error = _gethostbynisaddr_r(addr, len, af, &hd->host, &hd->data);
|
||||
_res.options = oresopt;
|
||||
statp->options = oresopt;
|
||||
return (error == 0) ? &hd->host : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
|
@ -51,7 +51,6 @@ extern int _nis_gethostbyname(void *, void *, va_list);
|
||||
extern int _ht_gethostbyaddr(void *, void *, va_list);
|
||||
extern int _dns_gethostbyaddr(void *, void *, va_list);
|
||||
extern int _nis_gethostbyaddr(void *, void *, va_list);
|
||||
extern const char *_res_hostalias(const char *, char *, size_t);
|
||||
|
||||
static int gethostbyname_internal(const char *, int, struct hostent *,
|
||||
struct hostent_data *);
|
||||
@ -112,11 +111,12 @@ gethostbyname_r(const char *name, struct hostent *he, struct hostent_data *hed)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
if (_res.options & RES_USE_INET6) {
|
||||
if (hed->res->options & RES_USE_INET6) {
|
||||
error = gethostbyname_internal(name, AF_INET6, he, hed);
|
||||
if (error == 0)
|
||||
return 0;
|
||||
@ -128,8 +128,9 @@ int
|
||||
gethostbyname2_r(const char *name, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
return gethostbyname_internal(name, af, he, hed);
|
||||
@ -159,7 +160,7 @@ gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
@ -173,7 +174,7 @@ gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
* function that looks up host names.
|
||||
*/
|
||||
if (!strchr(name, '.') &&
|
||||
(cp = _res_hostalias(name, abuf, sizeof abuf)))
|
||||
(cp = res_hostalias(hed->res, name, abuf, sizeof abuf)))
|
||||
name = cp;
|
||||
|
||||
/*
|
||||
@ -191,7 +192,8 @@ gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, hed->host_addr) <= 0) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(hed->res,
|
||||
HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
@ -204,9 +206,9 @@ gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
if (_res.options & RES_USE_INET6)
|
||||
if (hed->res->options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(he, &bp, ep);
|
||||
h_errno = NETDB_SUCCESS;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
if (!isdigit((u_char)*cp) && *cp != '.')
|
||||
@ -224,7 +226,8 @@ gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, hed->host_addr) <= 0) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(hed->res,
|
||||
HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
@ -235,7 +238,7 @@ gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
h_errno = NETDB_SUCCESS;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
if (!isxdigit((u_char)*cp) && *cp != ':' && *cp != '.')
|
||||
@ -264,15 +267,16 @@ gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
hed->res = __res_state();
|
||||
if ((hed->res->options & RES_INIT) == 0 && res_ninit(hed->res) == -1) {
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ) {
|
||||
addr6 = (const struct in6_addr *)(const void *)uaddr;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(addr6)) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(addr6) ||
|
||||
@ -292,12 +296,12 @@ gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
if (size != len) {
|
||||
errno = EINVAL;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -85,8 +85,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include "netdb_private.h"
|
||||
#include "res_config.h"
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
#define BYADDR 0
|
||||
#define BYNAME 1
|
||||
|
||||
@ -160,7 +158,7 @@ ipreverse(char *in, char *out)
|
||||
|
||||
static int
|
||||
getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
struct netent_data *ned)
|
||||
struct netent_data *ned, res_state statp)
|
||||
{
|
||||
|
||||
HEADER *hp;
|
||||
@ -195,9 +193,9 @@ getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (!qdcount) {
|
||||
if (hp->aa)
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
|
||||
else
|
||||
h_errno = TRY_AGAIN;
|
||||
RES_SET_H_ERRNO(statp, TRY_AGAIN);
|
||||
return -1;
|
||||
}
|
||||
while (qdcount-- > 0)
|
||||
@ -243,14 +241,14 @@ getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
in = *ne->n_aliases;
|
||||
n = strlen(ans) + 1;
|
||||
if (ep - bp < n) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, ans, ep - bp);
|
||||
ne->n_name = bp;
|
||||
if (strlen(in) + 1 > sizeof(aux)) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
@ -261,7 +259,7 @@ getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
|
||||
ne->n_aliases++;
|
||||
return 0;
|
||||
}
|
||||
h_errno = TRY_AGAIN;
|
||||
RES_SET_H_ERRNO(statp, TRY_AGAIN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -277,6 +275,7 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME];
|
||||
uint32_t net2;
|
||||
res_state statp;
|
||||
|
||||
net = va_arg(ap, uint32_t);
|
||||
net_type = va_arg(ap, int);
|
||||
@ -286,6 +285,12 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
if (net_type != AF_INET)
|
||||
return NS_UNAVAIL;
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
|
||||
for (nn = 4, net2 = net; net2; net2 >>= 8)
|
||||
netbr[--nn] = net2 & 0xff;
|
||||
switch (nn) {
|
||||
@ -305,26 +310,27 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
break;
|
||||
}
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)buf, sizeof(*buf));
|
||||
anslen = res_nquery(statp, qbuf, C_IN, T_PTR, (u_char *)buf,
|
||||
sizeof(*buf));
|
||||
if (anslen < 0) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_search failed\n");
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_nsearch failed\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
} else if (anslen > sizeof(*buf)) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_search static buffer too small\n");
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_nsearch static buffer too small\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
error = getnetanswer(buf, anslen, BYADDR, ne, ned);
|
||||
error = getnetanswer(buf, anslen, BYADDR, ne, ned, statp);
|
||||
free(buf);
|
||||
if (error == 0) {
|
||||
/* Strip trailing zeros */
|
||||
@ -345,38 +351,41 @@ _dns_getnetbyname(void *rval, void *cb_data, va_list ap)
|
||||
int anslen, error;
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME];
|
||||
res_state statp;
|
||||
|
||||
net = va_arg(ap, const char *);
|
||||
ne = va_arg(ap, struct netent *);
|
||||
ned = va_arg(ap, struct netent_data *);
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
if ((buf = malloc(sizeof(*buf))) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
strncpy(qbuf, net, sizeof(qbuf) - 1);
|
||||
qbuf[sizeof(qbuf) - 1] = '\0';
|
||||
anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)buf, sizeof(*buf));
|
||||
anslen = res_nsearch(statp, qbuf, C_IN, T_PTR, (u_char *)buf,
|
||||
sizeof(*buf));
|
||||
if (anslen < 0) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_search failed\n");
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_nsearch failed\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
} else if (anslen > sizeof(*buf)) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
if (statp->options & RES_DEBUG)
|
||||
printf("res_search static buffer too small\n");
|
||||
#endif
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
error = getnetanswer(buf, anslen, BYNAME, ne, ned);
|
||||
error = getnetanswer(buf, anslen, BYNAME, ne, ned, statp);
|
||||
free(buf);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
}
|
||||
@ -385,13 +394,21 @@ void
|
||||
_setnetdnsent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1)
|
||||
return;
|
||||
if (stayopen)
|
||||
_res.options |= RES_STAYOPEN | RES_USEVC;
|
||||
statp->options |= RES_STAYOPEN | RES_USEVC;
|
||||
}
|
||||
|
||||
void
|
||||
_endnetdnsent()
|
||||
{
|
||||
_res.options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_close();
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
statp->options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_nclose(statp);
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
@ -111,7 +112,7 @@ getnetent_r(struct netent *ne, struct netent_data *ned)
|
||||
*cp++ = '\0';
|
||||
len = strlen(p) + 1;
|
||||
if (ep - bp < len) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, p, ep - bp);
|
||||
|
@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@ -88,7 +89,7 @@ _getnetbynis(const char *name, char *map, int af, struct netent *ne,
|
||||
ep = ned->netbuf + sizeof ned->netbuf;
|
||||
len = strlen(result) + 1;
|
||||
if (ep - bp < len) {
|
||||
h_errno = NO_RECOVERY;
|
||||
RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, result, ep - bp);
|
||||
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1987, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
const char *h_errlist[] = {
|
||||
"Resolver Error 0 (no error)",
|
||||
"Unknown host", /* 1 HOST_NOT_FOUND */
|
||||
"Host name lookup failure", /* 2 TRY_AGAIN */
|
||||
"Unknown server error", /* 3 NO_RECOVERY */
|
||||
"No address associated with name", /* 4 NO_ADDRESS */
|
||||
};
|
||||
const int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
|
||||
|
||||
/*
|
||||
* herror --
|
||||
* print the error indicated by the h_errno value.
|
||||
*/
|
||||
void
|
||||
herror(s)
|
||||
const char *s;
|
||||
{
|
||||
struct iovec iov[4];
|
||||
struct iovec *v = iov;
|
||||
|
||||
if (s && *s) {
|
||||
v->iov_base = (char *)s;
|
||||
v->iov_len = strlen(s);
|
||||
v++;
|
||||
v->iov_base = ": ";
|
||||
v->iov_len = 2;
|
||||
v++;
|
||||
}
|
||||
v->iov_base = (char *)hstrerror(h_errno);
|
||||
v->iov_len = strlen(v->iov_base);
|
||||
v++;
|
||||
v->iov_base = "\n";
|
||||
v->iov_len = 1;
|
||||
_writev(STDERR_FILENO, iov, (v - iov) + 1);
|
||||
}
|
||||
|
||||
const char *
|
||||
hstrerror(err)
|
||||
int err;
|
||||
{
|
||||
if (err < 0)
|
||||
return ("Resolver internal error");
|
||||
else if (err < h_nerr)
|
||||
return (h_errlist[err]);
|
||||
return ("Unknown resolver error");
|
||||
}
|
||||
|
||||
#undef h_errno
|
||||
int h_errno;
|
@ -1,200 +0,0 @@
|
||||
/* $KAME: inet_addr.c,v 1.5 2001/08/20 02:32:40 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* ++Copyright++ 1983, 1990, 1993
|
||||
* -
|
||||
* Copyright (c) 1983, 1990, 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.
|
||||
* -
|
||||
* 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--
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* ASCII internet address interpretation routine.
|
||||
* The value returned is in network order.
|
||||
*/
|
||||
in_addr_t /* XXX should be struct in_addr :( */
|
||||
inet_addr(cp)
|
||||
const char *cp;
|
||||
{
|
||||
struct in_addr val;
|
||||
|
||||
if (inet_aton(cp, &val))
|
||||
return (val.s_addr);
|
||||
return (INADDR_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether "cp" is a valid ASCII representation
|
||||
* of an Internet address and convert to a binary address.
|
||||
* Returns 1 if the address is valid, 0 if not.
|
||||
* This replaces inet_addr, the return value from which
|
||||
* cannot distinguish between failure and a local broadcast address.
|
||||
*/
|
||||
int
|
||||
inet_aton(cp, addr)
|
||||
const char *cp;
|
||||
struct in_addr *addr;
|
||||
{
|
||||
u_long parts[4];
|
||||
in_addr_t val;
|
||||
char *c;
|
||||
char *endptr;
|
||||
int gotend, n;
|
||||
|
||||
c = (char *)cp;
|
||||
n = 0;
|
||||
/*
|
||||
* Run through the string, grabbing numbers until
|
||||
* the end of the string, or some error
|
||||
*/
|
||||
gotend = 0;
|
||||
while (!gotend) {
|
||||
errno = 0;
|
||||
val = strtoul(c, &endptr, 0);
|
||||
|
||||
if (errno == ERANGE) /* Fail completely if it overflowed. */
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* If the whole string is invalid, endptr will equal
|
||||
* c.. this way we can make sure someone hasn't
|
||||
* gone '.12' or something which would get past
|
||||
* the next check.
|
||||
*/
|
||||
if (endptr == c)
|
||||
return (0);
|
||||
parts[n] = val;
|
||||
c = endptr;
|
||||
|
||||
/* Check the next character past the previous number's end */
|
||||
switch (*c) {
|
||||
case '.' :
|
||||
/* Make sure we only do 3 dots .. */
|
||||
if (n == 3) /* Whoops. Quit. */
|
||||
return (0);
|
||||
n++;
|
||||
c++;
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
gotend = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isspace((unsigned char)*c)) {
|
||||
gotend = 1;
|
||||
break;
|
||||
} else
|
||||
return (0); /* Invalid character, so fail */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
|
||||
switch (n) {
|
||||
case 0: /* a -- 32 bits */
|
||||
/*
|
||||
* Nothing is necessary here. Overflow checking was
|
||||
* already done in strtoul().
|
||||
*/
|
||||
break;
|
||||
case 1: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffff || parts[0] > 0xff)
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 2: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
|
||||
parts[2] > 0xff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
}
|
||||
|
||||
if (addr != NULL)
|
||||
addr->s_addr = htonl(val);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_addr
|
||||
__weak_reference(__inet_addr, inet_addr);
|
||||
#undef inet_aton
|
||||
__weak_reference(__inet_aton, inet_aton);
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* Return the local network address portion of an
|
||||
* internet address; handles class a/b/c network
|
||||
* number formats.
|
||||
*/
|
||||
in_addr_t
|
||||
inet_lnaof(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
in_addr_t i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return ((i)&IN_CLASSA_HOST);
|
||||
else if (IN_CLASSB(i))
|
||||
return ((i)&IN_CLASSB_HOST);
|
||||
else
|
||||
return ((i)&IN_CLASSC_HOST);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_lnaof
|
||||
__weak_reference(__inet_lnaof, inet_lnaof);
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* Formulate an Internet address from network + host. Used in
|
||||
* building addresses stored in the ifnet structure.
|
||||
*/
|
||||
struct in_addr
|
||||
inet_makeaddr(net, host)
|
||||
in_addr_t net, host;
|
||||
{
|
||||
in_addr_t addr;
|
||||
|
||||
if (net < 128)
|
||||
addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
|
||||
else if (net < 65536)
|
||||
addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
|
||||
else if (net < 16777216L)
|
||||
addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
|
||||
else
|
||||
addr = net | host;
|
||||
addr = htonl(addr);
|
||||
return (*(struct in_addr *)&addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_makeaddr
|
||||
__weak_reference(__inet_makeaddr, inet_makeaddr);
|
@ -1,281 +0,0 @@
|
||||
/*
|
||||
* 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 orig_rcsid[] = "From Id: inet_net_ntop.c,v 1.1.2.1.8.1 2004/03/09 08:33:32 marka Exp";
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
static char * inet_net_ntop_ipv4(const u_char *src, int bits, char *dst,
|
||||
size_t size);
|
||||
static char * inet_net_ntop_ipv6(const u_char *src, int bits, char *dst,
|
||||
size_t size);
|
||||
|
||||
/*
|
||||
* char *
|
||||
* inet_net_ntop(af, src, bits, dst, size)
|
||||
* convert network number from network to presentation format.
|
||||
* generates CIDR style result always.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_net_ntop(af, src, bits, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_net_ntop_ipv4(src, bits, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_net_ntop_ipv6(src, bits, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* static char *
|
||||
* inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
* convert IPv4 network number from network to presentation format.
|
||||
* generates CIDR style result always.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0b11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
static char *
|
||||
inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
const u_char *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
u_int m;
|
||||
int b;
|
||||
|
||||
if (bits < 0 || bits > 32) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (bits == 0) {
|
||||
if (size < sizeof "0")
|
||||
goto emsgsize;
|
||||
*dst++ = '0';
|
||||
size--;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Format whole octets. */
|
||||
for (b = bits / 8; b > 0; b--) {
|
||||
if (size <= sizeof "255.")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
if (b > 1) {
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
|
||||
/* Format partial octet. */
|
||||
b = bits % 8;
|
||||
if (b > 0) {
|
||||
if (size <= sizeof ".255")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
if (dst != odst)
|
||||
*dst++ = '.';
|
||||
m = ((1 << b) - 1) << (8 - b);
|
||||
dst += SPRINTF((dst, "%u", *src & m));
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
|
||||
/* Format CIDR /width. */
|
||||
if (size <= sizeof "/32")
|
||||
goto emsgsize;
|
||||
dst += SPRINTF((dst, "/%u", bits));
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* static char *
|
||||
* inet_net_ntop_ipv6(src, bits, fakebits, dst, size)
|
||||
* convert IPv6 network number from network to presentation format.
|
||||
* generates CIDR style result always. Picks the shortest representation
|
||||
* unless the IP is really IPv4.
|
||||
* always prints specified number of bits (bits).
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0b11110000 in its fourth octet.
|
||||
* author:
|
||||
* Vadim Kogan (UCB), June 2001
|
||||
* Original version (IPv4) by Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
|
||||
static char *
|
||||
inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
|
||||
u_int m;
|
||||
int b;
|
||||
int p;
|
||||
int zero_s, zero_l, tmp_zero_s, tmp_zero_l;
|
||||
int i;
|
||||
int is_ipv4 = 0;
|
||||
unsigned char inbuf[16];
|
||||
char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
|
||||
char *cp;
|
||||
int words;
|
||||
u_char *s;
|
||||
|
||||
if (bits < 0 || bits > 128) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
cp = outbuf;
|
||||
|
||||
if (bits == 0) {
|
||||
*cp++ = ':';
|
||||
*cp++ = ':';
|
||||
*cp = '\0';
|
||||
} else {
|
||||
/* Copy src to private buffer. Zero host part. */
|
||||
p = (bits + 7) / 8;
|
||||
memcpy(inbuf, src, p);
|
||||
memset(inbuf + p, 0, 16 - p);
|
||||
b = bits % 8;
|
||||
if (b != 0) {
|
||||
m = ~0 << (8 - b);
|
||||
inbuf[p-1] &= m;
|
||||
}
|
||||
|
||||
s = inbuf;
|
||||
|
||||
/* how many words need to be displayed in output */
|
||||
words = (bits + 15) / 16;
|
||||
if (words == 1)
|
||||
words = 2;
|
||||
|
||||
/* Find the longest substring of zero's */
|
||||
zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0;
|
||||
for (i = 0; i < (words * 2); i += 2) {
|
||||
if ((s[i] | s[i+1]) == 0) {
|
||||
if (tmp_zero_l == 0)
|
||||
tmp_zero_s = i / 2;
|
||||
tmp_zero_l++;
|
||||
} else {
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l) {
|
||||
zero_s = tmp_zero_s;
|
||||
zero_l = tmp_zero_l;
|
||||
tmp_zero_l = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l) {
|
||||
zero_s = tmp_zero_s;
|
||||
zero_l = tmp_zero_l;
|
||||
}
|
||||
|
||||
if (zero_l != words && zero_s == 0 && ((zero_l == 6) ||
|
||||
((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
|
||||
((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
|
||||
is_ipv4 = 1;
|
||||
|
||||
/* Format whole words. */
|
||||
for (p = 0; p < words; p++) {
|
||||
if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) {
|
||||
/* Time to skip some zeros */
|
||||
if (p == zero_s)
|
||||
*cp++ = ':';
|
||||
if (p == words - 1)
|
||||
*cp++ = ':';
|
||||
s++;
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_ipv4 && p > 5 ) {
|
||||
*cp++ = (p == 6) ? ':' : '.';
|
||||
cp += SPRINTF((cp, "%u", *s++));
|
||||
/* we can potentially drop the last octet */
|
||||
if (p != 7 || bits > 120) {
|
||||
*cp++ = '.';
|
||||
cp += SPRINTF((cp, "%u", *s++));
|
||||
}
|
||||
} else {
|
||||
if (cp != outbuf)
|
||||
*cp++ = ':';
|
||||
cp += SPRINTF((cp, "%x", *s * 256 + s[1]));
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Format CIDR /width. */
|
||||
SPRINTF((cp, "/%u", bits));
|
||||
if (strlen(outbuf) + 1 > size)
|
||||
goto emsgsize;
|
||||
strcpy(dst, outbuf);
|
||||
|
||||
return (dst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_net_ntop
|
||||
__weak_reference(__inet_net_ntop, inet_net_ntop);
|
@ -1,410 +0,0 @@
|
||||
/*
|
||||
* 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 orig_rcsid[] = "From Id: inet_net_pton.c,v 1.4.2.1.8.2 2004/03/17 00:29:47 marka Exp";
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.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;
|
||||
} 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 <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_net_pton
|
||||
__weak_reference(__inet_net_pton, inet_net_pton);
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp";
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* char *
|
||||
* inet_neta(src, dst, size)
|
||||
* format an in_addr_t network number into presentation format.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* format of ``src'' is as for inet_network().
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_neta(src, dst, size)
|
||||
in_addr_t src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
char *odst = dst;
|
||||
char *tp;
|
||||
|
||||
while (src & 0xffffffff) {
|
||||
u_char b = (src & 0xff000000) >> 24;
|
||||
|
||||
src <<= 8;
|
||||
if (b) {
|
||||
if (size < sizeof "255.")
|
||||
goto emsgsize;
|
||||
tp = dst;
|
||||
dst += SPRINTF((dst, "%u", b));
|
||||
if (src != 0L) {
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - tp);
|
||||
}
|
||||
}
|
||||
if (dst == odst) {
|
||||
if (size < sizeof "0.0.0.0")
|
||||
goto emsgsize;
|
||||
strcpy(dst, "0.0.0.0");
|
||||
}
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_neta
|
||||
__weak_reference(__inet_neta, inet_neta);
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* Internet network address interpretation routine.
|
||||
* The library routines call this routine to interpret
|
||||
* network numbers.
|
||||
*/
|
||||
in_addr_t
|
||||
inet_network(cp)
|
||||
const char *cp;
|
||||
{
|
||||
in_addr_t val, base, n;
|
||||
char c;
|
||||
in_addr_t parts[4], *pp = parts;
|
||||
int i;
|
||||
|
||||
again:
|
||||
val = 0; base = 10;
|
||||
if (*cp == '0')
|
||||
base = 8, cp++;
|
||||
if (*cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
while ((c = *cp) != 0) {
|
||||
if (isdigit((unsigned char)c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (base == 16 && isxdigit((unsigned char)c)) {
|
||||
val = (val << 4) + (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*cp == '.') {
|
||||
if (pp >= parts + 3)
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val, cp++;
|
||||
goto again;
|
||||
}
|
||||
if (*cp && !isspace((unsigned char)*cp))
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val;
|
||||
n = pp - parts;
|
||||
for (val = 0, i = 0; i < n; i++) {
|
||||
val <<= 8;
|
||||
val |= parts[i] & 0xff;
|
||||
}
|
||||
return (val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_network
|
||||
__weak_reference(__inet_network, inet_network);
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Convert network-format internet address
|
||||
* to base 256 d.d.d.d representation.
|
||||
*/
|
||||
char *
|
||||
inet_ntoa(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
static char ret[18];
|
||||
|
||||
strcpy(ret, "[inet_ntoa error]");
|
||||
(void) inet_ntop(AF_INET, &in, ret, sizeof ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_ntoa
|
||||
__weak_reference(__inet_ntoa, inet_ntoa);
|
@ -1,188 +0,0 @@
|
||||
/* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char rcsid[] = "$Id: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size);
|
||||
static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size);
|
||||
|
||||
/* char *
|
||||
* inet_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
inet_ntop(int af, const void * __restrict src, char * __restrict dst,
|
||||
socklen_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address, more or less like inet_ntoa()
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a u_char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(const u_char *src, char *dst, socklen_t size)
|
||||
{
|
||||
static const char fmt[] = "%u.%u.%u.%u";
|
||||
|
||||
if ((socklen_t)snprintf(dst, size, fmt, src[0], src[1], src[2], src[3])
|
||||
>= size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop6(const u_char *src, char *dst, socklen_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += sprintf(tp, "%x", words[i]);
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((socklen_t)(tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_ntop
|
||||
__weak_reference(__inet_ntop, inet_ntop);
|
@ -1,219 +0,0 @@
|
||||
/* $KAME: inet_pton.c,v 1.5 2001/08/20 02:32:40 itojun Exp $ */
|
||||
|
||||
/* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, u_char *dst);
|
||||
static int inet_pton6(const char *src, u_char *dst);
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(int af, const char * __restrict src, void * __restrict dst)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(const char *src, u_char *dst)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
u_char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
u_int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (! saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(const char *src, u_char *dst)
|
||||
{
|
||||
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;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 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 (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
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)
|
||||
return (0);
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_pton
|
||||
__weak_reference(__inet_pton, inet_pton);
|
@ -122,6 +122,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "un-namespace.h"
|
||||
#include "netdb_private.h"
|
||||
#include "res_config.h"
|
||||
#include "res_private.h"
|
||||
|
||||
#ifndef _PATH_HOSTS
|
||||
#define _PATH_HOSTS "/etc/hosts"
|
||||
@ -199,18 +200,18 @@ struct hp_order {
|
||||
char *aio_h_addr;
|
||||
};
|
||||
|
||||
static struct hostent *_hpcopy(struct hostent *hp, int *errp);
|
||||
static struct hostent *_hpaddr(int af, const char *name, void *addr, int *errp);
|
||||
static struct hostent *_hpmerge(struct hostent *hp1, struct hostent *hp2, int *errp);
|
||||
static struct hostent *_hpcopy(struct hostent *, int *);
|
||||
static struct hostent *_hpaddr(int, const char *, void *, int *);
|
||||
static struct hostent *_hpmerge(struct hostent *, struct hostent *, int *);
|
||||
#ifdef INET6
|
||||
static struct hostent *_hpmapv6(struct hostent *hp, int *errp);
|
||||
static struct hostent *_hpmapv6(struct hostent *, int *);
|
||||
#endif
|
||||
static struct hostent *_hpsort(struct hostent *hp);
|
||||
static struct hostent *_ghbyname(const char *name, int af, int flags, int *errp);
|
||||
static char *_hgetword(char **pp);
|
||||
static struct hostent *_hpsort(struct hostent *, res_state);
|
||||
static struct hostent *_ghbyname(const char *, int, int, int *);
|
||||
static char *_hgetword(char **);
|
||||
static int _mapped_addr_enabled(void);
|
||||
|
||||
static struct hostent *_hpreorder(struct hostent *hp);
|
||||
static struct hostent *_hpreorder(struct hostent *);
|
||||
static int get_addrselectpolicy(struct policyhead *);
|
||||
static void free_addrselectpolicy(struct policyhead *);
|
||||
static struct policyqueue *match_addrselectpolicy(struct sockaddr *,
|
||||
@ -220,7 +221,7 @@ static int matchlen(struct sockaddr *, struct sockaddr *);
|
||||
static int comp_dst(const void *, const void *);
|
||||
static int gai_addr2scopetype(struct sockaddr *);
|
||||
|
||||
static FILE *_files_open(int *errp);
|
||||
static FILE *_files_open(int *);
|
||||
static int _files_ghbyname(void *, void *, va_list);
|
||||
static int _files_ghbyaddr(void *, void *, va_list);
|
||||
#ifdef YP
|
||||
@ -229,7 +230,7 @@ static int _nis_ghbyaddr(void *, void *, va_list);
|
||||
#endif
|
||||
static int _dns_ghbyname(void *, void *, va_list);
|
||||
static int _dns_ghbyaddr(void *, void *, va_list);
|
||||
static void _dns_shent(int stayopen) __unused;
|
||||
static void _dns_shent(int) __unused;
|
||||
static void _dns_ehent(void) __unused;
|
||||
#ifdef ICMPNL
|
||||
static int _icmp_ghbyaddr(void *, void *, va_list);
|
||||
@ -323,6 +324,7 @@ getipnodebyname(const char *name, int af, int flags, int *errp)
|
||||
{
|
||||
struct hostent *hp;
|
||||
union inx_addr addrbuf;
|
||||
res_state statp;
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
@ -357,6 +359,14 @@ getipnodebyname(const char *name, int af, int flags, int *errp)
|
||||
return _hpaddr(af, name, &addrbuf, errp);
|
||||
}
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0) {
|
||||
if (res_ninit(statp) < 0) {
|
||||
*errp = NETDB_INTERNAL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*errp = HOST_NOT_FOUND;
|
||||
hp = _ghbyname(name, af, flags, errp);
|
||||
|
||||
@ -375,7 +385,7 @@ getipnodebyname(const char *name, int af, int flags, int *errp)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return _hpreorder(_hpsort(hp));
|
||||
return _hpreorder(_hpsort(hp, statp));
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
@ -657,26 +667,27 @@ _hpmapv6(struct hostent *hp, int *errp)
|
||||
* _hpsort: sort address by sortlist
|
||||
*/
|
||||
static struct hostent *
|
||||
_hpsort(struct hostent *hp)
|
||||
_hpsort(struct hostent *hp, res_state statp)
|
||||
{
|
||||
int i, j, n;
|
||||
u_char *ap, *sp, *mp, **pp;
|
||||
char t;
|
||||
char order[MAXADDRS];
|
||||
int nsort = _res.nsort;
|
||||
int nsort = statp->nsort;
|
||||
|
||||
if (hp == NULL || hp->h_addr_list[1] == NULL || nsort == 0)
|
||||
return hp;
|
||||
for (i = 0; (ap = (u_char *)hp->h_addr_list[i]); i++) {
|
||||
for (j = 0; j < nsort; j++) {
|
||||
#ifdef INET6
|
||||
if (_res_ext.sort_list[j].af != hp->h_addrtype)
|
||||
if (statp->_u._ext.ext->sort_list[j].af !=
|
||||
hp->h_addrtype)
|
||||
continue;
|
||||
sp = (u_char *)&_res_ext.sort_list[j].addr;
|
||||
mp = (u_char *)&_res_ext.sort_list[j].mask;
|
||||
sp = (u_char *)&statp->_u._ext.ext->sort_list[j].addr;
|
||||
mp = (u_char *)&statp->_u._ext.ext->sort_list[j].mask;
|
||||
#else
|
||||
sp = (u_char *)&_res.sort_list[j].addr;
|
||||
mp = (u_char *)&_res.sort_list[j].mask;
|
||||
sp = (u_char *)&statp->sort_list[j].addr;
|
||||
mp = (u_char *)&statp->sort_list[j].mask;
|
||||
#endif
|
||||
for (n = 0; n < hp->h_length; n++) {
|
||||
if ((ap[n] & mp[n]) != sp[n])
|
||||
@ -1708,17 +1719,14 @@ _dns_ghbyname(void *rval, void *cb_data, va_list ap)
|
||||
int qtype;
|
||||
struct hostent hbuf;
|
||||
querybuf *buf;
|
||||
res_state statp;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
af = va_arg(ap, int);
|
||||
errp = va_arg(ap, int *);
|
||||
|
||||
if ((_res.options & RES_INIT) == 0) {
|
||||
if (res_init() < 0) {
|
||||
*errp = h_errno;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
statp = __res_state();
|
||||
|
||||
memset(&hbuf, 0, sizeof(hbuf));
|
||||
hbuf.h_addrtype = af;
|
||||
hbuf.h_length = ADDRLEN(af);
|
||||
@ -1741,10 +1749,10 @@ _dns_ghbyname(void *rval, void *cb_data, va_list ap)
|
||||
*errp = NETDB_INTERNAL;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
n = res_search(name, C_IN, qtype, buf->buf, sizeof(buf->buf));
|
||||
n = res_nsearch(statp, name, C_IN, qtype, buf->buf, sizeof(buf->buf));
|
||||
if (n < 0) {
|
||||
free(buf);
|
||||
*errp = h_errno;
|
||||
*errp = statp->res_h_errno;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
hp = getanswer(buf, n, name, qtype, &hbuf, errp);
|
||||
@ -1784,6 +1792,7 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
char *tld6[] = { "ip6.arpa", NULL };
|
||||
char *tld4[] = { "in-addr.arpa", NULL };
|
||||
char **tld;
|
||||
res_state statp;
|
||||
|
||||
addr = va_arg(ap, const void *);
|
||||
addrlen = va_arg(ap, int);
|
||||
@ -1811,9 +1820,10 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
|
||||
if ((_res.options & RES_INIT) == 0) {
|
||||
if (res_init() < 0) {
|
||||
*errp = h_errno;
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0) {
|
||||
if (res_ninit(statp) < 0) {
|
||||
*errp = NETDB_INTERNAL;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
@ -1863,9 +1873,10 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
break;
|
||||
}
|
||||
|
||||
n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf);
|
||||
n = res_nquery(statp, qbuf, C_IN, T_PTR, buf->buf,
|
||||
sizeof buf->buf);
|
||||
if (n < 0) {
|
||||
*errp = h_errno;
|
||||
*errp = statp->res_h_errno;
|
||||
err = NS_UNAVAIL;
|
||||
continue;
|
||||
} else if (n > sizeof(buf->buf)) {
|
||||
@ -1897,19 +1908,25 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
static void
|
||||
_dns_shent(int stayopen)
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0) {
|
||||
if (res_init() < 0)
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
if ((statp->options & RES_INIT) == 0) {
|
||||
if (res_ninit(statp) < 0)
|
||||
return;
|
||||
}
|
||||
if (stayopen)
|
||||
_res.options |= RES_STAYOPEN | RES_USEVC;
|
||||
statp->options |= RES_STAYOPEN | RES_USEVC;
|
||||
}
|
||||
|
||||
static void
|
||||
_dns_ehent(void)
|
||||
{
|
||||
_res.options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_close();
|
||||
res_state statp;
|
||||
|
||||
statp = __res_state();
|
||||
statp->options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_nclose(statp);
|
||||
}
|
||||
|
||||
#ifdef ICMPNL
|
||||
|
@ -36,6 +36,8 @@
|
||||
#define _HOSTBUFSIZE (8 * 1024)
|
||||
#define _NETBUFSIZE 1025
|
||||
|
||||
struct __res_state;
|
||||
|
||||
struct hostent_data {
|
||||
uint32_t host_addr[4]; /* IPv4 or IPv6 */
|
||||
char *h_addr_ptrs[_MAXADDRS + 1];
|
||||
@ -43,6 +45,7 @@ struct hostent_data {
|
||||
char hostbuf[_HOSTBUFSIZE];
|
||||
FILE *hostf;
|
||||
int stayopen;
|
||||
struct __res_state *res;
|
||||
#ifdef YP
|
||||
char *yp_domain;
|
||||
#endif
|
||||
|
@ -1,592 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Data. */
|
||||
|
||||
static char digits[] = "0123456789";
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static int special(int);
|
||||
static int printable(int);
|
||||
static int dn_find(const u_char *, const u_char *,
|
||||
const u_char * const *,
|
||||
const u_char * const *);
|
||||
|
||||
/* Public. */
|
||||
|
||||
/*
|
||||
* ns_name_ntop(src, dst, dstsiz)
|
||||
* Convert an encoded domain name to printable ascii as per RFC1035.
|
||||
* return:
|
||||
* Number of bytes written to buffer, or -1 (with errno set)
|
||||
* notes:
|
||||
* The root is returned as "."
|
||||
* All other domains are returned in non absolute form
|
||||
*/
|
||||
int
|
||||
ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
|
||||
const u_char *cp;
|
||||
char *dn, *eom;
|
||||
u_char c;
|
||||
u_int n;
|
||||
|
||||
cp = src;
|
||||
dn = dst;
|
||||
eom = dst + dstsiz;
|
||||
|
||||
while ((n = *cp++) != 0) {
|
||||
if ((n & NS_CMPRSFLGS) != 0) {
|
||||
/* Some kind of compression pointer. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (dn != dst) {
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '.';
|
||||
}
|
||||
if (dn + n >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
for ((void)NULL; n > 0; n--) {
|
||||
c = *cp++;
|
||||
if (special(c)) {
|
||||
if (dn + 1 >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '\\';
|
||||
*dn++ = (char)c;
|
||||
} else if (!printable(c)) {
|
||||
if (dn + 3 >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '\\';
|
||||
*dn++ = digits[c / 100];
|
||||
*dn++ = digits[(c % 100) / 10];
|
||||
*dn++ = digits[c % 10];
|
||||
} else {
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = (char)c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dn == dst) {
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '.';
|
||||
}
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '\0';
|
||||
return (dn - dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_pton(src, dst, dstsiz)
|
||||
* Convert an ascii string into an encoded domain name as per RFC1035.
|
||||
* return:
|
||||
* -1 if it fails
|
||||
* 1 if string was fully qualified
|
||||
* 0 is string was not fully qualified
|
||||
* notes:
|
||||
* Enforces label and domain length limits.
|
||||
*/
|
||||
|
||||
int
|
||||
ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
|
||||
u_char *label, *bp, *eom;
|
||||
int c, n, escaped;
|
||||
char *cp;
|
||||
|
||||
escaped = 0;
|
||||
bp = dst;
|
||||
eom = dst + dstsiz;
|
||||
label = bp++;
|
||||
|
||||
while ((c = *src++) != 0) {
|
||||
if (escaped) {
|
||||
if ((cp = strchr(digits, c)) != NULL) {
|
||||
n = (cp - digits) * 100;
|
||||
if ((c = *src++) == 0 ||
|
||||
(cp = strchr(digits, c)) == NULL) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
n += (cp - digits) * 10;
|
||||
if ((c = *src++) == 0 ||
|
||||
(cp = strchr(digits, c)) == NULL) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
n += (cp - digits);
|
||||
if (n > 255) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
c = n;
|
||||
}
|
||||
escaped = 0;
|
||||
} else if (c == '\\') {
|
||||
escaped = 1;
|
||||
continue;
|
||||
} else if (c == '.') {
|
||||
c = (bp - label - 1);
|
||||
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (label >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*label = c;
|
||||
/* Fully qualified ? */
|
||||
if (*src == '\0') {
|
||||
if (c != 0) {
|
||||
if (bp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*bp++ = '\0';
|
||||
}
|
||||
if ((bp - dst) > MAXCDNAME) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
if (c == 0) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
label = bp++;
|
||||
continue;
|
||||
}
|
||||
if (bp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*bp++ = (u_char)c;
|
||||
}
|
||||
c = (bp - label - 1);
|
||||
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (label >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*label = c;
|
||||
if (c != 0) {
|
||||
if (bp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*bp++ = 0;
|
||||
}
|
||||
if ((bp - dst) > MAXCDNAME) { /* src too big */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_unpack(msg, eom, src, dst, dstsiz)
|
||||
* Unpack a domain name from a message, source may be compressed.
|
||||
* return:
|
||||
* -1 if it fails, or consumed octets if it succeeds.
|
||||
*/
|
||||
int
|
||||
ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
|
||||
u_char *dst, size_t dstsiz)
|
||||
{
|
||||
const u_char *srcp, *dstlim;
|
||||
u_char *dstp;
|
||||
int n, len, checked;
|
||||
|
||||
len = -1;
|
||||
checked = 0;
|
||||
dstp = dst;
|
||||
srcp = src;
|
||||
dstlim = dst + dstsiz;
|
||||
if (srcp < msg || srcp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
/* Fetch next label in domain name. */
|
||||
while ((n = *srcp++) != 0) {
|
||||
/* Check for indirection. */
|
||||
switch (n & NS_CMPRSFLGS) {
|
||||
case 0:
|
||||
/* Limit checks. */
|
||||
if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
checked += n + 1;
|
||||
*dstp++ = n;
|
||||
memcpy(dstp, srcp, n);
|
||||
dstp += n;
|
||||
srcp += n;
|
||||
break;
|
||||
|
||||
case NS_CMPRSFLGS:
|
||||
if (srcp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (len < 0)
|
||||
len = srcp - src + 1;
|
||||
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
|
||||
if (srcp < msg || srcp >= eom) { /* Out of range. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
checked += 2;
|
||||
/*
|
||||
* Check for loops in the compressed name;
|
||||
* if we've looked at the whole message,
|
||||
* there must be a loop.
|
||||
*/
|
||||
if (checked >= eom - msg) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EMSGSIZE;
|
||||
return (-1); /* flag error */
|
||||
}
|
||||
}
|
||||
*dstp = '\0';
|
||||
if (len < 0)
|
||||
len = srcp - src;
|
||||
return (len);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
|
||||
* Pack domain name 'domain' into 'comp_dn'.
|
||||
* return:
|
||||
* Size of the compressed name, or -1.
|
||||
* notes:
|
||||
* 'dnptrs' is an array of pointers to previous compressed names.
|
||||
* dnptrs[0] is a pointer to the beginning of the message. The array
|
||||
* ends with NULL.
|
||||
* 'lastdnptr' is a pointer to the end of the array pointed to
|
||||
* by 'dnptrs'.
|
||||
* Side effects:
|
||||
* The list of pointers in dnptrs is updated for labels inserted into
|
||||
* the message as we compress the name. If 'dnptr' is NULL, we don't
|
||||
* try to compress names. If 'lastdnptr' is NULL, we don't update the
|
||||
* list.
|
||||
*/
|
||||
int
|
||||
ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
|
||||
const u_char **dnptrs, const u_char **lastdnptr)
|
||||
{
|
||||
u_char *dstp;
|
||||
const u_char **cpp, **lpp, *eob, *msg;
|
||||
const u_char *srcp;
|
||||
int n, l;
|
||||
|
||||
srcp = src;
|
||||
dstp = dst;
|
||||
eob = dstp + dstsiz;
|
||||
lpp = cpp = NULL;
|
||||
if (dnptrs != NULL) {
|
||||
if ((msg = *dnptrs++) != NULL) {
|
||||
for (cpp = dnptrs; *cpp != NULL; cpp++)
|
||||
(void)NULL;
|
||||
lpp = cpp; /* end of list to search */
|
||||
}
|
||||
} else
|
||||
msg = NULL;
|
||||
|
||||
/* make sure the domain we are about to add is legal */
|
||||
l = 0;
|
||||
do {
|
||||
n = *srcp;
|
||||
if ((n & NS_CMPRSFLGS) != 0) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
l += n + 1;
|
||||
if (l > MAXCDNAME) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
srcp += n + 1;
|
||||
} while (n != 0);
|
||||
|
||||
srcp = src;
|
||||
do {
|
||||
/* Look to see if we can use pointers. */
|
||||
n = *srcp;
|
||||
if (n != 0 && msg != NULL) {
|
||||
l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
|
||||
(const u_char * const *)lpp);
|
||||
if (l >= 0) {
|
||||
if (dstp + 1 >= eob) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dstp++ = (l >> 8) | NS_CMPRSFLGS;
|
||||
*dstp++ = l % 256;
|
||||
return (dstp - dst);
|
||||
}
|
||||
/* Not found, save it. */
|
||||
if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
|
||||
(dstp - msg) < 0x4000) {
|
||||
*cpp++ = dstp;
|
||||
*cpp = NULL;
|
||||
}
|
||||
}
|
||||
/* copy label to buffer */
|
||||
if (n & NS_CMPRSFLGS) { /* Should not happen. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (dstp + 1 + n >= eob) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
memcpy(dstp, srcp, n + 1);
|
||||
srcp += n + 1;
|
||||
dstp += n + 1;
|
||||
} while (n != 0);
|
||||
|
||||
if (dstp > eob) {
|
||||
if (msg != NULL)
|
||||
*lpp = NULL;
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
return (dstp - dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_uncompress(msg, eom, src, dst, dstsiz)
|
||||
* Expand compressed domain name to presentation format.
|
||||
* return:
|
||||
* Number of bytes read out of `src', or -1 (with errno set).
|
||||
* note:
|
||||
* Root domain returns as "." not "".
|
||||
*/
|
||||
int
|
||||
ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
|
||||
char *dst, size_t dstsiz)
|
||||
{
|
||||
u_char tmp[NS_MAXCDNAME];
|
||||
int n;
|
||||
|
||||
if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
|
||||
return (-1);
|
||||
if (ns_name_ntop(tmp, dst, dstsiz) == -1)
|
||||
return (-1);
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
|
||||
* Compress a domain name into wire format, using compression pointers.
|
||||
* return:
|
||||
* Number of bytes consumed in `dst' or -1 (with errno set).
|
||||
* notes:
|
||||
* 'dnptrs' is an array of pointers to previous compressed names.
|
||||
* dnptrs[0] is a pointer to the beginning of the message.
|
||||
* The list ends with NULL. 'lastdnptr' is a pointer to the end of the
|
||||
* array pointed to by 'dnptrs'. Side effect is to update the list of
|
||||
* pointers for labels inserted into the message as we compress the name.
|
||||
* If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
|
||||
* is NULL, we don't update the list.
|
||||
*/
|
||||
int
|
||||
ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
|
||||
const u_char **dnptrs, const u_char **lastdnptr)
|
||||
{
|
||||
u_char tmp[NS_MAXCDNAME];
|
||||
|
||||
if (ns_name_pton(src, tmp, sizeof tmp) == -1)
|
||||
return (-1);
|
||||
return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_skip(ptrptr, eom)
|
||||
* Advance *ptrptr to skip over the compressed name it points at.
|
||||
* return:
|
||||
* 0 on success, -1 (with errno set) on failure.
|
||||
*/
|
||||
int
|
||||
ns_name_skip(const u_char **ptrptr, const u_char *eom) {
|
||||
const u_char *cp;
|
||||
u_int n;
|
||||
|
||||
cp = *ptrptr;
|
||||
while (cp < eom && (n = *cp++) != 0) {
|
||||
/* Check for indirection. */
|
||||
switch (n & NS_CMPRSFLGS) {
|
||||
case 0: /* normal case, n == len */
|
||||
cp += n;
|
||||
continue;
|
||||
case NS_CMPRSFLGS: /* indirection */
|
||||
cp++;
|
||||
break;
|
||||
default: /* illegal type */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cp > eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*ptrptr = cp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
/*
|
||||
* special(ch)
|
||||
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* is this characted special ("in need of quoting") ?
|
||||
* return:
|
||||
* boolean.
|
||||
*/
|
||||
static int
|
||||
special(int ch) {
|
||||
switch (ch) {
|
||||
case 0x22: /* '"' */
|
||||
case 0x2E: /* '.' */
|
||||
case 0x3B: /* ';' */
|
||||
case 0x5C: /* '\\' */
|
||||
/* Special modifiers in zone files. */
|
||||
case 0x40: /* '@' */
|
||||
case 0x24: /* '$' */
|
||||
return (1);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* printable(ch)
|
||||
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* is this character visible and not a space when printed ?
|
||||
* return:
|
||||
* boolean.
|
||||
*/
|
||||
static int
|
||||
printable(int ch) {
|
||||
return (ch > 0x20 && ch < 0x7f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* convert this character to lower case if it's upper case.
|
||||
*/
|
||||
static int
|
||||
mklower(int ch) {
|
||||
if (ch >= 0x41 && ch <= 0x5A)
|
||||
return (ch + 0x20);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* dn_find(domain, msg, dnptrs, lastdnptr)
|
||||
* Search for the counted-label name in an array of compressed names.
|
||||
* return:
|
||||
* offset from msg if found, or -1.
|
||||
* notes:
|
||||
* dnptrs is the pointer to the first name on the list,
|
||||
* not the pointer to the start of the message.
|
||||
*/
|
||||
static int
|
||||
dn_find(const u_char *domain, const u_char *msg,
|
||||
const u_char * const *dnptrs,
|
||||
const u_char * const *lastdnptr)
|
||||
{
|
||||
const u_char *dn, *cp, *sp;
|
||||
const u_char * const *cpp;
|
||||
u_int n;
|
||||
|
||||
for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
|
||||
dn = domain;
|
||||
sp = cp = *cpp;
|
||||
while ((n = *cp++) != 0) {
|
||||
/*
|
||||
* check for indirection
|
||||
*/
|
||||
switch (n & NS_CMPRSFLGS) {
|
||||
case 0: /* normal case, n == len */
|
||||
if (n != *dn++)
|
||||
goto next;
|
||||
for ((void)NULL; n > 0; n--)
|
||||
if (mklower(*dn++) != mklower(*cp++))
|
||||
goto next;
|
||||
/* Is next root for both ? */
|
||||
if (*dn == '\0' && *cp == '\0')
|
||||
return (sp - msg);
|
||||
if (*dn)
|
||||
continue;
|
||||
goto next;
|
||||
|
||||
case NS_CMPRSFLGS: /* indirection */
|
||||
cp = msg + (((n & 0x3f) << 8) | *cp);
|
||||
break;
|
||||
|
||||
default: /* illegal type */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
next: ;
|
||||
}
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* Import. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
u_int
|
||||
ns_get16(const u_char *src) {
|
||||
u_int dst;
|
||||
|
||||
NS_GET16(dst, src);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
u_long
|
||||
ns_get32(const u_char *src) {
|
||||
u_long dst;
|
||||
|
||||
NS_GET32(dst, src);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
void
|
||||
ns_put16(u_int src, u_char *dst) {
|
||||
NS_PUT16(src, dst);
|
||||
}
|
||||
|
||||
void
|
||||
ns_put32(u_long src, u_char *dst) {
|
||||
NS_PUT32(src, dst);
|
||||
}
|
@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
|
||||
/* These need to be in the same order as the nres.h:ns_flag enum. */
|
||||
struct _ns_flagdata _ns_flagdata[16] = {
|
||||
{ 0x8000, 15 }, /* qr. */
|
||||
{ 0x7800, 11 }, /* opcode. */
|
||||
{ 0x0400, 10 }, /* aa. */
|
||||
{ 0x0200, 9 }, /* tc. */
|
||||
{ 0x0100, 8 }, /* rd. */
|
||||
{ 0x0080, 7 }, /* ra. */
|
||||
{ 0x0040, 6 }, /* z. */
|
||||
{ 0x0020, 5 }, /* ad. */
|
||||
{ 0x0010, 4 }, /* cd. */
|
||||
{ 0x000f, 0 }, /* rcode. */
|
||||
{ 0x0000, 0 }, /* expansion (1/6). */
|
||||
{ 0x0000, 0 }, /* expansion (2/6). */
|
||||
{ 0x0000, 0 }, /* expansion (3/6). */
|
||||
{ 0x0000, 0 }, /* expansion (4/6). */
|
||||
{ 0x0000, 0 }, /* expansion (5/6). */
|
||||
{ 0x0000, 0 }, /* expansion (6/6). */
|
||||
};
|
||||
|
||||
static int
|
||||
skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
|
||||
const u_char *optr = ptr;
|
||||
|
||||
for ((void)NULL; count > 0; count--) {
|
||||
int b, rdlength;
|
||||
|
||||
b = dn_skipname(ptr, eom);
|
||||
if (b < 0)
|
||||
goto emsgsize;
|
||||
ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
|
||||
if (section != ns_s_qd) {
|
||||
if (ptr + NS_INT32SZ > eom)
|
||||
goto emsgsize;
|
||||
ptr += NS_INT32SZ/*TTL*/;
|
||||
if (ptr + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rdlength, ptr);
|
||||
ptr += rdlength/*RData*/;
|
||||
}
|
||||
}
|
||||
if (ptr > eom)
|
||||
goto emsgsize;
|
||||
return (ptr - optr);
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
|
||||
const u_char *eom = msg + msglen;
|
||||
int i;
|
||||
|
||||
memset(handle, 0x5e, sizeof *handle);
|
||||
handle->_msg = msg;
|
||||
handle->_eom = eom;
|
||||
if (msg + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(handle->_id, msg);
|
||||
if (msg + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(handle->_flags, msg);
|
||||
for (i = 0; i < ns_s_max; i++) {
|
||||
if (msg + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(handle->_counts[i], msg);
|
||||
}
|
||||
for (i = 0; i < ns_s_max; i++)
|
||||
if (handle->_counts[i] == 0)
|
||||
handle->_sections[i] = NULL;
|
||||
else {
|
||||
int b = skiprr(msg, eom, (ns_sect)i,
|
||||
handle->_counts[i]);
|
||||
|
||||
if (b < 0)
|
||||
return (-1);
|
||||
handle->_sections[i] = msg;
|
||||
msg += b;
|
||||
}
|
||||
if (msg != eom)
|
||||
goto emsgsize;
|
||||
handle->_sect = ns_s_max;
|
||||
handle->_rrnum = -1;
|
||||
handle->_ptr = NULL;
|
||||
return (0);
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
|
||||
int b;
|
||||
|
||||
/* Make section right. */
|
||||
if (section < 0 || section >= ns_s_max)
|
||||
goto enodev;
|
||||
if ((int)section != (int)handle->_sect) {
|
||||
handle->_sect = section;
|
||||
handle->_rrnum = 0;
|
||||
handle->_ptr = handle->_sections[(int)section];
|
||||
}
|
||||
|
||||
/* Make rrnum right. */
|
||||
if (rrnum == -1)
|
||||
rrnum = handle->_rrnum;
|
||||
if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
|
||||
goto enodev;
|
||||
if (rrnum < handle->_rrnum) {
|
||||
handle->_rrnum = 0;
|
||||
handle->_ptr = handle->_sections[(int)section];
|
||||
}
|
||||
|
||||
b = skiprr(handle->_msg, handle->_eom, section,
|
||||
rrnum - handle->_rrnum);
|
||||
if (b < 0)
|
||||
return (-1);
|
||||
handle->_ptr += b;
|
||||
handle->_rrnum = rrnum;
|
||||
|
||||
/* Do the parse. */
|
||||
b = dn_expand(handle->_msg, handle->_eom,
|
||||
handle->_ptr, rr->name, NS_MAXDNAME);
|
||||
if (b < 0)
|
||||
return (-1);
|
||||
handle->_ptr += b;
|
||||
if (handle->_ptr + NS_INT16SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rr->type, handle->_ptr);
|
||||
if (handle->_ptr + NS_INT16SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rr->rr_class, handle->_ptr);
|
||||
if (section == ns_s_qd) {
|
||||
rr->ttl = 0;
|
||||
rr->rdlength = 0;
|
||||
rr->rdata = NULL;
|
||||
} else {
|
||||
if (handle->_ptr + NS_INT32SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET32(rr->ttl, handle->_ptr);
|
||||
if (handle->_ptr + NS_INT16SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rr->rdlength, handle->_ptr);
|
||||
if (handle->_ptr + rr->rdlength > handle->_eom)
|
||||
goto emsgsize;
|
||||
rr->rdata = handle->_ptr;
|
||||
handle->_ptr += rr->rdlength;
|
||||
}
|
||||
handle->_rrnum++;
|
||||
|
||||
/* All done. */
|
||||
return (0);
|
||||
enodev:
|
||||
errno = ENODEV;
|
||||
return (-1);
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
@ -1,742 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* Import. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define SPRINTF(x) ((size_t)sprintf x)
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static size_t prune_origin(const char *name, const char *origin);
|
||||
static int charstr(const u_char *rdata, const u_char *edata,
|
||||
char **buf, size_t *buflen);
|
||||
static int addname(const u_char *msg, size_t msglen,
|
||||
const u_char **p, const char *origin,
|
||||
char **buf, size_t *buflen);
|
||||
static void addlen(size_t len, char **buf, size_t *buflen);
|
||||
static int addstr(const char *src, size_t len,
|
||||
char **buf, size_t *buflen);
|
||||
static int addtab(size_t len, size_t target, int spaced,
|
||||
char **buf, size_t *buflen);
|
||||
|
||||
/* Macros. */
|
||||
|
||||
#define T(x) \
|
||||
do { \
|
||||
if ((x) < 0) \
|
||||
return (-1); \
|
||||
} while (0)
|
||||
|
||||
/* Public. */
|
||||
|
||||
/*
|
||||
* int
|
||||
* ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
|
||||
* Convert an RR to presentation format.
|
||||
* return:
|
||||
* Number of characters written to buf, or -1 (check errno).
|
||||
*/
|
||||
int
|
||||
ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
|
||||
const char *name_ctx, const char *origin,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
|
||||
ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
|
||||
ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
|
||||
name_ctx, origin, buf, buflen);
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* int
|
||||
* ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
|
||||
* name_ctx, origin, buf, buflen)
|
||||
* Convert the fields of an RR into presentation format.
|
||||
* return:
|
||||
* Number of characters written to buf, or -1 (check errno).
|
||||
*/
|
||||
int
|
||||
ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
const char *name, ns_class class, ns_type type,
|
||||
u_long ttl, const u_char *rdata, size_t rdlen,
|
||||
const char *name_ctx, const char *origin,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
const char *obuf = buf;
|
||||
const u_char *edata = rdata + rdlen;
|
||||
int spaced = 0;
|
||||
|
||||
const char *comment;
|
||||
char tmp[100];
|
||||
int len, x;
|
||||
|
||||
/*
|
||||
* Owner.
|
||||
*/
|
||||
if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {
|
||||
T(addstr("\t\t\t", 3, &buf, &buflen));
|
||||
} else {
|
||||
len = prune_origin(name, origin);
|
||||
if (len == 0) {
|
||||
T(addstr("@\t\t\t", 4, &buf, &buflen));
|
||||
} else {
|
||||
T(addstr(name, len, &buf, &buflen));
|
||||
/* Origin not used and no trailing dot? */
|
||||
if ((!origin || !origin[0] || name[len] == '\0') &&
|
||||
name[len - 1] != '.') {
|
||||
T(addstr(".", 1, &buf, &buflen));
|
||||
len++;
|
||||
}
|
||||
T(spaced = addtab(len, 24, spaced, &buf, &buflen));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TTL, Class, Type.
|
||||
*/
|
||||
T(x = ns_format_ttl(ttl, buf, buflen));
|
||||
addlen(x, &buf, &buflen);
|
||||
len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
|
||||
|
||||
/*
|
||||
* RData.
|
||||
*/
|
||||
switch (type) {
|
||||
case ns_t_a:
|
||||
if (rdlen != NS_INADDRSZ)
|
||||
goto formerr;
|
||||
(void) inet_ntop(AF_INET, rdata, buf, buflen);
|
||||
addlen(strlen(buf), &buf, &buflen);
|
||||
break;
|
||||
|
||||
case ns_t_cname:
|
||||
case ns_t_mb:
|
||||
case ns_t_mg:
|
||||
case ns_t_mr:
|
||||
case ns_t_ns:
|
||||
case ns_t_ptr:
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
break;
|
||||
|
||||
case ns_t_hinfo:
|
||||
case ns_t_isdn:
|
||||
/* First word. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Second word. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
break;
|
||||
|
||||
case ns_t_soa: {
|
||||
u_long t;
|
||||
|
||||
/* Server name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Administrator name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" (\n", 3, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
if ((edata - rdata) != 5*NS_INT32SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Serial number. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
len = SPRINTF((tmp, "%lu", t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; serial\n", 9, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Refresh interval. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; refresh\n", 10, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Retry interval. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; retry\n", 8, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Expiry. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; expiry\n", 9, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Minimum TTL. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(addstr(" )", 2, &buf, &buflen));
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; minimum\n", 10, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_mx:
|
||||
case ns_t_afsdb:
|
||||
case ns_t_rt: {
|
||||
u_int t;
|
||||
|
||||
if (rdlen < NS_INT16SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Priority. */
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Target. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_px: {
|
||||
u_int t;
|
||||
|
||||
if (rdlen < NS_INT16SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Priority. */
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Name1. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Name2. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_x25:
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
break;
|
||||
|
||||
case ns_t_txt:
|
||||
while (rdata < edata) {
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
if (rdata < edata)
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
}
|
||||
break;
|
||||
|
||||
case ns_t_nsap: {
|
||||
char t[255*3];
|
||||
|
||||
(void) inet_nsap_ntoa(rdlen, rdata, t);
|
||||
T(addstr(t, strlen(t), &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_aaaa:
|
||||
if (rdlen != NS_IN6ADDRSZ)
|
||||
goto formerr;
|
||||
(void) inet_ntop(AF_INET6, rdata, buf, buflen);
|
||||
addlen(strlen(buf), &buf, &buflen);
|
||||
break;
|
||||
|
||||
case ns_t_loc: {
|
||||
char t[255];
|
||||
|
||||
/* XXX protocol format checking? */
|
||||
(void) loc_ntoa(rdata, t);
|
||||
T(addstr(t, strlen(t), &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_naptr: {
|
||||
u_int order, preference;
|
||||
char t[50];
|
||||
|
||||
if (rdlen < 2*NS_INT16SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Order, Precedence. */
|
||||
order = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
preference = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((t, "%u %u ", order, preference));
|
||||
T(addstr(t, len, &buf, &buflen));
|
||||
|
||||
/* Flags. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Service. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Regexp. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len < 0)
|
||||
return (-1);
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Server. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_srv: {
|
||||
u_int priority, weight, port;
|
||||
char t[50];
|
||||
|
||||
if (rdlen < NS_INT16SZ*3)
|
||||
goto formerr;
|
||||
|
||||
/* Priority, Weight, Port. */
|
||||
priority = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
weight = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
port = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((t, "%u %u %u ", priority, weight, port));
|
||||
T(addstr(t, len, &buf, &buflen));
|
||||
|
||||
/* Server. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_minfo:
|
||||
case ns_t_rp:
|
||||
/* Name1. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Name2. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
break;
|
||||
|
||||
case ns_t_wks: {
|
||||
int n, lcnt;
|
||||
|
||||
if (rdlen < NS_INT32SZ + 1)
|
||||
goto formerr;
|
||||
|
||||
/* Address. */
|
||||
(void) inet_ntop(AF_INET, rdata, buf, buflen);
|
||||
addlen(strlen(buf), &buf, &buflen);
|
||||
rdata += NS_INADDRSZ;
|
||||
|
||||
/* Protocol. */
|
||||
len = SPRINTF((tmp, " %u ( ", *rdata));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
rdata += NS_INT8SZ;
|
||||
|
||||
/* Bit map. */
|
||||
n = 0;
|
||||
lcnt = 0;
|
||||
while (rdata < edata) {
|
||||
u_int c = *rdata++;
|
||||
do {
|
||||
if (c & 0200) {
|
||||
if (lcnt == 0) {
|
||||
T(addstr("\n\t\t\t\t", 5,
|
||||
&buf, &buflen));
|
||||
lcnt = 10;
|
||||
spaced = 0;
|
||||
}
|
||||
len = SPRINTF((tmp, "%d ", n));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
lcnt--;
|
||||
}
|
||||
c <<= 1;
|
||||
} while (++n & 07);
|
||||
}
|
||||
T(addstr(")", 1, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_key: {
|
||||
char base64_key[NS_MD5RSA_MAX_BASE64];
|
||||
u_int keyflags, protocol, algorithm;
|
||||
const char *leader;
|
||||
int n;
|
||||
|
||||
if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Key flags, Protocol, Algorithm. */
|
||||
keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
protocol = *rdata++;
|
||||
algorithm = *rdata++;
|
||||
len = SPRINTF((tmp, "0x%04x %u %u",
|
||||
keyflags, protocol, algorithm));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Public key data. */
|
||||
len = b64_ntop(rdata, edata - rdata,
|
||||
base64_key, sizeof base64_key);
|
||||
if (len < 0)
|
||||
goto formerr;
|
||||
if (len > 15) {
|
||||
T(addstr(" (", 2, &buf, &buflen));
|
||||
leader = "\n\t\t";
|
||||
spaced = 0;
|
||||
} else
|
||||
leader = " ";
|
||||
for (n = 0; n < len; n += 48) {
|
||||
T(addstr(leader, strlen(leader), &buf, &buflen));
|
||||
T(addstr(base64_key + n, MIN(len - n, 48),
|
||||
&buf, &buflen));
|
||||
}
|
||||
if (len > 15)
|
||||
T(addstr(" )", 2, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_sig: {
|
||||
char base64_key[NS_MD5RSA_MAX_BASE64];
|
||||
u_int type, algorithm, labels, footprint;
|
||||
const char *leader;
|
||||
u_long t;
|
||||
int n;
|
||||
|
||||
if (rdlen < 22)
|
||||
goto formerr;
|
||||
|
||||
/* Type covered, Algorithm, Label count, Original TTL. */
|
||||
type = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
algorithm = *rdata++;
|
||||
labels = *rdata++;
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, " %s %d %lu ",
|
||||
p_type(type), algorithm, t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
if (labels != (u_int)dn_count_labels(name))
|
||||
goto formerr;
|
||||
|
||||
/* Signature expiry. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Time signed. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Signature Footprint. */
|
||||
footprint = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", footprint));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Signer's name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
/* Signature. */
|
||||
len = b64_ntop(rdata, edata - rdata,
|
||||
base64_key, sizeof base64_key);
|
||||
if (len > 15) {
|
||||
T(addstr(" (", 2, &buf, &buflen));
|
||||
leader = "\n\t\t";
|
||||
spaced = 0;
|
||||
} else
|
||||
leader = " ";
|
||||
if (len < 0)
|
||||
goto formerr;
|
||||
for (n = 0; n < len; n += 48) {
|
||||
T(addstr(leader, strlen(leader), &buf, &buflen));
|
||||
T(addstr(base64_key + n, MIN(len - n, 48),
|
||||
&buf, &buflen));
|
||||
}
|
||||
if (len > 15)
|
||||
T(addstr(" )", 2, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_nxt: {
|
||||
int n, c;
|
||||
|
||||
/* Next domain name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
/* Type bit map. */
|
||||
n = edata - rdata;
|
||||
for (c = 0; c < n*8; c++)
|
||||
if (NS_NXT_BIT_ISSET(c, rdata)) {
|
||||
len = SPRINTF((tmp, " %s", p_type(c)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
comment = "unknown RR type";
|
||||
goto hexify;
|
||||
}
|
||||
return (buf - obuf);
|
||||
formerr:
|
||||
comment = "RR format error";
|
||||
hexify: {
|
||||
int n, m;
|
||||
char *p;
|
||||
|
||||
len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
while (rdata < edata) {
|
||||
p = tmp;
|
||||
p += SPRINTF((p, "\n\t"));
|
||||
spaced = 0;
|
||||
n = MIN(16, edata - rdata);
|
||||
for (m = 0; m < n; m++)
|
||||
p += SPRINTF((p, "%02x ", rdata[m]));
|
||||
T(addstr(tmp, p - tmp, &buf, &buflen));
|
||||
if (n < 16) {
|
||||
T(addstr(")", 1, &buf, &buflen));
|
||||
T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
|
||||
}
|
||||
p = tmp;
|
||||
p += SPRINTF((p, "; "));
|
||||
for (m = 0; m < n; m++)
|
||||
*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
|
||||
? rdata[m]
|
||||
: '.';
|
||||
T(addstr(tmp, p - tmp, &buf, &buflen));
|
||||
rdata += n;
|
||||
}
|
||||
return (buf - obuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
/*
|
||||
* size_t
|
||||
* prune_origin(name, origin)
|
||||
* Find out if the name is at or under the current origin.
|
||||
* return:
|
||||
* Number of characters in name before start of origin,
|
||||
* or length of name if origin does not match.
|
||||
* notes:
|
||||
* This function should share code with samedomain().
|
||||
*/
|
||||
static size_t
|
||||
prune_origin(const char *name, const char *origin) {
|
||||
const char *oname = name;
|
||||
|
||||
while (*name != '\0') {
|
||||
if (origin != NULL && strcasecmp(name, origin) == 0)
|
||||
return (name - oname - (name > oname));
|
||||
while (*name != '\0') {
|
||||
if (*name == '\\') {
|
||||
name++;
|
||||
/* XXX need to handle \nnn form. */
|
||||
if (*name == '\0')
|
||||
break;
|
||||
} else if (*name == '.') {
|
||||
name++;
|
||||
break;
|
||||
}
|
||||
name++;
|
||||
}
|
||||
}
|
||||
return (name - oname);
|
||||
}
|
||||
|
||||
/*
|
||||
* int
|
||||
* charstr(rdata, edata, buf, buflen)
|
||||
* Format a <character-string> into the presentation buffer.
|
||||
* return:
|
||||
* Number of rdata octets consumed
|
||||
* 0 for protocol format error
|
||||
* -1 for output buffer error
|
||||
* side effects:
|
||||
* buffer is advanced on success.
|
||||
*/
|
||||
static int
|
||||
charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
|
||||
const u_char *odata = rdata;
|
||||
size_t save_buflen = *buflen;
|
||||
char *save_buf = *buf;
|
||||
|
||||
if (addstr("\"", 1, buf, buflen) < 0)
|
||||
goto enospc;
|
||||
if (rdata < edata) {
|
||||
int n = *rdata;
|
||||
|
||||
if (rdata + 1 + n <= edata) {
|
||||
rdata++;
|
||||
while (n-- > 0) {
|
||||
if (strchr("\n\"\\", *rdata) != NULL)
|
||||
if (addstr("\\", 1, buf, buflen) < 0)
|
||||
goto enospc;
|
||||
if (addstr((const char *)rdata, 1,
|
||||
buf, buflen) < 0)
|
||||
goto enospc;
|
||||
rdata++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addstr("\"", 1, buf, buflen) < 0)
|
||||
goto enospc;
|
||||
return (rdata - odata);
|
||||
enospc:
|
||||
errno = ENOSPC;
|
||||
*buf = save_buf;
|
||||
*buflen = save_buflen;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
addname(const u_char *msg, size_t msglen,
|
||||
const u_char **pp, const char *origin,
|
||||
char **buf, size_t *buflen)
|
||||
{
|
||||
size_t newlen, save_buflen = *buflen;
|
||||
char *save_buf = *buf;
|
||||
int n;
|
||||
|
||||
n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
|
||||
if (n < 0)
|
||||
goto enospc; /* Guess. */
|
||||
newlen = prune_origin(*buf, origin);
|
||||
if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&
|
||||
(newlen == 0 || (*buf)[newlen - 1] != '.')) {
|
||||
/* No trailing dot. */
|
||||
if (newlen + 2 > *buflen)
|
||||
goto enospc; /* No room for ".\0". */
|
||||
(*buf)[newlen++] = '.';
|
||||
(*buf)[newlen] = '\0';
|
||||
}
|
||||
if (newlen == 0) {
|
||||
/* Use "@" instead of name. */
|
||||
if (newlen + 2 > *buflen)
|
||||
goto enospc; /* No room for "@\0". */
|
||||
(*buf)[newlen++] = '@';
|
||||
(*buf)[newlen] = '\0';
|
||||
}
|
||||
*pp += n;
|
||||
addlen(newlen, buf, buflen);
|
||||
**buf = '\0';
|
||||
return (newlen);
|
||||
enospc:
|
||||
errno = ENOSPC;
|
||||
*buf = save_buf;
|
||||
*buflen = save_buflen;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
addlen(size_t len, char **buf, size_t *buflen) {
|
||||
assert(len <= *buflen);
|
||||
*buf += len;
|
||||
*buflen -= len;
|
||||
}
|
||||
|
||||
static int
|
||||
addstr(const char *src, size_t len, char **buf, size_t *buflen) {
|
||||
if (len > *buflen) {
|
||||
errno = ENOSPC;
|
||||
return (-1);
|
||||
}
|
||||
memcpy(*buf, src, len);
|
||||
addlen(len, buf, buflen);
|
||||
**buf = '\0';
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
|
||||
size_t save_buflen = *buflen;
|
||||
char *save_buf = *buf;
|
||||
int t;
|
||||
|
||||
if (spaced || len >= target - 1) {
|
||||
T(addstr(" ", 2, buf, buflen));
|
||||
spaced = 1;
|
||||
} else {
|
||||
for (t = (target - len - 1) / 8; t >= 0; t--)
|
||||
if (addstr("\t", 1, buf, buflen) < 0) {
|
||||
*buflen = save_buflen;
|
||||
*buf = save_buf;
|
||||
return (-1);
|
||||
}
|
||||
spaced = 0;
|
||||
}
|
||||
return (spaced);
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* Import. */
|
||||
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SPRINTF(x) ((size_t)sprintf x)
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static int fmt1(int t, char s, char **buf, size_t *buflen);
|
||||
|
||||
/* Macros. */
|
||||
|
||||
#define T(x) if ((x) < 0) return (-1); else (void)NULL
|
||||
|
||||
/* Public. */
|
||||
|
||||
int
|
||||
ns_format_ttl(u_long src, char *dst, size_t dstlen) {
|
||||
char *odst = dst;
|
||||
int secs, mins, hours, days, weeks, x;
|
||||
char *p;
|
||||
|
||||
secs = src % 60; src /= 60;
|
||||
mins = src % 60; src /= 60;
|
||||
hours = src % 24; src /= 24;
|
||||
days = src % 7; src /= 7;
|
||||
weeks = src; src = 0;
|
||||
|
||||
x = 0;
|
||||
if (weeks) {
|
||||
T(fmt1(weeks, 'W', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (days) {
|
||||
T(fmt1(days, 'D', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (hours) {
|
||||
T(fmt1(hours, 'H', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (mins) {
|
||||
T(fmt1(mins, 'M', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (secs || !(weeks || days || hours || mins)) {
|
||||
T(fmt1(secs, 'S', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
|
||||
if (x > 1) {
|
||||
int ch;
|
||||
|
||||
for (p = odst; (ch = *p) != '\0'; p++)
|
||||
if (isascii(ch) && isupper(ch))
|
||||
*p = tolower(ch);
|
||||
}
|
||||
|
||||
return (dst - odst);
|
||||
}
|
||||
|
||||
int
|
||||
ns_parse_ttl(const char *src, u_long *dst) {
|
||||
u_long ttl, tmp;
|
||||
int ch, digits, dirty;
|
||||
|
||||
ttl = 0;
|
||||
tmp = 0;
|
||||
digits = 0;
|
||||
dirty = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
if (!isascii(ch) || !isprint(ch))
|
||||
goto einval;
|
||||
if (isdigit(ch)) {
|
||||
tmp *= 10;
|
||||
tmp += (ch - '0');
|
||||
digits++;
|
||||
continue;
|
||||
}
|
||||
if (digits == 0)
|
||||
goto einval;
|
||||
if (islower(ch))
|
||||
ch = toupper(ch);
|
||||
switch (ch) {
|
||||
case 'W': tmp *= 7;
|
||||
case 'D': tmp *= 24;
|
||||
case 'H': tmp *= 60;
|
||||
case 'M': tmp *= 60;
|
||||
case 'S': break;
|
||||
default: goto einval;
|
||||
}
|
||||
ttl += tmp;
|
||||
tmp = 0;
|
||||
digits = 0;
|
||||
dirty = 1;
|
||||
}
|
||||
if (digits > 0) {
|
||||
if (dirty)
|
||||
goto einval;
|
||||
else
|
||||
ttl += tmp;
|
||||
}
|
||||
*dst = ttl;
|
||||
return (0);
|
||||
|
||||
einval:
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static int
|
||||
fmt1(int t, char s, char **buf, size_t *buflen) {
|
||||
char tmp[50];
|
||||
size_t len;
|
||||
|
||||
len = SPRINTF((tmp, "%d%c", t, s));
|
||||
if (len + 1 > *buflen)
|
||||
return (-1);
|
||||
strcpy(*buf, tmp);
|
||||
*buf += len;
|
||||
*buflen -= len;
|
||||
return (0);
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
|
||||
static char
|
||||
xtob(c)
|
||||
int c;
|
||||
{
|
||||
return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
|
||||
}
|
||||
|
||||
u_int
|
||||
inet_nsap_addr(ascii, binary, maxlen)
|
||||
const char *ascii;
|
||||
u_char *binary;
|
||||
int maxlen;
|
||||
{
|
||||
u_char c, nib;
|
||||
u_int len = 0;
|
||||
|
||||
while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
|
||||
if (c == '.' || c == '+' || c == '/')
|
||||
continue;
|
||||
if (!isascii(c))
|
||||
return (0);
|
||||
if (islower(c))
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
nib = xtob(c);
|
||||
c = *ascii++;
|
||||
if (c != '\0') {
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
*binary++ = (nib << 4) | xtob(c);
|
||||
len++;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
char *
|
||||
inet_nsap_ntoa(binlen, binary, ascii)
|
||||
int binlen;
|
||||
const u_char *binary;
|
||||
char *ascii;
|
||||
{
|
||||
int nib;
|
||||
int i;
|
||||
static char tmpbuf[255*3];
|
||||
char *start;
|
||||
|
||||
if (ascii)
|
||||
start = ascii;
|
||||
else {
|
||||
ascii = tmpbuf;
|
||||
start = tmpbuf;
|
||||
}
|
||||
|
||||
if (binlen > 255)
|
||||
binlen = 255;
|
||||
|
||||
for (i = 0; i < binlen; i++) {
|
||||
nib = *binary >> 4;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
nib = *binary++ & 0x0f;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
if (((i % 2) == 0 && (i + 1) < binlen))
|
||||
*ascii++ = '.';
|
||||
}
|
||||
*ascii = '\0';
|
||||
return (start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_nsap_addr
|
||||
__weak_reference(__inet_nsap_addr, inet_nsap_addr);
|
||||
#undef inet_nsap_ntoa
|
||||
__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa);
|
@ -1,268 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1997/05/21 19:31:04 halley Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BIND_4_COMPAT
|
||||
|
||||
/*
|
||||
* Expand compressed domain name 'comp_dn' to full domain name.
|
||||
* 'msg' is a pointer to the begining of the message,
|
||||
* 'eomorig' points to the first location after the message,
|
||||
* 'exp_dn' is a pointer to a buffer of size 'length' for the result.
|
||||
* Return size of compressed name or -1 if there was an error.
|
||||
*/
|
||||
int
|
||||
dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
|
||||
char *dst, int dstsiz)
|
||||
{
|
||||
int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
|
||||
|
||||
if (n > 0 && dst[0] == '.')
|
||||
dst[0] = '\0';
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
|
||||
* Return the size of the compressed name or -1.
|
||||
* 'length' is the size of the array pointed to by 'comp_dn'.
|
||||
*/
|
||||
int
|
||||
dn_comp(const char *src, u_char *dst, int dstsiz,
|
||||
u_char **dnptrs, u_char **lastdnptr)
|
||||
{
|
||||
return (ns_name_compress(src, dst, (size_t)dstsiz,
|
||||
(const u_char **)dnptrs,
|
||||
(const u_char **)lastdnptr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over a compressed domain name. Return the size or -1.
|
||||
*/
|
||||
int
|
||||
dn_skipname(const u_char *ptr, const u_char *eom) {
|
||||
const u_char *saveptr = ptr;
|
||||
|
||||
if (ns_name_skip(&ptr, eom) == -1)
|
||||
return (-1);
|
||||
return (ptr - saveptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that a domain name uses an acceptable character set.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note the conspicuous absence of ctype macros in these definitions. On
|
||||
* non-ASCII hosts, we can't depend on string literals or ctype macros to
|
||||
* tell us anything about network-format data. The rest of the BIND system
|
||||
* is not careful about this, but for some reason, we're doing it right here.
|
||||
*/
|
||||
#define PERIOD 0x2e
|
||||
#define hyphenchar(c) ((c) == 0x2d)
|
||||
#define bslashchar(c) ((c) == 0x5c)
|
||||
#define periodchar(c) ((c) == PERIOD)
|
||||
#define asterchar(c) ((c) == 0x2a)
|
||||
#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
|
||||
|| ((c) >= 0x61 && (c) <= 0x7a))
|
||||
#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
|
||||
|
||||
#define borderchar(c) (alphachar(c) || digitchar(c))
|
||||
#define middlechar(c) (borderchar(c) || hyphenchar(c))
|
||||
#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
|
||||
|
||||
int
|
||||
res_hnok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
int pch = PERIOD, ch = *dn++;
|
||||
|
||||
while (ch != '\0') {
|
||||
int nch = *dn++;
|
||||
|
||||
if (periodchar(ch)) {
|
||||
(void)NULL;
|
||||
} else if (periodchar(pch)) {
|
||||
if (!borderchar(ch))
|
||||
return (0);
|
||||
} else if (periodchar(nch) || nch == '\0') {
|
||||
if (!borderchar(ch))
|
||||
return (0);
|
||||
} else {
|
||||
if (!middlechar(ch))
|
||||
return (0);
|
||||
}
|
||||
pch = ch, ch = nch;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* hostname-like (A, MX, WKS) owners can have "*" as their first label
|
||||
* but must otherwise be as a host name.
|
||||
*/
|
||||
int
|
||||
res_ownok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
if (asterchar(dn[0])) {
|
||||
if (periodchar(dn[1]))
|
||||
return (res_hnok(dn+2));
|
||||
if (dn[1] == '\0')
|
||||
return (1);
|
||||
}
|
||||
return (res_hnok(dn));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOA RNAMEs and RP RNAMEs can have any printable character in their first
|
||||
* label, but the rest of the name has to look like a host name.
|
||||
*/
|
||||
int
|
||||
res_mailok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
int ch, escaped = 0;
|
||||
|
||||
/* "." is a valid missing representation */
|
||||
if (*dn == '\0')
|
||||
return (1);
|
||||
|
||||
/* otherwise <label>.<hostname> */
|
||||
while ((ch = *dn++) != '\0') {
|
||||
if (!domainchar(ch))
|
||||
return (0);
|
||||
if (!escaped && periodchar(ch))
|
||||
break;
|
||||
if (escaped)
|
||||
escaped = 0;
|
||||
else if (bslashchar(ch))
|
||||
escaped = 1;
|
||||
}
|
||||
if (periodchar(ch))
|
||||
return (res_hnok(dn));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is quite liberal, since RFC 1034's character sets are only
|
||||
* recommendations.
|
||||
*/
|
||||
int
|
||||
res_dnok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
int ch;
|
||||
|
||||
while ((ch = *dn++) != '\0')
|
||||
if (!domainchar(ch))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef BIND_4_COMPAT
|
||||
/*
|
||||
* This module must export the following externally-visible symbols:
|
||||
* __putlong
|
||||
* __putshort
|
||||
* _getlong
|
||||
* _getshort
|
||||
* Note that one _ comes from C and the others come from us.
|
||||
*/
|
||||
void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
|
||||
void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
|
||||
u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
|
||||
u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
|
||||
#endif /*BIND_4_COMPAT*/
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <resolv.h>.
|
||||
*/
|
||||
#undef dn_comp
|
||||
__weak_reference(__dn_comp, dn_comp);
|
||||
#undef dn_expand
|
||||
__weak_reference(__dn_expand, dn_expand);
|
@ -2,9 +2,5 @@
|
||||
|
||||
#define DEBUG 1 /* enable debugging code (needed for dig) */
|
||||
#define RESOLVSORT /* allow sorting of addresses in gethostbyname */
|
||||
#define RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/
|
||||
#undef USELOOPBACK /* res_init() bind to localhost */
|
||||
#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
|
||||
#define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */
|
||||
#define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */
|
||||
#define BIND_UPDATE 1 /* update support */
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995,1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
const char *_res_opcodes[] = {
|
||||
"QUERY",
|
||||
"IQUERY",
|
||||
"CQUERYM",
|
||||
"CQUERYU", /* experimental */
|
||||
"NOTIFY", /* experimental */
|
||||
"UPDATE",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"ZONEINIT",
|
||||
"ZONEREF",
|
||||
};
|
||||
|
||||
const char *_res_resultcodes[] = {
|
||||
"NOERROR",
|
||||
"FORMERR",
|
||||
"SERVFAIL",
|
||||
"NXDOMAIN",
|
||||
"NOTIMP",
|
||||
"REFUSED",
|
||||
"YXDOMAIN",
|
||||
"YXRRSET",
|
||||
"NXRRSET",
|
||||
"NOTAUTH",
|
||||
"ZONEERR",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"NOCHANGE",
|
||||
};
|
||||
|
||||
#ifdef BIND_UPDATE
|
||||
const char *_res_sectioncodes[] = {
|
||||
"ZONE",
|
||||
"PREREQUISITES",
|
||||
"UPDATE",
|
||||
"ADDITIONAL",
|
||||
};
|
||||
#endif
|
@ -1,992 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SPRINTF(x) sprintf x
|
||||
|
||||
extern const char *_res_opcodes[];
|
||||
extern const char *_res_resultcodes[];
|
||||
extern const char *_res_sectioncodes[];
|
||||
|
||||
/*
|
||||
* Print the current options.
|
||||
*/
|
||||
void
|
||||
fp_resstat(struct __res_state *statp, FILE *file) {
|
||||
u_long mask;
|
||||
|
||||
fprintf(file, ";; res options:");
|
||||
if (!statp)
|
||||
statp = &_res;
|
||||
for (mask = 1; mask != 0; mask <<= 1)
|
||||
if (statp->options & mask)
|
||||
fprintf(file, " %s", p_option(mask));
|
||||
putc('\n', file);
|
||||
}
|
||||
|
||||
static void
|
||||
do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file) {
|
||||
int n, sflag, rrnum;
|
||||
char buf[2048]; /* XXX need to malloc */
|
||||
ns_opcode opcode;
|
||||
ns_rr rr;
|
||||
|
||||
/*
|
||||
* Print answer records.
|
||||
*/
|
||||
sflag = (_res.pfcode & pflag);
|
||||
if (_res.pfcode && !sflag)
|
||||
return;
|
||||
|
||||
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 &&
|
||||
(_res.pfcode & RES_PRF_HEAD1))
|
||||
putc('\n', file);
|
||||
return;
|
||||
}
|
||||
if (rrnum == 0 && sflag != 0 && (_res.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 {
|
||||
n = ns_sprintrr(handle, &rr, NULL, NULL,
|
||||
buf, sizeof buf);
|
||||
if (n < 0) {
|
||||
fprintf(file, ";; ns_sprintrr: %s\n",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
fputs(buf, file);
|
||||
fputc('\n', file);
|
||||
}
|
||||
rrnum++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
p_query(const u_char *msg) {
|
||||
fp_query(msg, stdout);
|
||||
}
|
||||
|
||||
void
|
||||
fp_query(const u_char *msg, FILE *file) {
|
||||
fp_nquery(msg, PACKETSZ, file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the contents of a query.
|
||||
* This is intended to be primarily a debugging routine.
|
||||
*/
|
||||
void
|
||||
fp_nquery(const u_char *msg, int len, FILE *file) {
|
||||
ns_msg handle;
|
||||
int qdcount, ancount, nscount, arcount;
|
||||
u_int opcode, rcode, id;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return;
|
||||
|
||||
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 ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || rcode)
|
||||
fprintf(file,
|
||||
";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
|
||||
_res_opcodes[opcode], _res_resultcodes[rcode], id);
|
||||
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
|
||||
putc(';', file);
|
||||
if ((!_res.pfcode) || (_res.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 ((!_res.pfcode) || (_res.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 ((!_res.pfcode) || (_res.pfcode &
|
||||
(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
|
||||
putc('\n',file);
|
||||
}
|
||||
/*
|
||||
* Print the various sections.
|
||||
*/
|
||||
do_section(&handle, ns_s_qd, RES_PRF_QUES, file);
|
||||
do_section(&handle, ns_s_an, RES_PRF_ANS, file);
|
||||
do_section(&handle, ns_s_ns, RES_PRF_AUTH, file);
|
||||
do_section(&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"},
|
||||
{C_CHAOS, "CHAOS"},
|
||||
{C_HS, "HS"},
|
||||
{C_HS, "HESIOD"},
|
||||
{C_ANY, "ANY"},
|
||||
{C_NONE, "NONE"},
|
||||
{C_IN, (char *)0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of message sections.
|
||||
*/
|
||||
static const struct res_sym __p_default_section_syms[] = {
|
||||
{ns_s_qd, "QUERY"},
|
||||
{ns_s_an, "ANSWER"},
|
||||
{ns_s_ns, "AUTHORITY"},
|
||||
{ns_s_ar, "ADDITIONAL"},
|
||||
{0, (char *)0}
|
||||
};
|
||||
|
||||
static const struct res_sym __p_update_section_syms[] = {
|
||||
{S_ZONE, "ZONE"},
|
||||
{S_PREREQ, "PREREQUISITE"},
|
||||
{S_UPDATE, "UPDATE"},
|
||||
{S_ADDT, "ADDITIONAL"},
|
||||
{0, (char *)0}
|
||||
};
|
||||
|
||||
/*
|
||||
* 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[] = {
|
||||
{T_A, "A", "address"},
|
||||
{T_NS, "NS", "name server"},
|
||||
{T_MD, "MD", "mail destination (deprecated)"},
|
||||
{T_MF, "MF", "mail forwarder (deprecated)"},
|
||||
{T_CNAME, "CNAME", "canonical name"},
|
||||
{T_SOA, "SOA", "start of authority"},
|
||||
{T_MB, "MB", "mailbox"},
|
||||
{T_MG, "MG", "mail group member"},
|
||||
{T_MR, "MR", "mail rename"},
|
||||
{T_NULL, "NULL", "null"},
|
||||
{T_WKS, "WKS", "well-known service (deprecated)"},
|
||||
{T_PTR, "PTR", "domain name pointer"},
|
||||
{T_HINFO, "HINFO", "host information"},
|
||||
{T_MINFO, "MINFO", "mailbox information"},
|
||||
{T_MX, "MX", "mail exchanger"},
|
||||
{T_TXT, "TXT", "text"},
|
||||
{T_RP, "RP", "responsible person"},
|
||||
{T_AFSDB, "AFSDB", "DCE or AFS server"},
|
||||
{T_X25, "X25", "X25 address"},
|
||||
{T_ISDN, "ISDN", "ISDN address"},
|
||||
{T_RT, "RT", "router"},
|
||||
{T_NSAP, "NSAP", "nsap address"},
|
||||
{T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
|
||||
{T_SIG, "SIG", "signature"},
|
||||
{T_KEY, "KEY", "key"},
|
||||
{T_PX, "PX", "mapping information"},
|
||||
{T_GPOS, "GPOS", "geographical position (withdrawn)"},
|
||||
{T_AAAA, "AAAA", "IPv6 address"},
|
||||
{T_LOC, "LOC", "location"},
|
||||
{T_NXT, "NXT", "next valid name (unimplemented)"},
|
||||
{T_EID, "EID", "endpoint identifier (unimplemented)"},
|
||||
{T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
|
||||
{T_SRV, "SRV", "server selection"},
|
||||
{T_ATMA, "ATMA", "ATM address (unimplemented)"},
|
||||
{T_IXFR, "IXFR", "incremental zone transfer"},
|
||||
{T_AXFR, "AXFR", "zone transfer"},
|
||||
{T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
|
||||
{T_MAILA, "MAILA", "mail agent (deprecated)"},
|
||||
{T_NAPTR, "NAPTR", "URN Naming Authority"},
|
||||
{T_ANY, "ANY", "\"any\""},
|
||||
{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) {
|
||||
static char unname[20];
|
||||
|
||||
for ((void)NULL; syms->name != 0; syms++) {
|
||||
if (number == syms->number) {
|
||||
if (success)
|
||||
*success = 1;
|
||||
return (syms->name);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(unname, "%d", number);
|
||||
if (success)
|
||||
*success = 0;
|
||||
return (unname);
|
||||
}
|
||||
|
||||
const char *
|
||||
sym_ntop(const struct res_sym *syms, int number, int *success) {
|
||||
static char unname[20];
|
||||
|
||||
for ((void)NULL; syms->name != 0; syms++) {
|
||||
if (number == syms->number) {
|
||||
if (success)
|
||||
*success = 1;
|
||||
return (syms->humanname);
|
||||
}
|
||||
}
|
||||
sprintf(unname, "%d", number);
|
||||
if (success)
|
||||
*success = 0;
|
||||
return (unname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string for the type.
|
||||
*/
|
||||
const char *
|
||||
p_type(int type) {
|
||||
return (sym_ntos(__p_type_syms, type, (int *)0));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
return (sym_ntos(__p_class_syms, class, (int *)0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a mnemonic for an option
|
||||
*/
|
||||
const char *
|
||||
p_option(u_long option) {
|
||||
static char nbuf[40];
|
||||
|
||||
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";
|
||||
case RES_NOTLDQUERY: return "no-tld-query";
|
||||
case RES_USE_EDNS0: return "edns0";
|
||||
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) {
|
||||
static char nbuf[40];
|
||||
|
||||
if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
|
||||
sprintf(nbuf, "%u", value);
|
||||
return (nbuf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
{
|
||||
static char retbuf[sizeof "90000000.00"];
|
||||
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, "%ld.%.2ld", val/100, val%100);
|
||||
return (retbuf);
|
||||
}
|
||||
|
||||
/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
|
||||
static u_int8_t
|
||||
precsize_aton(strptr)
|
||||
char **strptr;
|
||||
{
|
||||
unsigned int mval = 0, cmval = 0;
|
||||
u_int8_t retval = 0;
|
||||
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(latlonstrptr,which)
|
||||
char **latlonstrptr;
|
||||
int *which;
|
||||
{
|
||||
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 char *error = "?";
|
||||
const u_char *cp = binary;
|
||||
|
||||
int latdeg, latmin, latsec, latsecfrac;
|
||||
int longdeg, longmin, longsec, longsecfrac;
|
||||
char northsouth, eastwest;
|
||||
int altmeters, altfrac, altsign;
|
||||
|
||||
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 (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 = -1;
|
||||
} else {
|
||||
altval = templ - referencealt;
|
||||
altsign = 1;
|
||||
}
|
||||
|
||||
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) * altsign;
|
||||
|
||||
if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
|
||||
sizestr = error;
|
||||
if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
|
||||
hpstr = error;
|
||||
if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
|
||||
vpstr = error;
|
||||
|
||||
sprintf(ascii,
|
||||
"%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
|
||||
latdeg, latmin, latsec, latsecfrac, northsouth,
|
||||
longdeg, longmin, longsec, longsecfrac, eastwest,
|
||||
altmeters, altfrac, sizestr, hpstr, vpstr);
|
||||
|
||||
if (sizestr != error)
|
||||
free(sizestr);
|
||||
if (hpstr != error)
|
||||
free(hpstr);
|
||||
if (vpstr != error)
|
||||
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) {
|
||||
static char output[15]; /* YYYYMMDDHHMMSS and null */
|
||||
time_t clock = secs;
|
||||
struct tm *time;
|
||||
|
||||
time = gmtime(&clock);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <resolv.h>.
|
||||
*/
|
||||
#undef fp_resstat
|
||||
__weak_reference(__fp_resstat, fp_resstat);
|
||||
#undef p_query
|
||||
__weak_reference(__p_query, p_query);
|
||||
#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);
|
@ -1,715 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
|
||||
static char orig_rcsid[] = "From: Id: res_init.c,v 8.7 1996/11/18 09:10:04 vixie Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "namespace.h"
|
||||
#include "reentrant.h"
|
||||
#include "un-namespace.h"
|
||||
#include "res_config.h"
|
||||
#include "res_send_private.h"
|
||||
|
||||
#undef h_errno
|
||||
extern int h_errno;
|
||||
|
||||
static void res_setoptions(char *, char *);
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
static const char sort_mask[] = "/&";
|
||||
#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
|
||||
static u_int32_t net_mask(struct in_addr);
|
||||
#endif
|
||||
|
||||
#if !defined(isascii) /* XXX - could be a function */
|
||||
# define isascii(c) (!(c & 0200))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check structure for failed per-thread allocations.
|
||||
*/
|
||||
static struct res_per_thread {
|
||||
struct __res_state res_state;
|
||||
struct __res_state_ext res_state_ext;
|
||||
struct __res_send_private res_send_private;
|
||||
int h_errno;
|
||||
} _res_per_thread_bogus = { .res_send_private = { .s = -1 } }; /* socket */
|
||||
|
||||
/*
|
||||
* Set up default settings. If the configuration file exist, the values
|
||||
* there will have precedence. Otherwise, the server address is set to
|
||||
* INADDR_ANY and the default domain name comes from the gethostname().
|
||||
*
|
||||
* An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
|
||||
* rather than INADDR_ANY ("0.0.0.0") as the default name server address
|
||||
* since it was noted that INADDR_ANY actually meant ``the first interface
|
||||
* you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
|
||||
* it had to be "up" in order for you to reach your own name server. It
|
||||
* was later decided that since the recommended practice is to always
|
||||
* install local static routes through 127.0.0.1 for all your network
|
||||
* interfaces, that we could solve this problem without a code change.
|
||||
*
|
||||
* The configuration file should always be used, since it is the only way
|
||||
* to specify a default domain. If you are running a server on your local
|
||||
* machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
|
||||
* in the configuration file.
|
||||
*
|
||||
* Return 0 if completes successfully, -1 on error
|
||||
*/
|
||||
int
|
||||
res_init()
|
||||
{
|
||||
FILE *fp;
|
||||
struct __res_send_private *rsp;
|
||||
char *cp, **pp;
|
||||
int n;
|
||||
char buf[MAXDNAME];
|
||||
int nserv = 0; /* number of nameserver records read from file */
|
||||
int haveenv = 0;
|
||||
int havesearch = 0;
|
||||
#ifdef RESOLVSORT
|
||||
int nsort = 0;
|
||||
char *net;
|
||||
#endif
|
||||
#ifndef RFC1535
|
||||
int dots;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If allocation of memory for this thread's resolver has failed,
|
||||
* return the error to the user.
|
||||
*/
|
||||
if (&_res == &_res_per_thread_bogus.res_state)
|
||||
return (-1);
|
||||
rsp = ___res_send_private();
|
||||
rsp->s = -1;
|
||||
rsp->connected = 0;
|
||||
rsp->vc = 0;
|
||||
rsp->af = 0;
|
||||
rsp->Qhook = NULL;
|
||||
rsp->Rhook = NULL;
|
||||
/*
|
||||
* These three fields used to be statically initialized. This made
|
||||
* it hard to use this code in a shared library. It is necessary,
|
||||
* now that we're doing dynamic initialization here, that we preserve
|
||||
* the old semantics: if an application modifies one of these three
|
||||
* fields of _res before res_init() is called, res_init() will not
|
||||
* alter them. Of course, if an application is setting them to
|
||||
* _zero_ before calling res_init(), hoping to override what used
|
||||
* to be the static default, we can't detect it and unexpected results
|
||||
* will follow. Zero for any of these fields would make no sense,
|
||||
* so one can safely assume that the applications were already getting
|
||||
* unexpected results.
|
||||
*
|
||||
* _res.options is tricky since some apps were known to diddle the bits
|
||||
* before res_init() was first called. We can't replicate that semantic
|
||||
* with dynamic initialization (they may have turned bits off that are
|
||||
* set in RES_DEFAULT). Our solution is to declare such applications
|
||||
* "broken". They could fool us by setting RES_INIT but none do (yet).
|
||||
*/
|
||||
if (!_res.retrans)
|
||||
_res.retrans = RES_TIMEOUT;
|
||||
if (!_res.retry)
|
||||
_res.retry = RES_DFLRETRY;
|
||||
if (!(_res.options & RES_INIT))
|
||||
_res.options = RES_DEFAULT;
|
||||
|
||||
/*
|
||||
* This one used to initialize implicitly to zero, so unless the app
|
||||
* has set it to something in particular, we can randomize it now.
|
||||
*/
|
||||
if (!_res.id)
|
||||
_res.id = res_randomid();
|
||||
|
||||
#ifdef USELOOPBACK
|
||||
_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
|
||||
#else
|
||||
_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
_res.nsaddr.sin_family = AF_INET;
|
||||
_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
|
||||
_res.nsaddr.sin_len = sizeof(struct sockaddr_in);
|
||||
if (sizeof(_res_ext.nsaddr) >= _res.nsaddr.sin_len)
|
||||
memcpy(&_res_ext.nsaddr, &_res.nsaddr, _res.nsaddr.sin_len);
|
||||
_res.nscount = 1;
|
||||
_res.ndots = 1;
|
||||
_res.pfcode = 0;
|
||||
|
||||
/* Allow user to override the local domain definition */
|
||||
if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
|
||||
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
_res.defdname[sizeof(_res.defdname) - 1] = '\0';
|
||||
haveenv++;
|
||||
|
||||
/*
|
||||
* Set search list to be blank-separated strings
|
||||
* from rest of env value. Permits users of LOCALDOMAIN
|
||||
* to still have a search list, and anyone to set the
|
||||
* one that they want to use as an individual (even more
|
||||
* important now that the rfc1535 stuff restricts searches)
|
||||
*/
|
||||
cp = _res.defdname;
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = cp;
|
||||
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
|
||||
if (*cp == '\n') /* silly backwards compat */
|
||||
break;
|
||||
else if (*cp == ' ' || *cp == '\t') {
|
||||
*cp = 0;
|
||||
n = 1;
|
||||
} else if (n) {
|
||||
*pp++ = cp;
|
||||
n = 0;
|
||||
havesearch = 1;
|
||||
}
|
||||
}
|
||||
/* null terminate last domain if there are excess */
|
||||
while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
|
||||
cp++;
|
||||
*cp = '\0';
|
||||
*pp++ = 0;
|
||||
}
|
||||
|
||||
#define MATCH(line, name) \
|
||||
(!strncmp(line, name, sizeof(name) - 1) && \
|
||||
(line[sizeof(name) - 1] == ' ' || \
|
||||
line[sizeof(name) - 1] == '\t'))
|
||||
|
||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||
/* read the config file */
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
/* skip comments */
|
||||
if (*buf == ';' || *buf == '#')
|
||||
continue;
|
||||
/* read default domain name */
|
||||
if (MATCH(buf, "domain")) {
|
||||
if (haveenv) /* skip if have from environ */
|
||||
continue;
|
||||
cp = buf + sizeof("domain") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
_res.defdname[sizeof(_res.defdname) - 1] = '\0';
|
||||
if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
|
||||
*cp = '\0';
|
||||
havesearch = 0;
|
||||
continue;
|
||||
}
|
||||
/* set search list */
|
||||
if (MATCH(buf, "search")) {
|
||||
if (haveenv) /* skip if have from environ */
|
||||
continue;
|
||||
cp = buf + sizeof("search") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
_res.defdname[sizeof(_res.defdname) - 1] = '\0';
|
||||
if ((cp = strchr(_res.defdname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
/*
|
||||
* Set search list to be blank-separated strings
|
||||
* on rest of line.
|
||||
*/
|
||||
cp = _res.defdname;
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = cp;
|
||||
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
*cp = 0;
|
||||
n = 1;
|
||||
} else if (n) {
|
||||
*pp++ = cp;
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
/* null terminate last domain if there are excess */
|
||||
while (*cp != '\0' && *cp != ' ' && *cp != '\t')
|
||||
cp++;
|
||||
*cp = '\0';
|
||||
*pp++ = 0;
|
||||
havesearch = 1;
|
||||
continue;
|
||||
}
|
||||
/* read nameservers to query */
|
||||
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
|
||||
char *q;
|
||||
struct addrinfo hints, *res;
|
||||
char pbuf[NI_MAXSERV];
|
||||
|
||||
cp = buf + sizeof("nameserver") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
for (q = cp; *q; q++) {
|
||||
if (isspace(*q)) {
|
||||
*q = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
snprintf(pbuf, sizeof(pbuf), "%d", NAMESERVER_PORT);
|
||||
if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
|
||||
res->ai_next == NULL) {
|
||||
if (res->ai_addrlen <= sizeof(_res_ext.nsaddr_list[nserv])) {
|
||||
memcpy(&_res_ext.nsaddr_list[nserv], res->ai_addr,
|
||||
res->ai_addrlen);
|
||||
} else {
|
||||
memset(&_res_ext.nsaddr_list[nserv], 0,
|
||||
sizeof(_res_ext.nsaddr_list[nserv]));
|
||||
}
|
||||
if (res->ai_addrlen <= sizeof(_res.nsaddr_list[nserv])) {
|
||||
memcpy(&_res.nsaddr_list[nserv], res->ai_addr,
|
||||
res->ai_addrlen);
|
||||
} else {
|
||||
memset(&_res.nsaddr_list[nserv], 0,
|
||||
sizeof(_res.nsaddr_list[nserv]));
|
||||
}
|
||||
nserv++;
|
||||
}
|
||||
if (res)
|
||||
freeaddrinfo(res);
|
||||
continue;
|
||||
}
|
||||
#ifdef RESOLVSORT
|
||||
if (MATCH(buf, "sortlist")) {
|
||||
struct in_addr a;
|
||||
struct in6_addr a6;
|
||||
int m, i;
|
||||
u_char *u;
|
||||
|
||||
cp = buf + sizeof("sortlist") - 1;
|
||||
while (nsort < MAXRESOLVSORT) {
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if (*cp == '\0' || *cp == '\n' || *cp == ';')
|
||||
break;
|
||||
net = cp;
|
||||
while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
|
||||
isascii(*cp) && !isspace(*cp))
|
||||
cp++;
|
||||
n = *cp;
|
||||
*cp = 0;
|
||||
if (inet_aton(net, &a)) {
|
||||
_res.sort_list[nsort].addr = a;
|
||||
if (ISSORTMASK(n)) {
|
||||
*cp++ = n;
|
||||
net = cp;
|
||||
while (*cp && *cp != ';' &&
|
||||
isascii(*cp) && !isspace(*cp))
|
||||
cp++;
|
||||
n = *cp;
|
||||
*cp = 0;
|
||||
if (inet_aton(net, &a)) {
|
||||
_res.sort_list[nsort].mask = a.s_addr;
|
||||
} else {
|
||||
_res.sort_list[nsort].mask =
|
||||
net_mask(_res.sort_list[nsort].addr);
|
||||
}
|
||||
} else {
|
||||
_res.sort_list[nsort].mask =
|
||||
net_mask(_res.sort_list[nsort].addr);
|
||||
}
|
||||
_res_ext.sort_list[nsort].af = AF_INET;
|
||||
_res_ext.sort_list[nsort].addr.ina =
|
||||
_res.sort_list[nsort].addr;
|
||||
_res_ext.sort_list[nsort].mask.ina.s_addr =
|
||||
_res.sort_list[nsort].mask;
|
||||
nsort++;
|
||||
}
|
||||
else if (inet_pton(AF_INET6, net, &a6) == 1) {
|
||||
|
||||
_res_ext.sort_list[nsort].af = AF_INET6;
|
||||
_res_ext.sort_list[nsort].addr.in6a = a6;
|
||||
u = (u_char *)&_res_ext.sort_list[nsort].mask.in6a;
|
||||
*cp++ = n;
|
||||
net = cp;
|
||||
while (*cp && *cp != ';' &&
|
||||
isascii(*cp) && !isspace(*cp))
|
||||
cp++;
|
||||
m = n;
|
||||
n = *cp;
|
||||
*cp = 0;
|
||||
switch (m) {
|
||||
case '/':
|
||||
m = atoi(net);
|
||||
break;
|
||||
case '&':
|
||||
if (inet_pton(AF_INET6, net, u) == 1) {
|
||||
m = -1;
|
||||
break;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
m = sizeof(struct in6_addr) * CHAR_BIT;
|
||||
break;
|
||||
}
|
||||
if (m >= 0) {
|
||||
for (i = 0; i < sizeof(struct in6_addr); i++) {
|
||||
if (m <= 0) {
|
||||
*u = 0;
|
||||
} else {
|
||||
m -= CHAR_BIT;
|
||||
*u = (u_char)~0;
|
||||
if (m < 0)
|
||||
*u <<= -m;
|
||||
}
|
||||
u++;
|
||||
}
|
||||
}
|
||||
_res.sort_list[nsort].addr.s_addr =
|
||||
(u_int32_t)0xffffffff;
|
||||
_res.sort_list[nsort].mask = (u_int32_t)0xffffffff;
|
||||
nsort++;
|
||||
}
|
||||
*cp = n;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (MATCH(buf, "options")) {
|
||||
res_setoptions(buf + sizeof("options") - 1, "conf");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (nserv > 1)
|
||||
_res.nscount = nserv;
|
||||
#ifdef RESOLVSORT
|
||||
_res.nsort = nsort;
|
||||
#endif
|
||||
(void) fclose(fp);
|
||||
}
|
||||
if (_res.defdname[0] == 0 &&
|
||||
gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
|
||||
(cp = strchr(buf, '.')) != NULL)
|
||||
strcpy(_res.defdname, cp + 1);
|
||||
|
||||
/* find components of local domain that might be searched */
|
||||
if (havesearch == 0) {
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = _res.defdname;
|
||||
*pp = NULL;
|
||||
|
||||
#ifndef RFC1535
|
||||
dots = 0;
|
||||
for (cp = _res.defdname; *cp; cp++)
|
||||
dots += (*cp == '.');
|
||||
|
||||
cp = _res.defdname;
|
||||
while (pp < _res.dnsrch + MAXDFLSRCH) {
|
||||
if (dots < LOCALDOMAINPARTS)
|
||||
break;
|
||||
cp = strchr(cp, '.') + 1; /* we know there is one */
|
||||
*pp++ = cp;
|
||||
dots--;
|
||||
}
|
||||
*pp = NULL;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG) {
|
||||
printf(";; res_init()... default dnsrch list:\n");
|
||||
for (pp = _res.dnsrch; *pp; pp++)
|
||||
printf(";;\t%s\n", *pp);
|
||||
printf(";;\t..END..\n");
|
||||
}
|
||||
#endif
|
||||
#endif /* !RFC1535 */
|
||||
}
|
||||
|
||||
if (issetugid())
|
||||
_res.options |= RES_NOALIASES;
|
||||
else if ((cp = getenv("RES_OPTIONS")) != NULL)
|
||||
res_setoptions(cp, "env");
|
||||
_res.options |= RES_INIT;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
res_setoptions(options, source)
|
||||
char *options, *source;
|
||||
{
|
||||
char *cp = options;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_setoptions(\"%s\", \"%s\")...\n",
|
||||
options, source);
|
||||
#endif
|
||||
while (*cp) {
|
||||
/* skip leading and inner runs of spaces */
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
/* search for and process individual options */
|
||||
if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
|
||||
i = atoi(cp + sizeof("ndots:") - 1);
|
||||
if (i <= RES_MAXNDOTS)
|
||||
_res.ndots = i;
|
||||
else
|
||||
_res.ndots = RES_MAXNDOTS;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";;\tndots=%d\n", _res.ndots);
|
||||
#endif
|
||||
} else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) {
|
||||
i = atoi(cp + sizeof("timeout:") - 1);
|
||||
if (i <= RES_MAXRETRANS)
|
||||
_res.retrans = i;
|
||||
else
|
||||
_res.retrans = RES_MAXRETRANS;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";;\ttimeout=%d\n", _res.retrans);
|
||||
#endif
|
||||
} else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
|
||||
i = atoi(cp + sizeof("attempts:") - 1);
|
||||
if (i <= RES_MAXRETRY)
|
||||
_res.retry = i;
|
||||
else
|
||||
_res.retry = RES_MAXRETRY;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";;\tretry=%d\n", _res.retry);
|
||||
#endif
|
||||
} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
|
||||
#ifdef DEBUG
|
||||
if (!(_res.options & RES_DEBUG)) {
|
||||
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
|
||||
options, source);
|
||||
_res.options |= RES_DEBUG;
|
||||
}
|
||||
printf(";;\tdebug\n");
|
||||
#endif
|
||||
} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
|
||||
_res.options |= RES_USE_INET6;
|
||||
} else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) {
|
||||
_res.options |= RES_INSECURE1;
|
||||
} else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) {
|
||||
_res.options |= RES_INSECURE2;
|
||||
} else if (!strncmp(cp, "no_tld_query", sizeof("no_tld_query") - 1)) {
|
||||
_res.options |= RES_NOTLDQUERY;
|
||||
} else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
|
||||
_res.options |= RES_USE_EDNS0;
|
||||
} else {
|
||||
/* XXX - print a warning here? */
|
||||
}
|
||||
/* skip to next run of spaces */
|
||||
while (*cp && *cp != ' ' && *cp != '\t')
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
/* XXX - should really support CIDR which means explicit masks always. */
|
||||
static u_int32_t
|
||||
net_mask(in) /* XXX - should really use system's version of this */
|
||||
struct in_addr in;
|
||||
{
|
||||
u_int32_t i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return (htonl(IN_CLASSA_NET));
|
||||
else if (IN_CLASSB(i))
|
||||
return (htonl(IN_CLASSB_NET));
|
||||
return (htonl(IN_CLASSC_NET));
|
||||
}
|
||||
#endif
|
||||
|
||||
u_int
|
||||
res_randomid()
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolver state default settings.
|
||||
*/
|
||||
|
||||
#undef _res
|
||||
#undef _res_ext
|
||||
#ifdef __BIND_RES_TEXT
|
||||
struct __res_state _res = { RES_TIMEOUT }; /* Motorola, et al. */
|
||||
#else
|
||||
struct __res_state _res;
|
||||
#endif
|
||||
struct __res_state_ext _res_ext;
|
||||
static struct __res_send_private _res_send_private = { .s = -1 }; /* socket */
|
||||
|
||||
static thread_key_t res_key;
|
||||
static once_t res_init_once = ONCE_INITIALIZER;
|
||||
static int res_thr_keycreated = 0;
|
||||
|
||||
static void
|
||||
free_res(void *ptr)
|
||||
{
|
||||
struct res_per_thread *myrsp = ptr;
|
||||
|
||||
if (myrsp->res_state.options & RES_INIT)
|
||||
res_close();
|
||||
free(myrsp);
|
||||
}
|
||||
|
||||
static void
|
||||
res_keycreate(void)
|
||||
{
|
||||
res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0;
|
||||
}
|
||||
|
||||
static struct res_per_thread *
|
||||
allocate_res(void)
|
||||
{
|
||||
struct res_per_thread *myrsp;
|
||||
|
||||
if (thr_once(&res_init_once, res_keycreate) != 0 ||
|
||||
!res_thr_keycreated)
|
||||
return (&_res_per_thread_bogus);
|
||||
|
||||
myrsp = thr_getspecific(res_key);
|
||||
if (myrsp != NULL)
|
||||
return (myrsp);
|
||||
myrsp = calloc(1, sizeof(*myrsp));
|
||||
if (myrsp == NULL)
|
||||
return (&_res_per_thread_bogus);
|
||||
#ifdef __BIND_RES_TEXT
|
||||
myrsp->res_state.options = RES_TIMEOUT; /* Motorola, et al. */
|
||||
#endif
|
||||
myrsp->res_send_private.s = -1; /* socket */
|
||||
if (thr_setspecific(res_key, myrsp) == 0)
|
||||
return (myrsp);
|
||||
free(myrsp);
|
||||
return (&_res_per_thread_bogus);
|
||||
}
|
||||
|
||||
struct __res_state *
|
||||
___res(void)
|
||||
{
|
||||
if (thr_main() != 0)
|
||||
return (&_res);
|
||||
return (&allocate_res()->res_state);
|
||||
}
|
||||
|
||||
struct __res_state_ext *
|
||||
___res_ext(void)
|
||||
{
|
||||
if (thr_main() != 0)
|
||||
return (&_res_ext);
|
||||
return (&allocate_res()->res_state_ext);
|
||||
}
|
||||
|
||||
struct __res_send_private *
|
||||
___res_send_private(void)
|
||||
{
|
||||
if (thr_main() != 0)
|
||||
return (&_res_send_private);
|
||||
return (&allocate_res()->res_send_private);
|
||||
}
|
||||
|
||||
int *
|
||||
__h_error(void)
|
||||
{
|
||||
if (thr_main() != 0)
|
||||
return (&h_errno);
|
||||
return (&allocate_res()->h_errno);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <resolv.h>.
|
||||
*/
|
||||
#undef res_init
|
||||
__weak_reference(__res_init, res_init);
|
@ -1,246 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
/*
|
||||
* Form all types of queries.
|
||||
* Returns the size of the result or -1.
|
||||
*/
|
||||
int
|
||||
res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
|
||||
int op; /* opcode of query */
|
||||
const char *dname; /* domain name */
|
||||
int class, 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;
|
||||
int n;
|
||||
u_char *dnptrs[20], **dpp, **lastdnptr;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_mkquery(%d, %s, %d, %d)\n",
|
||||
op, dname, class, type);
|
||||
#endif
|
||||
/*
|
||||
* Initialize header fields.
|
||||
*/
|
||||
if ((buf == NULL) || (buflen < HFIXEDSZ))
|
||||
return (-1);
|
||||
memset(buf, 0, HFIXEDSZ);
|
||||
hp = (HEADER *) buf;
|
||||
hp->id = htons(++_res.id);
|
||||
hp->opcode = op;
|
||||
hp->rd = (_res.options & RES_RECURSE) != 0;
|
||||
hp->rcode = NOERROR;
|
||||
cp = buf + HFIXEDSZ;
|
||||
buflen -= HFIXEDSZ;
|
||||
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 ((buflen -= QFIXEDSZ) < 0)
|
||||
return (-1);
|
||||
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
buflen -= n;
|
||||
__putshort(type, cp);
|
||||
cp += INT16SZ;
|
||||
__putshort(class, cp);
|
||||
cp += INT16SZ;
|
||||
hp->qdcount = htons(1);
|
||||
if (op == QUERY || data == NULL)
|
||||
break;
|
||||
/*
|
||||
* Make an additional record for completion domain.
|
||||
*/
|
||||
buflen -= RRFIXEDSZ;
|
||||
n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
buflen -= n;
|
||||
__putshort(T_NULL, cp);
|
||||
cp += INT16SZ;
|
||||
__putshort(class, cp);
|
||||
cp += INT16SZ;
|
||||
__putlong(0, cp);
|
||||
cp += INT32SZ;
|
||||
__putshort(0, cp);
|
||||
cp += INT16SZ;
|
||||
hp->arcount = htons(1);
|
||||
break;
|
||||
|
||||
case IQUERY:
|
||||
/*
|
||||
* Initialize answer section
|
||||
*/
|
||||
if (buflen < 1 + RRFIXEDSZ + datalen)
|
||||
return (-1);
|
||||
*cp++ = '\0'; /* no domain name */
|
||||
__putshort(type, cp);
|
||||
cp += INT16SZ;
|
||||
__putshort(class, cp);
|
||||
cp += INT16SZ;
|
||||
__putlong(0, cp);
|
||||
cp += INT32SZ;
|
||||
__putshort(datalen, cp);
|
||||
cp += INT16SZ;
|
||||
if (datalen) {
|
||||
memcpy(cp, data, datalen);
|
||||
cp += datalen;
|
||||
}
|
||||
hp->ancount = htons(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
return (cp - buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <resolv.h>.
|
||||
*/
|
||||
#undef res_mkquery
|
||||
__weak_reference(__res_mkquery, res_mkquery);
|
||||
|
||||
/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
|
||||
int
|
||||
res_opt(n0, buf, buflen, anslen)
|
||||
int n0;
|
||||
u_char *buf; /* buffer to put query */
|
||||
int buflen; /* size of buffer */
|
||||
int anslen; /* answer buffer length */
|
||||
{
|
||||
HEADER *hp;
|
||||
u_char *cp;
|
||||
|
||||
hp = (HEADER *) buf;
|
||||
cp = buf + n0;
|
||||
buflen -= n0;
|
||||
|
||||
if (buflen < 1 + RRFIXEDSZ)
|
||||
return -1;
|
||||
|
||||
*cp++ = 0; /* "." */
|
||||
buflen--;
|
||||
|
||||
__putshort(T_OPT, cp); /* TYPE */
|
||||
cp += INT16SZ;
|
||||
if (anslen > 0xffff)
|
||||
anslen = 0xffff; /* limit to 16bit value */
|
||||
__putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */
|
||||
cp += INT16SZ;
|
||||
*cp++ = NOERROR; /* extended RCODE */
|
||||
*cp++ = 0; /* EDNS version */
|
||||
__putshort(0, cp); /* MBZ */
|
||||
cp += INT16SZ;
|
||||
__putshort(0, cp); /* RDLEN */
|
||||
cp += INT16SZ;
|
||||
hp->arcount = htons(ntohs(hp->arcount) + 1);
|
||||
buflen -= RRFIXEDSZ;
|
||||
|
||||
return cp - buf;
|
||||
}
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "res_update.h"
|
||||
#include "res_config.h"
|
||||
|
||||
static int getnum_str(u_char **, u_char *);
|
||||
@ -73,7 +74,7 @@ res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
|
||||
u_char *dnptrs[20], **dpp, **lastdnptr;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -1,478 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "$Id: res_query.c,v 8.14 1997/06/09 17:47:05 halley Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
const char *_res_hostalias(const char *, char *, size_t);
|
||||
|
||||
/*
|
||||
* 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_query(name, class, type, answer, anslen)
|
||||
const char *name; /* domain name */
|
||||
int class, 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;
|
||||
|
||||
hp->rcode = NOERROR; /* default */
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_query(%s, %d, %d)\n", name, class, type);
|
||||
#endif
|
||||
|
||||
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
|
||||
buf, sizeof(buf));
|
||||
if (n > 0 && (_res.options & RES_USE_EDNS0) != 0)
|
||||
n = res_opt(n, buf, sizeof(buf), anslen);
|
||||
if (n <= 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_query: mkquery failed\n");
|
||||
#endif
|
||||
h_errno = NO_RECOVERY;
|
||||
return (n);
|
||||
}
|
||||
n = res_send(buf, n, answer, anslen);
|
||||
if (n < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_query: send error\n");
|
||||
#endif
|
||||
h_errno = TRY_AGAIN;
|
||||
return (n);
|
||||
}
|
||||
|
||||
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; rcode = %d, ancount=%d\n", hp->rcode,
|
||||
ntohs(hp->ancount));
|
||||
#endif
|
||||
switch (hp->rcode) {
|
||||
case NXDOMAIN:
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
break;
|
||||
case SERVFAIL:
|
||||
h_errno = TRY_AGAIN;
|
||||
break;
|
||||
case NOERROR:
|
||||
h_errno = NO_DATA;
|
||||
break;
|
||||
case FORMERR:
|
||||
case NOTIMP:
|
||||
case REFUSED:
|
||||
default:
|
||||
h_errno = 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_search(name, class, type, answer, anslen)
|
||||
const char *name; /* domain name */
|
||||
int class, type; /* class and type of query */
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer */
|
||||
{
|
||||
const char *cp, * const *domain;
|
||||
char tmp[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;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
errno = 0;
|
||||
h_errno = HOST_NOT_FOUND; /* default, if we never query */
|
||||
dots = 0;
|
||||
for (cp = name; *cp; 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(name, tmp, sizeof tmp)) != NULL)
|
||||
return (res_query(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 >= _res.ndots || trailing_dot) {
|
||||
ret = res_querydomain(name, NULL, class, type, answer, anslen);
|
||||
if (ret > 0 || trailing_dot)
|
||||
return (ret);
|
||||
if (errno == ECONNREFUSED) {
|
||||
h_errno = TRY_AGAIN;
|
||||
return (-1);
|
||||
}
|
||||
switch (h_errno) {
|
||||
case NO_DATA:
|
||||
case HOST_NOT_FOUND:
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
saved_herrno = 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 && (_res.options & RES_DEFNAMES)) ||
|
||||
(dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
|
||||
int done = 0;
|
||||
|
||||
for (domain = (const char * const *)_res.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_querydomain(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) {
|
||||
h_errno = TRY_AGAIN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
switch (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 terminate the search
|
||||
* and 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;
|
||||
/* 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 (!(_res.options & RES_DNSRCH))
|
||||
done++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (h_errno) {
|
||||
case NO_DATA:
|
||||
case HOST_NOT_FOUND:
|
||||
break;
|
||||
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 || !(_res.options & RES_NOTLDQUERY)) &&
|
||||
!(tried_as_is || root_on_list)) {
|
||||
ret = res_querydomain(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)
|
||||
h_errno = saved_herrno;
|
||||
else if (got_nodata)
|
||||
h_errno = NO_DATA;
|
||||
else if (got_servfail)
|
||||
h_errno = 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_querydomain(name, domain, class, type, answer, anslen)
|
||||
const char *name, *domain;
|
||||
int class, 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;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_querydomain(%s, %s, %d, %d)\n",
|
||||
name, domain?domain:"<Nil>", class, type);
|
||||
#endif
|
||||
if (domain == NULL) {
|
||||
/*
|
||||
* Check for trailing '.';
|
||||
* copy without '.' if present.
|
||||
*/
|
||||
n = strlen(name);
|
||||
if (n >= MAXDNAME) {
|
||||
h_errno = 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) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (-1);
|
||||
}
|
||||
sprintf(nbuf, "%s.%s", name, domain);
|
||||
}
|
||||
return (res_query(longname, class, type, answer, anslen));
|
||||
}
|
||||
|
||||
const char *
|
||||
_res_hostalias(const char *name, char *dst, size_t siz)
|
||||
{
|
||||
char *file, *cp1, *cp2;
|
||||
char buf[BUFSIZ];
|
||||
FILE *fp;
|
||||
|
||||
if (_res.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 (!strcasecmp(buf, name)) {
|
||||
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);
|
||||
}
|
||||
|
||||
const char *
|
||||
hostalias(const char *name)
|
||||
{
|
||||
static char abuf[MAXDNAME];
|
||||
|
||||
return (_res_hostalias(name, abuf, sizeof abuf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <resolv.h>.
|
||||
*/
|
||||
#undef res_query
|
||||
__weak_reference(__res_query, res_query);
|
||||
#undef res_search
|
||||
__weak_reference(__res_search, res_search);
|
||||
#undef res_querydomain
|
||||
__weak_reference(__res_querydomain, res_querydomain);
|
@ -1,925 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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 char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid[] = "From: Id: res_send.c,v 8.20 1998/04/06 23:27:51 halley Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Send query to name server and wait for reply.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "res_config.h"
|
||||
#include "res_send_private.h"
|
||||
|
||||
|
||||
#define s ___res_send_private()->s
|
||||
#define connected ___res_send_private()->connected
|
||||
#define vc ___res_send_private()->vc
|
||||
#define af ___res_send_private()->af
|
||||
#define Qhook ___res_send_private()->Qhook
|
||||
#define Rhook ___res_send_private()->Rhook
|
||||
|
||||
#define CAN_RECONNECT 1
|
||||
|
||||
#ifndef DEBUG
|
||||
# define Dprint(cond, args) /*empty*/
|
||||
# define DprintQ(cond, args, query, size) /*empty*/
|
||||
# define Aerror(file, string, error, address) /*empty*/
|
||||
# define Perror(file, string, error) /*empty*/
|
||||
#else
|
||||
# define Dprint(cond, args) if (cond) {fprintf args;} else {}
|
||||
# define DprintQ(cond, args, query, size) if (cond) {\
|
||||
fprintf args;\
|
||||
__fp_nquery(query, size, stdout);\
|
||||
} else {}
|
||||
static void Aerror(FILE *, char *, int, struct sockaddr *);
|
||||
static void Perror(FILE *, char *, int);
|
||||
|
||||
static void
|
||||
Aerror(file, string, error, address)
|
||||
FILE *file;
|
||||
char *string;
|
||||
int error;
|
||||
struct sockaddr *address;
|
||||
{
|
||||
int save = errno;
|
||||
|
||||
if (_res.options & RES_DEBUG) {
|
||||
char abuf[NI_MAXHOST];
|
||||
char pbuf[NI_MAXSERV];
|
||||
|
||||
if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
|
||||
pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
|
||||
strncpy(abuf, "?", sizeof(abuf));
|
||||
strncpy(pbuf, "?", sizeof(pbuf));
|
||||
}
|
||||
fprintf(file, "res_send: %s ([%s].%s): %s\n",
|
||||
string, abuf, pbuf, strerror(error));
|
||||
}
|
||||
errno = save;
|
||||
}
|
||||
static void
|
||||
Perror(file, string, error)
|
||||
FILE *file;
|
||||
char *string;
|
||||
int error;
|
||||
{
|
||||
int save = errno;
|
||||
|
||||
if (_res.options & RES_DEBUG) {
|
||||
fprintf(file, "res_send: %s: %s\n",
|
||||
string, strerror(error));
|
||||
}
|
||||
errno = save;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct sockaddr * get_nsaddr(size_t);
|
||||
|
||||
/*
|
||||
* pick appropriate nsaddr_list for use. see res_init() for initialization.
|
||||
*/
|
||||
static struct sockaddr *
|
||||
get_nsaddr(n)
|
||||
size_t n;
|
||||
{
|
||||
|
||||
if (!_res.nsaddr_list[n].sin_family) {
|
||||
/*
|
||||
* - _res_ext.nsaddr_list[n] holds an address that is larger
|
||||
* than struct sockaddr, and
|
||||
* - user code did not update _res.nsaddr_list[n].
|
||||
*/
|
||||
return (struct sockaddr *)&_res_ext.nsaddr_list[n];
|
||||
} else {
|
||||
/*
|
||||
* - user code updated _res.nsaddr_list[n], or
|
||||
* - _res.nsaddr_list[n] has the same content as
|
||||
* _res_ext.nsaddr_list[n].
|
||||
*/
|
||||
return (struct sockaddr *)&_res.nsaddr_list[n];
|
||||
}
|
||||
}
|
||||
|
||||
/* int
|
||||
* res_isourserver(ina)
|
||||
* looks up "ina" in _res.ns_addr_list[]
|
||||
* returns:
|
||||
* 0 : not found
|
||||
* >0 : found
|
||||
* author:
|
||||
* paul vixie, 29may94
|
||||
*/
|
||||
int
|
||||
res_isourserver(inp)
|
||||
const struct sockaddr_in *inp;
|
||||
{
|
||||
const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
|
||||
const struct sockaddr_in6 *srv6;
|
||||
const struct sockaddr_in *srv;
|
||||
int ns, ret;
|
||||
|
||||
ret = 0;
|
||||
switch (inp->sin_family) {
|
||||
case AF_INET6:
|
||||
for (ns = 0; ns < _res.nscount; ns++) {
|
||||
srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
|
||||
if (srv6->sin6_family == in6p->sin6_family &&
|
||||
srv6->sin6_port == in6p->sin6_port &&
|
||||
srv6->sin6_scope_id == in6p->sin6_scope_id &&
|
||||
(IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
|
||||
IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr,
|
||||
&in6p->sin6_addr))) {
|
||||
ret++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AF_INET:
|
||||
for (ns = 0; ns < _res.nscount; ns++) {
|
||||
srv = (struct sockaddr_in *)get_nsaddr(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)) {
|
||||
ret++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* int
|
||||
* res_nameinquery(name, type, class, buf, eom)
|
||||
* look for (name,type,class) in the query section of packet (buf,eom)
|
||||
* requires:
|
||||
* buf + HFIXEDSZ <= eom
|
||||
* returns:
|
||||
* -1 : format error
|
||||
* 0 : not found
|
||||
* >0 : found
|
||||
* author:
|
||||
* paul vixie, 29may94
|
||||
*/
|
||||
int
|
||||
res_nameinquery(name, type, class, buf, eom)
|
||||
const char *name;
|
||||
int type, class;
|
||||
const u_char *buf, *eom;
|
||||
{
|
||||
const u_char *cp = buf + HFIXEDSZ;
|
||||
int qdcount = ntohs(((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 &&
|
||||
strcasecmp(tname, name) == 0)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* int
|
||||
* res_queriesmatch(buf1, eom1, buf2, eom2)
|
||||
* is there a 1:1 mapping of (name,type,class)
|
||||
* in (buf1,eom1) and (buf2,eom2)?
|
||||
* returns:
|
||||
* -1 : format error
|
||||
* 0 : not a 1:1 mapping
|
||||
* >0 : is a 1:1 mapping
|
||||
* author:
|
||||
* paul vixie, 29may94
|
||||
*/
|
||||
int
|
||||
res_queriesmatch(buf1, eom1, buf2, eom2)
|
||||
const u_char *buf1, *eom1;
|
||||
const u_char *buf2, *eom2;
|
||||
{
|
||||
const u_char *cp = buf1 + HFIXEDSZ;
|
||||
int qdcount = ntohs(((HEADER*)buf1)->qdcount);
|
||||
|
||||
if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Only header section present in replies to
|
||||
* dynamic update packets.
|
||||
*/
|
||||
if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
|
||||
(((HEADER *)buf2)->opcode == ns_o_update) )
|
||||
return (1);
|
||||
|
||||
if (qdcount != ntohs(((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_send(buf, buflen, ans, anssiz)
|
||||
const u_char *buf;
|
||||
int buflen;
|
||||
u_char *ans;
|
||||
int anssiz;
|
||||
{
|
||||
HEADER *hp = (HEADER *) buf;
|
||||
HEADER *anhp = (HEADER *) ans;
|
||||
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
|
||||
int kq;
|
||||
u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
/* errno should have been set by res_init() in this case. */
|
||||
return (-1);
|
||||
}
|
||||
if (anssiz < HFIXEDSZ) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
|
||||
(stdout, ";; res_send()\n"), buf, buflen);
|
||||
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
|
||||
gotsomewhere = 0;
|
||||
connreset = 0;
|
||||
terrno = ETIMEDOUT;
|
||||
badns = 0;
|
||||
|
||||
if ((kq = kqueue()) < 0) {
|
||||
Perror(stderr, "kqueue", errno);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send request, RETRY times, or until successful
|
||||
*/
|
||||
for (try = 0; try < _res.retry; try++) {
|
||||
for (ns = 0; ns < _res.nscount; ns++) {
|
||||
char abuf[NI_MAXHOST];
|
||||
struct sockaddr *nsap = get_nsaddr(ns);
|
||||
socklen_t salen;
|
||||
|
||||
if (nsap->sa_len)
|
||||
salen = nsap->sa_len;
|
||||
else if (nsap->sa_family == AF_INET6)
|
||||
salen = sizeof(struct sockaddr_in6);
|
||||
else if (nsap->sa_family == AF_INET)
|
||||
salen = sizeof(struct sockaddr_in);
|
||||
else
|
||||
salen = 0; /*unknown, die on connect*/
|
||||
|
||||
same_ns:
|
||||
if (badns & (1 << ns)) {
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
|
||||
if (Qhook) {
|
||||
int done = 0, loops = 0;
|
||||
|
||||
do {
|
||||
res_sendhookact act;
|
||||
|
||||
act = (*Qhook)(&nsap,
|
||||
&buf, &buflen,
|
||||
ans, anssiz, &resplen);
|
||||
switch (act) {
|
||||
case res_goahead:
|
||||
done = 1;
|
||||
break;
|
||||
case res_nextns:
|
||||
res_close();
|
||||
goto next_ns;
|
||||
case res_done:
|
||||
_close(kq);
|
||||
return (resplen);
|
||||
case res_modified:
|
||||
/* give the hook another try */
|
||||
if (++loops < 42) /*doug adams*/
|
||||
break;
|
||||
/*FALLTHROUGH*/
|
||||
case res_error:
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
_close(kq);
|
||||
return (-1);
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
Dprint((_res.options & RES_DEBUG) &&
|
||||
getnameinfo(nsap, salen, abuf, sizeof(abuf),
|
||||
NULL, 0, NI_NUMERICHOST) == 0,
|
||||
(stdout, ";; Querying server (# %d) address = %s\n",
|
||||
ns + 1, abuf));
|
||||
|
||||
if (v_circuit) {
|
||||
int truncated;
|
||||
struct iovec iov[2];
|
||||
u_short len;
|
||||
u_char *cp;
|
||||
|
||||
/*
|
||||
* Use virtual circuit;
|
||||
* at most one attempt per server.
|
||||
*/
|
||||
try = _res.retry;
|
||||
truncated = 0;
|
||||
if (s < 0 || !vc || hp->opcode == ns_o_update ||
|
||||
af != nsap->sa_family) {
|
||||
if (s >= 0)
|
||||
res_close();
|
||||
|
||||
af = nsap->sa_family;
|
||||
s = _socket(af, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
terrno = errno;
|
||||
Perror(stderr, "socket(vc)", errno);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
errno = 0;
|
||||
if (_connect(s, nsap, salen) < 0) {
|
||||
terrno = errno;
|
||||
Aerror(stderr, "connect/vc",
|
||||
errno, nsap);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
vc = 1;
|
||||
}
|
||||
/*
|
||||
* Send length & message
|
||||
*/
|
||||
putshort((u_short)buflen, (u_char*)&len);
|
||||
iov[0].iov_base = (caddr_t)&len;
|
||||
iov[0].iov_len = INT16SZ;
|
||||
iov[1].iov_base = (caddr_t)buf;
|
||||
iov[1].iov_len = buflen;
|
||||
if (_writev(s, iov, 2) != (INT16SZ + buflen)) {
|
||||
terrno = errno;
|
||||
Perror(stderr, "write failed", errno);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
/*
|
||||
* Receive length & response
|
||||
*/
|
||||
read_len:
|
||||
cp = ans;
|
||||
len = INT16SZ;
|
||||
while ((n = _read(s, (char *)cp, (int)len)) > 0) {
|
||||
cp += n;
|
||||
if ((len -= n) <= 0)
|
||||
break;
|
||||
}
|
||||
if (n <= 0) {
|
||||
terrno = errno;
|
||||
Perror(stderr, "read failed", errno);
|
||||
res_close();
|
||||
/*
|
||||
* 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_close();
|
||||
goto same_ns;
|
||||
}
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
resplen = ns_get16(ans);
|
||||
if (resplen > anssiz) {
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; response truncated\n")
|
||||
);
|
||||
truncated = 1;
|
||||
len = anssiz;
|
||||
} else
|
||||
len = resplen;
|
||||
if (len < HFIXEDSZ) {
|
||||
/*
|
||||
* Undersized message.
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; undersized: %d\n", len));
|
||||
terrno = EMSGSIZE;
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
cp = ans;
|
||||
while (len != 0 &&
|
||||
(n = _read(s, (char *)cp, (int)len)) > 0) {
|
||||
cp += n;
|
||||
len -= n;
|
||||
}
|
||||
if (n <= 0) {
|
||||
terrno = errno;
|
||||
Perror(stderr, "read(vc)", errno);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
if (truncated) {
|
||||
/*
|
||||
* Flush rest of answer
|
||||
* so connection stays in synch.
|
||||
*/
|
||||
anhp->tc = 1;
|
||||
len = resplen - anssiz;
|
||||
while (len != 0) {
|
||||
char junk[PACKETSZ];
|
||||
|
||||
n = (len > sizeof(junk)
|
||||
? sizeof(junk)
|
||||
: len);
|
||||
if ((n = _read(s, junk, n)) > 0)
|
||||
len -= n;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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. Anyway drop the packet and
|
||||
* wait for the correct one.
|
||||
*/
|
||||
if (hp->id != anhp->id) {
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ";; old answer (unexpected):\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto read_len;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Use datagrams.
|
||||
*/
|
||||
struct kevent kv;
|
||||
struct timespec ts;
|
||||
struct timeval timeout, ctv;
|
||||
struct sockaddr_storage from;
|
||||
socklen_t fromlen;
|
||||
|
||||
if (s < 0 || vc || af != nsap->sa_family) {
|
||||
if (vc)
|
||||
res_close();
|
||||
af = nsap->sa_family;
|
||||
s = _socket(af, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
#ifndef CAN_RECONNECT
|
||||
bad_dg_sock:
|
||||
#endif
|
||||
terrno = errno;
|
||||
Perror(stderr, "socket(dg)", errno);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
connected = 0;
|
||||
}
|
||||
#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.
|
||||
* If we have sent queries to at least two servers,
|
||||
* however, we don't want to remain connected,
|
||||
* as we wish to receive answers from the first
|
||||
* server to respond.
|
||||
*
|
||||
* 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 (!(_res.options & RES_INSECURE1) &&
|
||||
(_res.nscount == 1 || (try == 0 && ns == 0))) {
|
||||
/*
|
||||
* Connect only if we are sure we won't
|
||||
* receive a response from another server.
|
||||
*/
|
||||
if (!connected) {
|
||||
if (_connect(s, nsap, salen) < 0) {
|
||||
Aerror(stderr,
|
||||
"connect(dg)",
|
||||
errno, nsap);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
connected = 1;
|
||||
}
|
||||
if (send(s, (char*)buf, buflen, 0) != buflen) {
|
||||
Perror(stderr, "send", errno);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Disconnect if we want to listen
|
||||
* for responses from more than one server.
|
||||
*/
|
||||
if (connected) {
|
||||
#ifdef CAN_RECONNECT
|
||||
/* XXX: any errornous address */
|
||||
struct sockaddr_in no_addr;
|
||||
|
||||
no_addr.sin_family = AF_INET;
|
||||
no_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
no_addr.sin_port = 0;
|
||||
(void) _connect(s,
|
||||
(struct sockaddr *)
|
||||
&no_addr,
|
||||
sizeof no_addr);
|
||||
#else
|
||||
int s1 = _socket(af, SOCK_DGRAM,0);
|
||||
if (s1 < 0)
|
||||
goto bad_dg_sock;
|
||||
(void)_dup2(s1, s);
|
||||
(void)_close(s1);
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; new DG socket\n"))
|
||||
#endif /* CAN_RECONNECT */
|
||||
connected = 0;
|
||||
errno = 0;
|
||||
}
|
||||
#endif /* !CANNOT_CONNECT_DGRAM */
|
||||
if (_sendto(s, (char*)buf, buflen, 0,
|
||||
nsap, salen) != buflen) {
|
||||
Aerror(stderr, "sendto", errno, nsap);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
#ifndef CANNOT_CONNECT_DGRAM
|
||||
}
|
||||
#endif /* !CANNOT_CONNECT_DGRAM */
|
||||
|
||||
/*
|
||||
* Wait for reply
|
||||
*/
|
||||
|
||||
timeout.tv_sec = (_res.retrans << try);
|
||||
if (try > 0)
|
||||
timeout.tv_sec /= _res.nscount;
|
||||
if ((long) timeout.tv_sec <= 0)
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
TIMEVAL_TO_TIMESPEC(&timeout, &ts);
|
||||
(void) gettimeofday(&ctv, NULL);
|
||||
timeradd(&timeout, &ctv, &timeout);
|
||||
wait:
|
||||
if (s < 0) {
|
||||
Perror(stderr, "s out-of-bounds", EMFILE);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
|
||||
EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0,0,0);
|
||||
|
||||
n = _kevent(kq, &kv, 1, &kv, 1, &ts);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR) {
|
||||
(void) gettimeofday(&ctv, NULL);
|
||||
if (timercmp(&ctv, &timeout, <)) {
|
||||
timersub(&timeout, &ctv, &ctv);
|
||||
TIMEVAL_TO_TIMESPEC(&ctv, &ts);
|
||||
goto wait;
|
||||
}
|
||||
}
|
||||
Perror(stderr, "kevent", errno);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
/*
|
||||
* timeout
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; timeout\n"));
|
||||
gotsomewhere = 1;
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
errno = 0;
|
||||
fromlen = sizeof(from);
|
||||
resplen = _recvfrom(s, (char*)ans, anssiz, 0,
|
||||
(struct sockaddr *)&from, &fromlen);
|
||||
if (resplen <= 0) {
|
||||
Perror(stderr, "recvfrom", errno);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
gotsomewhere = 1;
|
||||
if (resplen < HFIXEDSZ) {
|
||||
/*
|
||||
* Undersized message.
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; undersized: %d\n",
|
||||
resplen));
|
||||
terrno = EMSGSIZE;
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
if (hp->id != anhp->id) {
|
||||
/*
|
||||
* response from old query, ignore it.
|
||||
* XXX - potential security hazard could
|
||||
* be detected here.
|
||||
*/
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ";; old answer:\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto wait;
|
||||
}
|
||||
#ifdef CHECK_SRVR_ADDR
|
||||
if (!(_res.options & RES_INSECURE1) &&
|
||||
!res_isourserver((struct sockaddr_in *)&from)) {
|
||||
/*
|
||||
* response from wrong server? ignore it.
|
||||
* XXX - potential security hazard could
|
||||
* be detected here.
|
||||
*/
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ";; not our server:\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto wait;
|
||||
}
|
||||
#endif
|
||||
if (!(_res.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((_res.options & RES_DEBUG) ||
|
||||
(_res.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(_res.options & RES_DEBUG,
|
||||
(stdout, "server rejected query:\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
/* don't retry if called from dig */
|
||||
if (!_res.pfcode)
|
||||
goto next_ns;
|
||||
}
|
||||
if (!(_res.options & RES_IGNTC) && anhp->tc) {
|
||||
/*
|
||||
* get rest of answer;
|
||||
* use TCP with same server.
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; truncated answer\n"));
|
||||
v_circuit = 1;
|
||||
res_close();
|
||||
goto same_ns;
|
||||
}
|
||||
} /*if vc/dg*/
|
||||
Dprint((_res.options & RES_DEBUG) ||
|
||||
((_res.pfcode & RES_PRF_REPLY) &&
|
||||
(_res.pfcode & RES_PRF_HEAD1)),
|
||||
(stdout, ";; got answer:\n"));
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, "%.*s", 0, ""),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
/*
|
||||
* If using virtual circuits, we assume that the first server
|
||||
* is preferred over the rest (i.e. it is on the local
|
||||
* machine) and only keep that one open.
|
||||
* 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 && (!(_res.options & RES_USEVC) || ns != 0)) ||
|
||||
!(_res.options & RES_STAYOPEN)) {
|
||||
res_close();
|
||||
}
|
||||
if (Rhook) {
|
||||
int done = 0, loops = 0;
|
||||
|
||||
do {
|
||||
res_sendhookact act;
|
||||
|
||||
act = (*Rhook)(nsap,
|
||||
buf, buflen,
|
||||
ans, anssiz, &resplen);
|
||||
switch (act) {
|
||||
case res_goahead:
|
||||
case res_done:
|
||||
done = 1;
|
||||
break;
|
||||
case res_nextns:
|
||||
res_close();
|
||||
goto next_ns;
|
||||
case res_modified:
|
||||
/* give the hook another try */
|
||||
if (++loops < 42) /*doug adams*/
|
||||
break;
|
||||
/*FALLTHROUGH*/
|
||||
case res_error:
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
_close(kq);
|
||||
return (-1);
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
}
|
||||
_close(kq);
|
||||
return (resplen);
|
||||
next_ns: ;
|
||||
} /*foreach ns*/
|
||||
} /*foreach retry*/
|
||||
res_close();
|
||||
_close(kq);
|
||||
if (!v_circuit) {
|
||||
if (!gotsomewhere)
|
||||
errno = ECONNREFUSED; /* no nameservers found */
|
||||
else
|
||||
errno = ETIMEDOUT; /* no answer obtained */
|
||||
} else
|
||||
errno = terrno;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is for closing the socket if a virtual circuit is used and
|
||||
* the program wants to close it. This provides support for endhostent()
|
||||
* which expects to close the socket.
|
||||
*
|
||||
* This routine is not expected to be user visible.
|
||||
*/
|
||||
void
|
||||
res_close()
|
||||
{
|
||||
if (s >= 0) {
|
||||
(void)_close(s);
|
||||
s = -1;
|
||||
connected = 0;
|
||||
vc = 0;
|
||||
af = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <resolv.h>.
|
||||
*/
|
||||
#undef res_close
|
||||
__weak_reference(__res_close, _res_close);
|
||||
#undef res_send
|
||||
__weak_reference(__res_send, res_send);
|
@ -1,82 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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) 1996 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
struct __res_send_private {
|
||||
int s; /* socket used for communications */
|
||||
int connected; /* is the socket connected */
|
||||
int vc; /* is the socket a virtual circuit? */
|
||||
int af; /* address family of socket */
|
||||
res_send_qhook Qhook;
|
||||
res_send_rhook Rhook;
|
||||
};
|
||||
|
||||
struct __res_send_private *___res_send_private(void);
|
@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "res_update.h"
|
||||
|
||||
/*
|
||||
* Separate a linked list of records into groups so that all records
|
||||
* in a group will belong to a single zone on the nameserver.
|
||||
@ -85,7 +87,7 @@ res_update(ns_updrec *rrecp_in) {
|
||||
u_int32_t ttl;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
/*-
|
||||
* Copyright (c) 1983, 1987, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -31,37 +31,45 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifndef _RES_UPDATE_H_
|
||||
#define _RES_UPDATE_H_
|
||||
|
||||
/*
|
||||
* Return the network number from an internet
|
||||
* address; handles class a/b/c network #'s.
|
||||
* This RR-like structure is particular to UPDATE.
|
||||
*/
|
||||
in_addr_t
|
||||
inet_netof(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
in_addr_t i = ntohl(in.s_addr);
|
||||
struct ns_updrec {
|
||||
struct ns_updrec *r_prev; /* prev record */
|
||||
struct ns_updrec *r_next; /* next record */
|
||||
u_int8_t r_section; /* ZONE/PREREQUISITE/UPDATE */
|
||||
char * r_dname; /* owner of the RR */
|
||||
u_int16_t r_class; /* class number */
|
||||
u_int16_t r_type; /* type number */
|
||||
u_int32_t r_ttl; /* time to live */
|
||||
u_char * r_data; /* rdata fields as text string */
|
||||
u_int16_t r_size; /* size of r_data field */
|
||||
int r_opcode; /* type of operation */
|
||||
/* following fields for private use by the resolver/server routines */
|
||||
struct ns_updrec *r_grpnext; /* next record when grouped */
|
||||
struct databuf *r_dp; /* databuf to process */
|
||||
struct databuf *r_deldp; /* databuf's deleted/overwritten */
|
||||
u_int16_t r_zone; /* zone number on server */
|
||||
};
|
||||
typedef struct ns_updrec ns_updrec;
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
|
||||
else if (IN_CLASSB(i))
|
||||
return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
|
||||
else
|
||||
return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
|
||||
}
|
||||
#define res_freeupdrec __res_freeupdrec
|
||||
#define res_mkupdate __res_mkupdate
|
||||
#define res_mkupdrec __res_mkupdrec
|
||||
#if 0
|
||||
#define res_update __res_update
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Weak aliases for applications that use certain private entry points,
|
||||
* and fail to include <arpa/inet.h>.
|
||||
*/
|
||||
#undef inet_netof
|
||||
__weak_reference(__inet_netof, inet_netof);
|
||||
__BEGIN_DECLS
|
||||
void res_freeupdrec(ns_updrec *);
|
||||
int res_mkupdate(ns_updrec *, u_char *, int);
|
||||
ns_updrec * res_mkupdrec(int, const char *, u_int, u_int, u_long);
|
||||
int res_update(ns_updrec *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _RES_UPDATE_H_ */
|
Loading…
Reference in New Issue
Block a user