* Makefile.in (DLL_OFILES): Add minires-os-if.o and minires.o.

(SUBLIBS): Add libresolv.a.
	Add rule for libresolv.a.
	* autoload.cc: Fix return code handling for IP Helper API in case
	of being unable to load iphlpapi.dll.
	(DnsQuery_A): Define.
	(DnsRecordListFree): Define.
	* cygwin.din: Export resolver functions.
	* include/resolv.h: New header.
	* include/arpa/nameser.h: New header.
	* include/arpa/nameser_compat.h: New header.
	* include/cygwin/version.h: Bump API minor number.
	* libc/minires-os-if.c: New file.
	* libc/minires.c: New file.
	* libc/minires.h: New file.
This commit is contained in:
Corinna Vinschen 2006-12-11 19:59:06 +00:00
parent 12cb181da7
commit 0c365c631f
12 changed files with 2891 additions and 16 deletions

View File

@ -1,3 +1,21 @@
2006-12-11 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (DLL_OFILES): Add minires-os-if.o and minires.o.
(SUBLIBS): Add libresolv.a.
Add rule for libresolv.a.
* autoload.cc: Fix return code handling for IP Helper API in case
of being unable to load iphlpapi.dll.
(DnsQuery_A): Define.
(DnsRecordListFree): Define.
* cygwin.din: Export resolver functions.
* include/resolv.h: New header.
* include/arpa/nameser.h: New header.
* include/arpa/nameser_compat.h: New header.
* include/cygwin/version.h: Bump API minor number.
* libc/minires-os-if.c: New file.
* libc/minires.c: New file.
* libc/minires.h: New file.
2006-12-11 Christopher Faylor <me@cgf.cx>
* sigproc.cc (child_info::child_info): Move old comment about msv_count

View File

@ -134,15 +134,15 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \
fhandler_tty.o fhandler_virtual.o fhandler_windows.o fhandler_zero.o \
flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o grp.o heap.o \
hookapi.o inet_addr.o inet_network.o init.o ioctl.o ipc.o localtime.o \
lsearch.o malloc_wrapper.o memmem.o miscfuncs.o mktemp.o mmap.o msg.o \
net.o netdb.o nftw.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o \
pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o resource.o \
rexec.o rcmd.o scandir.o sched.o sec_acl.o sec_helper.o security.o \
select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \
spawn.o strace.o strptime.o strsep.o strsig.o sync.o syscalls.o \
sysconf.o syslog.o termios.o thread.o timelocal.o timer.o times.o tty.o \
uinfo.o uname.o v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o \
window.o winf.o \
lsearch.o malloc_wrapper.o memmem.o minires-os-if.o minires.o \
miscfuncs.o mktemp.o mmap.o msg.o net.o netdb.o nftw.o ntea.o passwd.o \
path.o pinfo.o pipe.o poll.o pthread.o regcomp.o regerror.o regexec.o \
regfree.o registry.o resource.o rexec.o rcmd.o scandir.o sched.o \
sec_acl.o sec_helper.o security.o select.o sem.o shared.o shm.o sigfe.o \
signal.o sigproc.o smallprint.o spawn.o strace.o strptime.o strsep.o \
strsig.o sync.o syscalls.o sysconf.o syslog.o termios.o thread.o \
timelocal.o timer.o times.o tty.o uinfo.o uname.o v8_regexp.o \
v8_regerror.o v8_regsub.o wait.o wincap.o window.o winf.o \
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)
GMON_OFILES:=gmon.o mcount.o profil.o
@ -219,7 +219,7 @@ API_VER:=$(srcdir)/include/cygwin/version.h
PWD:=${shell pwd}
LIB_NAME:=$(PWD)/libcygwin.a
LIBSERVER:=@LIBSERVER@
SUBLIBS:=$(PWD)/libpthread.a $(PWD)/libutil.a $(PWD)/libm.a $(PWD)/libc.a $(PWD)/libdl.a
SUBLIBS:=$(PWD)/libpthread.a $(PWD)/libutil.a $(PWD)/libm.a $(PWD)/libc.a $(PWD)/libdl.a $(PWD)/libresolv.a
EXTRALIBS:=libautomode.a libbinmode.a libtextmode.a libtextreadmode.a
INSTOBJS:=automode.o binmode.o textmode.o textreadmode.o
TARGET_LIBS:=$(LIB_NAME) $(CYGWIN_START) $(GMON_START) $(LIBGMON_A) $(SUBLIBS) $(INSTOBJS) $(EXTRALIBS)
@ -443,6 +443,9 @@ $(PWD)/libc.a: speclib $(LIB_NAME) $(PWD)/libm.a libpthread.a libutil.a
$(PWD)/libdl.a: speclib $(LIB_NAME) dlfcn.o
/bin/sh ${word 1, $^} $@ "${NM}" "$(AR)" ${wordlist 2, 99, $^}
$(PWD)/libresolv.a: speclib $(LIB_NAME) minires.o
/bin/sh ${word 1, $^} $@ "${NM}" "$(AR)" ${wordlist 2, 99, $^}
lib%.a: %.o
$(AR) cru $@ $?

View File

@ -492,11 +492,11 @@ LoadDLLfunc (WSASetLastError, 4, ws2_32)
// LoadDLLfunc (WSAStartup, 8, ws2_32)
LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32)
LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1)
LoadDLLfuncEx (GetIfEntry, 4, iphlpapi, 1)
LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1)
LoadDLLfuncEx (GetNetworkParams, 8, iphlpapi, 1)
LoadDLLfuncEx (GetTcpTable, 12, iphlpapi, 1)
// 50 = ERROR_NOT_SUPPORTED. Returned if OS doesn't supprot iphlpapi funcs
LoadDLLfuncEx2 (GetIfEntry, 4, iphlpapi, 1, 50)
LoadDLLfuncEx2 (GetIpAddrTable, 12, iphlpapi, 1, 50)
LoadDLLfuncEx2 (GetNetworkParams, 8, iphlpapi, 1, 50)
LoadDLLfuncEx2 (GetTcpTable, 12, iphlpapi, 1, 50)
LoadDLLfunc (CoTaskMemFree, 4, ole32)
@ -559,4 +559,7 @@ LoadDLLfunc (WNetCloseEnum, 4, mpr)
LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
LoadDLLfuncEx2 (DnsQuery_A, 24, dnsapi, 1, 127) // ERROR_PROC_NOT_FOUND
LoadDLLfuncEx (DnsRecordListFree, 8, dnsapi, 1)
}

View File

@ -269,6 +269,12 @@ dll_entry@12 NOSIGFE
dll_noncygwin_dllcrt0 NOSIGFE
dlopen SIGFE
dlsym SIGFE
dn_comp = __dn_comp SIGFE
__dn_comp SIGFE
dn_expand = __dn_expand SIGFE
__dn_expand SIGFE
dn_skipname = __dn_skipname SIGFE
__dn_skipname SIGFE
drand48 NOSIGFE
_drand48 = drand48 NOSIGFE
drem NOSIGFE
@ -1124,6 +1130,35 @@ remquo NOSIGFE
remquof NOSIGFE
rename SIGFE
_rename = rename SIGFE
res_close = __res_close SIGFE
__res_close SIGFE
res_init = __res_init SIGFE
__res_init SIGFE
res_mkquery = __res_mkquery SIGFE
__res_mkquery SIGFE
res_nclose = __res_nclose SIGFE
__res_nclose SIGFE
res_ninit = __res_ninit SIGFE
__res_ninit SIGFE
res_nmkquery = __res_nmkquery SIGFE
__res_nmkquery SIGFE
res_nquery = __res_nquery SIGFE
__res_nquery SIGFE
res_nquerydomain = __res_nquerydomain SIGFE
__res_nquerydomain SIGFE
res_nsearch = __res_nsearch SIGFE
__res_nsearch SIGFE
res_nsend = __res_nsend SIGFE
__res_nsend SIGFE
res_query = __res_query SIGFE
__res_query SIGFE
res_querydomain = __res_querydomain SIGFE
__res_querydomain SIGFE
res_search = __res_search SIGFE
__res_search SIGFE
res_send = __res_send SIGFE
__res_send SIGFE
__res_state SIGFE
revoke SIGFE
rewind SIGFE
_rewind = rewind SIGFE

View File

