diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/net/Makefile.inc | 8 | ||||
| -rw-r--r-- | lib/libc/net/base64.c | 321 | ||||
| -rw-r--r-- | lib/libc/net/gethostbydns.c | 49 | ||||
| -rw-r--r-- | lib/libc/net/gethostbyht.c | 13 | ||||
| -rw-r--r-- | lib/libc/net/getnetbydns.c | 5 | ||||
| -rw-r--r-- | lib/libc/net/getnetnamadr.c | 6 | ||||
| -rw-r--r-- | lib/libc/net/inet_net_ntop.c | 140 | ||||
| -rw-r--r-- | lib/libc/net/inet_net_pton.c | 208 | ||||
| -rw-r--r-- | lib/libc/net/inet_neta.c | 83 | ||||
| -rw-r--r-- | lib/libc/net/map_v4v6.c | 3 | ||||
| -rw-r--r-- | lib/libc/net/ns_addr.c | 2 | ||||
| -rw-r--r-- | lib/libc/net/nsap_addr.c | 4 | ||||
| -rw-r--r-- | lib/libc/net/res_comp.c | 11 | ||||
| -rw-r--r-- | lib/libc/net/res_config.h | 1 | ||||
| -rw-r--r-- | lib/libc/net/res_debug.c | 481 | ||||
| -rw-r--r-- | lib/libc/net/res_init.c | 10 | ||||
| -rw-r--r-- | lib/libc/net/res_mkquery.c | 63 | ||||
| -rw-r--r-- | lib/libc/net/res_query.c | 11 | ||||
| -rw-r--r-- | lib/libc/net/res_send.c | 65 | 
19 files changed, 1268 insertions, 216 deletions
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc index 112e7a4ec144..43de58fc69b4 100644 --- a/lib/libc/net/Makefile.inc +++ b/lib/libc/net/Makefile.inc @@ -3,16 +3,18 @@  # machine-independent net sources  .PATH: ${.CURDIR}/${MACHINE}/net ${.CURDIR}/net -SRCS+=	addr2ascii.c ascii2addr.c \ +SRCS+=	addr2ascii.c ascii2addr.c base64.c \  	gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \  	getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \  	getproto.c getprotoent.c getprotoname.c getservbyname.c \  	getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \  	inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \ +	inet_net_ntop.c inet_net_pton.c inet_neta.c \  	inet_pton.c linkaddr.c map_v4v6.c nsap_addr.c \  	rcmd.c recv.c res_comp.c res_data.c res_debug.c \ -	res_init.c res_mkquery.c res_query.c res_send.c send.c ether_addr.c \ -	ns_addr.c ns_ntoa.c +	res_init.c res_mkquery.c res_query.c res_send.c res_stubs.c \ +	send.c ether_addr.c \ +	ns_addr.c ns_ntoa.c   # iso_addr.c   # machine-dependent net sources diff --git a/lib/libc/net/base64.c b/lib/libc/net/base64.c new file mode 100644 index 000000000000..868826a777dc --- /dev/null +++ b/lib/libc/net/base64.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software.  No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <ctype.h> +#include <resolv.h> +#include <stdio.h> + +#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) +# include <stdlib.h> +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = +	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) +   The following encoding technique is taken from RFC 1521 by Borenstein +   and Freed.  It is reproduced here in a slightly edited form for +   convenience. + +   A 65-character subset of US-ASCII is used, enabling 6 bits to be +   represented per printable character. (The extra 65th character, "=", +   is used to signify a special processing function.) + +   The encoding process represents 24-bit groups of input bits as output +   strings of 4 encoded characters. Proceeding from left to right, a +   24-bit input group is formed by concatenating 3 8-bit input groups. +   These 24 bits are then treated as 4 concatenated 6-bit groups, each +   of which is translated into a single digit in the base64 alphabet. + +   Each 6-bit group is used as an index into an array of 64 printable +   characters. The character referenced by the index is placed in the +   output string. + +                         Table 1: The Base64 Alphabet + +      Value Encoding  Value Encoding  Value Encoding  Value Encoding +          0 A            17 R            34 i            51 z +          1 B            18 S            35 j            52 0 +          2 C            19 T            36 k            53 1 +          3 D            20 U            37 l            54 2 +          4 E            21 V            38 m            55 3 +          5 F            22 W            39 n            56 4 +          6 G            23 X            40 o            57 5 +          7 H            24 Y            41 p            58 6 +          8 I            25 Z            42 q            59 7 +          9 J            26 a            43 r            60 8 +         10 K            27 b            44 s            61 9 +         11 L            28 c            45 t            62 + +         12 M            29 d            46 u            63 / +         13 N            30 e            47 v +         14 O            31 f            48 w         (pad) = +         15 P            32 g            49 x +         16 Q            33 h            50 y + +   Special processing is performed if fewer than 24 bits are available +   at the end of the data being encoded.  A full encoding quantum is +   always completed at the end of a quantity.  When fewer than 24 input +   bits are available in an input group, zero bits are added (on the +   right) to form an integral number of 6-bit groups.  Padding at the +   end of the data is performed using the '=' character. + +   Since all base64 input is an integral number of octets, only the +         -------------------------------------------------                        +   following cases can arise: +    +       (1) the final quantum of encoding input is an integral +           multiple of 24 bits; here, the final unit of encoded +	   output will be an integral multiple of 4 characters +	   with no "=" padding, +       (2) the final quantum of encoding input is exactly 8 bits; +           here, the final unit of encoded output will be two +	   characters followed by two "=" padding characters, or +       (3) the final quantum of encoding input is exactly 16 bits; +           here, the final unit of encoded output will be three +	   characters followed by one "=" padding character. +   */ + +int +b64_ntop(src, srclength, target, targsize) +	u_char const *src; +	size_t srclength; +	char *target; +	size_t targsize; +{ +	size_t datalength = 0; +	u_char input[3]; +	u_char output[4]; +	int i; + +	while (2 < srclength) { +		input[0] = *src++; +		input[1] = *src++; +		input[2] = *src++; +		srclength -= 3; + +		output[0] = input[0] >> 2; +		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); +		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); +		output[3] = input[2] & 0x3f; +		Assert(output[0] < 64); +		Assert(output[1] < 64); +		Assert(output[2] < 64); +		Assert(output[3] < 64); + +		if (datalength + 4 > targsize) +			return (-1); +		target[datalength++] = Base64[output[0]]; +		target[datalength++] = Base64[output[1]]; +		target[datalength++] = Base64[output[2]]; +		target[datalength++] = Base64[output[3]]; +	} +     +	/* Now we worry about padding. */ +	if (0 != srclength) { +		/* Get what's left. */ +		input[0] = input[1] = input[2] = '\0'; +		for (i = 0; i < srclength; i++) +			input[i] = *src++; +	 +		output[0] = input[0] >> 2; +		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); +		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); +		Assert(output[0] < 64); +		Assert(output[1] < 64); +		Assert(output[2] < 64); + +		if (datalength + 4 > targsize) +			return (-1); +		target[datalength++] = Base64[output[0]]; +		target[datalength++] = Base64[output[1]]; +		if (srclength == 1) +			target[datalength++] = Pad64; +		else +			target[datalength++] = Base64[output[2]]; +		target[datalength++] = Pad64; +	} +	if (datalength >= targsize) +		return (-1); +	target[datalength] = '\0';	/* Returned value doesn't count \0. */ +	return (datalength); +} + +/* skips all whitespace anywhere. +   converts characters, four at a time, starting at (or after) +   src from base - 64 numbers into three 8 bit bytes in the target area. +   it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(src, target, targsize) +	char const *src; +	u_char *target; +	size_t targsize; +{ +	int tarindex, state, ch; +	char *pos; + +	state = 0; +	tarindex = 0; + +	while ((ch = *src++) != '\0') { +		if (isspace(ch))	/* Skip whitespace anywhere. */ +			continue; + +		if (ch == Pad64) +			break; + +		pos = strchr(Base64, ch); +		if (pos == 0) 		/* A non-base64 character. */ +			return (-1); + +		switch (state) { +		case 0: +			if (target) { +				if (tarindex >= targsize) +					return (-1); +				target[tarindex] = (pos - Base64) << 2; +			} +			state = 1; +			break; +		case 1: +			if (target) { +				if (tarindex + 1 >= targsize) +					return (-1); +				target[tarindex]   |=  (pos - Base64) >> 4; +				target[tarindex+1]  = ((pos - Base64) & 0x0f) +							<< 4 ; +			} +			tarindex++; +			state = 2; +			break; +		case 2: +			if (target) { +				if (tarindex + 1 >= targsize) +					return (-1); +				target[tarindex]   |=  (pos - Base64) >> 2; +				target[tarindex+1]  = ((pos - Base64) & 0x03) +							<< 6; +			} +			tarindex++; +			state = 3; +			break; +		case 3: +			if (target) { +				if (tarindex >= targsize) +					return (-1); +				target[tarindex] |= (pos - Base64); +			} +			tarindex++; +			state = 0; +			break; +		default: +			abort(); +		} +	} + +	/* +	 * We are done decoding Base-64 chars.  Let's see if we ended +	 * on a byte boundary, and/or with erroneous trailing characters. +	 */ + +	if (ch == Pad64) {		/* We got a pad char. */ +		ch = *src++;		/* Skip it, get next. */ +		switch (state) { +		case 0:		/* Invalid = in first position */ +		case 1:		/* Invalid = in second position */ +			return (-1); + +		case 2:		/* Valid, means one byte of info */ +			/* Skip any number of spaces. */ +			for (NULL; ch != '\0'; ch = *src++) +				if (!isspace(ch)) +					break; +			/* Make sure there is another trailing = sign. */ +			if (ch != Pad64) +				return (-1); +			ch = *src++;		/* Skip the = */ +			/* Fall through to "single trailing =" case. */ +			/* FALLTHROUGH */ + +		case 3:		/* Valid, means two bytes of info */ +			/* +			 * We know this char is an =.  Is there anything but +			 * whitespace after it? +			 */ +			for (NULL; ch != '\0'; ch = *src++) +				if (!isspace(ch)) +					return (-1); + +			/* +			 * Now make sure for cases 2 and 3 that the "extra" +			 * bits that slopped past the last full byte were +			 * zeros.  If we don't check them, they become a +			 * subliminal channel. +			 */ +			if (target && target[tarindex] != 0) +				return (-1); +		} +	} else { +		/* +		 * We ended by seeing the end of the string.  Make sure we +		 * have no partial bytes lying around. +		 */ +		if (state != 0) +			return (-1); +	} + +	return (tarindex); +} diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c index 2808c9518eed..f25abfc29ff1 100644 --- a/lib/libc/net/gethostbydns.c +++ b/lib/libc/net/gethostbydns.c @@ -1,4 +1,6 @@ -/*- +/* + * ++Copyright++ 1985, 1988, 1993 + * -   * Copyright (c) 1985, 1988, 1993   *	The Regents of the University of California.  All rights reserved.   * @@ -53,7 +55,8 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethostbydns.c,v 1.14 1996/12/24 02:10:24 wpaul Exp $"; +static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.20 1996/09/28 06:51:07 vixie Exp"; +static char rcsid[] = "$Id: gethostbydns.c,v 1.15 1996/12/27 18:21:05 wpaul Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -74,8 +77,6 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.14 1996/12/24 02:10:24 wpaul Exp  #include "res_config.h" -extern void _res_close __P((void)); -  #define SPRINTF(x) ((size_t)sprintf x)  #define	MAXALIASES	35 @@ -85,7 +86,6 @@ static const char AskedForGot[] =  		"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";  static char *h_addr_ptrs[MAXADDRS + 1]; -static struct hostent *gethostbyname_ipv4 __P((const char *));  static struct hostent host;  static char *host_aliases[MAXALIASES]; @@ -147,7 +147,7 @@ gethostanswer(answer, anslen, qname, qtype)  	int type, class, buflen, ancount, qdcount;  	int haveanswer, had_error;  	int toobig = 0; -	char tbuf[MAXDNAME+1]; +	char tbuf[MAXDNAME];  	const char *tname;  	int (*name_ok) __P((const char *)); @@ -274,7 +274,7 @@ gethostanswer(answer, anslen, qname, qtype)  		}  		if (type != qtype) {  			syslog(LOG_NOTICE|LOG_AUTH, -       "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"", +	"gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",  			       qname, p_class(C_IN), p_type(qtype),  			       p_type(type));  			cp += n; @@ -362,10 +362,11 @@ gethostanswer(answer, anslen, qname, qtype)  			dprintf("Impossible condition (type=%d)\n", type);  			h_errno = NO_RECOVERY;  			return (NULL); -		} /*switch*/ +			/* BIND has abort() here, too risky on bad data */ +		}  		if (!had_error)  			haveanswer++; -	} /*while*/ +	}  	if (haveanswer) {  		*ap = NULL;  		*hap = NULL; @@ -496,6 +497,36 @@ _gethostbydnsname(name, af)  			if (!isdigit(*cp) && *cp != '.')   				break;  		} +	if (isxdigit(name[0]) || name[0] == ':') +		for (cp = name;; ++cp) { +			if (!*cp) { +				if (*--cp == '.') +					break; +				/* +				 * All-IPv6-legal, no dot at the end. +				 * Fake up a hostent as if we'd actually +				 * done a lookup. +				 */ +				if (inet_pton(af, name, host_addr) <= 0) { +					h_errno = HOST_NOT_FOUND; +					return (NULL); +				} +				strncpy(hostbuf, name, MAXDNAME); +				hostbuf[MAXDNAME] = '\0'; +				bp = hostbuf + MAXDNAME; +				len = sizeof hostbuf - MAXDNAME; +				host.h_name = hostbuf; +				host.h_aliases = host_aliases; +				host_aliases[0] = NULL; +				h_addr_ptrs[0] = (char *)host_addr; +				h_addr_ptrs[1] = NULL; +				host.h_addr_list = h_addr_ptrs; +				h_errno = NETDB_SUCCESS; +				return (&host); +			} +			if (!isxdigit(*cp) && *cp != ':' && *cp != '.')  +				break; +		}  	if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {  		dprintf("res_search failed (%d)\n", n); diff --git a/lib/libc/net/gethostbyht.c b/lib/libc/net/gethostbyht.c index 3623ced42d76..77d0b3c41bc4 100644 --- a/lib/libc/net/gethostbyht.c +++ b/lib/libc/net/gethostbyht.c @@ -53,7 +53,7 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethostbyht.c,v 1.5 1996/08/29 20:07:51 peter Exp $"; +static char rcsid[] = "$Id: gethostbyht.c,v 1.6 1996/08/30 00:26:49 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/param.h> @@ -86,7 +86,7 @@ _sethosthtent(f)  		hostf = fopen(_PATH_HOSTS, "r" );  	else  		rewind(hostf); -	stayopen |= f; +	stayopen = f;  }  void @@ -147,7 +147,7 @@ gethostent()  		cp++;  	host.h_name = cp;  	q = host.h_aliases = host_aliases; -	if (cp = strpbrk(cp, " \t")) +	if ((cp = strpbrk(cp, " \t")) != NULL)  		*cp++ = '\0';  	while (cp && *cp) {  		if (*cp == ' ' || *cp == '\t') { @@ -156,7 +156,7 @@ gethostent()  		}  		if (q < &host_aliases[MAXALIASES - 1])  			*q++ = cp; -		if (cp = strpbrk(cp, " \t")) +		if ((cp = strpbrk(cp, " \t")) != NULL)  			*cp++ = '\0';  	}  	*q = NULL; @@ -179,7 +179,7 @@ _gethostbyhtname(name, af)  	register char **cp;  	sethostent(0); -	while ( (p = gethostent()) ) { +	while ((p = gethostent()) != NULL) {  		if (p->h_addrtype != af)  			continue;  		if (strcasecmp(p->h_name, name) == 0) @@ -201,10 +201,9 @@ _gethostbyhtaddr(addr, len, af)  	register struct hostent *p;  	sethostent(0); -	while ( (p = gethostent()) ) +	while ((p = gethostent()) != NULL)  		if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))  			break;  	endhostent();  	return (p);  } - diff --git a/lib/libc/net/getnetbydns.c b/lib/libc/net/getnetbydns.c index 1f7607b2012a..d3f031c39e5f 100644 --- a/lib/libc/net/getnetbydns.c +++ b/lib/libc/net/getnetbydns.c @@ -60,7 +60,7 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: getnetbydns.c,v 1.6 1996/07/12 18:54:37 jkh Exp $"; +static char rcsid[] = "$Id: getnetbydns.c,v 1.7 1996/08/29 20:07:58 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/param.h> @@ -80,7 +80,6 @@ static char rcsid[] = "$Id: getnetbydns.c,v 1.6 1996/07/12 18:54:37 jkh Exp $";  #include "res_config.h" -extern void _res_close __P((void));  extern int h_errno;  #define BYADDR 0 @@ -307,5 +306,5 @@ void  _endnetdnsent()  {  	_res.options &= ~(RES_STAYOPEN | RES_USEVC); -	_res_close(); +	res_close();  } diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c index b0e7468babed..9e5fce14d8b7 100644 --- a/lib/libc/net/getnetnamadr.c +++ b/lib/libc/net/getnetnamadr.c @@ -24,8 +24,8 @@   */  #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)$Id: getnetnamadr.c,v 1.5 1996/07/12 18:54:40 jkh Exp $"; -static char rcsid[] = "$Id: getnetnamadr.c,v 1.5 1996/07/12 18:54:40 jkh Exp $"; +static char sccsid[] = "@(#)$Id: getnetnamadr.c,v 1.6 1996/08/29 20:08:04 peter Exp $"; +static char rcsid[] = "$Id: getnetnamadr.c,v 1.6 1996/08/29 20:08:04 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/param.h> @@ -147,7 +147,7 @@ getnetbyname(const char *name)  struct netent *  getnetbyaddr(addr, af) -	long addr; +	u_long addr;  	int af;  {  	struct netent *hp = 0; diff --git a/lib/libc/net/inet_net_ntop.c b/lib/libc/net/inet_net_ntop.c new file mode 100644 index 000000000000..4c7893d417ff --- /dev/null +++ b/lib/libc/net/inet_net_ntop.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp"; +static const char rcsid[] = "$Id$"; +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static char *	inet_net_ntop_ipv4 __P((const u_char *src, int bits, +					char *dst, size_t size)); + +/* + * char * + * inet_net_ntop(af, src, bits, dst, size) + *	convert network number from network to presentation format. + *	generates CIDR style result always. + * return: + *	pointer to dst, or NULL if an error occurred (check errno). + * author: + *	Paul Vixie (ISC), July 1996 + */ +char * +inet_net_ntop(af, src, bits, dst, size) +	int af; +	const void *src; +	int bits; +	char *dst; +	size_t size; +{ +	switch (af) { +	case AF_INET: +		return (inet_net_ntop_ipv4(src, bits, dst, size)); +	default: +		errno = EAFNOSUPPORT; +		return (NULL); +	} +} + +/* + * static char * + * inet_net_ntop_ipv4(src, bits, dst, size) + *	convert IPv4 network number from network to presentation format. + *	generates CIDR style result always. + * return: + *	pointer to dst, or NULL if an error occurred (check errno). + * note: + *	network byte order assumed.  this means 192.5.5.240/28 has + *	0x11110000 in its fourth octet. + * author: + *	Paul Vixie (ISC), July 1996 + */ +static char * +inet_net_ntop_ipv4(src, bits, dst, size) +	const u_char *src; +	int bits; +	char *dst; +	size_t size; +{ +	char *odst = dst; +	char *t; +	u_int m; +	int b; + +	if (bits < 0 || bits > 32) { +		errno = EINVAL; +		return (NULL); +	} +	if (bits == 0) { +		if (size < sizeof "0") +			goto emsgsize; +		*dst++ = '0'; +		*dst = '\0'; +	} + +	/* Format whole octets. */ +	for (b = bits / 8; b > 0; b--) { +		if (size < sizeof "255.") +			goto emsgsize; +		t = dst; +		dst += SPRINTF((dst, "%u", *src++)); +		if (b > 1) { +			*dst++ = '.'; +			*dst = '\0'; +		} +		size -= (size_t)(dst - t); +	} + +	/* Format partial octet. */ +	b = bits % 8; +	if (b > 0) { +		if (size < sizeof ".255") +			goto emsgsize; +		t = dst; +		if (dst != odst) +			*dst++ = '.'; +		m = ((1 << b) - 1) << (8 - b); +		dst += SPRINTF((dst, "%u", *src & m)); +		size -= (size_t)(dst - t); +	} + +	/* Format CIDR /width. */ +	if (size < sizeof "/32") +		goto emsgsize; +	dst += SPRINTF((dst, "/%u", bits)); +	return (odst); + + emsgsize: +	errno = EMSGSIZE; +	return (NULL); +} diff --git a/lib/libc/net/inet_net_pton.c b/lib/libc/net/inet_net_pton.c new file mode 100644 index 000000000000..6fd6a06c6da9 --- /dev/null +++ b/lib/libc/net/inet_net_pton.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp"; +static const char rcsid[] = "$Id$"; +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static int	inet_net_pton_ipv4 __P((const char *src, u_char *dst, +					size_t size)); + +/* + * static int + * inet_net_pton(af, src, dst, size) + *	convert network number from presentation to network format. + *	accepts hex octets, hex strings, decimal octets, and /CIDR. + *	"size" is in bytes and describes "dst". + * return: + *	number of bits, either imputed classfully or specified with /CIDR, + *	or -1 if some failure occurred (check errno).  ENOENT means it was + *	not a valid network specification. + * author: + *	Paul Vixie (ISC), June 1996 + */ +int +inet_net_pton(af, src, dst, size) +	int af; +	const char *src; +	void *dst; +	size_t size; +{ +	switch (af) { +	case AF_INET: +		return (inet_net_pton_ipv4(src, dst, size)); +	default: +		errno = EAFNOSUPPORT; +		return (-1); +	} +} + +/* + * static int + * inet_net_pton_ipv4(src, dst, size) + *	convert IPv4 network number from presentation to network format. + *	accepts hex octets, hex strings, decimal octets, and /CIDR. + *	"size" is in bytes and describes "dst". + * return: + *	number of bits, either imputed classfully or specified with /CIDR, + *	or -1 if some failure occurred (check errno).  ENOENT means it was + *	not an IPv4 network specification. + * note: + *	network byte order assumed.  this means 192.5.5.240/28 has + *	0x11110000 in its fourth octet. + * author: + *	Paul Vixie (ISC), June 1996 + */ +static int +inet_net_pton_ipv4(src, dst, size) +	const char *src; +	u_char *dst; +	size_t size; +{ +	static const char +		xdigits[] = "0123456789abcdef", +		digits[] = "0123456789"; +	int n, ch, tmp, dirty, bits; +	const u_char *odst = dst; + +	ch = *src++; +	if (ch == '0' && (src[0] == 'x' || src[0] == 'X') +	    && isascii(src[1]) && isxdigit(src[1])) { +		/* Hexadecimal: Eat nybble string. */ +		if (size <= 0) +			goto emsgsize; +		*dst = 0, dirty = 0; +		src++;	/* skip x or X. */ +		while ((ch = *src++) != '\0' && +		       isascii(ch) && isxdigit(ch)) { +			if (isupper(ch)) +				ch = tolower(ch); +			n = strchr(xdigits, ch) - xdigits; +			assert(n >= 0 && n <= 15); +			*dst |= n; +			if (!dirty++) +				*dst <<= 4; +			else if (size-- > 0) +				*++dst = 0, dirty = 0; +			else +				goto emsgsize; +		} +		if (dirty) +			size--; +	} else if (isascii(ch) && isdigit(ch)) { +		/* Decimal: eat dotted digit string. */ +		for (;;) { +			tmp = 0; +			do { +				n = strchr(digits, ch) - digits; +				assert(n >= 0 && n <= 9); +				tmp *= 10; +				tmp += n; +				if (tmp > 255) +					goto enoent; +			} while ((ch = *src++) != '\0' && +				 isascii(ch) && isdigit(ch)); +			if (size-- <= 0) +				goto emsgsize; +			*dst++ = (u_char) tmp; +			if (ch == '\0' || ch == '/') +				break; +			if (ch != '.') +				goto enoent; +			ch = *src++; +			if (!isascii(ch) || !isdigit(ch)) +				goto enoent; +		} +	} else +		goto enoent; + +	bits = -1; +	if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) { +		/* CIDR width specifier.  Nothing can follow it. */ +		ch = *src++;	/* Skip over the /. */ +		bits = 0; +		do { +			n = strchr(digits, ch) - digits; +			assert(n >= 0 && n <= 9); +			bits *= 10; +			bits += n; +		} while ((ch = *src++) != '\0' && +			 isascii(ch) && isdigit(ch)); +		if (ch != '\0') +			goto enoent; +		if (bits > 32) +			goto emsgsize; +	} + +	/* Firey death and destruction unless we prefetched EOS. */ +	if (ch != '\0') +		goto enoent; + +	/* If nothing was written to the destination, we found no address. */ +	if (dst == odst) +		goto enoent; +	/* If no CIDR spec was given, infer width from net class. */ +	if (bits == -1) { +		if (*odst >= 240)	/* Class E */ +			bits = 32; +		else if (*odst >= 224)	/* Class D */ +			bits = 4; +		else if (*odst >= 192)	/* Class C */ +			bits = 24; +		else if (*odst >= 128)	/* Class B */ +			bits = 16; +		else			/* Class A */ +			bits = 8; +		/* If imputed mask is narrower than specified octets, widen. */ +		if (bits >= 8 && bits < ((dst - odst) * 8)) +			bits = (dst - odst) * 8; +	} +	/* Extend network to cover the actual mask. */ +	while (bits > ((dst - odst) * 8)) { +		if (size-- <= 0) +			goto emsgsize; +		*dst++ = '\0'; +	} +	return (bits); + + enoent: +	errno = ENOENT; +	return (-1); + + emsgsize: +	errno = EMSGSIZE; +	return (-1); +} diff --git a/lib/libc/net/inet_neta.c b/lib/libc/net/inet_neta.c new file mode 100644 index 000000000000..15a1c70529ac --- /dev/null +++ b/lib/libc/net/inet_neta.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp"; +static const char rcsid[] = "$Id$"; +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <errno.h> +#include <stdio.h> + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +/* + * char * + * inet_neta(src, dst, size) + *	format a u_long network number into presentation format. + * return: + *	pointer to dst, or NULL if an error occurred (check errno). + * note: + *	format of ``src'' is as for inet_network(). + * author: + *	Paul Vixie (ISC), July 1996 + */ +char * +inet_neta(src, dst, size) +	u_long src; +	char *dst; +	size_t size; +{ +	char *odst = dst; +	char *tp; + +	while (src & 0xffffffff) { +		u_char b = (src & 0xff000000) >> 24; + +		src <<= 8; +		if (b) { +			if (size < sizeof "255.") +				goto emsgsize; +			tp = dst; +			dst += SPRINTF((dst, "%u", b)); +			if (src != 0L) { +				*dst++ = '.'; +				*dst = '\0'; +			} +			size -= (size_t)(dst - tp); +		} +	} +	if (dst == odst) { +		if (size < sizeof "0.0.0.0") +			goto emsgsize; +		strcpy(dst, "0.0.0.0"); +	} +	return (odst); + + emsgsize: +	errno = EMSGSIZE; +	return (NULL); +} diff --git a/lib/libc/net/map_v4v6.c b/lib/libc/net/map_v4v6.c index f4fdc2329d8d..01c0103ac937 100644 --- a/lib/libc/net/map_v4v6.c +++ b/lib/libc/net/map_v4v6.c @@ -55,7 +55,7 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethnamaddr.c,v 8.17 1996/08/05 08:31:35 vixie Exp $"; +static char rcsid[] = "$Id: map_v4v6.c,v 1.1 1996/08/29 20:08:07 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -66,6 +66,7 @@ static char rcsid[] = "$Id: gethnamaddr.c,v 8.17 1996/08/05 08:31:35 vixie Exp $  #include <arpa/nameser.h>  #include <stdio.h> +#include <string.h>  #include <netdb.h>  #include <resolv.h>  #include <ctype.h> diff --git a/lib/libc/net/ns_addr.c b/lib/libc/net/ns_addr.c index da8f8b4d72ca..3446e08c19a6 100644 --- a/lib/libc/net/ns_addr.c +++ b/lib/libc/net/ns_addr.c @@ -64,7 +64,7 @@ ns_addr(name)  	 * form  2-272.AA001234H.01777, i.e. XDE standard.  	 * Great efforts are made to insure backward compatability.  	 */ -	if (hostname = strchr(buf, '#')) +	if ((hostname = strchr(buf, '#')) != NULL)  		separator = '#';  	else {  		hostname = strchr(buf, '.'); diff --git a/lib/libc/net/nsap_addr.c b/lib/libc/net/nsap_addr.c index fcbbf1ebc2d7..0c295825eb96 100644 --- a/lib/libc/net/nsap_addr.c +++ b/lib/libc/net/nsap_addr.c @@ -16,7 +16,7 @@   */  #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$Id: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; +static char rcsid[] = "$Id: nsap_addr.c,v 1.1 1996/08/29 20:08:08 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -52,7 +52,7 @@ inet_nsap_addr(ascii, binary, maxlen)  			c = toupper(c);  		if (isxdigit(c)) {  			nib = xtob(c); -			if (c = *ascii++) { +			if ((c = *ascii++) != '\0') {  				c = toupper(c);  				if (isxdigit(c)) {  					*binary++ = (nib << 4) | xtob(c); diff --git a/lib/libc/net/res_comp.c b/lib/libc/net/res_comp.c index 6f4d31f74266..20b0e3a66f4d 100644 --- a/lib/libc/net/res_comp.c +++ b/lib/libc/net/res_comp.c @@ -55,7 +55,8 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)res_comp.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_comp.c,v 8.8 1996/08/05 08:31:35 vixie Exp $"; +static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp"; +static char rcsid[] = "$Id: res_comp.c,v 1.7 1996/08/30 21:13:27 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -390,8 +391,12 @@ int  res_ownok(dn)  	const char *dn;  { -	if (asterchar(dn[0]) && periodchar(dn[1])) -		dn += 2; +	if (asterchar(dn[0])) { +		if (periodchar(dn[1])) +			return (res_hnok(dn+2)); +		if (dn[1] == '\0') +			return (1); +	}  	return (res_hnok(dn));  } diff --git a/lib/libc/net/res_config.h b/lib/libc/net/res_config.h index 2c21b13eaab7..f29246a57e8f 100644 --- a/lib/libc/net/res_config.h +++ b/lib/libc/net/res_config.h @@ -4,6 +4,5 @@  #define	RFC1535		/* comply with RFC1535 (STRONGLY reccomended by vixie)*/  #undef	USELOOPBACK	/* res_init() bind to localhost */  #undef	SUNSECURITY	/* verify gethostbyaddr() calls - WE DONT NEED IT  */ -#define	ALLOW_UPDATES	/* compile recognition for update REQUESTS - harmless */  #define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */  #define	CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */ diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c index 8af52875943d..9b388d278ba1 100644 --- a/lib/libc/net/res_debug.c +++ b/lib/libc/net/res_debug.c @@ -50,29 +50,54 @@   * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS   * SOFTWARE.   * - + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software.  No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.   * --Copyright--   */  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_debug.c,v 8.12 1996/08/05 08:31:35 vixie Exp $"; +static char orig_rcsid[] = "From: Id: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp"; +static char rcsid[] = "$Id: res_debug.c,v 1.10 1996/08/30 21:13:33 peter Exp $";  #endif /* LIBC_SCCS and not lint */ +#include "res_config.h" +  #include <sys/param.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <netinet/in.h>  #include <arpa/inet.h> - -#include "res_config.h"  #include <arpa/nameser.h> -#include <stdio.h> +#include <ctype.h>  #include <netdb.h>  #include <resolv.h> -#include <ctype.h> -#include <string.h> +#include <stdio.h> +#include <time.h> +#include <stdlib.h> +#include <string.h>  extern const char *_res_opcodes[];  extern const char *_res_resultcodes[]; @@ -173,7 +198,7 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)  	 * Print answer records.  	 */  	sflag = (_res.pfcode & pflag); -	if ( (n = ntohs(cnt)) ) { +	if ((n = ntohs(cnt)) != 0) {  		if ((!_res.pfcode) ||  		    ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))  			fprintf(file, hs); @@ -244,7 +269,7 @@ __fp_nquery(msg, len, file)  	if ((_res.options & RES_INIT) == 0 && res_init() == -1)  		return; -#define TruncTest(x) if (x >= endMark) goto trunc +#define TruncTest(x) if (x > endMark) goto trunc  #define	ErrorTest(x) if (x == NULL) goto error  	/* @@ -252,7 +277,7 @@ __fp_nquery(msg, len, file)  	 */  	hp = (HEADER *)msg;  	cp = msg + HFIXEDSZ; -	endMark = cp + len; +	endMark = msg + len;  	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {  		fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",  			_res_opcodes[hp->opcode], @@ -274,6 +299,12 @@ __fp_nquery(msg, len, file)  			fprintf(file, " rd");  		if (hp->ra)  			fprintf(file, " ra"); +		if (hp->unused) +			fprintf(file, " UNUSED-BIT-ON"); +		if (hp->ad) +			fprintf(file, " ad"); +		if (hp->cd) +			fprintf(file, " cd");  	}  	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {  		fprintf(file, "; Ques: %d", ntohs(hp->qdcount)); @@ -288,7 +319,7 @@ __fp_nquery(msg, len, file)  	/*  	 * Print question records.  	 */ -	if ( (n = ntohs(hp->qdcount)) ) { +	if ((n = ntohs(hp->qdcount)) != 0) {  		if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))  			fprintf(file, ";; QUESTIONS:\n");  		while (--n >= 0) { @@ -387,6 +418,30 @@ __p_cdname(cp, msg, file)  	return (p_cdnname(cp, msg, PACKETSZ, file));  } + +/* Return a fully-qualified domain name from a compressed name (with +   length supplied).  */ + +const u_char * +__p_fqnname(cp, msg, msglen, name, namelen) +	const u_char *cp, *msg; +	int msglen; +	char *name; +	int namelen; +{ +	int n, newlen; + +	if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0) +		return (NULL); +	newlen = strlen (name); +	if (newlen == 0 || name[newlen - 1] != '.') +		if (newlen+1 >= namelen)	/* Lack space for final dot */ +			return (NULL); +		else +			strcpy(name + newlen, "."); +	return (cp + n); +} +  /* XXX:	the rest of these functions need to become length-limited, too. (vix)   */ @@ -396,18 +451,13 @@ __p_fqname(cp, msg, file)  	FILE *file;  {  	char name[MAXDNAME]; -	int n; +	const u_char *n; -	if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0) +	n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name); +	if (n == NULL)  		return (NULL); -	if (name[0] == '\0') { -		putc('.', file); -	} else { -		fputs(name, file); -		if (name[strlen(name) - 1] != '.') -			putc('.', file); -	} -	return (cp + n); +	fputs(name, file); +	return (n);  }  /* @@ -423,13 +473,19 @@ __p_rr(cp, msg, file)  	const u_char *cp1, *cp2;  	u_int32_t tmpttl, t;  	int lcnt; +	u_int16_t keyflags; +	char rrname[MAXDNAME];		/* The fqdn of this RR */ +	char base64_key[MAX_KEY_BASE64];  	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {  		h_errno = NETDB_INTERNAL;  		return (NULL);  	} -	if ((cp = p_fqname(cp, msg, file)) == NULL) +	cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname); +	if (!cp)  		return (NULL);			/* compression error */ +	fputs(rrname, file); +	  	type = _getshort((u_char*)cp);  	cp += INT16SZ;  	class = _getshort((u_char*)cp); @@ -464,7 +520,7 @@ __p_rr(cp, msg, file)  				address = inet_ntoa(inaddr);  				cp += INADDRSZ;  				protocol = *(u_char*)cp; -				cp += sizeof(u_char); +				cp += sizeof (u_char);  				port = _getshort((u_char*)cp);  				cp += INT16SZ;  				fprintf(file, "\t%s\t; proto %d, port %d", @@ -488,16 +544,16 @@ __p_rr(cp, msg, file)  	case T_HINFO:  	case T_ISDN: -		(void) fputs("\t\"", file);  		cp2 = cp + dlen; +		(void) fputs("\t\"", file);  		if ((n = (unsigned char) *cp++) != 0) {  			for (c = n; c > 0 && cp < cp2; c--) {  				if (strchr("\n\"\\", *cp))  					(void) putc('\\', file);  				(void) putc(*cp++, file);  			} -			putc('"', file);  		} +		putc('"', file);  		if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {  			(void) fputs ("\t\"", file);  			for (c = n; c > 0 && cp < cp2; c--) { @@ -555,20 +611,35 @@ __p_rr(cp, msg, file)  			return (NULL);  		break; -	case T_TXT:  	case T_X25: +		cp2 = cp + dlen;  		(void) fputs("\t\"", file); +		if ((n = (unsigned char) *cp++) != 0) { +			for (c = n; c > 0 && cp < cp2; c--) { +				if (strchr("\n\"\\", *cp)) +					(void) putc('\\', file); +				(void) putc(*cp++, file); +			} +		} +		putc('"', file); +		break; + +	case T_TXT: +		(void) putc('\t', file);  		cp2 = cp1 + dlen;  		while (cp < cp2) { -			if (n = (unsigned char) *cp++) { +			putc('"', file); +			if ((n = (unsigned char) *cp++) != '\0') {  				for (c = n; c > 0 && cp < cp2; c--) {  					if (strchr("\n\"\\", *cp))  						(void) putc('\\', file);  					(void) putc(*cp++, file);  				}  			} +			putc('"', file); +			if (cp < cp2) +				putc(' ', file);  		} -		putc('"', file);  		break;  	case T_NSAP: @@ -579,18 +650,53 @@ __p_rr(cp, msg, file)  	case T_AAAA: {  		char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; -		fprintf(file, "\t%s\n", inet_ntop(AF_INET6, cp, t, sizeof t)); +		fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));  		cp += dlen;  		break; -	} +	    }  	case T_LOC: {  		char t[255]; -		(void) fprintf(file, "\t%s\n", loc_ntoa(cp, t)); +		fprintf(file, "\t%s", loc_ntoa(cp, t));  		cp += dlen;  		break; -	} +	    } + +	case T_NAPTR: { +		u_int order, preference; + +		order = _getshort(cp);  cp += INT16SZ; +		preference   = _getshort(cp);  cp += INT16SZ; +		fprintf(file, "\t%u %u ",order, preference); +		/* Flags */ +		n = *cp++; +		fprintf(file,"\"%.*s\" ", (int)n, cp); +		cp += n; +		/* Service */ +		n = *cp++; +		fprintf(file,"\"%.*s\" ", (int)n, cp); +		cp += n; +		/* Regexp */ +		n = *cp++; +		fprintf(file,"\"%.*s\" ", (int)n, cp); +		cp += n; +		if ((cp = p_fqname(cp, msg, file)) == NULL) +			return (NULL); +		break; +	    } + +	case T_SRV: { +		u_int priority, weight, port; + +		priority = _getshort(cp);  cp += INT16SZ; +		weight   = _getshort(cp);  cp += INT16SZ; +		port     = _getshort(cp);  cp += INT16SZ; +		fprintf(file, "\t%u %u %u ", priority, weight, port); +		if ((cp = p_fqname(cp, msg, file)) == NULL) +			return (NULL); +		break; +	    }  	case T_MINFO:  	case T_RP: @@ -624,7 +730,7 @@ __p_rr(cp, msg, file)  		fprintf(file, "\t%s %s ( ",  			inet_ntoa(inaddr),  			deproto((int) *cp)); -		cp += sizeof(u_char); +		cp += sizeof (u_char);  		n = 0;  		lcnt = 0;  		while (cp < cp1 + dlen) { @@ -645,6 +751,72 @@ __p_rr(cp, msg, file)  		putc(')', file);  		break; +	case T_KEY: +		putc('\t', file); +		keyflags = _getshort(cp); +		cp += 2; +		fprintf(file,"0x%04x", keyflags );	/* flags */ +		fprintf(file," %u", *cp++);	/* protocol */ +		fprintf(file," %u (", *cp++);	/* algorithm */ + +		n = b64_ntop(cp, (cp1 + dlen) - cp, +			     base64_key, sizeof base64_key); +		for (c = 0; c < n; ++c) { +			if (0 == (c & 0x3F)) +				fprintf(file, "\n\t"); +			putc(base64_key[c], file);  /* public key data */ +		} + +		fprintf(file, " )"); +		if (n < 0) +			fprintf(file, "\t; BAD BASE64"); +		fflush(file); +		cp = cp1 + dlen; +		break; + +	case T_SIG: +	        type = _getshort((u_char*)cp); +		cp += INT16SZ; +		fprintf(file, " %s", p_type(type)); +		fprintf(file, "\t%d", *cp++);	/* algorithm */ +		/* Check label value and print error if wrong. */ +		n = *cp++; +		c = dn_count_labels (rrname); +		if (n != c) +			fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t", +				n, c); +		/* orig ttl */ +		n = _getlong((u_char*)cp); +		if (n != tmpttl) +			fprintf(file, " %u", n); +		cp += INT32SZ; +		/* sig expire */ +		fprintf(file, " (\n\t%s", +				     __p_secstodate(_getlong((u_char*)cp))); +		cp += INT32SZ; +		/* time signed */ +		fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp))); +		cp += INT32SZ; +		/* sig footprint */ +		fprintf(file," %u ", _getshort((u_char*)cp)); +		cp += INT16SZ; +		/* signer's name */ +		cp = p_fqname(cp, msg, file); +		n = b64_ntop(cp, (cp1 + dlen) - cp, +			     base64_key, sizeof base64_key); +		for (c = 0; c < n; c++) { +			if (0 == (c & 0x3F)) +				fprintf (file, "\n\t"); +			putc(base64_key[c], file);		/* signature */ +		} +		/* Clean up... */ +		fprintf(file, " )"); +		if (n < 0) +			fprintf(file, "\t; BAD BASE64"); +		fflush(file); +		cp = cp1+dlen; +		break; +  #ifdef ALLOW_T_UNSPEC  	case T_UNSPEC:  		{ @@ -680,54 +852,144 @@ __p_rr(cp, msg, file)  }  /* + * Names of RR classes and qclasses.  Classes and qclasses are the same, except + * that C_ANY is a qclass but not a class.  (You can ask for records of class + * C_ANY, but you can't have any records of that class in the database.) + */ +const struct res_sym __p_class_syms[] = { +	{C_IN,		"IN"}, +	{C_CHAOS,	"CHAOS"}, +	{C_HS,		"HS"}, +	{C_HS,		"HESIOD"}, +	{C_ANY,		"ANY"}, +	{C_IN, 		(char *)0} +}; + +/* + * Names of RR types and qtypes.  Types and qtypes are the same, except + * that T_ANY is a qtype but not a type.  (You can ask for records of type + * T_ANY, but you can't have any records of that type in the database.) + */ +const struct res_sym __p_type_syms[] = { +	{T_A,		"A",		"address"}, +	{T_NS,		"NS",		"name server"}, +	{T_MD,		"MD",		"mail destination (deprecated)"}, +	{T_MF,		"MF",		"mail forwarder (deprecated)"}, +	{T_CNAME,	"CNAME",	"canonical name"}, +	{T_SOA,		"SOA",		"start of authority"}, +	{T_MB,		"MB",		"mailbox"}, +	{T_MG,		"MG",		"mail group member"}, +	{T_MR,		"MR",		"mail rename"}, +	{T_NULL,	"NULL",		"null"}, +	{T_WKS,		"WKS",		"well-known service (deprecated)"}, +	{T_PTR,		"PTR",		"domain name pointer"}, +	{T_HINFO,	"HINFO",	"host information"}, +	{T_MINFO,	"MINFO",	"mailbox information"}, +	{T_MX,		"MX",		"mail exchanger"}, +	{T_TXT,		"TXT",		"text"}, +	{T_RP,		"RP",		"responsible person"}, +	{T_AFSDB,	"AFSDB",	"DCE or AFS server"}, +	{T_X25,		"X25",		"X25 address"}, +	{T_ISDN,	"ISDN",		"ISDN address"}, +	{T_RT,		"RT",		"router"}, +	{T_NSAP,	"NSAP",		"nsap address"}, +	{T_NSAP_PTR,	"NSAP_PTR",	"domain name pointer"}, +	{T_SIG,		"SIG",		"signature"}, +	{T_KEY,		"KEY",		"key"}, +	{T_PX,		"PX",		"mapping information"}, +	{T_GPOS,	"GPOS",		"geographical position (withdrawn)"}, +	{T_AAAA,	"AAAA",		"IPv6 address"}, +	{T_LOC,		"LOC",		"location"}, +	{T_NXT,		"NXT",		"next valid name (unimplemented)"}, +	{T_EID,		"EID",		"endpoint identifier (unimplemented)"}, +	{T_NIMLOC,	"NIMLOC",	"NIMROD locator (unimplemented)"}, +	{T_SRV,		"SRV",		"server selection"}, +	{T_ATMA,	"ATMA",		"ATM address (unimplemented)"}, +	{T_IXFR,	"IXFR",		"incremental zone transfer"}, +	{T_AXFR,	"AXFR",		"zone transfer"}, +	{T_MAILB,	"MAILB",	"mailbox-related data (deprecated)"}, +	{T_MAILA,	"MAILA",	"mail agent (deprecated)"}, +	{T_UINFO,	"UINFO",	"user information (nonstandard)"}, +	{T_UID,		"UID",		"user ID (nonstandard)"}, +	{T_GID,		"GID",		"group ID (nonstandard)"}, +	{T_NAPTR,	"NAPTR",	"URN Naming Authority"}, +#ifdef ALLOW_T_UNSPEC +	{T_UNSPEC,	"UNSPEC",	"unspecified data (nonstandard)"}, +#endif /* ALLOW_T_UNSPEC */ +	{T_ANY,		"ANY",		"\"any\""}, +	{0, 		NULL,		NULL} +}; + +int +__sym_ston(syms, name, success) +	const struct res_sym *syms; +	char *name; +	int *success; +{ +	for (NULL; syms->name != 0; syms++) { +		if (strcasecmp (name, syms->name) == 0) { +			if (success) +				*success = 1; +			return (syms->number); +		} +	} +	if (success) +		*success = 0; +	return (syms->number);		/* The default value. */ +} + +const char * +__sym_ntos(syms, number, success) +	const struct res_sym *syms; +	int number; +	int *success; +{ +	static char unname[20]; + +	for (NULL; syms->name != 0; syms++) { +		if (number == syms->number) { +			if (success) +				*success = 1; +			return (syms->name); +		} +	} + +	sprintf (unname, "%d", number); +	if (success) +		*success = 0; +	return (unname); +} + + +const char * +__sym_ntop(syms, number, success) +	const struct res_sym *syms; +	int number; +	int *success; +{ +	static char unname[20]; + +	for (NULL; syms->name != 0; syms++) { +		if (number == syms->number) { +			if (success) +				*success = 1; +			return (syms->humanname); +		} +	} +	sprintf(unname, "%d", number); +	if (success) +		*success = 0; +	return (unname); +} + +/*   * Return a string for the type   */  const char *  __p_type(type)  	int type;  { -	static char nbuf[20]; - -	switch (type) { -	case T_A:	return "A"; -	case T_NS:	return "NS"; -	case T_CNAME:	return "CNAME"; -	case T_SOA:	return "SOA"; -	case T_MB:	return "MB"; -	case T_MG:	return "MG"; -	case T_MR:	return "MR"; -	case T_NULL:	return "NULL"; -	case T_WKS:	return "WKS"; -	case T_PTR:	return "PTR"; -	case T_HINFO:	return "HINFO"; -	case T_MINFO:	return "MINFO"; -	case T_MX:	return "MX"; -	case T_TXT:	return "TXT"; -	case T_RP:	return "RP"; -	case T_AFSDB:	return "AFSDB"; -	case T_X25:	return "X25"; -	case T_ISDN:	return "ISDN"; -	case T_RT:	return "RT"; -	case T_NSAP:	return "NSAP"; -	case T_NSAP_PTR: return "NSAP_PTR"; -	case T_SIG:	return "SIG"; -	case T_KEY:	return "KEY"; -	case T_PX:	return "PX"; -	case T_GPOS:	return "GPOS"; -	case T_AAAA:	return "AAAA"; -	case T_LOC:	return "LOC"; -	case T_AXFR:	return "AXFR"; -	case T_MAILB:	return "MAILB"; -	case T_MAILA:	return "MAILA"; -	case T_ANY:	return "ANY"; -	case T_UINFO:	return "UINFO"; -	case T_UID:	return "UID"; -	case T_GID:	return "GID"; -#ifdef ALLOW_T_UNSPEC -	case T_UNSPEC:	return "UNSPEC"; -#endif /* ALLOW_T_UNSPEC */ -	default:	(void)sprintf(nbuf, "%d", type); return (nbuf); -	} +	return (__sym_ntos (__p_type_syms, type, (int *)0));  }  /* @@ -737,14 +999,7 @@ const char *  __p_class(class)  	int class;  { -	static char nbuf[20]; - -	switch (class) { -	case C_IN:	return "IN"; -	case C_HS:	return "HS"; -	case C_ANY:	return "ANY"; -	default:	(void)sprintf(nbuf, "%d", class); return (nbuf); -	} +	return (__sym_ntos (__p_class_syms, class, (int *)0));  }  /* @@ -777,8 +1032,8 @@ __p_option(option)  /*   * Return a mnemonic for a time to live   */ -char * -__p_time(value) +const char * +p_time(value)  	u_int32_t value;  {  	static char nbuf[40]; @@ -839,7 +1094,7 @@ static const char *  precsize_ntoa(prec)  	u_int8_t prec;  { -	static char retbuf[sizeof("90000000.00")]; +	static char retbuf[sizeof "90000000.00"];  	unsigned long val;  	int mantissa, exponent; @@ -1026,11 +1281,11 @@ loc_aton(ascii, binary)  			longit = lltemp1;  			latit = lltemp2;  		} else {	/* some kind of brokenness */ -			return 0; +			return (0);  		}  		break;  	default:		/* we didn't get one of each */ -		return 0; +		return (0);  	}  	/* altitude */ @@ -1105,7 +1360,7 @@ loc_aton(ascii, binary)  }  /* takes an on-the-wire LOC RR and formats it in a human readable format. */ -char * +const char *  loc_ntoa(binary, ascii)  	const u_char *binary;  	char *ascii; @@ -1206,3 +1461,53 @@ loc_ntoa(binary, ascii)  	return (ascii);  } + + +/* Return the number of DNS hierarchy levels in the name. */ +int +__dn_count_labels(name) +	char *name; +{ +	int i, len, count; + +	len = strlen(name); + +	for(i = 0, count = 0; i < len; i++) { +		if (name[i] == '.') +			count++; +	} + +	/* don't count initial wildcard */ +	if (name[0] == '*') +		if (count) +			count--; + +	/* don't count the null label for root. */ +	/* if terminating '.' not found, must adjust */ +	/* count to include last label */ +	if (len > 0 && name[len-1] != '.') +		count++; +	return (count); +} + + +/*  + * Make dates expressed in seconds-since-Jan-1-1970 easy to read.   + * SIG records are required to be printed like this, by the Secure DNS RFC. + */ +char * +__p_secstodate (secs) +	unsigned long secs; +{ +	static char output[15];		/* YYYYMMDDHHMMSS and null */ +	time_t clock = secs; +	struct tm *time; +	 +	time = gmtime(&clock); +	time->tm_year += 1900; +	time->tm_mon += 1; +	sprintf(output, "%04d%02d%02d%02d%02d%02d", +		time->tm_year, time->tm_mon, time->tm_mday, +		time->tm_hour, time->tm_min, time->tm_sec); +	return (output); +} diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c index aeb021f72a84..7fd1a0e64e82 100644 --- a/lib/libc/net/res_init.c +++ b/lib/libc/net/res_init.c @@ -55,7 +55,7 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93"; -static char rcsid[] = "$Id: res_init.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; +static char rcsid[] = "$Id: res_init.c,v 1.9 1996/08/30 21:13:35 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -87,7 +87,11 @@ static u_int32_t net_mask __P((struct in_addr));   * Resolver state default settings.   */ -struct __res_state _res; +struct __res_state _res +# if defined(__BIND_RES_TEXT) +	= { RES_TIMEOUT, }	/* Motorola, et al. */ +# endif +	;  /*   * Set up default settings.  If the configuration file exist, the values @@ -444,7 +448,7 @@ net_mask(in)		/* XXX - should really use system's version of this */  }  #endif -u_int16_t +u_int  res_randomid()  {  	struct timeval now; diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c index ebf0de759a57..491d155f9b3e 100644 --- a/lib/libc/net/res_mkquery.c +++ b/lib/libc/net/res_mkquery.c @@ -55,7 +55,8 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)res_mkquery.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_mkquery.c,v 8.4 1996/08/05 08:31:35 vixie Exp $"; +static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp "; +static char rcsid[] = "$Id: res_mkquery.c,v 1.9 1996/08/30 21:13:39 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -89,9 +90,6 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)  	register HEADER *hp;  	register u_char *cp;  	register int n; -#ifdef ALLOW_UPDATES -	struct rrec *newrr = (struct rrec *) newrr_in; -#endif  	u_char *dnptrs[20], **dpp, **lastdnptr;  	if ((_res.options & RES_INIT) == 0 && res_init() == -1) { @@ -181,63 +179,6 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)  		hp->ancount = htons(1);  		break; -#ifdef ALLOW_UPDATES -	/* -	 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA -	 * (Record to be modified is followed by its replacement in msg.) -	 */ -	case UPDATEM: -	case UPDATEMA: - -	case UPDATED: -		/* -		 * The res code for UPDATED and UPDATEDA is the same; user -		 * calls them differently: specifies data for UPDATED; server -		 * ignores data if specified for UPDATEDA. -		 */ -	case UPDATEDA: -		buflen -= RRFIXEDSZ + datalen; -		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) -			return (-1); -		cp += n; -		__putshort(type, cp); -		cp += INT16SZ; -		__putshort(class, cp); -		cp += INT16SZ; -		__putlong(0, cp); -		cp += INT32SZ; -		__putshort(datalen, cp); -		cp += INT16SZ; -		if (datalen) { -			bcopy(data, cp, datalen); -			cp += datalen; -		} -		if ( (op == UPDATED) || (op == UPDATEDA) ) { -			hp->ancount = htons(0); -			break; -		} -		/* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ - -	case UPDATEA:	/* Add new resource record */ -		buflen -= RRFIXEDSZ + datalen; -		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) -			return (-1); -		cp += n; -		__putshort(newrr->r_type, cp); -		cp += INT16SZ; -		__putshort(newrr->r_class, cp); -		cp += INT16SZ; -		__putlong(0, cp); -		cp += INT32SZ; -		__putshort(newrr->r_size, cp); -		cp += INT16SZ; -		if (newrr->r_size) { -			bcopy(newrr->r_data, cp, newrr->r_size); -			cp += newrr->r_size; -		} -		hp->ancount = htons(0); -		break; -#endif /* ALLOW_UPDATES */  	default:  		return (-1);  	} diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c index 0a2c3e4bd3f1..6ff54accb8dc 100644 --- a/lib/libc/net/res_query.c +++ b/lib/libc/net/res_query.c @@ -55,7 +55,8 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)res_query.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_query.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; +static char orig_rcsid = "From: Id: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp"; +static char rcsid[] = "$Id: res_query.c,v 1.9 1996/08/30 21:13:40 peter Exp $";  #endif /* LIBC_SCCS and not lint */  #include <sys/types.h> @@ -80,7 +81,7 @@ static char rcsid[] = "$Id: res_query.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";  #define MAXPACKET	1024  #endif -char *__hostalias __P((const char *)); +const char *hostalias __P((const char *));  int h_errno;  /* @@ -315,7 +316,7 @@ res_querydomain(name, domain, class, type, answer, anslen)  	u_char *answer;		/* buffer to put answer */  	int anslen;		/* size of answer */  { -	char nbuf[2*MAXDNAME+2]; +	char nbuf[MAXDNAME];  	const char *longname = nbuf;  	int n; @@ -345,8 +346,8 @@ res_querydomain(name, domain, class, type, answer, anslen)  	return (res_query(longname, class, type, answer, anslen));  } -char * -__hostalias(name) +const char * +hostalias(name)  	register const char *name;  {  	register char *cp1, *cp2; diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c index dcb0220f9bc2..cc23a22a9fb6 100644 --- a/lib/libc/net/res_send.c +++ b/lib/libc/net/res_send.c @@ -55,7 +55,8 @@  #if defined(LIBC_SCCS) && !defined(lint)  static char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_send.c,v 8.9 1996/08/05 08:31:35 vixie Exp $"; +static char orig_rcsid[] = "From: Id: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp"; +static char rcsid[] = "$Id: res_send.c,v 1.10 1996/08/30 21:13:42 peter Exp $";  #endif /* LIBC_SCCS and not lint */  /* @@ -81,13 +82,12 @@ static char rcsid[] = "$Id: res_send.c,v 8.9 1996/08/05 08:31:35 vixie Exp $";  #include <string.h>  #include <unistd.h> - -void _res_close __P((void)); -  static int s = -1;	/* socket used for communications */  static int connected = 0;	/* is the socket connected */  static int vc = 0;	/* is the socket a virtual ciruit? */ +#define CAN_RECONNECT 1 +  #ifndef DEBUG  #   define Dprint(cond, args) /*empty*/  #   define DprintQ(cond, args, query, size) /*empty*/ @@ -291,7 +291,7 @@ res_send(buf, buflen, ans, anssiz)  		struct sockaddr_in *nsap = &_res.nsaddr_list[ns];      same_ns:  		if (badns & (1 << ns)) { -			_res_close(); +			res_close();  			goto next_ns;  		} @@ -308,7 +308,7 @@ res_send(buf, buflen, ans, anssiz)  					done = 1;  					break;  				case res_nextns: -					_res_close(); +					res_close();  					goto next_ns;  				case res_done:  					return (resplen); @@ -343,7 +343,7 @@ res_send(buf, buflen, ans, anssiz)  			truncated = 0;  			if ((s < 0) || (!vc)) {  				if (s >= 0) -					_res_close(); +					res_close();  				s = socket(PF_INET, SOCK_STREAM, 0);  				if (s < 0) { @@ -358,7 +358,7 @@ res_send(buf, buflen, ans, anssiz)  					Aerror(stderr, "connect/vc",  					       errno, *nsap);  					badns |= (1 << ns); -					_res_close(); +					res_close();  					goto next_ns;  				}  				vc = 1; @@ -375,7 +375,7 @@ res_send(buf, buflen, ans, anssiz)  				terrno = errno;  				Perror(stderr, "write failed", errno);  				badns |= (1 << ns); -				_res_close(); +				res_close();  				goto next_ns;  			}  			/* @@ -392,7 +392,7 @@ read_len:  			if (n <= 0) {  				terrno = errno;  				Perror(stderr, "read failed", errno); -				_res_close(); +				res_close();  				/*  				 * A long running process might get its TCP  				 * connection reset if the remote server was @@ -404,10 +404,10 @@ read_len:  				 */  				if (terrno == ECONNRESET && !connreset) {  					connreset = 1; -					_res_close(); +					res_close();  					goto same_ns;  				} -				_res_close(); +				res_close();  				goto next_ns;  			}  			resplen = _getshort(ans); @@ -428,7 +428,7 @@ read_len:  			if (n <= 0) {  				terrno = errno;  				Perror(stderr, "read(vc)", errno); -				_res_close(); +				res_close();  				goto next_ns;  			}  			if (truncated) { @@ -475,9 +475,12 @@ read_len:  			if ((s < 0) || vc) {  				if (vc) -					_res_close(); +					res_close();  				s = socket(PF_INET, SOCK_DGRAM, 0);  				if (s < 0) { +#if !CAN_RECONNECT + bad_dg_sock: +#endif  					terrno = errno;  					Perror(stderr, "socket(dg)", errno);  					return (-1); @@ -512,7 +515,7 @@ read_len:  						       "connect(dg)",  						       errno, *nsap);  						badns |= (1 << ns); -						_res_close(); +						res_close();  						goto next_ns;  					}  					connected = 1; @@ -520,7 +523,7 @@ read_len:  				if (send(s, (char*)buf, buflen, 0) != buflen) {  					Perror(stderr, "send", errno);  					badns |= (1 << ns); -					_res_close(); +					res_close();  					goto next_ns;  				}  			} else { @@ -529,6 +532,7 @@ read_len:  				 * for responses from more than one server.  				 */  				if (connected) { +#if CAN_RECONNECT  					struct sockaddr_in no_addr;  					no_addr.sin_family = AF_INET; @@ -538,6 +542,15 @@ read_len:  						       (struct sockaddr *)  						        &no_addr,  						       sizeof(no_addr)); +#else +					int s1 = socket(PF_INET, SOCK_DGRAM,0); +					if (s1 < 0) +						goto bad_dg_sock; +					(void) dup2(s1, s); +					(void) close(s1); +					Dprint(_res.options & RES_DEBUG, +						(stdout, ";; new DG socket\n")) +#endif  					connected = 0;  					errno = 0;  				} @@ -547,7 +560,7 @@ read_len:  				    != buflen) {  					Aerror(stderr, "sendto", errno, *nsap);  					badns |= (1 << ns); -					_res_close(); +					res_close();  					goto next_ns;  				}  			} @@ -570,7 +583,7 @@ read_len:  				if (errno == EINTR)  					goto wait;  				Perror(stderr, "select", errno); -				_res_close(); +				res_close();  				goto next_ns;  			}  			if (n == 0) { @@ -580,7 +593,7 @@ read_len:  				Dprint(_res.options & RES_DEBUG,  				       (stdout, ";; timeout\n"));  				gotsomewhere = 1; -				_res_close(); +				res_close();  				goto next_ns;  			}  			errno = 0; @@ -589,7 +602,7 @@ read_len:  					   (struct sockaddr *)&from, &fromlen);  			if (resplen <= 0) {  				Perror(stderr, "recvfrom", errno); -				_res_close(); +				res_close();  				goto next_ns;  			}  			gotsomewhere = 1; @@ -641,7 +654,7 @@ read_len:  					(stdout, "server rejected query:\n"),  					ans, (resplen>anssiz)?anssiz:resplen);  				badns |= (1 << ns); -				_res_close(); +				res_close();  				/* don't retry if called from dig */  				if (!_res.pfcode)  					goto next_ns; @@ -654,7 +667,7 @@ read_len:  				Dprint(_res.options & RES_DEBUG,  				       (stdout, ";; truncated answer\n"));  				v_circuit = 1; -				_res_close(); +				res_close();  				goto same_ns;  			}  		} /*if vc/dg*/ @@ -676,7 +689,7 @@ read_len:  		 */  		if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||  		    !(_res.options & RES_STAYOPEN)) { -			_res_close(); +			res_close();  		}  		if (Rhook) {  			int done = 0, loops = 0; @@ -692,7 +705,7 @@ read_len:  					done = 1;  					break;  				case res_nextns: -					_res_close(); +					res_close();  					goto next_ns;  				case res_modified:  					/* give the hook another try */ @@ -711,7 +724,7 @@ read_len:      next_ns: ;  	   } /*foreach ns*/  	} /*foreach retry*/ -	_res_close(); +	res_close();  	if (!v_circuit)  		if (!gotsomewhere)  			errno = ECONNREFUSED;	/* no nameservers found */ @@ -730,7 +743,7 @@ read_len:   * This routine is not expected to be user visible.   */  void -_res_close() +res_close()  {  	if (s >= 0) {  		(void) close(s);  | 