@ -0,0 +1,563 @@
/*
* Copyright (c) 1983, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 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.
*/
/*
* $Id$
*/
#ifndef _ARPA_NAMESER_H_
#define _ARPA_NAMESER_H_
#ifdef __CYGWIN__
#define BSD 199903 /* Used inside the .h file */
#endif
#define BIND_4_COMPAT
#include <sys/param.h>
#if (!defined(BSD)) || (BSD < 199306)
# include <sys/bitypes.h>
#else
# include <sys/types.h>
#endif
#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 libbind.a
* contains a new enough lib/nameser/ to support the feature you need.
*/
#define __NAMESER 19991006 /* New interface version stamp. */
/*
* Define constants based on RFC 883, RFC 1034, RFC 1035
*/
#define NS_PACKETSZ 512 /* maximum packet size */
#define NS_MAXDNAME 1025 /* maximum domain name */
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
#define NS_MAXLABEL 63 /* maximum length of domain label */
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */
#define NS_INADDRSZ 4 /* IPv4 T_A */
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
/*
* These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
* in synch with it.
*/
typedef enum __ns_sect {
ns_s_qd = 0, /* Query: Question. */
ns_s_zn = 0, /* Update: Zone. */
ns_s_an = 1, /* Query: Answer. */
ns_s_pr = 1, /* Update: Prerequisites. */
ns_s_ns = 2, /* Query: Name servers. */
ns_s_ud = 2, /* Update: Update. */
ns_s_ar = 3, /* Query|Update: Additional records. */
ns_s_max = 4
} ns_sect;
/*
* This is a message handle. It is caller allocated and has no dynamic data.
* This structure is intended to be opaque to all but ns_parse.c, thus the
* leading _'s on the member names. Use the accessor functions, not the _'s.
*/
typedef struct __ns_msg {
const u_char *_msg, *_eom;
u_int16_t _id, _flags, _counts[ns_s_max];
const u_char *_sections[ns_s_max];
ns_sect _sect;
int _rrnum;
const u_char *_msg_ptr;
} ns_msg;
/* Private data structure - do not use from outside library. */
struct _ns_flagdata { int mask, shift; };
extern struct _ns_flagdata _ns_flagdata[];
/* Accessor macros - this is part of the public interface. */
#define ns_msg_id(handle) ((handle)._id + 0)
#define ns_msg_base(handle) ((handle)._msg + 0)
#define ns_msg_end(handle) ((handle)._eom + 0)
#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
/*
* This is a parsed record. It is caller allocated and has no dynamic data.
*/
typedef struct __ns_rr {
char name[NS_MAXDNAME];
u_int16_t type;
u_int16_t rr_class;
u_int32_t ttl;
u_int16_t rdlength;
const u_char * rdata;
} ns_rr;
/* Accessor macros - this is part of the public interface. */
#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
#define ns_rr_ttl(rr) ((rr).ttl + 0)
#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
#define ns_rr_rdata(rr) ((rr).rdata + 0)
/*
* These don't have to be in the same order as in the packet flags word,
* and they can even overlap in some cases, but they will need to be kept
* in synch with ns_parse.c:ns_flagdata[].
*/
typedef enum __ns_flag {
ns_f_qr, /* Question/Response. */
ns_f_opcode, /* Operation code. */
ns_f_aa, /* Authoritative Answer. */
ns_f_tc, /* Truncation occurred. */
ns_f_rd, /* Recursion Desired. */
ns_f_ra, /* Recursion Available. */
ns_f_z, /* MBZ. */
ns_f_ad, /* Authentic Data (DNSSEC). */
ns_f_cd, /* Checking Disabled (DNSSEC). */
ns_f_rcode, /* Response code. */
ns_f_max
} ns_flag;
/*
* Currently defined opcodes.
*/
typedef enum __ns_opcode {
ns_o_query = 0, /* Standard query. */
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
ns_o_status = 2, /* Name server status query (unsupported). */
/* Opcode 3 is undefined/reserved. */
ns_o_notify = 4, /* Zone change notification. */
ns_o_update = 5, /* Zone update message. */
ns_o_max = 6
} ns_opcode;
/*
* Currently defined response codes.
*/
typedef enum __ns_rcode {
ns_r_noerror = 0, /* No error occurred. */
ns_r_formerr = 1, /* Format error. */
ns_r_servfail = 2, /* Server failure. */
ns_r_nxdomain = 3, /* Name error. */
ns_r_notimpl = 4, /* Unimplemented. */
ns_r_refused = 5, /* Operation refused. */
/* these are for BIND_UPDATE */
ns_r_yxdomain = 6, /* Name exists */
ns_r_yxrrset = 7, /* RRset exists */
ns_r_nxrrset = 8, /* RRset does not exist */
ns_r_notauth = 9, /* Not authoritative for zone */
ns_r_notzone = 10, /* Zone of record different from zone section */
ns_r_max = 11,
/* The following are TSIG extended errors */
ns_r_badsig = 16,
ns_r_badkey = 17,
ns_r_badtime = 18
} ns_rcode;
/* BIND_UPDATE */
typedef enum __ns_update_operation {
ns_uop_delete = 0,
ns_uop_add = 1,
ns_uop_max = 2
} ns_update_operation;
/*
* This structure is used for TSIG authenticated messages
*/
struct ns_tsig_key {
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
unsigned char *data;
int len;
};
typedef struct ns_tsig_key ns_tsig_key;
/*
* This structure is used for TSIG authenticated TCP messages
*/
struct ns_tcp_tsig_state {
int counter;
struct dst_key *key;
void *ctx;
unsigned char sig[NS_PACKETSZ];
int siglen;
};
typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
#define NS_TSIG_FUDGE 300
#define NS_TSIG_TCP_COUNT 100
#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
#define NS_TSIG_ERROR_NO_TSIG -10
#define NS_TSIG_ERROR_NO_SPACE -11
#define NS_TSIG_ERROR_FORMERR -12
/*
* Currently defined type values for resources and queries.
*/
typedef enum __ns_type {
ns_t_invalid = 0, /* Cookie. */
ns_t_a = 1, /* Host address. */
ns_t_ns = 2, /* Authoritative server. */
ns_t_md = 3, /* Mail destination. */
ns_t_mf = 4, /* Mail forwarder. */
ns_t_cname = 5, /* Canonical name. */
ns_t_soa = 6, /* Start of authority zone. */
ns_t_mb = 7, /* Mailbox domain name. */
ns_t_mg = 8, /* Mail group member. */
ns_t_mr = 9, /* Mail rename name. */
ns_t_null = 10, /* Null resource record. */
ns_t_wks = 11, /* Well known service. */
ns_t_ptr = 12, /* Domain name pointer. */
ns_t_hinfo = 13, /* Host information. */
ns_t_minfo = 14, /* Mailbox information. */
ns_t_mx = 15, /* Mail routing information. */
ns_t_txt = 16, /* Text strings. */
ns_t_rp = 17, /* Responsible person. */
ns_t_afsdb = 18, /* AFS cell database. */
ns_t_x25 = 19, /* X_25 calling address. */
ns_t_isdn = 20, /* ISDN calling address. */
ns_t_rt = 21, /* Router. */
ns_t_nsap = 22, /* NSAP address. */
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
ns_t_sig = 24, /* Security signature. */
ns_t_key = 25, /* Security key. */
ns_t_px = 26, /* X.400 mail mapping. */
ns_t_gpos = 27, /* Geographical position (withdrawn). */
ns_t_aaaa = 28, /* Ip6 Address. */
ns_t_loc = 29, /* Location Information. */
ns_t_nxt = 30, /* Next domain (security). */
ns_t_eid = 31, /* Endpoint identifier. */
ns_t_nimloc = 32, /* Nimrod Locator. */
ns_t_srv = 33, /* Server Selection. */
ns_t_atma = 34, /* ATM Address */
ns_t_naptr = 35, /* Naming Authority PoinTeR */
ns_t_kx = 36, /* Key Exchange */
ns_t_cert = 37, /* Certification record */
ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
ns_t_sink = 40, /* Kitchen sink (experimentatl) */
ns_t_opt = 41, /* EDNS0 option (meta-RR) */
ns_t_tkey = 249, /* Transaction key */
ns_t_tsig = 250, /* Transaction signature. */
ns_t_ixfr = 251, /* Incremental zone transfer. */
ns_t_axfr = 252, /* Transfer zone of authority. */
ns_t_mailb = 253, /* Transfer mailbox records. */
ns_t_maila = 254, /* Transfer mail agent records. */
ns_t_any = 255, /* Wildcard match. */
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
ns_t_max = 65536
} ns_type;
/* Exclusively a QTYPE? (not also an RTYPE) */
#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
(t) == ns_t_mailb || (t) == ns_t_maila)
/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
(t) == ns_t_zxfr)
/*
* Values for class field
*/
typedef enum __ns_class {
ns_c_invalid = 0, /* Cookie. */
ns_c_in = 1, /* Internet. */
ns_c_2 = 2, /* unallocated/unsupported. */
ns_c_chaos = 3, /* MIT Chaos-net. */
ns_c_hs = 4, /* MIT Hesiod. */
/* Query class values which do not appear in resource records */
ns_c_none = 254, /* for prereq. sections in update requests */
ns_c_any = 255, /* Wildcard match. */
ns_c_max = 65536
} ns_class;
/* DNSSEC constants. */
typedef enum __ns_key_types {
ns_kt_rsa = 1, /* key type RSA/MD5 */
ns_kt_dh = 2, /* Diffie Hellman */
ns_kt_dsa = 3, /* Digital Signature Standard (MANDATORY) */
ns_kt_private = 254 /* Private key type starts with OID */
} ns_key_types;
typedef enum __ns_cert_types {
cert_t_pkix = 1, /* PKIX (X.509v3) */
cert_t_spki = 2, /* SPKI */
cert_t_pgp = 3, /* PGP */
cert_t_url = 253, /* URL private type */
cert_t_oid = 254 /* OID private type */
} ns_cert_types;
/* Flags field of the KEY RR rdata. */
#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
/* The type bits can also be interpreted independently, as single bits: */
#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */
#define NS_KEY_EXTENDED_FLAGS 0x1000 /* reserved - must be zero */
#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
#define NS_KEY_RESERVED5 0x0400 /* reserved - must be zero */
#define NS_KEY_NAME_TYPE 0x0300 /* these bits determine the type */
#define NS_KEY_NAME_USER 0x0000 /* key is assoc. with user */
#define NS_KEY_NAME_ENTITY 0x0200 /* key is assoc. with entity eg host */
#define NS_KEY_NAME_ZONE 0x0100 /* key is zone key */
#define NS_KEY_NAME_RESERVED 0x0300 /* reserved meaning */
#define NS_KEY_RESERVED8 0x0080 /* reserved - must be zero */
#define NS_KEY_RESERVED9 0x0040 /* reserved - must be zero */
#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
NS_KEY_RESERVED4 | \
NS_KEY_RESERVED5 | \
NS_KEY_RESERVED8 | \
NS_KEY_RESERVED9 | \
NS_KEY_RESERVED10 | \
NS_KEY_RESERVED11 )
#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
#define NS_ALG_DH 2 /* Diffie Hellman KEY */
#define NS_ALG_DSA 3 /* DSA KEY */
#define NS_ALG_DSS NS_ALG_DSA
#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
/* Protocol values */
/* value 0 is reserved */
#define NS_KEY_PROT_TLS 1
#define NS_KEY_PROT_EMAIL 2
#define NS_KEY_PROT_DNSSEC 3
#define NS_KEY_PROT_IPSEC 4
#define NS_KEY_PROT_ANY 255
/* Signatures */
#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
#define NS_MD5RSA_MAX_BITS 2552
/* Total of binary mod and exp */
#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
/* Max length of text sig block */
#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
#define NS_DSA_SIG_SIZE 41
#define NS_DSA_MIN_SIZE 213
#define NS_DSA_MAX_BYTES 405
/* Offsets into SIG record rdata to find various values */
#define NS_SIG_TYPE 0 /* Type flags */
#define NS_SIG_ALG 2 /* Algorithm */
#define NS_SIG_LABELS 3 /* How many labels in name */
#define NS_SIG_OTTL 4 /* Original TTL */
#define NS_SIG_EXPIR 8 /* Expiration time */
#define NS_SIG_SIGNED 12 /* Signature time */
#define NS_SIG_FOOT 16 /* Key footprint */
#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
/* How RR types are represented as bit-flags in NXT records */
#define NS_NXT_BITS 8
#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_MAX 127
/*
* Inline versions of get/put short/long. Pointer is advanced.
*/
#define NS_GET16(s, cp) do { \
register const u_char *t_cp = (const u_char *)(cp); \
(s) = ((u_int16_t)t_cp[0] << 8) \
| ((u_int16_t)t_cp[1]) \
; \
(cp) += NS_INT16SZ; \
} while (0)
#define NS_GET32(l, cp) do { \
register const u_char *t_cp = (const u_char *)(cp); \
(l) = ((u_int32_t)t_cp[0] << 24) \
| ((u_int32_t)t_cp[1] << 16) \
| ((u_int32_t)t_cp[2] << 8) \
| ((u_int32_t)t_cp[3]) \
; \
(cp) += NS_INT32SZ; \
} while (0)
#define NS_PUT16(s, cp) do { \
register u_int16_t t_s = (u_int16_t)(s); \
register u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_s >> 8; \
*t_cp = t_s; \
(cp) += NS_INT16SZ; \
} while (0)
#define NS_PUT32(l, cp) do { \
register u_int32_t t_l = (u_int32_t)(l); \
register u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_l >> 24; \
*t_cp++ = t_l >> 16; \
*t_cp++ = t_l >> 8; \
*t_cp = t_l; \
(cp) += NS_INT32SZ; \
} while (0)
/*
* ANSI C identifier hiding for bind's lib/nameser.
*/
#define ns_msg_getflag __ns_msg_getflag
#define ns_get16 __ns_get16
#define ns_get32 __ns_get32
#define ns_put16 __ns_put16
#define ns_put32 __ns_put32
#define ns_initparse __ns_initparse
#define ns_skiprr __ns_skiprr
#define ns_parserr __ns_parserr
#define ns_sprintrr __ns_sprintrr
#define ns_sprintrrf __ns_sprintrrf
#define ns_format_ttl __ns_format_ttl
#define ns_parse_ttl __ns_parse_ttl
#define ns_datetosecs __ns_datetosecs
#define ns_name_ntol __ns_name_ntol
#define ns_name_ntop __ns_name_ntop
#define ns_name_pton __ns_name_pton
#define ns_name_unpack __ns_name_unpack
#define ns_name_pack __ns_name_pack
#define ns_name_compress __ns_name_compress
#define ns_name_uncompress __ns_name_uncompress
#define ns_name_skip __ns_name_skip
#define ns_name_rollback __ns_name_rollback
#define ns_sign __ns_sign
#define ns_sign_tcp __ns_sign_tcp
#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
#define ns_makecanon __ns_makecanon
#define ns_samename __ns_samename
__BEGIN_DECLS
int ns_msg_getflag __P((ns_msg, int));
u_int ns_get16 __P((const u_char *));
u_long ns_get32 __P((const u_char *));
void ns_put16 __P((u_int, u_char *));
void ns_put32 __P((u_long, u_char *));
int ns_initparse __P((const u_char *, int, ns_msg *));
int ns_skiprr __P((const u_char *, const u_char *, ns_sect, int));
int ns_parserr __P((ns_msg *, ns_sect, int, ns_rr *));
int ns_sprintrr __P((const ns_msg *, const ns_rr *,
const char *, const char *, char *, size_t));
int ns_sprintrrf __P((const u_char *, size_t, const char *,
ns_class, ns_type, u_long, const u_char *,
size_t, const char *, const char *,
char *, size_t));
int ns_format_ttl __P((u_long, char *, size_t));
int ns_parse_ttl __P((const char *, u_long *));
u_int32_t ns_datetosecs __P((const char *cp, int *errp));
int ns_name_ntol __P((const u_char *, u_char *, size_t));
int ns_name_ntop __P((const u_char *, char *, size_t));
int ns_name_pton __P((const char *, u_char *, size_t));
int ns_name_unpack __P((const u_char *, const u_char *,
const u_char *, u_char *, size_t));
int ns_name_pack __P((const u_char *, u_char *, int,
const u_char **, const u_char **));
int ns_name_uncompress __P((const u_char *, const u_char *,
const u_char *, char *, size_t));
int ns_name_compress __P((const char *, u_char *, size_t,
const u_char **, const u_char **));
int ns_name_skip __P((const u_char **, const u_char *));
void ns_name_rollback __P((const u_char *, const u_char **,
const u_char **));
int ns_sign __P((u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t));
int ns_sign_tcp __P((u_char *, int *, int, int,
ns_tcp_tsig_state *, int));
int ns_sign_tcp_init __P((void *, const u_char *, int,
ns_tcp_tsig_state *));
u_char *ns_find_tsig __P((u_char *, u_char *));
int ns_verify __P((u_char *, int *, void *,
const u_char *, int, u_char *, int *,
time_t *, int));
int ns_verify_tcp __P((u_char *, int *, ns_tcp_tsig_state *, int));
int ns_verify_tcp_init __P((void *, const u_char *, int,
ns_tcp_tsig_state *));
int ns_samedomain __P((const char *, const char *));
int ns_subdomain __P((const char *, const char *));
int ns_makecanon __P((const char *, char *, size_t));
int ns_samename __P((const char *, const char *));
__END_DECLS
#ifdef BIND_4_COMPAT
#include <arpa/nameser_compat.h>
#endif
#endif /* !_ARPA_NAMESER_H_ */

View File

@ -0,0 +1,231 @@
/* Copyright (c) 1983, 1989
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* from nameser.h 8.1 (Berkeley) 6/2/93
* $Id$
*/
#ifndef _ARPA_NAMESER_COMPAT_
#define _ARPA_NAMESER_COMPAT_
#define __BIND 19950621 /* (DEAD) interface version stamp. */
#ifndef BYTE_ORDER
#if (BSD >= 199103)
# include <machine/endian.h>
#else
#ifdef linux
# include <endian.h>
#else
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
defined(__alpha__) || defined(__alpha) || \
(defined(__Lynx__) && defined(__x86__))
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
defined(apollo) || defined(__convex__) || defined(_CRAY) || \
defined(__hppa) || defined(__hp9000) || \
defined(__hp9000s300) || defined(__hp9000s700) || \
defined(__hp3000s900) || defined(MPE) || \
defined (BIT_ZERO_ON_LEFT) || defined(m68k) || \
(defined(__Lynx__) && \
(defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif /* linux */
#endif /* BSD */
#endif /* BYTE_ORDER */
#if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
BYTE_ORDER != PDP_ENDIAN)
/* you must determine what the correct bit order is for
* your compiler - the next line is an intentional error
* which will force your compiles to bomb until you fix
* the above macros.
*/
error "Undefined or invalid BYTE_ORDER";
#endif
/*
* Structure for query header. The order of the fields is machine- and
* compiler-dependent, depending on the byte/bit order and the layout
* of bit fields. We use bit fields only in int variables, as this
* is all ANSI requires. This requires a somewhat confusing rearrangement.
*/
typedef struct {
unsigned id :16; /* query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
unsigned qr: 1; /* response flag */
unsigned opcode: 4; /* purpose of message */
unsigned aa: 1; /* authoritive answer */
unsigned tc: 1; /* truncated message */
unsigned rd: 1; /* recursion desired */
/* fields in fourth byte */
unsigned ra: 1; /* recursion available */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ad: 1; /* authentic data from named */
unsigned cd: 1; /* checking disabled by resolver */
unsigned rcode :4; /* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields in third byte */
unsigned rd :1; /* recursion desired */
unsigned tc :1; /* truncated message */
unsigned aa :1; /* authoritive answer */
unsigned opcode :4; /* purpose of message */
unsigned qr :1; /* response flag */
/* fields in fourth byte */
unsigned rcode :4; /* response code */
unsigned cd: 1; /* checking disabled by resolver */
unsigned ad: 1; /* authentic data from named */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ra :1; /* recursion available */
#endif
/* remaining bytes */
unsigned qdcount :16; /* number of question entries */
unsigned ancount :16; /* number of answer entries */
unsigned nscount :16; /* number of authority entries */
unsigned arcount :16; /* number of resource entries */
} HEADER;
#define PACKETSZ NS_PACKETSZ
#define MAXDNAME NS_MAXDNAME
#define MAXCDNAME NS_MAXCDNAME
#define MAXLABEL NS_MAXLABEL
#define HFIXEDSZ NS_HFIXEDSZ
#define QFIXEDSZ NS_QFIXEDSZ
#define RRFIXEDSZ NS_RRFIXEDSZ
#define INT32SZ NS_INT32SZ
#define INT16SZ NS_INT16SZ
#define INADDRSZ NS_INADDRSZ
#define IN6ADDRSZ NS_IN6ADDRSZ
#define INDIR_MASK NS_CMPRSFLGS
#define NAMESERVER_PORT NS_DEFAULTPORT
#define S_ZONE ns_s_zn
#define S_PREREQ ns_s_pr
#define S_UPDATE ns_s_ud
#define S_ADDT ns_s_ar
#define QUERY ns_o_query
#define IQUERY ns_o_iquery
#define STATUS ns_o_status
#define NS_NOTIFY_OP ns_o_notify
#define NS_UPDATE_OP ns_o_update
#define NOERROR ns_r_noerror
#define FORMERR ns_r_formerr
#define SERVFAIL ns_r_servfail
#define NXDOMAIN ns_r_nxdomain
#define NOTIMP ns_r_notimpl
#define REFUSED ns_r_refused
#define YXDOMAIN ns_r_yxdomain
#define YXRRSET ns_r_yxrrset
#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
#define T_A ns_t_a
#define T_NS ns_t_ns
#define T_MD ns_t_md
#define T_MF ns_t_mf
#define T_CNAME ns_t_cname
#define T_SOA ns_t_soa
#define T_MB ns_t_mb
#define T_MG ns_t_mg
#define T_MR ns_t_mr
#define T_NULL ns_t_null
#define T_WKS ns_t_wks
#define T_PTR ns_t_ptr
#define T_HINFO ns_t_hinfo
#define T_MINFO ns_t_minfo
#define T_MX ns_t_mx
#define T_TXT ns_t_txt
#define T_RP ns_t_rp
#define T_AFSDB ns_t_afsdb
#define T_X25 ns_t_x25
#define T_ISDN ns_t_isdn
#define T_RT ns_t_rt
#define T_NSAP ns_t_nsap
#define T_NSAP_PTR ns_t_nsap_ptr
#define T_SIG ns_t_sig
#define T_KEY ns_t_key
#define T_PX ns_t_px
#define T_GPOS ns_t_gpos
#define T_AAAA ns_t_aaaa
#define T_LOC ns_t_loc
#define T_NXT ns_t_nxt
#define T_EID ns_t_eid
#define T_NIMLOC ns_t_nimloc
#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_TSIG ns_t_tsig
#define T_IXFR ns_t_ixfr
#define T_AXFR ns_t_axfr
#define T_MAILB ns_t_mailb
#define T_MAILA ns_t_maila
#define T_ANY ns_t_any
#define C_IN ns_c_in
#define C_CHAOS ns_c_chaos
#define C_HS ns_c_hs
/* BIND_UPDATE */
#define C_NONE ns_c_none
#define C_ANY ns_c_any
#define GETSHORT NS_GET16
#define GETLONG NS_GET32
#define PUTSHORT NS_PUT16
#define PUTLONG NS_PUT32
#endif /* _ARPA_NAMESER_COMPAT_ */

View File

@ -295,12 +295,13 @@ details. */
rresvport_af.
159: Export posix_openpt.
160: Export posix_fadvice, posix_fallocate.
161: Export resolver functions.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 160
#define CYGWIN_VERSION_API_MINOR 161
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible

464
winsup/cygwin/include/resolv.h Executable file
View File

@ -0,0 +1,464 @@
/*
* Copyright (c) 1983, 1987, 1989
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* 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.
*/
/*
* @(#)resolv.h 8.1 (Berkeley) 6/2/93
* $Id$
*/
#ifndef _RESOLV_H_
#define _RESOLV_H_
#include <sys/param.h>
#if !defined(__CYGWIN__) && ((!defined(BSD)) || (BSD < 199306))
# include <sys/bitypes.h>
#else
# include <sys/types.h>
#endif
#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.
* It can change every day so the right thing to do with it is use it
* in preprocessor commands such as "#if (__RES > 19931104)". Do not
* compare for equality; rather, use it to determine whether your resolver
* is new enough to contain a certain feature.
*/
#define __RES 19991006
/*
* 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 *res, int err);
__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.
*/
#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)__P((struct sockaddr * const *ns,
const u_char **query,
int *querylen,
u_char *ans,
int anssiz,
int *resplen));
typedef res_sendhookact (*res_send_rhook)__P((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 */
const char * name; /* Its symbolic name, like "MX" */
const char * humanname; /* Its fun name, like "mail exchanger" */
};
/*
* Global defines and variables for resolver stub.
*/
#define MAXNS 3 /* max # name servers we'll track */
#define MAXDFLSRCH 3 /* # default domain levels to try */
#define MAXDNSRCH 6 /* max # domains in search path */
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
#define RES_TIMEOUT 5 /* min. seconds between retries */
#define MAXRESOLVSORT 10 /* number of net to sort on */
#define RES_MAXNDOTS 15 /* should reflect bit field size */
#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */
#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
#define RES_DFLRETRY 2 /* Default #/tries. */
#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
struct __res_state_ext;
struct __res_state {
int retrans; /* retransmition time interval */
int retry; /* number of times to retransmit */
u_long options; /* option flags - see below. */
int nscount; /* number of name servers */
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
#define nsaddr nsaddr_list[0] /* for backward compatibility */
u_short id; /* current message id */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
char defdname[256]; /* default domain (deprecated) */
u_long pfcode; /* RES_PRF_ flags - see below. */
unsigned ndots:4; /* threshold for initial abs. query */
unsigned nsort:4; /* number of elements in sort_list[] */
char unused[3];
struct {
struct in_addr addr;
u_int32_t mask;
} sort_list[MAXRESOLVSORT];
res_send_qhook qhook; /* query hook */
res_send_rhook rhook; /* response hook */
int res_h_errno; /* last one set for this context */
int _vcsock; /* PRIVATE: for res_send VC i/o */
u_int _flags; /* PRIVATE: see below */
union {
/* On an 32-bit arch this means 512b total. */
char pad[72 - 3*sizeof (int) - 2*sizeof (void *)];
struct {
u_int16_t nscount;
u_int16_t nstimes[MAXNS]; /* ms. */
int nssocks[MAXNS];
struct __res_state_ext *ext; /* extention for IPv6 */
} _ext;
} _u;
};
typedef struct __res_state *res_state;
union res_sockaddr_union {
struct sockaddr_in sin;
#ifdef IN6ADDR_ANY_INIT
struct sockaddr_in6 sin6;
#endif
#ifdef ISC_ALIGN64
int64_t __align; /* 64bit alignment */
#else
int32_t __align; /* 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 */
/* res_findzonecut() options */
#define RES_EXHAUSTIVE 0x00000001 /* always do all queries */
/*
* Resolver options (keep these in synch with res_debug.c, please)
*/
#define RES_INIT 0x00000001 /* address initialized */
#define RES_DEBUG 0x00000002 /* print debug messages */
#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
#define RES_USEVC 0x00000008 /* use virtual circuit */
#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
#define RES_IGNTC 0x00000020 /* ignore trucation errors */
#define RES_RECURSE 0x00000040 /* recursion desired */
#define RES_DEFNAMES 0x00000080 /* use default domain name */
#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
#define RES_DNSRCH 0x00000200 /* search up local domain tree */
#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
#define RES_ROTATE 0x00004000 /* rotate ns list after each query */
#define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */
#define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */
#define RES_BLAST 0x00020000 /* blast all recursive servers */
#define RES_NO_NIBBLE 0x00040000 /* disable IPv6 nibble mode reverse */
#define RES_NO_BITSTRING 0x00080000 /* disable IPv6 bit string mode reverse */
/* KAME extensions: use higher bit to avoid conflict with ISC use */
#define RES_USE_DNAME 0x10000000 /* use DNAME */
#define RES_USE_A6 0x20000000 /* use A6 */
#define RES_USE_EDNS0 0x40000000 /* use EDNS0 if configured */
#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
/*
* Resolver "pfcode" values. Used by dig.
*/
#define RES_PRF_STATS 0x00000001
#define RES_PRF_UPDATE 0x00000002
#define RES_PRF_CLASS 0x00000004
#define RES_PRF_CMD 0x00000008
#define RES_PRF_QUES 0x00000010
#define RES_PRF_ANS 0x00000020
#define RES_PRF_AUTH 0x00000040
#define RES_PRF_ADD 0x00000080
#define RES_PRF_HEAD1 0x00000100
#define RES_PRF_HEAD2 0x00000200
#define RES_PRF_TTLID 0x00000400
#define RES_PRF_HEADX 0x00000800
#define RES_PRF_QUERY 0x00001000
#define RES_PRF_REPLY 0x00002000
#define RES_PRF_INIT 0x00004000
/* 0x00008000 */
/* Things involving an internal (static) resolver context. */
#if defined(_REENTRANT) || defined(__CYGWIN__)
__BEGIN_DECLS
extern struct __res_state *__res_state(void);
__END_DECLS
#define _res (*__res_state())
#else
#ifndef __BIND_NOSTATIC
extern struct __res_state _res;
#endif
#endif
#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_query __res_query
#define res_querydomain __res_querydomain
#define res_search __res_search
#define res_send __res_send
#define res_sendsigned __res_sendsigned
__BEGIN_DECLS
void fp_nquery __P((const u_char *, int, FILE *));
void fp_query __P((const u_char *, FILE *));
const char * hostalias __P((const char *));
void p_query __P((const u_char *));
void res_close __P((void));
int res_init __P((void));
int res_isourserver __P((const struct sockaddr_in *));
int res_mkquery __P((int, const char *, int, int, const u_char *,
int, const u_char *, u_char *, int));
int res_query __P((const char *, int, int, u_char *, int));
int res_querydomain __P((const char *, const char *, int, int,
u_char *, int));
int res_search __P((const char *, int, int, u_char *, int));
int res_send __P((const u_char *, int, u_char *, int));
int res_sendsigned __P((const u_char *, int, ns_tsig_key *,
u_char *, int));
__END_DECLS
#endif
#if !defined(SHARED_LIBBIND) || defined(LIB)
/*
* If libbind is a shared object (well, DLL anyway)
* these externs break the linker when resolv.h is
* included by a lib client (like named)
* Make them go away if a client is including this
*
*/
extern const struct res_sym __p_key_syms[];
extern const struct res_sym __p_cert_syms[];
extern const struct res_sym __p_class_syms[];
extern const struct res_sym __p_type_syms[];
extern const struct res_sym __p_rcode_syms[];
#endif /* SHARED_LIBBIND */
#define b64_ntop __b64_ntop
#define b64_pton __b64_pton
#define dn_comp __dn_comp
#define dn_count_labels __dn_count_labels
#define dn_expand __dn_expand
#define dn_skipname __dn_skipname
#define fp_resstat __fp_resstat
#define loc_aton __loc_aton
#define loc_ntoa __loc_ntoa
#define p_cdname __p_cdname
#define p_cdnname __p_cdnname
#define p_class __p_class
#define p_fqname __p_fqname
#define p_fqnname __p_fqnname
#define p_option __p_option
#define p_secstodate __p_secstodate
#define p_section __p_section
#define p_time __p_time
#define p_type __p_type
#define p_rcode __p_rcode
#define putlong __putlong
#define putshort __putshort
#define res_dnok __res_dnok
#define res_findzonecut __res_findzonecut
#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
#define res_nsendsigned __res_nsendsigned
#define res_nisourserver __res_nisourserver
#define res_ownok __res_ownok
#define res_queriesmatch __res_queriesmatch
#define res_randomid __res_randomid
#define sym_ntop __sym_ntop
#define sym_ntos __sym_ntos
#define sym_ston __sym_ston
#define res_nopt __res_nopt
#define res_ndestroy __res_ndestroy
#define res_nametoclass __res_nametoclass
#define res_nametotype __res_nametotype
#define res_setservers __res_setservers
#define res_getservers __res_getservers
__BEGIN_DECLS
int res_hnok __P((const char *));
int res_ownok __P((const char *));
int res_mailok __P((const char *));
int res_dnok __P((const char *));
int sym_ston __P((const struct res_sym *, const char *, int *));
const char * sym_ntos __P((const struct res_sym *, int, int *));
const char * sym_ntop __P((const struct res_sym *, int, int *));
int b64_ntop __P((u_char const *, size_t, char *, size_t));
int b64_pton __P((char const *, u_char *, size_t));
int loc_aton __P((const char *ascii, u_char *binary));
const char * loc_ntoa __P((const u_char *binary, char *ascii));
int dn_skipname __P((const u_char *, const u_char *));
void putlong __P((u_int32_t, u_char *));
void putshort __P((u_int16_t, u_char *));
#ifndef __ultrix__
u_int16_t _getshort __P((const u_char *src));
u_int32_t _getlong __P((const u_char *src));
#endif
const char * p_class __P((int));
const char * p_time __P((u_int32_t));
const char * p_type __P((int));
const char * p_rcode __P((int));
const u_char * p_cdnname __P((const u_char *, const u_char *, int, FILE *));
const u_char * p_cdname __P((const u_char *, const u_char *, FILE *));
const u_char * p_fqnname __P((const u_char *cp, const u_char *msg,
int, char *, int));
const u_char * p_fqname __P((const u_char *, const u_char *, FILE *));
const char * p_option __P((u_long option));
char * p_secstodate __P((u_long));
int dn_count_labels __P((const char *));
int dn_comp __P((const char *, u_char *, int,
u_char **, u_char **));
int dn_expand __P((const u_char *, const u_char *, const u_char *,
char *, int));
u_int res_randomid __P((void));
int res_nameinquery __P((const char *, int, int,
const u_char *, const u_char *));
int res_queriesmatch __P((const u_char *, const u_char *,
const u_char *, const u_char *));
const char * p_section __P((int section, int opcode));
/* Things involving a resolver context. */
int res_ninit __P((res_state));
int res_nisourserver __P((const res_state,
const struct sockaddr_in *));
void fp_resstat __P((const res_state, FILE *));
void res_pquery __P((const res_state, const u_char *, int, FILE *));
const char * res_hostalias __P((const res_state, const char *,
char *, size_t));
int res_nquery __P((res_state,
const char *, int, int, u_char *, int));
int res_nsearch __P((res_state, const char *, int,
int, u_char *, int));
int res_nquerydomain __P((res_state,
const char *, const char *, int, int,
u_char *, int));
int res_nmkquery __P((res_state,
int, const char *, int, int, const u_char *,
int, const u_char *, u_char *, int));
int res_nsend __P((res_state, const u_char *, int, u_char *, int));
int res_nsendsigned __P((res_state, const u_char *, int,
ns_tsig_key *, u_char *, int));
int res_findzonecut __P((res_state, const char *, ns_class, int,
char *, size_t, struct in_addr *, int));
void res_nclose __P((res_state));
int res_nopt __P((res_state, int, u_char *, int, int));
void res_send_setqhook __P((res_send_qhook hook));
void res_send_setrhook __P((res_send_rhook hook));
int __res_vinit __P((res_state, int));
void res_destroyservicelist __P((void));
const char * res_servicename __P((u_int16_t port, const char *proto));
const char * res_protocolname __P((int num));
void res_destroyprotolist __P((void));
void res_buildprotolist __P((void));
const char * res_get_nibblesuffix __P((res_state));
const char * res_get_bitstringsuffix __P((res_state));
void res_ndestroy __P((res_state));
u_int16_t res_nametoclass __P((const char *buf, int *success));
u_int16_t res_nametotype __P((const char *buf, int *success));
void res_setservers __P((res_state,
const union res_sockaddr_union *, int));
int res_getservers __P((res_state,
union res_sockaddr_union *, int));
__END_DECLS
#endif /* !_RESOLV_H_ */

View File

@ -0,0 +1,572 @@
/* minires-os-if.c. Stub synchronous resolver for Cygwin.
Copyright 2006 Red Hat, Inc.
Written by Pierre A. Humblet <Pierre.Humblet@ieee.org>
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "minires.h"
#ifdef __CYGWIN__
/***********************************************************************
*
Windows interface code
***********************************************************************/
/* Conflict between Windows definitions and others */
#undef ERROR
#undef NOERROR
#undef DELETE
#include <windows.h>
#include <iphlpapi.h>
#include <windns.h>
#include <sys/cygwin.h>
/***********************************************************************
*
write_record: Translates a Windows DNS record into a compressed record
***********************************************************************/
#define PUTDOMAIN(d,p)\
{int res = dn_comp(d, p, EndPtr - p, dnptrs, lastdnptr); p += res < 0 ? strlen(d) : res; }
static u_char * write_record(unsigned char * ptr, PDNS_RECORD rr, unsigned char * EndPtr,
unsigned char ** dnptrs, unsigned char ** lastdnptr, int debug)
{
u_char * rd_length_ptr;
PUTDOMAIN(rr->pName, ptr);
if (ptr + 4 > EndPtr)
ptr += 4;
else {
PUTSHORT(rr->wType, ptr);
PUTSHORT(ns_c_in, ptr);
}
if ((rr->Flags.DW & 0x3) == DnsSectionQuestion)
return ptr;
if (ptr + 4 > EndPtr)
ptr += 4;
else {
PUTLONG(rr->dwTtl, ptr);
}
rd_length_ptr = ptr;
ptr += 2; /* Placeholder for RDLENGTH */
/* The default case uses an undocumented feature of the Windows
resolver for types greater than 16.
The DNS_RECORD Data contains the record in wire format. */
switch(rr->wType) {
case DNS_TYPE_A:
{
u_char * aptr = (u_char *) & rr->Data.A.IpAddress;
if (ptr + 4 <= EndPtr) {
ptr[0] = aptr[0];
ptr[1] = aptr[1];
ptr[2] = aptr[2];
ptr[3] = aptr[3];
}
ptr += 4;
break;
}
case DNS_TYPE_NS:
case DNS_TYPE_MD:
case DNS_TYPE_MF:
case DNS_TYPE_CNAME:
case DNS_TYPE_MB:
case DNS_TYPE_MG:
case DNS_TYPE_MR:
case DNS_TYPE_PTR:
PUTDOMAIN(rr->Data.PTR.pNameHost, ptr);
break;
case DNS_TYPE_SOA:
PUTDOMAIN(rr->Data.SOA.pNamePrimaryServer, ptr);
PUTDOMAIN(rr->Data.SOA.pNameAdministrator, ptr);
if (ptr + 20 > EndPtr)
ptr += 20;
else {
PUTLONG(rr->Data.SOA.dwSerialNo, ptr);
PUTLONG(rr->Data.SOA.dwRefresh, ptr);
PUTLONG(rr->Data.SOA.dwRetry, ptr);
PUTLONG(rr->Data.SOA.dwExpire, ptr);
PUTLONG(rr->Data.SOA.dwDefaultTtl, ptr);
}
break;
case DNS_TYPE_NULL:
if (ptr + rr->Data.Null.dwByteCount <= EndPtr)
memcpy(ptr, rr->Data.Null.Data, rr->Data.Null.dwByteCount);
ptr += rr->Data.Null.dwByteCount;
if (rr->Data.Null.dwByteCount == rr->wDataLength - sizeof(DNS_NULL_DATA) + 1)
DPRINTF(debug, "Null byte count has an unexpected value\n");
break;
case DNS_TYPE_WKS:
if (ptr + rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5 > EndPtr)
ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5;
else {
PUTLONG(rr->Data.WKS.IpAddress, ptr);
*ptr++ = rr->Data.WKS.chProtocol;
memcpy(ptr, rr->Data.WKS.BitMask, rr->wDataLength - sizeof(DNS_WKS_DATA) + 1);
ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1;
}
break;
case DNS_TYPE_MINFO:
PUTDOMAIN(rr->Data.MINFO.pNameMailbox, ptr);
PUTDOMAIN(rr->Data.MINFO.pNameErrorsMailbox, ptr);
break;
case DNS_TYPE_MX:
if (ptr + 2 > EndPtr)
ptr += 2;
else
PUTSHORT(rr->Data.MX.wPreference, ptr);
PUTDOMAIN(rr->Data.MX.pNameExchange, ptr);
break;
case DNS_TYPE_HINFO:
case DNS_TYPE_TEXT:
{
unsigned int i, len;
for (i = 0; i < rr->Data.TXT.dwStringCount; i++) {
len = strlen(rr->Data.TXT.pStringArray[i]) & 0xFF;
if (ptr + len + 1 > EndPtr)
ptr += len + 1;
else {
*ptr++ = len;
memcpy(ptr, rr->Data.TXT.pStringArray[i], len);
ptr += len;
}
}
break;
}
default:
{
unsigned int len = rr->wDataLength;
DPRINTF(debug, "No structure for wType %d\n", rr->wType);
if (ptr + len <= EndPtr)
memcpy(ptr, (char *) &rr->Data, len);
ptr += len;
break;
}
}
if (rd_length_ptr + 2 <= EndPtr)
PUTSHORT(ptr - rd_length_ptr - 2, rd_length_ptr);
return ptr;
}
/***********************************************************************
*
cygwin_query: implements res_nquery by calling DnsQuery
***********************************************************************/
static int cygwin_query(res_state statp, const char * DomName, int Class, int Type,
unsigned char * AnsPtr, int AnsLength)
{
DNS_STATUS res;
PDNS_RECORD pQueryResultsSet, rr;
int section, len, counts[4] = {0, 0, 0, 0}, debug = statp->options & RES_DEBUG;
unsigned char * dnptrs[256], * ptr;
dnptrs[0] = AnsPtr;
dnptrs[1] = NULL;
if (Class != ns_c_in) {
errno = ENOSYS;
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
res = DnsQuery_A(DomName, Type, DNS_QUERY_TREAT_AS_FQDN,
NULL, &pQueryResultsSet, NULL);
#if 0
#define NETDB_INTERNAL -1 /* see errno */
#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
#define NO_DATA 4 /* Valid name, no data record of requested type */
#endif
DPRINTF(debug, "DnsQuery: %lu (Windows)\n", res);
if (res) {
switch (res) {
case ERROR_PROC_NOT_FOUND:
errno = ENOSYS;
statp->res_h_errno = NO_RECOVERY;
break;
case ERROR_INVALID_NAME:
errno = EINVAL;
statp->res_h_errno = NETDB_INTERNAL;;
break;
case ERROR_TIMEOUT:
statp->res_h_errno = TRY_AGAIN;
break;
case DNS_ERROR_RCODE_NAME_ERROR:
statp->res_h_errno = HOST_NOT_FOUND;
break;
case DNS_ERROR_RCODE_SERVER_FAILURE:
statp->res_h_errno = TRY_AGAIN;
break;
case DNS_ERROR_NO_DNS_SERVERS:
case DNS_ERROR_RCODE_FORMAT_ERROR:
case DNS_ERROR_RCODE_NOT_IMPLEMENTED:
case DNS_ERROR_RCODE_REFUSED:
statp->res_h_errno = NO_RECOVERY;
break;
case DNS_INFO_NO_RECORDS: /* May be returned even if the host doesn't exist */
statp->res_h_errno = NO_DATA;
break;
default:
DPRINTF(debug, "Unknown code %lu for %s %d\n", res, DomName, Type);
statp->res_h_errno = NO_RECOVERY;
break;
}
len = -1;
goto done;
}
ptr = AnsPtr + HFIXEDSZ; /* Skip header */
rr = pQueryResultsSet;
section = 0;
while (rr) {
if (!counts[0] && (rr->Flags.DW & 0x3)) {
/* No question. Adopt the first name as the name in the question */
if ((len = dn_comp(rr->pName, ptr, AnsLength - 4,
dnptrs, &dnptrs[DIM(dnptrs) - 1])) < 0) {
ptr = NULL;
break;
}
ptr += len;
PUTSHORT(Type, ptr);
PUTSHORT(ns_c_in, ptr);
counts[0] = 1;
}
DPRINTF(debug, "%s Section %d Type %u Windows Record Length %u\n",
rr->pName, rr->Flags.DW & 0x3, rr->wType, rr->wDataLength);
/* Check the records are in correct section order */
if ((rr->Flags.DW & 0x3) < section) {
DPRINTF(debug, "Unexpected section order %s %d\n", DomName, Type);
continue;
}
section = rr->Flags.DW & 0x3;
ptr = write_record(ptr, rr, AnsPtr + AnsLength, dnptrs,
&dnptrs[DIM(dnptrs) - 1], debug);
counts[section]++;
rr = rr->pNext;
}
DnsRecordListFree(pQueryResultsSet, DnsFreeRecordList);
len = ptr - AnsPtr;
done:
ptr = AnsPtr;
PUTSHORT(0, ptr); /* Id */
PUTSHORT((QR << 8) + RA + RD, ptr);
for (section = 0; section < DIM(counts); section++) {
PUTSHORT(counts[section], ptr);
}
return len;
}
/***********************************************************************
*
get_registry_items: returns dns items from the registry
kHey: Handle to registry key
KeyValue: key value to read
what: 0 addresses ; 1 search list
***********************************************************************/
static void get_registry_dns_items(HKEY hKey, LPCTSTR KeyValue,
res_state statp, int what)
{
DWORD size = 0;
LONG res;
LPBYTE list;
int debug = statp->options & RES_DEBUG;
res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, NULL, &size);
DPRINTF(debug, "value %s, error %lu (Windows), size %lu\n",
KeyValue, res, size);
if ((res == ERROR_SUCCESS) && (size > 1)) {
if (!(list = (LPBYTE) alloca(size))) {
DPRINTF(debug, "alloca: %s\n", strerror(errno));
}
else if ((res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, list,
&size )) != ERROR_SUCCESS) {
DPRINTF(debug, "RegQueryValueEx: error %lu (Windows)\n", res);
}
else if (what == 0) { /* Get the addresses */
BYTE *ap, *srch;
int numAddresses = 0;
for (ap = list; ap < list + size && *ap; ap = srch) {
/* The separation character can be 0, ' ', or ','. */
for (srch = ap; *srch && (isdigit(*srch) || *srch == '.' ); srch++);
*srch++ = 0;
if (numAddresses < DIM(statp->nsaddr_list)) {
DPRINTF(debug, "server \"%s\"\n", ap);
statp->nsaddr_list[numAddresses].sin_addr.s_addr = cygwin_inet_addr(ap);
if ( statp->nsaddr_list[numAddresses].sin_addr.s_addr != 0 )
numAddresses++;
}
else
DPRINTF(debug, "no space for server \"%s\"\n", ap);
}
statp->nscount = numAddresses;
}
else /* Parse the search line */
minires_get_search(list, statp);
}
return;
}
/***********************************************************************
*
get_registry_dns:
Read the registry to get dns server addresses in Network Byte Order,
and set statp->nscount
(for Win9x and NT <= 4.0, but not Win95 with DHCP)
Read the registry SearchList
***********************************************************************/
static void get_registry_dns(res_state statp)
{
HKEY hKey;
DWORD res;
const char *keyName[] = {"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
"System\\CurrentControlSet\\Services\\VxD\\MSTCP"};
int is9x = !!(GetVersion() & 0x80000000);
DPRINTF(statp->options & RES_DEBUG, "key %s\n", keyName[is9x]);
if ((res = RegOpenKeyEx( HKEY_LOCAL_MACHINE, keyName[is9x], 0,
KEY_QUERY_VALUE | KEY_READ, &hKey)) != ERROR_SUCCESS) {
DPRINTF(statp->options & RES_DEBUG, "RegOpenKeyEx: error %lu (Windows)\n", res);
return;
}
if (statp->nscount == 0)
get_registry_dns_items(hKey, "NameServer", statp, 0);
if (statp->nscount == 0 && !is9x)
get_registry_dns_items(hKey, "DhcpNameServer", statp, 0);
if (statp->dnsrch[0] == NULL)
get_registry_dns_items(hKey, "SearchList", statp, 1);
RegCloseKey(hKey);
return;
}
/***********************************************************************
*
get_dns_info: Get the search list or the domain name
and the dns server addresses in Network Byte Order
Set statp->os_query if DnsQuery is available.
***********************************************************************/
void get_dns_info(res_state statp)
{
#if MAX_HOSTNAME_LEN > MAXHOSTNAMELEN
#define MAX_HOSTNAME_SIZE (MAX_HOSTNAME_LEN + 1)
#else
#define MAX_HOSTNAME_SIZE (MAXHOSTNAMELEN + 1)
#endif
#if MAX_HOSTNAME_SIZE > 256 /* sizeof(defdname) */
#error stap->defdname too short
#endif
int res, debug = statp->options & RES_DEBUG;
ULONG ulOutBufLen = 0;
DWORD dwRetVal;
IP_ADDR_STRING * pIPAddr;
FIXED_INFO * pFixedInfo;
HINSTANCE kerneldll;
typedef DWORD WINAPI (*GNPType)(PFIXED_INFO, PULONG);
GNPType PGetNetworkParams;
int numAddresses = 0;
if (statp->use_os) {
DPRINTF(debug, "using dnsapi.dll\n");
statp->os_query = (typeof(statp->os_query)) cygwin_query;
/* We just need the search list. Avoid loading iphlpapi. */
statp->nscount = -1;
}
if (statp->nscount != 0)
goto use_registry;
if (!(kerneldll = LoadLibrary("IPHLPAPI.DLL"))) {
DPRINTF(debug, "LoadLibrary: error %lu (Windows)\n", GetLastError());
goto use_registry;
}
if (!(PGetNetworkParams = (GNPType) GetProcAddress(kerneldll,
"GetNetworkParams"))) {
DPRINTF(debug, "GetProcAddress: error %lu (Windows)\n", GetLastError());
goto use_registry;
}
/* First call to get the buffer length we need */
dwRetVal = PGetNetworkParams((FIXED_INFO *) 0, &ulOutBufLen);
if (dwRetVal != ERROR_BUFFER_OVERFLOW) {
DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal);
goto use_registry;
}
if ((pFixedInfo = (FIXED_INFO *) alloca(ulOutBufLen)) == 0) {
DPRINTF(debug, "alloca: %s\n", strerror(errno));
goto use_registry;
}
if ((dwRetVal = PGetNetworkParams((FIXED_INFO *) pFixedInfo, & ulOutBufLen))) {
DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal);
goto use_registry;
}
DPRINTF(debug, "GetNetworkParams: OK\n");
/* Record server addresses, up to array size */
for (pIPAddr = &(pFixedInfo->DnsServerList), numAddresses = 0;
pIPAddr;
pIPAddr = pIPAddr->Next) {
if (numAddresses < DIM(statp->nsaddr_list)) {
DPRINTF(debug, "server \"%s\"\n", pIPAddr->IpAddress.String);
statp->nsaddr_list[numAddresses].sin_addr.s_addr = cygwin_inet_addr(pIPAddr->IpAddress.String);
if (statp->nsaddr_list[numAddresses].sin_addr.s_addr != 0) {
numAddresses++;
statp->nscount++;
}
}
else
DPRINTF(debug, "no space for server \"%s\"\n", pIPAddr->IpAddress.String);
}
use_registry:
get_registry_dns(statp);
if (!statp->dnsrch[0]) {
statp->defdname[sizeof(statp->defdname) - 1] = 0;
if (!(res = getdomainname(statp->defdname, sizeof(statp->defdname)))) {
if (statp->defdname[0] && !statp->defdname[sizeof(statp->defdname) - 1])
statp->dnsrch[0] = statp->defdname;
}
DPRINTF(debug, "getdomainname \"%s\"\n",
(res)? strerror(errno) : statp->defdname);
}
}
#else
/***********************************************************************
*
Default interface code
***********************************************************************/
void get_dns_info(res_state statp)
{
return;
}
#endif
#if 0
#define DNS_ERROR_RCODE_FORMAT_ERROR 9001L
#define DNS_ERROR_RCODE_SERVER_FAILURE 9002L
#define DNS_ERROR_RCODE_NAME_ERROR 9003L
#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004L
#define DNS_ERROR_RCODE_REFUSED 9005L
#define DNS_ERROR_RCODE_YXDOMAIN 9006L
#define DNS_ERROR_RCODE_YXRRSET 9007L
#define DNS_ERROR_RCODE_NXRRSET 9008L
#define DNS_ERROR_RCODE_NOTAUTH 9009L
#define DNS_ERROR_RCODE_NOTZONE 9010L
#define DNS_ERROR_RCODE_BADSIG 9016L
#define DNS_ERROR_RCODE_BADKEY 9017L
#define DNS_ERROR_RCODE_BADTIME 9018L
#define DNS_INFO_NO_RECORDS 9501L
#define DNS_ERROR_BAD_PACKET 9502L
#define DNS_ERROR_NO_PACKET 9503L
#define DNS_ERROR_RCODE 9504L
#define DNS_ERROR_UNSECURE_PACKET 9505L
#define DNS_ERROR_INVALID_TYPE 9551L
#define DNS_ERROR_INVALID_IP_ADDRESS 9552L
#define DNS_ERROR_INVALID_PROPERTY 9553L
#define DNS_ERROR_TRY_AGAIN_LATER 9554L
#define DNS_ERROR_NOT_UNIQUE 9555L
#define DNS_ERROR_NON_RFC_NAME 9556L
#define DNS_STATUS_FQDN 9557L
#define DNS_STATUS_DOTTED_NAME 9558L
#define DNS_STATUS_SINGLE_PART_NAME 9559L
#define DNS_ERROR_INVALID_NAME_CHAR 9560L
#define DNS_ERROR_NUMERIC_NAME 9561L
#define DNS_ERROR_NOT_LALOWED_ON_ROOT_SERVER 9562L
#define DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION 9563L
#define DNS_ERROR_CANNOT_FIND_ROOT_HINTS 9564L
#define DNS_ERROR_INCONSISTENT_ROOT_HINTS 9565L
#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601L
#define DNS_ERROR_NO_ZONE_INFO 9602L
#define DNS_ERROR_INVALID_ZONE_OPERATION 9603L
#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604L
#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605L
#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606L
#define DNS_ERROR_ZONE_LOCKED 9607L
#define DNS_ERROR_ZONE_CREATION_FAILED 9608L
#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609L
#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610L
#define DNS_ERROR_INVALID_ZONE_TYPE 9611L
#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612L
#define DNS_ERROR_ZONE_NOT_SECONDARY 9613L
#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614L
#define DNS_ERROR_WINS_INIT_FAILED 9615L
#define DNS_ERROR_NEED_WINS_SERVERS 9616L
#define DNS_ERROR_NBSTAT_INIT_FAILED 9617L
#define DNS_ERROR_SOA_DELETE_INVALID 9618L
#define DNS_ERROR_FORWARDER_ALREADY_EXISTS 9619L
#define DNS_ERROR_ZONE_REQUIRES_MASTER_IP 9620L
#define DNS_ERROR_ZONE_IS_SHUTDOWN 9621L
#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651L
#define DNS_ERROR_INVALID_DATAFILE_NAME 9652L
#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653L
#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654L
#define DNS_ERROR_DATAFILE_PARSING 9655L
#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701L
#define DNS_ERROR_RECORD_FORMAT 9702L
#define DNS_ERROR_NODE_CREATION_FAILED 9703L
#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704L
#define DNS_ERROR_RECORD_TIMED_OUT 9705L
#define DNS_ERROR_NAME_NOT_IN_ZONE 9706L
#define DNS_ERROR_CNAME_LOOP 9707L
#define DNS_ERROR_NODE_IS_CNAME 9708L
#define DNS_ERROR_CNAME_COLLISION 9709L
#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710L
#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711L
#define DNS_ERROR_SECONDARY_DATA 9712L
#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713L
#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714L
#define DNS_WARNING_PTR_CREATE_FAILED 9715L
#define DNS_WARNING_DOMAIN_UNDELETED 9716L
#define DNS_ERROR_DS_UNAVAILABLE 9717L
#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718L
#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719L
#define DNS_INFO_AXFR_COMPLETE 9751L
#define DNS_ERROR_AXFR 9752L
#define DNS_INFO_ADDED_LOCAL_WINS 9753L
#define DNS_STATUS_CONTINUE_NEEDED 9801L
#define DNS_ERROR_NO_TCPIP 9851L
#define DNS_ERROR_NO_DNS_SERVERS 9852L
#define DNS_ERROR_DP_DOES_NOT_EXIST 9901L
#define DNS_ERROR_DP_ALREADY_EXISTS 9902L
#define DNS_ERROR_DP_NOT_ENLISTED 9903L
#define DNS_ERROR_DP_ALREADY_ENLISTED 9904L
#define DNS_ERROR_DP_NOT_AVAILABLE 9905L
#endif

View File

@ -0,0 +1,916 @@
/* minires.c. Stub synchronous resolver for Cygwin.
Copyright 2006 Red Hat, Inc.
Written by Pierre A. Humblet <Pierre.Humblet@ieee.org>
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "minires.h"
/***********************************************************************
Utilities
***********************************************************************/
/***********************************************************************
dprintf
***********************************************************************/
void minires_dprintf(const char * format, ...)
{
va_list args;
va_start(args, format);
fprintf(stderr, "Minires: ");
vfprintf(stderr, format, args);
va_end(args);
}
/***********************************************************************
scanline
Put pointers in list[] to the beginning of each space or comma delimited
word in "in", and put the lengths in sizes[] (counting the final 0).
Return the number of words found
***********************************************************************/
static int scanline(char * in, char **list, int * sizes, int maxnum)
{
int i;
char * startp;
for (i = 0; i < maxnum; i++) {
while((*in) && (isspace(*in) || *in == ',')) in++;
if (*in == 0)
break;
startp = in++;
while((*in) && !isspace(*in) && *in != ',') in++;
list[i] = startp;
sizes[i] = in - startp + 1;
if (*in)
*in++ = 0;
}
return i;
}
/***********************************************************************
Read the search string.
***********************************************************************/
void minires_get_search(char * string, res_state statp)
{
char * words[MAXDNSRCH+1], * ptr;
int sizes[MAXDNSRCH+1];
int i, j, debug = statp->options & RES_DEBUG;
i = scanline(string, words, sizes, MAXDNSRCH+1);
ptr = statp->defdname;
for (j = 0; j < i; j++) {
if (j < MAXDNSRCH
&& ptr + sizes[j] < &statp->defdname[DIM(statp->defdname)]) {
statp->dnsrch[j] = strcpy(ptr, words[j]);
statp->dnsrch[j+1] = NULL;
ptr += sizes[j];
DPRINTF(debug, "search \"%s\"\n", words[j]);
}
else
DPRINTF(debug, "no space for \"%s\"\n", words[j]);
}
}
/***********************************************************************
Read options
***********************************************************************/
static void get_options(res_state statp, int i, char **words)
{
char *ptr;
int value;
while (i-- > 0) {
if (!strcasecmp("debug", words[i])) {
statp->options |= RES_DEBUG;
DPRINTF(statp->options & RES_DEBUG, "%s: 1\n", words[i]);
continue;
}
if (!strcasecmp("osquery", words[i])) {
statp->use_os = 1;
DPRINTF(statp->options & RES_DEBUG, "%s: 1\n", words[i]);
continue;
}
if ((ptr = strchr(words[i], ':'))) {
*ptr++ = 0;
value = atoi(ptr);
/* Not supported
if (!strcasecmp("ndots", words[i])) {
statp->ndots = value;
continue;
}
*/
if (!strcasecmp("retry", words[i])) {
if (value < 1)
value = 1;
statp->retry = value;
DPRINTF(statp->options & RES_DEBUG, "%s: %d\n", words[i], value);
continue;
}
if (!strcasecmp("retrans", words[i])) {
if (value < 1)
value = 1;
statp->retrans = value;
DPRINTF(statp->options & RES_DEBUG, "%s: %d\n", words[i], value);
continue;
}
}
DPRINTF(statp->options & RES_DEBUG, "unknown option: \"%s\"\n", words[i]);
}
}
/***********************************************************************
Read the resolv.conf file.
We only look for nameserver, domain, search and options
***********************************************************************/
#if MAXNS > MAXDNSRCH + 1
#define MAXSIZE MAXNS
#else
#define MAXSIZE MAXDNSRCH + 1 /* Make unused one visible */
#endif
static void get_resolv(res_state statp)
{
FILE * fd;
char *words[MAXSIZE + 1], line[4096], *ptr;
int sizes[DIM(words)];
int i, j, ns = 0, have_search, have_address, debug = statp->options & RES_DEBUG;
fd = fopen(_PATH_RESCONF, "r");
DPRINTF(debug, _PATH_RESCONF ": %s\n", fd?"OK":strerror(errno));
if (fd == NULL)
return;
statp->use_os = 0; /* Do not use os_query, except if allowed by "options" */
have_search = (statp->dnsrch[0] != NULL);
have_address = (statp->nscount != 0);
while ( fgets(line, sizeof(line), fd) != 0) {
DPRINTF(debug, "resolv.conf %s", line);
if ((i = scanline(line, words, sizes, DIM(words))) > 0) {
if (!have_address
&& !strncasecmp("nameserver", words[0], sizes[0])) {
for ( j = 1; j < i ; j++) {
unsigned int address;
address = cygwin_inet_addr(words[j]);
if (address == -1) {
DPRINTF(debug, "invalid server \"%s\"\n", words[j]);
}
else if (ns >= MAXNS) {
DPRINTF(debug, "no space for server \"%s\"\n", words[j]);
}
else {
statp->nsaddr_list[ns++].sin_addr.s_addr = address;
statp->nscount++;
DPRINTF(debug, "server \"%s\"\n", words[j]);
}
}
}
else if (!have_search
&& (!strncasecmp("search", words[0], sizes[0])
|| !strncasecmp("domain", words[0], sizes[0]))) {
ptr = statp->defdname;
for (j = 0; j + 1 < i; j++) {
if (j < MAXDNSRCH
&& ptr + sizes[j + 1] < &statp->defdname[DIM(statp->defdname)]) {
statp->dnsrch[j] = strcpy(ptr, words[j+1]);
statp->dnsrch[j+1] = 0;
ptr += sizes[j+1];
DPRINTF(debug, "domain|search \"%s\"\n", statp->dnsrch[j]);
}
else {
DPRINTF(debug, "no space for \"%s\"\n", words[j+1]);
}
}
}
/* Options line */
else if (!strncasecmp("options", words[0], sizes[0]))
get_options(statp, i - 1, &words[1]);
}
}
fclose(fd);
return;
}
/****************************************************************************/
/*
open_sock()
Create a datagram socket and call bind.
****************************************************************************/
static int open_sock(struct sockaddr_in *CliAddr, int debug)
{
int fd;
DPRINTF(debug, "opening UDP socket\n");
/* Create a datagram socket */
if ((fd = cygwin_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
DPRINTF(debug, "socket(UDP): %s\n", strerror(errno));
return -1;
}
CliAddr->sin_family = AF_INET;
CliAddr->sin_addr.s_addr = htonl(INADDR_ANY);
CliAddr->sin_port = htons(0);
bzero(CliAddr->sin_zero, sizeof(CliAddr->sin_zero));
/* Get a port */
if (cygwin_bind(fd, (struct sockaddr *) CliAddr, sizeof(*CliAddr)) < 0) {
DPRINTF(debug, "bind: %s\n", strerror(errno));
return -1;
}
return fd;
}
/*****************************************************************
*
__res_state()
Undocumented but public. Accessed through _res
*****************************************************************/
static struct __res_state res;
struct __res_state *__res_state(void)
{
return & res;
}
/*****************************************************************
*
res_init()
*****************************************************************/
int res_ninit(res_state statp)
{
int i;
char * ptr;
statp->res_h_errno = NETDB_SUCCESS;
statp->nscount = 0;
statp->os_query = NULL;
statp->retrans = RES_TIMEOUT; /* timeout in seconds */
statp->retry = RES_MAXRETRY; /* max number of retries */
statp->use_os = 1; /* use os_query if available and allowed by get_resolv */
statp->mypid = -1;
statp->sockfd = -1;
for (i = 0; i < DIM(statp->dnsrch); i++) statp->dnsrch[i] = 0;
/* Get search list from LOCALDOMAIN */
if ((ptr = getenv("LOCALDOMAIN")) != 0 ) {
DPRINTF(statp->options & RES_DEBUG, "LOCALDOMAIN \"%s\"\n", ptr);
minires_get_search(ptr, statp); /* domain or dnsrch */
}
/* resolv.conf (dns servers & search list)*/
get_resolv(statp);
/* Get dns servers and search list from an os-specific routine, set os_query */
get_dns_info(statp);
if (statp->nscount == 0 && !statp->os_query) {
errno = ENONET;
statp->res_h_errno = NETDB_INTERNAL;
DPRINTF(statp->options & RES_DEBUG, "no dns server found\n");
return -1;
}
for (i = 0; i < statp->nscount; i++) {
statp->nsaddr_list[i].sin_family = AF_INET;
statp->nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
bzero(statp->nsaddr_list[i].sin_zero, sizeof(statp->nsaddr_list[i].sin_zero));
}
/* Only debug may be set before calling init */
statp->options &= RES_DEBUG;
statp->options |= RES_INIT | RES_DEFAULT;
return 0;
}
int res_init()
{
int r = res_ninit(& res);
h_errno = res.res_h_errno;
return r;
}
/*****************************************************************
*
res_close()
*****************************************************************/
void res_nclose(res_state statp)
{
int res;
if (statp->sockfd != -1) {
res = close(statp->sockfd);
DPRINTF(statp->options & RES_DEBUG, "close sockfd %d: %s\n",
statp->sockfd, (res == 0)?"OK":strerror(errno));
statp->sockfd = -1;
}
}
void res_close()
{
res_nclose(& res);
}
/*****************************************************************
*
get_tcp_buf()
*****************************************************************/
static int get_tcp_buf(int fd, unsigned char *buf, int size, int debug)
{
int res;
while (size > 0) {
if ((res = read(fd, buf, size)) < 0) {
DPRINTF(debug, "read: %s\n", strerror(errno));
return -1;
}
DPRINTF(debug, "read %d out of %d\n", res, size);
size -= res;
buf += res;
}
return 0;
}
/*****************************************************************
*
get_tcp()
*****************************************************************/
static int get_tcp(struct sockaddr_in *CliAddr,
const unsigned char * MsgPtr, int MsgLength,
unsigned char * AnsPtr, int AnsLength, int debug)
{
int fd, res = -1;
unsigned short ans_length;
union {short len; u_char buf[sizeof(short)];} len_buf;
DPRINTF(debug, "retrying with TCP\n");
/* Create a tcp socket */
if ((fd = cygwin_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
DPRINTF(debug, "socket(TCP): %s\n", strerror(errno));
return -1;
}
if (cygwin_connect(fd, (struct sockaddr *) CliAddr, sizeof(* CliAddr)) < 0) {
DPRINTF(debug, "connect: %s\n", strerror(errno));
goto done;
}
/* Send the length then the message */
len_buf.len = htons(MsgLength);
if (write(fd, len_buf.buf, sizeof(len_buf)) != sizeof(len_buf)
|| write(fd, MsgPtr, MsgLength) != MsgLength) {
DPRINTF(debug, "write: %s\n", strerror(errno));
goto done;
}
/* Read the answer length */
if (get_tcp_buf(fd, len_buf.buf, sizeof(len_buf), debug))
goto done;
ans_length = ntohs(len_buf.len);
/* Read the answer */
if (get_tcp_buf(fd, AnsPtr, MIN(ans_length, AnsLength), debug))
goto done;
res = ans_length;
done:
close (fd);
return res;
}
/*****************************************************************
**
res_send
Assumes that the message is a query starting with a short id.
Handles retransmissions until that id is received.
*****************************************************************/
int res_nsend( res_state statp, const unsigned char * MsgPtr,
int MsgLength, unsigned char * AnsPtr, int AnsLength)
{
/* Current server, shared by all tasks */
volatile static unsigned int SServ = 0XFFFFFFFF;
int tcp;
const int debug = statp->options & RES_DEBUG;
fd_set fdset_read;
int rslt, addrLen, transNum, wServ;
struct sockaddr_in mySockAddr, dnsSockAddr;
struct timeval timeOut;
statp->res_h_errno = NETDB_SUCCESS;
if (((statp->options & RES_INIT) == 0) && (res_ninit(statp) != 0))
return -1;
/* Close the socket if it had been opened before a fork.
Reuse of pid's cannot hurt */
if ((statp->sockfd != -1) && (statp->mypid != getpid())) {
res_nclose(statp);
}
/* Open a socket for this process */
if (statp->sockfd == -1) {
/* Create a socket and bind it (to any port) */
statp->sockfd = open_sock(& mySockAddr, debug);
if (statp->sockfd < 0 ) {
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
/* Set close on exec flag */
if (fcntl(statp->sockfd, F_SETFD, 1) == -1) {
DPRINTF(debug, "fcntl: %s\n",
strerror(errno));
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
statp->mypid = getpid();
if (SServ == 0XFFFFFFFF) /* Pseudo random */
SServ = statp->mypid % statp->nscount;
}
transNum = 0;
while ( transNum++ < statp->retry) {
if ((wServ = SServ + 1) >= statp->nscount)
wServ = 0;
SServ = wServ;
/* Send the message */
rslt = cygwin_sendto(statp->sockfd, MsgPtr, MsgLength, 0,
(struct sockaddr *) &statp->nsaddr_list[wServ],
sizeof(struct sockaddr_in));
DPRINTF(debug, "sendto: server %08x sockfd %d %s\n",
statp->nsaddr_list[wServ].sin_addr.s_addr,
statp->sockfd, (rslt == MsgLength)?"OK":strerror(errno));
if (rslt != MsgLength) {
statp->res_h_errno = NETDB_INTERNAL;
return -1;
};
/*
Wait for a reply with select()
*/
FD_ZERO(&fdset_read);
FD_SET (statp->sockfd, &fdset_read );
timeOut.tv_sec = statp->retrans;
timeOut.tv_usec = 0;
rslt = cygwin_select(statp->sockfd + 1, &fdset_read, NULL, NULL, &timeOut);
if ( rslt == 0 ) { /* Timeout */
DPRINTF(statp->options & RES_DEBUG, "timeout for server %08x\n",
statp->nsaddr_list[wServ].sin_addr.s_addr);
continue;
}
else if ((rslt != 1) || (FD_ISSET(statp->sockfd, &fdset_read) == 0)) {
DPRINTF(debug, "select: %s\n", strerror(errno));
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
addrLen = sizeof(dnsSockAddr);
rslt = cygwin_recvfrom(statp->sockfd, AnsPtr, AnsLength, 0,
(struct sockaddr *) & dnsSockAddr, & addrLen);
if (rslt <= 0) {
DPRINTF(debug, "recvfrom: %s\n", strerror(errno));
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
/*
Prepare to retry with tcp
*/
for (tcp = 0; tcp < 2; tcp++) {
/* Check if this is the message we expected */
if ((*MsgPtr == *AnsPtr) /* Ids match */
&& (*(MsgPtr + 1) == *(AnsPtr + 1))
/* We have stopped checking this because the question may not be present on error,
in particular when the name in the question is not a valid name.
Simply check that the header is present. */
&& (rslt >= HFIXEDSZ)
/* && (rslt >= MsgLength )
&& (memcmp(MsgPtr + HFIXEDSZ, AnsPtr + HFIXEDSZ, MsgLength - HFIXEDSZ) == 0) */
&& ((AnsPtr[2] & QR) != 0)) {
DPRINTF(debug, "answer %u from %08x. Error %d. Count %d.\n",
rslt, dnsSockAddr.sin_addr.s_addr,
AnsPtr[3] & ERR_MASK, AnsPtr[6]*256 + AnsPtr[7]);
#if 0
NETDB_INTERNAL -1 /* see errno */
NETDB_SUCCESS 0 /* no problem */
HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
Also seen returned by some servers when the name is too long
NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
NO_DATA 4 /* Valid name, no data record of requested type */
#endif
if ((AnsPtr[3] & ERR_MASK) == NOERROR) {
if ((AnsPtr[2] & TC) && !(statp->options & RES_IGNTC)) { /* Truncated. Try TCP */
rslt = get_tcp(&statp->nsaddr_list[wServ], MsgPtr, MsgLength,
AnsPtr, AnsLength, statp->options & RES_DEBUG);
continue;
}
else if ((AnsPtr[6] | AnsPtr[7])!= 0)
return rslt;
else
statp->res_h_errno = NO_DATA;
}
else {
/* return HOST_NOT_FOUND even for non-authoritative answers */
if ((AnsPtr[3] & ERR_MASK) == NXDOMAIN)
statp->res_h_errno = HOST_NOT_FOUND;
else if ((AnsPtr[3] & ERR_MASK) == SERVFAIL)
statp->res_h_errno = TRY_AGAIN;
else
statp->res_h_errno = NO_RECOVERY;
}
return -1;
}
else {
DPRINTF(debug, "unexpected answer %u from %x to query to %x\n",
rslt, dnsSockAddr.sin_addr.s_addr,
statp->nsaddr_list[wServ].sin_addr.s_addr);
break;
}
} /* TCP */
}
DPRINTF(debug, "too many retries\n");
statp->res_h_errno = TRY_AGAIN;
return -1;
}
int res_send( const unsigned char * MsgPtr, int MsgLength,
unsigned char * AnsPtr, int AnsLength)
{
int r = res_nsend(& res, MsgPtr, MsgLength, AnsPtr, AnsLength);
h_errno = res.res_h_errno;
return r;
}
/*****************************************************************
*
res_mkquery
Return: packet size
-1 name format is incorrect
*****************************************************************/
int res_nmkquery (res_state statp,
int op, const char * dnameptr, int qclass, int qtype,
const unsigned char * dataptr, int datalen,
const unsigned char * newrr, unsigned char * buf, int buflen)
{
int i, len;
short id;
if (op == QUERY) {
/* Write the name and verify buffer length */
len = dn_comp(dnameptr, buf + HFIXEDSZ, buflen - HFIXEDSZ - QFIXEDSZ, NULL, NULL);
if (len < 0) {
DPRINTF(statp->options & RES_DEBUG,
"\"%s\" invalid or buffer too short\n", dnameptr);
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
/* Fill the header */
id = statp->id;
PUTSHORT(id, buf);
PUTSHORT(RD, buf);
PUTSHORT(1, buf); /* Number of questions */
for (i = 0; i < 3; i++)
PUTSHORT(0, buf); /* Number of answers */
/* Write qtype and qclass */
buf += len;
PUTSHORT(qtype, buf);
PUTSHORT(qclass, buf);
return len + 16; /* packet size */
}
else { /* Not implemented */
errno = ENOSYS;
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
}
int res_mkquery (int op, const char * dnameptr, int qclass, int qtype,
const unsigned char * dataptr, int datalen,
const unsigned char * newrr, unsigned char * buf, int buflen)
{
int r = res_nmkquery (& res, op, dnameptr, qclass, qtype,
dataptr, datalen, newrr, buf, buflen);
h_errno = res.res_h_errno;
return r;
}
/*****************************************************************
*
res_query()
*****************************************************************/
int res_nquery( res_state statp, const char * DomName, int Class, int Type,
unsigned char * AnsPtr, int AnsLength)
{
u_char packet[PACKETSZ];
int len;
DPRINTF(statp->options & RES_DEBUG, "query \"%s\" type %d\n", DomName, Type);
statp->res_h_errno = NETDB_SUCCESS;
/* If a hook exists to a native implementation, use it */
if (statp->os_query)
return ((os_query_t *) statp->os_query)(statp, DomName, Class, Type, AnsPtr, AnsLength);
if ((len = res_nmkquery (statp, QUERY, DomName, Class, Type,
0, 0, 0, packet, PACKETSZ)) < 0)
return -1;
return res_nsend( statp, packet, len, AnsPtr, AnsLength);
}
int res_query( const char * DomName, int Class, int Type, unsigned char * AnsPtr, int AnsLength)
{
int r = res_nquery(& res, DomName, Class, Type, AnsPtr, AnsLength);
h_errno = res.res_h_errno;
return r;
}
/*****************************************************************
*
res_querydomain()
*****************************************************************/
int res_nquerydomain( res_state statp, const char * Name, const char * DomName,
int Class, int Type, unsigned char * AnsPtr, int AnsLength)
{
char fqdn[MAXDNAME], *ptr;
int nlen;
if (!DomName)
ptr = (char *) Name;
else if ((nlen = strlen(Name)) >= sizeof(fqdn) - 1)
goto error;
else {
strcpy(fqdn, Name);
ptr = &fqdn[nlen];
if (nlen && *(ptr - 1) != '.')
*(ptr++ - 1) = '.';
fqdn[sizeof(fqdn) - 1] = 0;
strncpy(ptr, DomName, sizeof(fqdn) - (ptr - fqdn));
if (fqdn[sizeof(fqdn) - 1])
goto error;
ptr = fqdn;
}
return res_nquery(statp, ptr, Class, Type, AnsPtr, AnsLength);
error:
DPRINTF(statp->options & RES_DEBUG, "querydomain: name too long\n");
errno = EINVAL;
statp->res_h_errno = NETDB_INTERNAL;;
return -1;
}
int res_querydomain( const char * Name, const char * DomName, int Class,
int Type, unsigned char * AnsPtr, int AnsLength)
{
int r = res_nquerydomain(& res, Name, DomName, Class, Type, AnsPtr,
AnsLength);
h_errno = res.res_h_errno;
return r;
}
/*****************************************************************
*
res_search()
*****************************************************************/
int res_nsearch( res_state statp, const char * DomName, int Class, int Type,
unsigned char * AnsPtr, int AnsLength)
{
int len, stat, i;
char fullDomName[MAXDNAME], *ptr, *sptr;
DPRINTF(statp->options & RES_DEBUG, "search \"%s\" type %d\n", DomName, Type);
if (((statp->options & RES_INIT) == 0) && (res_ninit(statp) != 0))
return -1;
stat = res_nquery( statp, DomName, Class, Type, AnsPtr, AnsLength);
/* Check if will skip search */
if (statp->res_h_errno != HOST_NOT_FOUND /* Success or hard failure */
|| ((ptr = strrchr(DomName, '.')) && (!*(ptr+1))) /* Final dot */
|| (((statp->options & RES_DNSRCH) == 0) /* Or no search */
&& ((ptr != NULL) /* And some dot */
|| ((statp->options & RES_DEFNAMES) == 0)))/* or no def domain */
|| (!(sptr = statp->dnsrch[0])))
return stat;
len = strlen(DomName);
if (len >= MAXDNAME - 1) /* Space for next dot */
goto error;
strcpy(fullDomName, DomName);
fullDomName[len++] = '.';
fullDomName[MAXDNAME - 1] = 0; /* Overflow indicator */
i = 0;
do {
strncpy(fullDomName + len, sptr, MAXDNAME - len);
if (fullDomName[MAXDNAME - 1])
goto error;
stat = res_nquery(statp, fullDomName, Class, Type, AnsPtr, AnsLength);
} while ((sptr = statp->dnsrch[++i]) != NULL
&& statp->res_h_errno == HOST_NOT_FOUND
&& (statp->options & RES_DNSRCH) != 0);
/* Return last stat */
return stat;
error:
DPRINTF(statp->options & RES_DEBUG, "name too long during search\n");
errno = EINVAL;
statp->res_h_errno = NETDB_INTERNAL;
return -1;
}
int res_search( const char * DomName, int Class, int Type,
unsigned char * AnsPtr, int AnsLength)
{
int r = res_nsearch(& res, DomName, Class, Type, AnsPtr, AnsLength);
h_errno = res.res_h_errno;
return r;
}
/*****************************************************************
*
dn_expand
*****************************************************************/
int dn_expand(const unsigned char *msg, const unsigned char *eomorig,
const unsigned char *comp_dn, char *exp_dn, int length)
{
unsigned int len, complen = 0;
const unsigned char *comp_dn_orig = comp_dn;
/* char * exp_start = exp_dn; */
errno = EINVAL;
if (comp_dn >= eomorig)
goto expand_fail;
if ((len = *comp_dn++) == 0) /* Weird case */
exp_dn++;
else do {
if (len <= MAXLABEL) {
if ((length -= (len + 1)) > 0 /* Need space for final . */
&& comp_dn + len <= eomorig) {
do { *exp_dn++ = *comp_dn++; } while (--len != 0);
*exp_dn++ = '.';
}
else
goto expand_fail;
}
else if (len >= (128+64)) {
if (!complen) /* Still in the original field? */
complen = (comp_dn - comp_dn_orig) + 1;
comp_dn = msg + (((len & ~(128+64)) << 8) + *comp_dn);
if (comp_dn >= eomorig)
goto expand_fail;
}
else
goto expand_fail;
} while ((len = *comp_dn++) != 0);
/* Replace last . with a 0 */
*(--exp_dn) = 0;
if (!complen)
complen = comp_dn - comp_dn_orig;
/* fprintf(stderr, "dn_expand %s\n", exp_start); */
return complen;
expand_fail:
/* fprintf(stderr, "dn_expand fails\n"); */
return -1;
}
/*****************************************************************
*
dn_comp
Return -1 in case of overflow, but still fill buffer correctly.
We do not check the alphabet of the host names
nor the length of the compressed name and we
preserve the letter cases.
*****************************************************************/
int dn_comp(const char * exp_dn, u_char * comp_dn, int length,
u_char ** dnptrs, u_char ** lastdnptr)
{
u_char *cptr = comp_dn, *dptr, *lptr, *rptr;
unsigned int i, len;
u_char * const eptr = comp_dn + length - 1; /* Last valid */
errno = EINVAL;
if (*exp_dn == '.' && !*(exp_dn + 1))
exp_dn++;
while (1) {
if (*exp_dn == '.' || cptr > eptr)
return -1;
if (*exp_dn == 0) {
*cptr++ = 0;
break;
}
/* Try to compress */
if (dnptrs) {
for (i = 1; dnptrs[i]; i++) {
dptr = dnptrs[i];
if (dptr >= comp_dn) /* Handle name.name */
continue;
rptr = (u_char *) exp_dn;
len = *dptr++;
while (1) {
do {
if (*dptr++ != *rptr++)
goto next_dn;
} while (--len);
len = *dptr++;
if (len == 0) { /* last label */
if (!*rptr || (*rptr == '.' && !*(rptr + 1))) { /* Full match */
len = (dnptrs[i] - dnptrs[0]) | 0xC000;
/* Write pointer */
*cptr++ = len >> 8;
if (cptr > eptr)
return -1;
*cptr++ = len;
goto done;
}
goto next_dn;
}
if (*rptr++ != '.')
goto next_dn;
if (len >= 128 + 64) {
dptr = dnptrs[0] + ((len - 128 - 64) << 8) + *dptr;
len = *dptr++;
}
}
next_dn: ;
}
/* Record label if asked and if space is available and if not too far off */
if (lastdnptr && (lastdnptr != &dnptrs[i]) && (cptr - dnptrs[0]) < 0xC000) {
dnptrs[i] = cptr;
dnptrs[i+1] = NULL;
}
}
/* Write label */
lptr = cptr++; /* Length byte */
rptr = (u_char *) exp_dn;
do {
if (cptr <= eptr)
*cptr++ = *rptr;
} while ((*++rptr != '.') && (*rptr != 0));
len = rptr - (u_char *) exp_dn;
if (len > MAXLABEL)
return -1;
*lptr = len;
exp_dn = (char *) rptr;
if (*exp_dn != 0)
exp_dn++; /* Skip over . */
}
done:
return cptr - comp_dn;
}
/*****************************************************************
*
dn_skipname
Measures the compressed domain name length and returns it.
*****************************************************************/
int dn_skipname(const unsigned char *comp_dn, const unsigned char *eom)
{
int len;
const unsigned char *comp_dn_orig = comp_dn;
do {
len = *comp_dn++;
if (len >= (128 + 64)) {
comp_dn++;
break;
}
if (len > MAXLABEL ||
(comp_dn += len) > eom)
return -1;
} while (len != 0);
return comp_dn - comp_dn_orig;
}

View File

@ -0,0 +1,68 @@
/* minires.h. Stub synchronous resolver for Cygwin.
Copyright 2006 Red Hat, Inc.
Written by Pierre A. Humblet <Pierre.Humblet@ieee.org>
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#define __INSIDE_CYGWIN_NET__
#include "winsup.h"
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <netdb.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/unistd.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
extern in_addr_t cygwin_inet_addr (const char *);
extern int cygwin_socket (int, int, int);
extern int cygwin_bind (int, const struct sockaddr *, socklen_t);
extern int cygwin_connect (int, const struct sockaddr *, socklen_t);
extern int cygwin_select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
extern int cygwin_sendto (int, const void *, size_t, int,
const struct sockaddr *, socklen_t);
extern int cygwin_recvfrom (int, void *, size_t, int, struct sockaddr *,
socklen_t *);
/* Number of elements is an array */
#define DIM(x) (sizeof(x) / sizeof(*(x)))
/* Definitions to parse the messages */
#define RD (1<<8) /* Offset in a short */
#define RA (1<<7)
#define QR (1<<7) /* Offsets in a char */
#define TC (1<<1)
#define ERR_MASK 0xF
/* Type for os specific res_lookup */
typedef int (os_query_t) (res_state, const char *, int, int, u_char *, int);
/* Special use of state elements */
#define sockfd _vcsock
#define mypid _flags
#define os_query qhook
#define use_os pfcode
#define DPRINTF(cond, format...) if (cond) minires_dprintf(format)
/* Utility functions */
void minires_dprintf(const char * format, ...);
void minires_get_search(char * string, res_state statp);
void get_dns_info(res_state statp);

View File

@ -515,6 +515,7 @@ sigproc_terminate (exit_states es)
sigproc_printf ("entering");
sig_send (myself_nowait, __SIGEXIT);
proc_terminate (); // clean up process stuff
CloseHandle (my_sendsig);
}
}