summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordm <>1996-02-19 19:53:30 +0000
committerdm <>1996-02-19 19:53:30 +0000
commit543eeae2382e5de0b9518bdd9f7a75e5686fd056 (patch)
tree094165ba891a348ad41b10f58ccb57f1a01f8e74
parent4a12c1341f3a7e10bd98cebfe52fc96867f82baf (diff)
downloadopenbsd-543eeae2382e5de0b9518bdd9f7a75e5686fd056.tar.gz
openbsd-543eeae2382e5de0b9518bdd9f7a75e5686fd056.tar.bz2
openbsd-543eeae2382e5de0b9518bdd9f7a75e5686fd056.zip
netbsd: bind 4.9.3
-rw-r--r--src/lib/libc/net/Makefile.inc8
-rw-r--r--src/lib/libc/net/gethostnamadr.c2
-rw-r--r--src/lib/libc/net/getnetbyname.c10
-rw-r--r--src/lib/libc/net/getnetent.c25
-rw-r--r--src/lib/libc/net/herror.c23
-rw-r--r--src/lib/libc/net/inet_addr.c7
-rw-r--r--src/lib/libc/net/nsap_addr.c130
-rw-r--r--src/lib/libc/net/res_comp.c63
-rw-r--r--src/lib/libc/net/res_debug.c513
-rw-r--r--src/lib/libc/net/res_init.c32
-rw-r--r--src/lib/libc/net/res_mkquery.c46
-rw-r--r--src/lib/libc/net/res_query.c73
-rw-r--r--src/lib/libc/net/res_send.c718
-rw-r--r--src/lib/libc/net/resolver.33
-rw-r--r--src/lib/libc/net/sethostent.c9
15 files changed, 1120 insertions, 542 deletions
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
index 2d220067e4..054d9a7492 100644
--- a/src/lib/libc/net/Makefile.inc
+++ b/src/lib/libc/net/Makefile.inc
@@ -1,4 +1,4 @@
1# $NetBSD: Makefile.inc,v 1.23 1995/03/02 09:09:07 chopps Exp $ 1# $NetBSD: Makefile.inc,v 1.24 1996/02/02 15:22:14 mrg Exp $
2# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93 2# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
3 3
4# net sources 4# net sources
@@ -8,9 +8,9 @@ SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \
8 getproto.c getprotoent.c getprotoname.c getservbyname.c \ 8 getproto.c getprotoent.c getprotoname.c getservbyname.c \
9 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ 9 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \
10 inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ 10 inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \
11 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c rcmd.c recv.c res_comp.c \ 11 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \
12 res_debug.c res_init.c res_mkquery.c res_query.c res_send.c \ 12 res_comp.c res_debug.c res_init.c res_mkquery.c res_query.c \
13 send.c sethostent.c ethers.c 13 res_send.c send.c sethostent.c ethers.c
14 14
15# machine-dependent net sources 15# machine-dependent net sources
16# m-d Makefile.inc must include sources for: 16# m-d Makefile.inc must include sources for:
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
index 2c0595803b..ec3f14a900 100644
--- a/src/lib/libc/net/gethostnamadr.c
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -270,7 +270,6 @@ gethostbyname(name)
270 register struct hostent *hp; 270 register struct hostent *hp;
271 char lookups[MAXDNSLUS]; 271 char lookups[MAXDNSLUS];
272 272
273#ifdef insecure
274 /* 273 /*
275 * disallow names consisting only of digits/dots, unless 274 * disallow names consisting only of digits/dots, unless
276 * they end in a dot. 275 * they end in a dot.
@@ -302,7 +301,6 @@ gethostbyname(name)
302 if (!isdigit(*cp) && *cp != '.') 301 if (!isdigit(*cp) && *cp != '.')
303 break; 302 break;
304 } 303 }
305#endif
306 304
307 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 305 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
308 return (_gethtbyname(name)); 306 return (_gethtbyname(name));
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c
index 93a2e1256c..f660f79b20 100644
--- a/src/lib/libc/net/getnetbyname.c
+++ b/src/lib/libc/net/getnetbyname.c
@@ -1,4 +1,4 @@
1/* $NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $ */ 1/* $NetBSD: getnetbyname.c,v 1.5 1996/02/02 15:22:20 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1993 4 * Copyright (c) 1983, 1993
@@ -35,9 +35,11 @@
35 35
36#if defined(LIBC_SCCS) && !defined(lint) 36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 37#if 0
38static char sccsid_[] = "from getnetbyname.c 1.1 (Coimbra) 93/06/02";
39static char rcsid[] = "=Id: getnetbyname.c,v 1.6 1994/05/31 01:49:35 vixie Exp =";
38static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93"; 40static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93";
39#else 41#else
40static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $"; 42static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.5 1996/02/02 15:22:20 mrg Exp $";
41#endif 43#endif
42#endif /* LIBC_SCCS and not lint */ 44#endif /* LIBC_SCCS and not lint */
43 45
@@ -55,10 +57,10 @@ getnetbyname(name)
55 57
56 setnetent(_net_stayopen); 58 setnetent(_net_stayopen);
57 while (p = getnetent()) { 59 while (p = getnetent()) {
58 if (strcmp(p->n_name, name) == 0) 60 if (strcasecmp(p->n_name, name) == 0)
59 break; 61 break;
60 for (cp = p->n_aliases; *cp != 0; cp++) 62 for (cp = p->n_aliases; *cp != 0; cp++)
61 if (strcmp(*cp, name) == 0) 63 if (strcasecmp(*cp, name) == 0)
62 goto found; 64 goto found;
63 } 65 }
64found: 66found:
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c
index 8ecdf6c5a3..2e897201a8 100644
--- a/src/lib/libc/net/getnetent.c
+++ b/src/lib/libc/net/getnetent.c
@@ -1,4 +1,4 @@
1/* $NetBSD: getnetent.c,v 1.5 1996/01/14 05:02:41 ghudson Exp $ */ 1/* $NetBSD: getnetent.c,v 1.6 1996/02/02 15:22:21 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1993 4 * Copyright (c) 1983, 1993
@@ -37,7 +37,7 @@
37#if 0 37#if 0
38static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93"; 38static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
39#else 39#else
40static char rcsid[] = "$NetBSD: getnetent.c,v 1.5 1996/01/14 05:02:41 ghudson Exp $"; 40static char rcsid[] = "$NetBSD: getnetent.c,v 1.6 1996/02/02 15:22:21 mrg Exp $";
41#endif 41#endif
42#endif /* LIBC_SCCS and not lint */ 42#endif /* LIBC_SCCS and not lint */
43 43
@@ -109,19 +109,18 @@ again:
109 net.n_net = inet_network(cp); 109 net.n_net = inet_network(cp);
110 net.n_addrtype = AF_INET; 110 net.n_addrtype = AF_INET;
111 q = net.n_aliases = net_aliases; 111 q = net.n_aliases = net_aliases;
112 if (p != NULL) { 112 if (p != NULL)
113 cp = p; 113 cp = p;
114 while (cp && *cp) { 114 while (cp && *cp) {
115 if (*cp == ' ' || *cp == '\t') { 115 if (*cp == ' ' || *cp == '\t') {
116 cp++; 116 cp++;
117 continue; 117 continue;
118 }
119 if (q < &net_aliases[MAXALIASES - 1])
120 *q++ = cp;
121 cp = strpbrk(cp, " \t");
122 if (cp != NULL)
123 *cp++ = '\0';
124 } 118 }
119 if (q < &net_aliases[MAXALIASES - 1])
120 *q++ = cp;
121 cp = strpbrk(cp, " \t");
122 if (cp != NULL)
123 *cp++ = '\0';
125 } 124 }
126 *q = NULL; 125 *q = NULL;
127 return (&net); 126 return (&net);
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c
index 41adbf1055..f2d241385d 100644
--- a/src/lib/libc/net/herror.c
+++ b/src/lib/libc/net/herror.c
@@ -1,4 +1,4 @@
1/* $NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $ */ 1/* $NetBSD: herror.c,v 1.6 1996/02/02 15:22:22 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1987, 1993 4 * Copyright (c) 1987, 1993
@@ -56,9 +56,9 @@
56#if defined(LIBC_SCCS) && !defined(lint) 56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 57#if 0
58static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; 58static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: herror.c,v 4.9.1.1 1993/05/02 23:14:35 vixie Rel "; 59static char rcsid[] = "$Id: herror.c,v 8.2 1995/06/19 08:35:01 vixie Exp ";
60#else 60#else
61static char rcsid[] = "$NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $"; 61static char rcsid[] = "$NetBSD: herror.c,v 1.6 1996/02/02 15:22:22 mrg Exp $";
62#endif 62#endif
63#endif /* LIBC_SCCS and not lint */ 63#endif /* LIBC_SCCS and not lint */
64 64
@@ -68,14 +68,14 @@ static char rcsid[] = "$NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $";
68#include <unistd.h> 68#include <unistd.h>
69#include <string.h> 69#include <string.h>
70 70
71char *h_errlist[] = { 71const char *h_errlist[] = {
72 "Error 0", 72 "Resolver Error 0 (no error)",
73 "Unknown host", /* 1 HOST_NOT_FOUND */ 73 "Unknown host", /* 1 HOST_NOT_FOUND */
74 "Host name lookup failure", /* 2 TRY_AGAIN */ 74 "Host name lookup failure", /* 2 TRY_AGAIN */
75 "Unknown server error", /* 3 NO_RECOVERY */ 75 "Unknown server error", /* 3 NO_RECOVERY */
76 "No address associated with name", /* 4 NO_ADDRESS */ 76 "No address associated with name", /* 4 NO_ADDRESS */
77}; 77};
78int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) }; 78int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
79 79
80extern int h_errno; 80extern int h_errno;
81 81
@@ -98,8 +98,7 @@ herror(s)
98 v->iov_len = 2; 98 v->iov_len = 2;
99 v++; 99 v++;
100 } 100 }
101 v->iov_base = (u_int)h_errno < h_nerr ? 101 v->iov_base = (char *)hstrerror(h_errno);
102 h_errlist[h_errno] : "Unknown error";
103 v->iov_len = strlen(v->iov_base); 102 v->iov_len = strlen(v->iov_base);
104 v++; 103 v++;
105 v->iov_base = "\n"; 104 v->iov_base = "\n";
@@ -107,9 +106,13 @@ herror(s)
107 writev(STDERR_FILENO, iov, (v - iov) + 1); 106 writev(STDERR_FILENO, iov, (v - iov) + 1);
108} 107}
109 108
110char * 109const char *
111hstrerror(err) 110hstrerror(err)
112 int err; 111 int err;
113{ 112{
114 return (u_int)err < h_nerr ? h_errlist[err] : "Unknown resolver error"; 113 if (err < 0)
114 return ("Resolver internal error");
115 else if (err < h_nerr)
116 return (h_errlist[err]);
117 return ("Unknown resolver error");
115} 118}
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c
index b5b9d8302f..e527c6b384 100644
--- a/src/lib/libc/net/inet_addr.c
+++ b/src/lib/libc/net/inet_addr.c
@@ -1,4 +1,4 @@
1/* $NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $ */ 1/* $NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1990, 1993 4 * Copyright (c) 1983, 1990, 1993
@@ -37,7 +37,7 @@
37#if 0 37#if 0
38static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; 38static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
39#else 39#else
40static char rcsid[] = "$NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $"; 40static char rcsid[] = "$NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $";
41#endif 41#endif
42#endif /* LIBC_SCCS and not lint */ 42#endif /* LIBC_SCCS and not lint */
43 43
@@ -131,6 +131,9 @@ inet_aton(cp, addr)
131 n = pp - parts + 1; 131 n = pp - parts + 1;
132 switch (n) { 132 switch (n) {
133 133
134 case 0:
135 return (0); /* initial nondigit */
136
134 case 1: /* a -- 32 bits */ 137 case 1: /* a -- 32 bits */
135 break; 138 break;
136 139
diff --git a/src/lib/libc/net/nsap_addr.c b/src/lib/libc/net/nsap_addr.c
new file mode 100644
index 0000000000..e4583a3db8
--- /dev/null
+++ b/src/lib/libc/net/nsap_addr.c
@@ -0,0 +1,130 @@
1/* $NetBSD: nsap_addr.c,v 1.1 1996/02/02 15:22:24 mrg Exp $ */
2
3/*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char rcsid[] = "$Id: lib-libc-net,v 8.1 1995/12/22 21:59:52 vixie Exp ";
39#else
40static char rcsid[] = "$NetBSD: nsap_addr.c,v 1.1 1996/02/02 15:22:24 mrg Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <sys/param.h>
45#include <sys/socket.h>
46#include <netinet/in.h>
47#include <arpa/nameser.h>
48#include <ctype.h>
49#include <resolv.h>
50
51static char
52xtob(c)
53 register int c;
54{
55 return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
56}
57
58/* These have to be here for BIND and its utilities (DiG, nslookup, et al)
59 * but should not be promulgated since the calling interface is not pretty.
60 * (They do, however, implement the RFC standard way of representing ISO NSAPs
61 * and as such, are preferred over the more general iso_addr.c routines.
62 */
63
64u_int
65inet_nsap_addr(ascii, binary, maxlen)
66 const char *ascii;
67 u_char *binary;
68 int maxlen;
69{
70 register u_char c, nib;
71 u_int len = 0;
72
73 while ((c = *ascii++) != '\0' && len < maxlen) {
74 if (c == '.' || c == '+' || c == '/')
75 continue;
76 if (!isascii(c))
77 return (0);
78 if (islower(c))
79 c = toupper(c);
80 if (isxdigit(c)) {
81 nib = xtob(c);
82 if (c = *ascii++) {
83 c = toupper(c);
84 if (isxdigit(c)) {
85 *binary++ = (nib << 4) | xtob(c);
86 len++;
87 } else
88 return (0);
89 }
90 else
91 return (0);
92 }
93 else
94 return (0);
95 }
96 return (len);
97}
98
99char *
100inet_nsap_ntoa(binlen, binary, ascii)
101 int binlen;
102 register const u_char *binary;
103 register char *ascii;
104{
105 register int nib;
106 int i;
107 static char tmpbuf[255*3];
108 char *start;
109
110 if (ascii)
111 start = ascii;
112 else {
113 ascii = tmpbuf;
114 start = tmpbuf;
115 }
116
117 if (binlen > 255)
118 binlen = 255;
119
120 for (i = 0; i < binlen; i++) {
121 nib = *binary >> 4;
122 *ascii++ = nib + (nib < 10 ? '0' : '7');
123 nib = *binary++ & 0x0f;
124 *ascii++ = nib + (nib < 10 ? '0' : '7');
125 if (((i % 2) == 0 && (i + 1) < binlen))
126 *ascii++ = '.';
127 }
128 *ascii = '\0';
129 return (start);
130}
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c
index 9d7bbecdda..2d81327aaf 100644
--- a/src/lib/libc/net/res_comp.c
+++ b/src/lib/libc/net/res_comp.c
@@ -1,4 +1,4 @@
1/* $NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $ */ 1/* $NetBSD: res_comp.c,v 1.7 1996/02/02 15:22:26 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1985, 1993 4 * Copyright (c) 1985, 1993
@@ -56,9 +56,9 @@
56#if defined(LIBC_SCCS) && !defined(lint) 56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 57#if 0
58static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; 58static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_comp.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; 59static char rcsid[] = "$Id: res_comp.c,v 8.3 1995/12/06 20:34:50 vixie Exp ";
60#else 60#else
61static char rcsid[] = "$NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $"; 61static char rcsid[] = "$NetBSD: res_comp.c,v 1.7 1996/02/02 15:22:26 mrg Exp $";
62#endif 62#endif
63#endif /* LIBC_SCCS and not lint */ 63#endif /* LIBC_SCCS and not lint */
64 64
@@ -67,8 +67,11 @@ static char rcsid[] = "$NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $";
67#include <netinet/in.h> 67#include <netinet/in.h>
68#include <resolv.h> 68#include <resolv.h>
69#include <stdio.h> 69#include <stdio.h>
70#include <ctype.h>
71#include <unistd.h>
72#include <string.h>
70 73
71static int dn_find(); 74static int dn_find __P((u_char *, u_char *, u_char **, u_char **));
72 75
73/* 76/*
74 * Expand compressed domain name 'comp_dn' to full domain name. 77 * Expand compressed domain name 'comp_dn' to full domain name.
@@ -77,18 +80,20 @@ static int dn_find();
77 * 'exp_dn' is a pointer to a buffer of size 'length' for the result. 80 * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
78 * Return size of compressed name or -1 if there was an error. 81 * Return size of compressed name or -1 if there was an error.
79 */ 82 */
83int
80dn_expand(msg, eomorig, comp_dn, exp_dn, length) 84dn_expand(msg, eomorig, comp_dn, exp_dn, length)
81 const u_char *msg, *eomorig, *comp_dn; 85 const u_char *msg, *eomorig, *comp_dn;
82 u_char *exp_dn; 86 char *exp_dn;
83 int length; 87 int length;
84{ 88{
85 register u_char *cp, *dn; 89 register const u_char *cp;
90 register char *dn;
86 register int n, c; 91 register int n, c;
87 u_char *eom; 92 char *eom;
88 int len = -1, checked = 0; 93 int len = -1, checked = 0;
89 94
90 dn = exp_dn; 95 dn = exp_dn;
91 cp = (u_char *)comp_dn; 96 cp = comp_dn;
92 eom = exp_dn + length; 97 eom = exp_dn + length;
93 /* 98 /*
94 * fetch next label in domain name 99 * fetch next label in domain name
@@ -108,23 +113,23 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
108 return (-1); 113 return (-1);
109 checked += n + 1; 114 checked += n + 1;
110 while (--n >= 0) { 115 while (--n >= 0) {
111 if ((c = *cp++) == '.') { 116 if ((c = *cp++) == '.' || c == '\\') {
112 if (dn + n + 2 >= eom) 117 if (dn + n + 2 >= eom)
113 return (-1); 118 return (-1);
114 *dn++ = '\\'; 119 *dn++ = '\\';
115 } 120 }
116 *dn++ = c; 121 *dn++ = c;
117 if (cp >= eomorig) /* out of range */ 122 if (cp >= eomorig) /* out of range */
118 return(-1); 123 return (-1);
119 } 124 }
120 break; 125 break;
121 126
122 case INDIR_MASK: 127 case INDIR_MASK:
123 if (len < 0) 128 if (len < 0)
124 len = cp - comp_dn + 1; 129 len = cp - comp_dn + 1;
125 cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff)); 130 cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
126 if (cp < msg || cp >= eomorig) /* out of range */ 131 if (cp < msg || cp >= eomorig) /* out of range */
127 return(-1); 132 return (-1);
128 checked += 2; 133 checked += 2;
129 /* 134 /*
130 * Check for loops in the compressed name; 135 * Check for loops in the compressed name;
@@ -140,6 +145,9 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
140 } 145 }
141 } 146 }
142 *dn = '\0'; 147 *dn = '\0';
148 for (dn = exp_dn; (c = *dn) != '\0'; dn++)
149 if (isascii(c) && isspace(c))
150 return (-1);
143 if (len < 0) 151 if (len < 0)
144 len = cp - comp_dn; 152 len = cp - comp_dn;
145 return (len); 153 return (len);
@@ -157,8 +165,9 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
157 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' 165 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
158 * is NULL, we don't update the list. 166 * is NULL, we don't update the list.
159 */ 167 */
168int
160dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) 169dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
161 const u_char *exp_dn; 170 const char *exp_dn;
162 u_char *comp_dn, **dnptrs, **lastdnptr; 171 u_char *comp_dn, **dnptrs, **lastdnptr;
163 int length; 172 int length;
164{ 173{
@@ -170,6 +179,7 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
170 dn = (u_char *)exp_dn; 179 dn = (u_char *)exp_dn;
171 cp = comp_dn; 180 cp = comp_dn;
172 eob = cp + length; 181 eob = cp + length;
182 lpp = cpp = NULL;
173 if (dnptrs != NULL) { 183 if (dnptrs != NULL) {
174 if ((msg = *dnptrs++) != NULL) { 184 if ((msg = *dnptrs++) != NULL) {
175 for (cpp = dnptrs; *cpp != NULL; cpp++) 185 for (cpp = dnptrs; *cpp != NULL; cpp++)
@@ -235,13 +245,14 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
235/* 245/*
236 * Skip over a compressed domain name. Return the size or -1. 246 * Skip over a compressed domain name. Return the size or -1.
237 */ 247 */
248int
238__dn_skipname(comp_dn, eom) 249__dn_skipname(comp_dn, eom)
239 const u_char *comp_dn, *eom; 250 const u_char *comp_dn, *eom;
240{ 251{
241 register u_char *cp; 252 register const u_char *cp;
242 register int n; 253 register int n;
243 254
244 cp = (u_char *)comp_dn; 255 cp = comp_dn;
245 while (cp < eom && (n = *cp++)) { 256 while (cp < eom && (n = *cp++)) {
246 /* 257 /*
247 * check for indirection 258 * check for indirection
@@ -263,6 +274,15 @@ __dn_skipname(comp_dn, eom)
263 return (cp - comp_dn); 274 return (cp - comp_dn);
264} 275}
265 276
277static int
278mklower(ch)
279 register int ch;
280{
281 if (isascii(ch) && isupper(ch))
282 return (tolower(ch));
283 return (ch);
284}
285
266/* 286/*
267 * Search for expanded name from a list of previously compressed names. 287 * Search for expanded name from a list of previously compressed names.
268 * Return the offset from msg if found or -1. 288 * Return the offset from msg if found or -1.
@@ -292,7 +312,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
292 goto next; 312 goto next;
293 if (*dn == '\\') 313 if (*dn == '\\')
294 dn++; 314 dn++;
295 if (*dn++ != *cp++) 315 if (mklower(*dn++) != mklower(*cp++))
296 goto next; 316 goto next;
297 } 317 }
298 if ((n = *dn++) == '\0' && *cp == '\0') 318 if ((n = *dn++) == '\0' && *cp == '\0')
@@ -301,11 +321,12 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
301 continue; 321 continue;
302 goto next; 322 goto next;
303 323
304 default: /* illegal type */
305 return (-1);
306
307 case INDIR_MASK: /* indirection */ 324 case INDIR_MASK: /* indirection */
308 cp = msg + (((n & 0x3f) << 8) | *cp); 325 cp = msg + (((n & 0x3f) << 8) | *cp);
326 break;
327
328 default: /* illegal type */
329 return (-1);
309 } 330 }
310 } 331 }
311 if (*dn == '\0') 332 if (*dn == '\0')
@@ -325,7 +346,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
325 346
326u_short 347u_short
327_getshort(msgp) 348_getshort(msgp)
328 register u_char *msgp; 349 register const u_char *msgp;
329{ 350{
330 register u_int16_t u; 351 register u_int16_t u;
331 352
@@ -335,7 +356,7 @@ _getshort(msgp)
335 356
336u_int32_t 357u_int32_t
337_getlong(msgp) 358_getlong(msgp)
338 register u_char *msgp; 359 register const u_char *msgp;
339{ 360{
340 register u_int32_t u; 361 register u_int32_t u;
341 362
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
index d841293f18..14e5ddf790 100644
--- a/src/lib/libc/net/res_debug.c
+++ b/src/lib/libc/net/res_debug.c
@@ -1,4 +1,4 @@
1/* $NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $ */ 1/* $NetBSD: res_debug.c,v 1.8 1996/02/02 15:22:27 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1985, 1990, 1993 4 * Copyright (c) 1985, 1990, 1993
@@ -56,8 +56,9 @@
56#if defined(LIBC_SCCS) && !defined(lint) 56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 57#if 0
58static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; 58static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_debug.c,v 8.7 1995/12/22 10:20:39 vixie Exp ";
59#else 60#else
60static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $"; 61static char rcsid[] = "$NetBSD: res_debug.c,v 1.8 1996/02/02 15:22:27 mrg Exp $";
61#endif 62#endif
62#endif /* LIBC_SCCS and not lint */ 63#endif /* LIBC_SCCS and not lint */
63 64
@@ -68,18 +69,16 @@ static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $"
68#include <resolv.h> 69#include <resolv.h>
69#include <stdio.h> 70#include <stdio.h>
70#include <string.h> 71#include <string.h>
72#include <netdb.h>
71 73
72void __fp_query(); 74void __fp_query();
73char *__p_class(), *__p_time(), *__p_type();
74char *p_cdname(), *p_fqname(), *p_rr();
75static char *p_option __P((u_int32_t));
76 75
77char *_res_opcodes[] = { 76char *_res_opcodes[] = {
78 "QUERY", 77 "QUERY",
79 "IQUERY", 78 "IQUERY",
80 "CQUERYM", 79 "CQUERYM",
81 "CQUERYU", 80 "CQUERYU", /* experimental */
82 "4", 81 "NOTIFY", /* experimental */
83 "5", 82 "5",
84 "6", 83 "6",
85 "7", 84 "7",
@@ -112,102 +111,118 @@ char *_res_resultcodes[] = {
112 "NOCHANGE", 111 "NOCHANGE",
113}; 112};
114 113
115static char retbuf[16];
116
117static char * 114static char *
118dewks(wks) 115dewks(wks)
119 int wks; 116 int wks;
120{ 117{
118 static char nbuf[20];
119
121 switch (wks) { 120 switch (wks) {
122 case 5: return("rje"); 121 case 5: return "rje";
123 case 7: return("echo"); 122 case 7: return "echo";
124 case 9: return("discard"); 123 case 9: return "discard";
125 case 11: return("systat"); 124 case 11: return "systat";
126 case 13: return("daytime"); 125 case 13: return "daytime";
127 case 15: return("netstat"); 126 case 15: return "netstat";
128 case 17: return("qotd"); 127 case 17: return "qotd";
129 case 19: return("chargen"); 128 case 19: return "chargen";
130 case 20: return("ftp-data"); 129 case 20: return "ftp-data";
131 case 21: return("ftp"); 130 case 21: return "ftp";
132 case 23: return("telnet"); 131 case 23: return "telnet";
133 case 25: return("smtp"); 132 case 25: return "smtp";
134 case 37: return("time"); 133 case 37: return "time";
135 case 39: return("rlp"); 134 case 39: return "rlp";
136 case 42: return("name"); 135 case 42: return "name";
137 case 43: return("whois"); 136 case 43: return "whois";
138 case 53: return("domain"); 137 case 53: return "domain";
139 case 57: return("apts"); 138 case 57: return "apts";
140 case 59: return("apfs"); 139 case 59: return "apfs";
141 case 67: return("bootps"); 140 case 67: return "bootps";
142 case 68: return("bootpc"); 141 case 68: return "bootpc";
143 case 69: return("tftp"); 142 case 69: return "tftp";
144 case 77: return("rje"); 143 case 77: return "rje";
145 case 79: return("finger"); 144 case 79: return "finger";
146 case 87: return("link"); 145 case 87: return "link";
147 case 95: return("supdup"); 146 case 95: return "supdup";
148 case 100: return("newacct"); 147 case 100: return "newacct";
149 case 101: return("hostnames"); 148 case 101: return "hostnames";
150 case 102: return("iso-tsap"); 149 case 102: return "iso-tsap";
151 case 103: return("x400"); 150 case 103: return "x400";
152 case 104: return("x400-snd"); 151 case 104: return "x400-snd";
153 case 105: return("csnet-ns"); 152 case 105: return "csnet-ns";
154 case 109: return("pop-2"); 153 case 109: return "pop-2";
155 case 111: return("sunrpc"); 154 case 111: return "sunrpc";
156 case 113: return("auth"); 155 case 113: return "auth";
157 case 115: return("sftp"); 156 case 115: return "sftp";
158 case 117: return("uucp-path"); 157 case 117: return "uucp-path";
159 case 119: return("nntp"); 158 case 119: return "nntp";
160 case 121: return("erpc"); 159 case 121: return "erpc";
161 case 123: return("ntp"); 160 case 123: return "ntp";
162 case 133: return("statsrv"); 161 case 133: return "statsrv";
163 case 136: return("profile"); 162 case 136: return "profile";
164 case 144: return("NeWS"); 163 case 144: return "NeWS";
165 case 161: return("snmp"); 164 case 161: return "snmp";
166 case 162: return("snmp-trap"); 165 case 162: return "snmp-trap";
167 case 170: return("print-srv"); 166 case 170: return "print-srv";
168 default: (void) sprintf(retbuf, "%d", wks); return(retbuf); 167 default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
169 } 168 }
170} 169}
171 170
172static char * 171/* XXX: we should use getprotobynumber() instead. */
172static const char *
173deproto(protonum) 173deproto(protonum)
174 int protonum; 174 int protonum;
175{ 175{
176 static char nbuf[20];
177
176 switch (protonum) { 178 switch (protonum) {
177 case 1: return("icmp"); 179 case 1: return "icmp";
178 case 2: return("igmp"); 180 case 2: return "igmp";
179 case 3: return("ggp"); 181 case 3: return "ggp";
180 case 5: return("st"); 182 case 5: return "st";
181 case 6: return("tcp"); 183 case 6: return "tcp";
182 case 7: return("ucl"); 184 case 7: return "ucl";
183 case 8: return("egp"); 185 case 8: return "egp";
184 case 9: return("igp"); 186 case 9: return "igp";
185 case 11: return("nvp-II"); 187 case 11: return "nvp-II";
186 case 12: return("pup"); 188 case 12: return "pup";
187 case 16: return("chaos"); 189 case 16: return "chaos";
188 case 17: return("udp"); 190 case 17: return "udp";
189 default: (void) sprintf(retbuf, "%d", protonum); return(retbuf); 191 default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
190 } 192 }
191} 193}
192 194
193static char * 195static const u_char *
194do_rrset(msg, cp, cnt, pflag, file, hs) 196do_rrset(msg, len, cp, cnt, pflag, file, hs)
195 int cnt, pflag; 197 int cnt, pflag, len;
196 char *cp,*msg, *hs; 198 const u_char *cp, *msg;
199 const char *hs;
197 FILE *file; 200 FILE *file;
198{ 201{
199 int n; 202 int n;
200 int sflag; 203 int sflag;
204
201 /* 205 /*
202 * Print answer records 206 * Print answer records.
203 */ 207 */
204 sflag = (_res.pfcode & pflag); 208 sflag = (_res.pfcode & pflag);
205 if (n = ntohs(cnt)) { 209 if (n = ntohs(cnt)) {
206 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 210 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
207 fprintf(file, hs); 211 fprintf(file, hs);
208 while (--n >= 0) { 212 while (--n >= 0) {
209 cp = p_rr(cp, msg, file); 213 if ((!_res.pfcode) || sflag) {
210 if ((cp-msg) > PACKETSZ) 214 cp = p_rr(cp, msg, file);
215 } else {
216 unsigned int dlen;
217 cp += __dn_skipname(cp, cp + MAXCDNAME);
218 cp += sizeof(u_int16_t);
219 cp += sizeof(u_int16_t);
220 cp += sizeof(u_int32_t);
221 dlen = _getshort((u_char*)cp);
222 cp += sizeof(u_int16_t);
223 cp += dlen;
224 }
225 if ((cp - msg) > len)
211 return (NULL); 226 return (NULL);
212 } 227 }
213 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 228 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
@@ -216,8 +231,9 @@ do_rrset(msg, cp, cnt, pflag, file, hs)
216 return(cp); 231 return(cp);
217} 232}
218 233
234void
219__p_query(msg) 235__p_query(msg)
220 char *msg; 236 const u_char *msg;
221{ 237{
222 __fp_query(msg, stdout); 238 __fp_query(msg, stdout);
223} 239}
@@ -231,15 +247,14 @@ __fp_resstat(statp, file)
231 struct __res_state *statp; 247 struct __res_state *statp;
232 FILE *file; 248 FILE *file;
233{ 249{
234 int bit; 250 register u_long mask;
235 251
236 fprintf(file, ";; res options:"); 252 fprintf(file, ";; res options:");
237 if (!statp) 253 if (!statp)
238 statp = &_res; 254 statp = &_res;
239 for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */ 255 for (mask = 1; mask != 0; mask <<= 1)
240 if (statp->options & (1<<bit)) 256 if (statp->options & mask)
241 fprintf(file, " %s", p_option(1<<bit)); 257 fprintf(file, " %s", p_option(mask));
242 }
243 putc('\n', file); 258 putc('\n', file);
244} 259}
245 260
@@ -248,19 +263,27 @@ __fp_resstat(statp, file)
248 * This is intended to be primarily a debugging routine. 263 * This is intended to be primarily a debugging routine.
249 */ 264 */
250void 265void
251__fp_query(msg,file) 266__fp_nquery(msg, len, file)
252 char *msg; 267 const u_char *msg;
268 int len;
253 FILE *file; 269 FILE *file;
254{ 270{
255 register char *cp; 271 register const u_char *cp, *endMark;
256 register HEADER *hp; 272 register const HEADER *hp;
257 register int n; 273 register int n;
258 274
275 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
276 return;
277
278#define TruncTest(x) if (x >= endMark) goto trunc
279#define ErrorTest(x) if (x == NULL) goto error
280
259 /* 281 /*
260 * Print header fields. 282 * Print header fields.
261 */ 283 */
262 hp = (HEADER *)msg; 284 hp = (HEADER *)msg;
263 cp = msg + sizeof(HEADER); 285 cp = msg + HFIXEDSZ;
286 endMark = cp + len;
264 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { 287 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
265 fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", 288 fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
266 _res_opcodes[hp->opcode], 289 _res_opcodes[hp->opcode],
@@ -268,7 +291,8 @@ __fp_query(msg,file)
268 ntohs(hp->id)); 291 ntohs(hp->id));
269 putc('\n', file); 292 putc('\n', file);
270 } 293 }
271 putc(';', file); 294 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
295 putc(';', file);
272 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { 296 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
273 fprintf(file,"; flags:"); 297 fprintf(file,"; flags:");
274 if (hp->qr) 298 if (hp->qr)
@@ -281,20 +305,17 @@ __fp_query(msg,file)
281 fprintf(file," rd"); 305 fprintf(file," rd");
282 if (hp->ra) 306 if (hp->ra)
283 fprintf(file," ra"); 307 fprintf(file," ra");
284 if (hp->pr)
285 fprintf(file," pr");
286 } 308 }
287 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { 309 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
288 fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); 310 fprintf(file,"; Ques: %d", ntohs(hp->qdcount));
289 fprintf(file,", Ans: %d", ntohs(hp->ancount)); 311 fprintf(file,", Ans: %d", ntohs(hp->ancount));
290 fprintf(file,", Auth: %d", ntohs(hp->nscount)); 312 fprintf(file,", Auth: %d", ntohs(hp->nscount));
291 fprintf(file,", Addit: %d\n", ntohs(hp->arcount)); 313 fprintf(file, ", Addit: %d", ntohs(hp->arcount));
292 } 314 }
293#if 0 315 if ((!_res.pfcode) || (_res.pfcode &
294 if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) { 316 (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
295 putc('\n',file); 317 putc('\n',file);
296 } 318 }
297#endif
298 /* 319 /*
299 * Print question records. 320 * Print question records.
300 */ 321 */
@@ -302,55 +323,85 @@ __fp_query(msg,file)
302 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 323 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
303 fprintf(file,";; QUESTIONS:\n"); 324 fprintf(file,";; QUESTIONS:\n");
304 while (--n >= 0) { 325 while (--n >= 0) {
326 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
305 fprintf(file,";;\t"); 327 fprintf(file,";;\t");
306 cp = p_cdname(cp, msg, file); 328 TruncTest(cp);
307 if (cp == NULL) 329 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
308 return; 330 cp = p_cdnname(cp, msg, len, file);
331 else {
332 int n;
333 char name[MAXDNAME];
334
335 if ((n = dn_expand(msg, msg+len, cp, name,
336 sizeof name)) < 0)
337 cp = NULL;
338 else
339 cp += n;
340 }
341 ErrorTest(cp);
342 TruncTest(cp);
309 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 343 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
310 fprintf(file, ", type = %s", 344 fprintf(file, ", type = %s",
311 __p_type(_getshort(cp))); 345 __p_type(_getshort((u_char*)cp)));
312 cp += sizeof(u_int16_t); 346 cp += INT16SZ;
347 TruncTest(cp);
313 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 348 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
314 fprintf(file, ", class = %s\n\n", 349 fprintf(file, ", class = %s\n",
315 __p_class(_getshort(cp))); 350 __p_class(_getshort((u_char*)cp)));
316 cp += sizeof(u_int16_t); 351 cp += INT16SZ;
352 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
353 putc('\n', file);
317 } 354 }
318 } 355 }
319 /* 356 /*
320 * Print authoritative answer records 357 * Print authoritative answer records
321 */ 358 */
322 cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file, 359 TruncTest(cp);
360 cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
323 ";; ANSWERS:\n"); 361 ";; ANSWERS:\n");
324 if (cp == NULL) 362 ErrorTest(cp);
325 return;
326 363
327 /* 364 /*
328 * print name server records 365 * print name server records
329 */ 366 */
330 cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file, 367 TruncTest(cp);
368 cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
331 ";; AUTHORITY RECORDS:\n"); 369 ";; AUTHORITY RECORDS:\n");
332 if (!cp) 370 ErrorTest(cp);
333 return;
334 371
372 TruncTest(cp);
335 /* 373 /*
336 * print additional records 374 * print additional records
337 */ 375 */
338 cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file, 376 cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
339 ";; ADDITIONAL RECORDS:\n"); 377 ";; ADDITIONAL RECORDS:\n");
340 if (!cp) 378 ErrorTest(cp);
379 return;
380 trunc:
381 fprintf(file, "\n;; ...truncated\n");
341 return; 382 return;
383 error:
384 fprintf(file, "\n;; ...malformed\n");
342} 385}
343 386
344char * 387void
345p_cdname(cp, msg, file) 388__fp_query(msg, file)
346 char *cp, *msg; 389 const u_char *msg;
390 FILE *file;
391{
392 fp_nquery(msg, PACKETSZ, file);
393}
394
395const u_char *
396__p_cdnname(cp, msg, len, file)
397 const u_char *cp, *msg;
398 int len;
347 FILE *file; 399 FILE *file;
348{ 400{
349 char name[MAXDNAME]; 401 char name[MAXDNAME];
350 int n; 402 int n;
351 403
352 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 404 if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
353 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
354 return (NULL); 405 return (NULL);
355 if (name[0] == '\0') 406 if (name[0] == '\0')
356 putc('.', file); 407 putc('.', file);
@@ -359,16 +410,26 @@ p_cdname(cp, msg, file)
359 return (cp + n); 410 return (cp + n);
360} 411}
361 412
362char * 413const u_char *
363p_fqname(cp, msg, file) 414__p_cdname(cp, msg, file)
364 char *cp, *msg; 415 const u_char *cp, *msg;
416 FILE *file;
417{
418 return (p_cdnname(cp, msg, PACKETSZ, file));
419}
420
421/* XXX: the rest of these functions need to become length-limited, too. (vix)
422 */
423
424const u_char *
425__p_fqname(cp, msg, file)
426 const u_char *cp, *msg;
365 FILE *file; 427 FILE *file;
366{ 428{
367 char name[MAXDNAME]; 429 char name[MAXDNAME];
368 int n, len; 430 int n;
369 431
370 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 432 if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
371 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
372 return (NULL); 433 return (NULL);
373 if (name[0] == '\0') { 434 if (name[0] == '\0') {
374 putc('.', file); 435 putc('.', file);
@@ -383,17 +444,21 @@ p_fqname(cp, msg, file)
383/* 444/*
384 * Print resource record fields in human readable form. 445 * Print resource record fields in human readable form.
385 */ 446 */
386char * 447const u_char *
387p_rr(cp, msg, file) 448__p_rr(cp, msg, file)
388 char *cp, *msg; 449 const u_char *cp, *msg;
389 FILE *file; 450 FILE *file;
390{ 451{
391 int type, class, dlen, n, c; 452 int type, class, dlen, n, c;
392 struct in_addr inaddr; 453 struct in_addr inaddr;
393 char *cp1, *cp2; 454 const u_char *cp1, *cp2;
394 u_int32_t tmpttl, t; 455 u_int32_t tmpttl, t;
395 int lcnt; 456 int lcnt;
396 457
458 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
459 h_errno = NETDB_INTERNAL;
460 return (NULL);
461 }
397 if ((cp = p_fqname(cp, msg, file)) == NULL) 462 if ((cp = p_fqname(cp, msg, file)) == NULL)
398 return (NULL); /* compression error */ 463 return (NULL); /* compression error */
399 type = _getshort(cp); 464 type = _getshort(cp);
@@ -406,7 +471,7 @@ p_rr(cp, msg, file)
406 cp += sizeof(u_int16_t); 471 cp += sizeof(u_int16_t);
407 cp1 = cp; 472 cp1 = cp;
408 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) 473 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
409 fprintf(file, "\t%lu", tmpttl); 474 fprintf(file, "\t%lu", (u_long)tmpttl);
410 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) 475 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
411 fprintf(file, "\t%s", __p_class(class)); 476 fprintf(file, "\t%s", __p_class(class));
412 fprintf(file, "\t%s", __p_type(type)); 477 fprintf(file, "\t%s", __p_type(type));
@@ -429,7 +494,7 @@ p_rr(cp, msg, file)
429 494
430 address = inet_ntoa(inaddr); 495 address = inet_ntoa(inaddr);
431 cp += sizeof(inaddr); 496 cp += sizeof(inaddr);
432 protocol = *(u_char*)cp; 497 protocol = *cp;
433 cp += sizeof(u_char); 498 cp += sizeof(u_char);
434 port = _getshort(cp); 499 port = _getshort(cp);
435 cp += sizeof(u_int16_t); 500 cp += sizeof(u_int16_t);
@@ -448,52 +513,75 @@ p_rr(cp, msg, file)
448 case T_NS: 513 case T_NS:
449 case T_PTR: 514 case T_PTR:
450 putc('\t', file); 515 putc('\t', file);
451 cp = p_fqname(cp, msg, file); 516 if ((cp = p_fqname(cp, msg, file)) == NULL)
517 return (NULL);
452 break; 518 break;
453 519
454 case T_HINFO: 520 case T_HINFO:
521 case T_ISDN:
522 cp2 = cp + dlen;
455 if (n = *cp++) { 523 if (n = *cp++) {
456 fprintf(file,"\t%.*s", n, cp); 524 fprintf(file,"\t%.*s", n, cp);
457 cp += n; 525 cp += n;
458 } 526 }
459 if (n = *cp++) { 527 if ((cp < cp2) && (n = *cp++)) {
460 fprintf(file,"\t%.*s", n, cp); 528 fprintf(file,"\t%.*s", n, cp);
461 cp += n; 529 cp += n;
462 } 530 } else if (type == T_HINFO)
531 fprintf(file, "\n;; *** Warning *** OS-type missing");
463 break; 532 break;
464 533
465 case T_SOA: 534 case T_SOA:
466 putc('\t', file); 535 putc('\t', file);
467 cp = p_fqname(cp, msg, file); /* origin */ 536 if ((cp = p_fqname(cp, msg, file)) == NULL)
537 return (NULL);
468 putc(' ', file); 538 putc(' ', file);
469 cp = p_fqname(cp, msg, file); /* mail addr */ 539 if ((cp = p_fqname(cp, msg, file)) == NULL)
540 return (NULL);
470 fputs(" (\n", file); 541 fputs(" (\n", file);
471 t = _getlong(cp); cp += sizeof(u_int32_t); 542 t = _getlong(cp); cp += sizeof(u_int32_t);
472 fprintf(file,"\t\t\t%lu\t; serial\n", t); 543 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
473 t = _getlong(cp); cp += sizeof(u_int32_t); 544 t = _getlong(cp); cp += sizeof(u_int32_t);
474 fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t)); 545 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
546 (u_long)t, __p_time(t));
475 t = _getlong(cp); cp += sizeof(u_int32_t); 547 t = _getlong(cp); cp += sizeof(u_int32_t);
476 fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t)); 548 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
549 (u_long)t, __p_time(t));
477 t = _getlong(cp); cp += sizeof(u_int32_t); 550 t = _getlong(cp); cp += sizeof(u_int32_t);
478 fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t)); 551 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
552 (u_long)t, __p_time(t));
479 t = _getlong(cp); cp += sizeof(u_int32_t); 553 t = _getlong(cp); cp += sizeof(u_int32_t);
480 fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t)); 554 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
555 (u_long)t, __p_time(t));
481 break; 556 break;
482 557
483 case T_MX: 558 case T_MX:
484 case T_AFSDB: 559 case T_AFSDB:
485 fprintf(file,"\t%d ", _getshort(cp)); 560 case T_RT:
486 cp += sizeof(u_int16_t); 561 fprintf(file, "\t%d ", _getshort(cp));
487 cp = p_fqname(cp, msg, file); 562 cp += INT16SZ;
563 if ((cp = p_fqname(cp, msg, file)) == NULL)
564 return (NULL);
565 break;
566
567 case T_PX:
568 fprintf(file, "\t%d ", _getshort(cp));
569 cp += INT16SZ;
570 if ((cp = p_fqname(cp, msg, file)) == NULL)
571 return (NULL);
572 putc(' ', file);
573 if ((cp = p_fqname(cp, msg, file)) == NULL)
574 return (NULL);
488 break; 575 break;
489 576
490 case T_TXT: 577 case T_TXT:
578 case T_X25:
491 (void) fputs("\t\"", file); 579 (void) fputs("\t\"", file);
492 cp2 = cp1 + dlen; 580 cp2 = cp1 + dlen;
493 while (cp < cp2) { 581 while (cp < cp2) {
494 if (n = (unsigned char) *cp++) { 582 if (n = (unsigned char) *cp++) {
495 for (c = n; c > 0 && cp < cp2; c--) 583 for (c = n; c > 0 && cp < cp2; c--)
496 if (*cp == '\n') { 584 if ((*cp == '\n') || (*cp == '"')) {
497 (void) putc('\\', file); 585 (void) putc('\\', file);
498 (void) putc(*cp++, file); 586 (void) putc(*cp++, file);
499 } else 587 } else
@@ -503,12 +591,19 @@ p_rr(cp, msg, file)
503 putc('"', file); 591 putc('"', file);
504 break; 592 break;
505 593
594 case T_NSAP:
595 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
596 cp += dlen;
597 break;
598
506 case T_MINFO: 599 case T_MINFO:
507 case T_RP: 600 case T_RP:
508 putc('\t', file); 601 putc('\t', file);
509 cp = p_fqname(cp, msg, file); 602 if ((cp = p_fqname(cp, msg, file)) == NULL)
603 return (NULL);
510 putc(' ', file); 604 putc(' ', file);
511 cp = p_fqname(cp, msg, file); 605 if ((cp = p_fqname(cp, msg, file)) == NULL)
606 return (NULL);
512 break; 607 break;
513 608
514 case T_UINFO: 609 case T_UINFO:
@@ -558,7 +653,7 @@ p_rr(cp, msg, file)
558 case T_UNSPEC: 653 case T_UNSPEC:
559 { 654 {
560 int NumBytes = 8; 655 int NumBytes = 8;
561 char *DataPtr; 656 u_char *DataPtr;
562 int i; 657 int i;
563 658
564 if (dlen < NumBytes) NumBytes = dlen; 659 if (dlen < NumBytes) NumBytes = dlen;
@@ -588,113 +683,98 @@ p_rr(cp, msg, file)
588 return (cp); 683 return (cp);
589} 684}
590 685
591static char nbuf[40];
592
593/* 686/*
594 * Return a string for the type 687 * Return a string for the type
595 */ 688 */
596char * 689const char *
597__p_type(type) 690__p_type(type)
598 int type; 691 int type;
599{ 692{
693 static char nbuf[20];
694
600 switch (type) { 695 switch (type) {
601 case T_A: 696 case T_A: return "A";
602 return("A"); 697 case T_NS: return "NS";
603 case T_NS: /* authoritative server */ 698 case T_CNAME: return "CNAME";
604 return("NS"); 699 case T_SOA: return "SOA";
605 case T_CNAME: /* canonical name */ 700 case T_MB: return "MB";
606 return("CNAME"); 701 case T_MG: return "MG";
607 case T_SOA: /* start of authority zone */ 702 case T_MR: return "MR";
608 return("SOA"); 703 case T_NULL: return "NULL";
609 case T_MB: /* mailbox domain name */ 704 case T_WKS: return "WKS";
610 return("MB"); 705 case T_PTR: return "PTR";
611 case T_MG: /* mail group member */ 706 case T_HINFO: return "HINFO";
612 return("MG"); 707 case T_MINFO: return "MINFO";
613 case T_MR: /* mail rename name */ 708 case T_MX: return "MX";
614 return("MR"); 709 case T_TXT: return "TXT";
615 case T_NULL: /* null resource record */ 710 case T_RP: return "RP";
616 return("NULL"); 711 case T_AFSDB: return "AFSDB";
617 case T_WKS: /* well known service */ 712 case T_X25: return "X25";
618 return("WKS"); 713 case T_ISDN: return "ISDN";
619 case T_PTR: /* domain name pointer */ 714 case T_RT: return "RT";
620 return("PTR"); 715 case T_NSAP: return "NSAP";
621 case T_HINFO: /* host information */ 716 case T_NSAP_PTR: return "NSAP_PTR";
622 return("HINFO"); 717 case T_SIG: return "SIG";
623 case T_MINFO: /* mailbox information */ 718 case T_KEY: return "KEY";
624 return("MINFO"); 719 case T_PX: return "PX";
625 case T_MX: /* mail routing info */ 720 case T_GPOS: return "GPOS";
626 return("MX"); 721 case T_AAAA: return "AAAA";
627 case T_TXT: /* text */ 722 case T_LOC: return "LOC";
628 return("TXT"); 723 case T_AXFR: return "AXFR";
629 case T_RP: /* responsible person */ 724 case T_MAILB: return "MAILB";
630 return("RP"); 725 case T_MAILA: return "MAILA";
631 case T_AFSDB: /* AFS cell database */ 726 case T_ANY: return "ANY";
632 return("AFSDB"); 727 case T_UINFO: return "UINFO";
633 case T_AXFR: /* zone transfer */ 728 case T_UID: return "UID";
634 return("AXFR"); 729 case T_GID: return "GID";
635 case T_MAILB: /* mail box */
636 return("MAILB");
637 case T_MAILA: /* mail address */
638 return("MAILA");
639 case T_ANY: /* matches any type */
640 return("ANY");
641 case T_UINFO:
642 return("UINFO");
643 case T_UID:
644 return("UID");
645 case T_GID:
646 return("GID");
647#ifdef ALLOW_T_UNSPEC 730#ifdef ALLOW_T_UNSPEC
648 case T_UNSPEC: 731 case T_UNSPEC: return "UNSPEC";
649 return("UNSPEC");
650#endif /* ALLOW_T_UNSPEC */ 732#endif /* ALLOW_T_UNSPEC */
651 733 default: (void)sprintf(nbuf, "%d", type); return (nbuf);
652 default:
653 (void)sprintf(nbuf, "%d", type);
654 return(nbuf);
655 } 734 }
656} 735}
657 736
658/* 737/*
659 * Return a mnemonic for class 738 * Return a mnemonic for class
660 */ 739 */
661char * 740const char *
662__p_class(class) 741__p_class(class)
663 int class; 742 int class;
664{ 743{
744 static char nbuf[20];
665 745
666 switch (class) { 746 switch (class) {
667 case C_IN: /* internet class */ 747 case C_IN: return "IN";
668 return("IN"); 748 case C_HS: return "HS";
669 case C_HS: /* hesiod class */ 749 case C_ANY: return "ANY";
670 return("HS"); 750 default: (void)sprintf(nbuf, "%d", class); return (nbuf);
671 case C_ANY: /* matches any class */
672 return("ANY");
673 default:
674 (void)sprintf(nbuf, "%d", class);
675 return(nbuf);
676 } 751 }
677} 752}
678 753
679/* 754/*
680 * Return a mnemonic for an option 755 * Return a mnemonic for an option
681 */ 756 */
682static char * 757const char *
683p_option(option) 758__p_option(option)
684 u_int32_t option; 759 u_long option;
685{ 760{
761 static char nbuf[40];
762
686 switch (option) { 763 switch (option) {
687 case RES_INIT: return "init"; 764 case RES_INIT: return "init";
688 case RES_DEBUG: return "debug"; 765 case RES_DEBUG: return "debug";
689 case RES_AAONLY: return "aaonly"; 766 case RES_AAONLY: return "aaonly(unimpl)";
690 case RES_USEVC: return "usevc"; 767 case RES_USEVC: return "usevc";
691 case RES_PRIMARY: return "primry"; 768 case RES_PRIMARY: return "primry(unimpl)";
692 case RES_IGNTC: return "igntc"; 769 case RES_IGNTC: return "igntc";
693 case RES_RECURSE: return "recurs"; 770 case RES_RECURSE: return "recurs";
694 case RES_DEFNAMES: return "defnam"; 771 case RES_DEFNAMES: return "defnam";
695 case RES_STAYOPEN: return "styopn"; 772 case RES_STAYOPEN: return "styopn";
696 case RES_DNSRCH: return "dnsrch"; 773 case RES_DNSRCH: return "dnsrch";
697 default: sprintf(nbuf, "?0x%x?", option); return nbuf; 774 case RES_INSECURE1: return "insecure1";
775 case RES_INSECURE2: return "insecure2";
776 default: sprintf(nbuf, "?0x%lx?", (u_long)option);
777 return (nbuf);
698 } 778 }
699} 779}
700 780
@@ -705,6 +785,7 @@ char *
705__p_time(value) 785__p_time(value)
706 u_int32_t value; 786 u_int32_t value;
707{ 787{
788 static char nbuf[40];
708 int secs, mins, hours, days; 789 int secs, mins, hours, days;
709 register char *p; 790 register char *p;
710 791
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c
index 33cc8d39f1..ff8e1b1e5e 100644
--- a/src/lib/libc/net/res_init.c
+++ b/src/lib/libc/net/res_init.c
@@ -1,4 +1,4 @@
1/* $NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $ */ 1/* $NetBSD: res_init.c,v 1.9 1996/02/02 15:22:30 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1985, 1989, 1993 4 * Copyright (c) 1985, 1989, 1993
@@ -56,9 +56,9 @@
56#if defined(LIBC_SCCS) && !defined(lint) 56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 57#if 0
58static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; 58static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
59static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; 59static char rcsid[] = "$Id: res_init.c,v 8.3 1995/06/29 09:26:28 vixie Exp ";
60#else 60#else
61static char rcsid[] = "$NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $"; 61static char rcsid[] = "$NetBSD: res_init.c,v 1.9 1996/02/02 15:22:30 mrg Exp $";
62#endif 62#endif
63#endif /* LIBC_SCCS and not lint */ 63#endif /* LIBC_SCCS and not lint */
64 64
@@ -92,11 +92,23 @@ struct __res_state _res = {
92 * there will have precedence. Otherwise, the server address is set to 92 * there will have precedence. Otherwise, the server address is set to
93 * INADDR_ANY and the default domain name comes from the gethostname(). 93 * INADDR_ANY and the default domain name comes from the gethostname().
94 * 94 *
95 * The configuration file should only be used if you want to redefine your 95 * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
96 * domain or run without a server on your machine. 96 * rather than INADDR_ANY ("0.0.0.0") as the default name server address
97 * since it was noted that INADDR_ANY actually meant ``the first interface
98 * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
99 * it had to be "up" in order for you to reach your own name server. It
100 * was later decided that since the recommended practice is to always
101 * install local static routes through 127.0.0.1 for all your network
102 * interfaces, that we could solve this problem without a code change.
103 *
104 * The configuration file should always be used, since it is the only way
105 * to specify a default domain. If you are running a server on your local
106 * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
107 * in the configuration file.
97 * 108 *
98 * Return 0 if completes successfully, -1 on error 109 * Return 0 if completes successfully, -1 on error
99 */ 110 */
111int
100res_init() 112res_init()
101{ 113{
102 register FILE *fp; 114 register FILE *fp;
@@ -107,6 +119,7 @@ res_init()
107 int haveenv = 0; 119 int haveenv = 0;
108 int havesearch = 0; 120 int havesearch = 0;
109 int nsort = 0; 121 int nsort = 0;
122 int dots;
110 u_long mask; 123 u_long mask;
111 124
112 _res.nsaddr.sin_len = sizeof(struct sockaddr_in); 125 _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
@@ -392,3 +405,12 @@ net_mask(in) /* XXX - should really use system's version of this */
392 return (htonl(IN_CLASSB_NET)); 405 return (htonl(IN_CLASSB_NET));
393 return (htonl(IN_CLASSC_NET)); 406 return (htonl(IN_CLASSC_NET));
394} 407}
408
409u_int16_t
410res_randomid()
411{
412 struct timeval now;
413
414 gettimeofday(&now, NULL);
415 return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
416}
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c
index 25f025e147..1f04c96272 100644
--- a/src/lib/libc/net/res_mkquery.c
+++ b/src/lib/libc/net/res_mkquery.c
@@ -1,4 +1,4 @@
1/* $NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $ */ 1/* $NetBSD: res_mkquery.c,v 1.6 1996/02/02 15:22:32 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1985, 1993 4 * Copyright (c) 1985, 1993
@@ -56,9 +56,9 @@
56#if defined(LIBC_SCCS) && !defined(lint) 56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 57#if 0
58static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; 58static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp "; 59static char rcsid[] = "$Id: res_mkquery.c,v 8.3 1995/06/29 09:26:28 vixie Exp ";
60#else 60#else
61static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $"; 61static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.6 1996/02/02 15:22:32 mrg Exp $";
62#endif 62#endif
63#endif /* LIBC_SCCS and not lint */ 63#endif /* LIBC_SCCS and not lint */
64 64
@@ -73,21 +73,22 @@ static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp
73 * Form all types of queries. 73 * Form all types of queries.
74 * Returns the size of the result or -1. 74 * Returns the size of the result or -1.
75 */ 75 */
76int
76res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) 77res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
77 int op; /* opcode of query */ 78 int op; /* opcode of query */
78 const char *dname; /* domain name */ 79 const char *dname; /* domain name */
79 int class, type; /* class and type of query */ 80 int class, type; /* class and type of query */
80 const char *data; /* resource record data */ 81 const u_char *data; /* resource record data */
81 int datalen; /* length of data */ 82 int datalen; /* length of data */
82 const char *newrr_in; /* new rr for modify or append */ 83 const u_char *newrr_in; /* new rr for modify or append */
83 char *buf; /* buffer to put query */ 84 u_char *buf; /* buffer to put query */
84 int buflen; /* size of buffer */ 85 int buflen; /* size of buffer */
85{ 86{
86 register HEADER *hp; 87 register HEADER *hp;
87 register char *cp; 88 register u_char *cp;
88 register int n; 89 register int n;
89 struct rrec *newrr = (struct rrec *) newrr_in; 90 struct rrec *newrr = (struct rrec *) newrr_in;
90 char *dnptrs[10], **dpp, **lastdnptr; 91 u_char *dnptrs[10], **dpp, **lastdnptr;
91 92
92#ifdef DEBUG 93#ifdef DEBUG
93 if (_res.options & RES_DEBUG) 94 if (_res.options & RES_DEBUG)
@@ -117,16 +118,16 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
117 */ 118 */
118 switch (op) { 119 switch (op) {
119 case QUERY: 120 case QUERY:
121 case NS_NOTIFY_OP:
120 if ((buflen -= QFIXEDSZ) < 0) 122 if ((buflen -= QFIXEDSZ) < 0)
121 return(-1); 123 return(-1);
122 if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen, 124 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
123 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
124 return (-1); 125 return (-1);
125 cp += n; 126 cp += n;
126 buflen -= n; 127 buflen -= n;
127 __putshort(type, (u_char *)cp); 128 __putshort(type, cp);
128 cp += sizeof(u_int16_t); 129 cp += sizeof(u_int16_t);
129 __putshort(class, (u_char *)cp); 130 __putshort(class, cp);
130 cp += sizeof(u_int16_t); 131 cp += sizeof(u_int16_t);
131 hp->qdcount = htons(1); 132 hp->qdcount = htons(1);
132 if (op == QUERY || data == NULL) 133 if (op == QUERY || data == NULL)
@@ -135,18 +136,17 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
135 * Make an additional record for completion domain. 136 * Make an additional record for completion domain.
136 */ 137 */
137 buflen -= RRFIXEDSZ; 138 buflen -= RRFIXEDSZ;
138 if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen, 139 if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
139 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
140 return (-1); 140 return (-1);
141 cp += n; 141 cp += n;
142 buflen -= n; 142 buflen -= n;
143 __putshort(T_NULL, (u_char *)cp); 143 __putshort(T_NULL, cp);
144 cp += sizeof(u_int16_t); 144 cp += sizeof(u_int16_t);
145 __putshort(class, (u_char *)cp); 145 __putshort(class, cp);
146 cp += sizeof(u_int16_t); 146 cp += sizeof(u_int16_t);
147 __putlong(0, (u_char *)cp); 147 __putlong(0, cp);
148 cp += sizeof(u_int32_t); 148 cp += sizeof(u_int32_t);
149 __putshort(0, (u_char *)cp); 149 __putshort(0, cp);
150 cp += sizeof(u_int16_t); 150 cp += sizeof(u_int16_t);
151 hp->arcount = htons(1); 151 hp->arcount = htons(1);
152 break; 152 break;
@@ -158,13 +158,13 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
158 if (buflen < 1 + RRFIXEDSZ + datalen) 158 if (buflen < 1 + RRFIXEDSZ + datalen)
159 return (-1); 159 return (-1);
160 *cp++ = '\0'; /* no domain name */ 160 *cp++ = '\0'; /* no domain name */
161 __putshort(type, (u_char *)cp); 161 __putshort(type, cp);
162 cp += sizeof(u_int16_t); 162 cp += sizeof(u_int16_t);
163 __putshort(class, (u_char *)cp); 163 __putshort(class, cp);
164 cp += sizeof(u_int16_t); 164 cp += sizeof(u_int16_t);
165 __putlong(0, (u_char *)cp); 165 __putlong(0, cp);
166 cp += sizeof(u_int32_t); 166 cp += sizeof(u_int32_t);
167 __putshort(datalen, (u_char *)cp); 167 __putshort(datalen, cp);
168 cp += sizeof(u_int16_t); 168 cp += sizeof(u_int16_t);
169 if (datalen) { 169 if (datalen) {
170 bcopy(data, cp, datalen); 170 bcopy(data, cp, datalen);
@@ -231,6 +231,8 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
231 break; 231 break;
232 232
233#endif /* ALLOW_UPDATES */ 233#endif /* ALLOW_UPDATES */
234 default:
235 return (-1);
234 } 236 }
235 return (cp - buf); 237 return (cp - buf);
236} 238}
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c
index 7649462e56..81c4d3194d 100644
--- a/src/lib/libc/net/res_query.c
+++ b/src/lib/libc/net/res_query.c
@@ -1,4 +1,4 @@
1/* $NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $ */ 1/* $NetBSD: res_query.c,v 1.10 1996/02/02 15:22:34 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1988, 1993 4 * Copyright (c) 1988, 1993
@@ -56,9 +56,9 @@
56#if defined(LIBC_SCCS) && !defined(lint) 56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 57#if 0
58static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; 58static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_query.c,v 1.1 1993/06/01 09:42:14 vixie Exp vixie "; 59static char rcsid[] = "$Id: res_query.c,v 8.6 1995/06/29 09:26:28 vixie Exp ";
60#else 60#else
61static char rcsid[] = "$NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $"; 61static char rcsid[] = "$NetBSD: res_query.c,v 1.10 1996/02/02 15:22:34 mrg Exp $";
62#endif 62#endif
63#endif /* LIBC_SCCS and not lint */ 63#endif /* LIBC_SCCS and not lint */
64 64
@@ -90,27 +90,33 @@ int h_errno;
90 * if no error is indicated and the answer count is nonzero. 90 * if no error is indicated and the answer count is nonzero.
91 * Return the size of the response on success, -1 on error. 91 * Return the size of the response on success, -1 on error.
92 * Error number is left in h_errno. 92 * Error number is left in h_errno.
93 *
93 * Caller must parse answer and determine whether it answers the question. 94 * Caller must parse answer and determine whether it answers the question.
94 */ 95 */
96int
95res_query(name, class, type, answer, anslen) 97res_query(name, class, type, answer, anslen)
96 char *name; /* domain name */ 98 const char *name; /* domain name */
97 int class, type; /* class and type of query */ 99 int class, type; /* class and type of query */
98 u_char *answer; /* buffer to put answer */ 100 u_char *answer; /* buffer to put answer */
99 int anslen; /* size of answer buffer */ 101 int anslen; /* size of answer buffer */
100{ 102{
101 char buf[MAXPACKET]; 103 u_char buf[MAXPACKET];
102 HEADER *hp; 104 register HEADER *hp = (HEADER *) answer;
103 int n; 105 int n;
104 106
105 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 107 hp->rcode = NOERROR; /* default */
108
109 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
110 h_errno = NETDB_INTERNAL;
106 return (-1); 111 return (-1);
112 }
107#ifdef DEBUG 113#ifdef DEBUG
108 if (_res.options & RES_DEBUG) 114 if (_res.options & RES_DEBUG)
109 printf(";; res_query(%s, %d, %d)\n", name, class, type); 115 printf(";; res_query(%s, %d, %d)\n", name, class, type);
110#endif 116#endif
111 n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL,
112 buf, sizeof(buf));
113 117
118 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
119 buf, sizeof(buf));
114 if (n <= 0) { 120 if (n <= 0) {
115#ifdef DEBUG 121#ifdef DEBUG
116 if (_res.options & RES_DEBUG) 122 if (_res.options & RES_DEBUG)
@@ -119,7 +125,7 @@ res_query(name, class, type, answer, anslen)
119 h_errno = NO_RECOVERY; 125 h_errno = NO_RECOVERY;
120 return (n); 126 return (n);
121 } 127 }
122 n = res_send(buf, n, (char *)answer, anslen); 128 n = res_send(buf, n, answer, anslen);
123 if (n < 0) { 129 if (n < 0) {
124#ifdef DEBUG 130#ifdef DEBUG
125 if (_res.options & RES_DEBUG) 131 if (_res.options & RES_DEBUG)
@@ -174,10 +180,15 @@ res_search(name, class, type, answer, anslen)
174 int anslen; /* size of answer */ 180 int anslen; /* size of answer */
175{ 181{
176 register char *cp, **domain; 182 register char *cp, **domain;
177 int dots, trailing_dot, ret, got_nodata, saved_herrno, tried_as_is; 183 HEADER *hp = (HEADER *) answer;
184 u_int dots;
185 int trailing_dot, ret, saved_herrno;
186 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
178 187
179 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 188 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
189 h_errno = NETDB_INTERNAL;
180 return (-1); 190 return (-1);
191 }
181 192
182 got_nodata = 0; 193 got_nodata = 0;
183 errno = 0; 194 errno = 0;
@@ -188,13 +199,13 @@ res_search(name, class, type, answer, anslen)
188 dots++; 199 dots++;
189 } 200 }
190 trailing_dot = 0; 201 trailing_dot = 0;
191 if ((cp > name) && (*--cp == '.')) 202 if (cp > name && *--cp == '.')
192 trailing_dot++; 203 trailing_dot++;
193 204
194 /* 205 /*
195 * if there aren't any dots, it could be a user-level alias 206 * if there aren't any dots, it could be a user-level alias
196 */ 207 */
197 if (!dots && (cp = __hostalias(name))) 208 if (!dots && (cp = __hostalias(name)) != NULL)
198 return (res_query(cp, class, type, answer, anslen)); 209 return (res_query(cp, class, type, answer, anslen));
199 210
200 /* 211 /*
@@ -251,6 +262,13 @@ res_search(name, class, type, answer, anslen)
251 case HOST_NOT_FOUND: 262 case HOST_NOT_FOUND:
252 /* keep trying */ 263 /* keep trying */
253 break; 264 break;
265 case TRY_AGAIN:
266 if (hp->rcode == SERVFAIL) {
267 /* try next search element, if any */
268 got_servfail++;
269 break;
270 }
271 /* FALLTHROUGH */
254 default: 272 default:
255 /* anything else implies that we're done */ 273 /* anything else implies that we're done */
256 done++; 274 done++;
@@ -291,6 +309,8 @@ res_search(name, class, type, answer, anslen)
291 h_errno = saved_herrno; 309 h_errno = saved_herrno;
292 else if (got_nodata) 310 else if (got_nodata)
293 h_errno = NO_DATA; 311 h_errno = NO_DATA;
312 else if (got_servfail)
313 h_errno = TRY_AGAIN;
294 return (-1); 314 return (-1);
295} 315}
296 316
@@ -298,20 +318,25 @@ res_search(name, class, type, answer, anslen)
298 * Perform a call on res_query on the concatenation of name and domain, 318 * Perform a call on res_query on the concatenation of name and domain,
299 * removing a trailing dot from name if domain is NULL. 319 * removing a trailing dot from name if domain is NULL.
300 */ 320 */
321int
301res_querydomain(name, domain, class, type, answer, anslen) 322res_querydomain(name, domain, class, type, answer, anslen)
302 char *name, *domain; 323 const char *name, *domain;
303 int class, type; /* class and type of query */ 324 int class, type; /* class and type of query */
304 u_char *answer; /* buffer to put answer */ 325 u_char *answer; /* buffer to put answer */
305 int anslen; /* size of answer */ 326 int anslen; /* size of answer */
306{ 327{
307 char nbuf[2*MAXDNAME+2]; 328 char nbuf[2*MAXDNAME+2];
308 char *longname = nbuf; 329 const char *longname = nbuf;
309 int n; 330 int n;
310 331
332 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
333 h_errno = NETDB_INTERNAL;
334 return (-1);
335 }
311#ifdef DEBUG 336#ifdef DEBUG
312 if (_res.options & RES_DEBUG) 337 if (_res.options & RES_DEBUG)
313 printf(";; res_querydomain(%s, %s, %d, %d)\n", 338 printf(";; res_querydomain(%s, %s, %d, %d)\n",
314 name, domain, class, type); 339 name, domain?domain:"<Nil>", class, type);
315#endif 340#endif
316 if (domain == NULL) { 341 if (domain == NULL) {
317 /* 342 /*
@@ -337,24 +362,30 @@ __hostalias(name)
337{ 362{
338 register char *cp1, *cp2; 363 register char *cp1, *cp2;
339 FILE *fp; 364 FILE *fp;
340 char *file, *getenv(), *strcpy(), *strncpy(); 365 char *file;
341 char buf[BUFSIZ]; 366 char buf[BUFSIZ];
342 static char abuf[MAXDNAME]; 367 static char abuf[MAXDNAME];
343 368
369 if (_res.options & RES_NOALIASES)
370 return (NULL);
344 file = getenv("HOSTALIASES"); 371 file = getenv("HOSTALIASES");
345 if (file == NULL || (fp = fopen(file, "r")) == NULL) 372 if (file == NULL || (fp = fopen(file, "r")) == NULL)
346 return (NULL); 373 return (NULL);
374 setbuf(fp, NULL);
347 buf[sizeof(buf) - 1] = '\0'; 375 buf[sizeof(buf) - 1] = '\0';
348 while (fgets(buf, sizeof(buf), fp)) { 376 while (fgets(buf, sizeof(buf), fp)) {
349 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1); 377 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
378 ;
350 if (!*cp1) 379 if (!*cp1)
351 break; 380 break;
352 *cp1 = '\0'; 381 *cp1 = '\0';
353 if (!strcasecmp(buf, name)) { 382 if (!strcasecmp(buf, name)) {
354 while (isspace(*++cp1)); 383 while (isspace(*++cp1))
384 ;
355 if (!*cp1) 385 if (!*cp1)
356 break; 386 break;
357 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2); 387 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
388 ;
358 abuf[sizeof(abuf) - 1] = *cp2 = '\0'; 389 abuf[sizeof(abuf) - 1] = *cp2 = '\0';
359 (void)strncpy(abuf, cp1, sizeof(abuf) - 1); 390 (void)strncpy(abuf, cp1, sizeof(abuf) - 1);
360 fclose(fp); 391 fclose(fp);
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
index e608358180..f0e9b098b6 100644
--- a/src/lib/libc/net/res_send.c
+++ b/src/lib/libc/net/res_send.c
@@ -1,9 +1,9 @@
1/* $NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $ */ 1/* $NetBSD: res_send.c,v 1.5 1996/02/02 15:22:36 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1985, 1989, 1993 4 * Copyright (c) 1985, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
@@ -14,12 +14,12 @@
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by the University of 17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors. 18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors 19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 21 * without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -56,12 +56,19 @@
56#if defined(LIBC_SCCS) && !defined(lint) 56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 57#if 0
58static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; 58static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_send.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel "; 59static char rcsid[] = "$Id: res_send.c,v 8.7 1995/12/03 08:31:17 vixie Exp ";
60#else 60#else
61static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $"; 61static char rcsid[] = "$NetBSD: res_send.c,v 1.5 1996/02/02 15:22:36 mrg Exp $";
62#endif 62#endif
63#endif /* LIBC_SCCS and not lint */ 63#endif /* LIBC_SCCS and not lint */
64 64
65 /* change this to "0"
66 * if you talk to a lot
67 * of multi-homed SunOS
68 * ("broken") name servers.
69 */
70#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
71
65/* 72/*
66 * Send query to name server and wait for reply. 73 * Send query to name server and wait for reply.
67 */ 74 */
@@ -73,139 +80,335 @@ static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $";
73#include <netinet/in.h> 80#include <netinet/in.h>
74#include <arpa/nameser.h> 81#include <arpa/nameser.h>
75#include <arpa/inet.h> 82#include <arpa/inet.h>
83
76#include <stdio.h> 84#include <stdio.h>
85#include <netdb.h>
77#include <errno.h> 86#include <errno.h>
78#include <resolv.h> 87#include <resolv.h>
79#include <unistd.h> 88#if defined(BSD) && (BSD >= 199306)
80#include <string.h> 89# include <stdlib.h>
90# include <string.h>
91# include <unistd.h>
92#else
93# include "../conf/portability.h"
94#endif
95
96#if defined(USE_OPTIONS_H)
97# include <../conf/options.h>
98#endif
99
100void _res_close __P((void));
81 101
82static int s = -1; /* socket used for communications */ 102static int s = -1; /* socket used for communications */
83static struct sockaddr no_addr; 103static int connected = 0; /* is the socket connected */
84 104static int vc = 0; /* is the socket a virtual ciruit? */
85#ifndef FD_SET 105
86#define NFDBITS 32 106#define CAN_RECONNECT 1
87#define FD_SETSIZE 32 107
88#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) 108#ifndef DEBUG
89#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) 109# define Dprint(cond, args) /*empty*/
90#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) 110# define DprintQ(cond, args, query, size) /*empty*/
91#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) 111# define Aerror(file, string, error, address) /*empty*/
112# define Perror(file, string, error) /*empty*/
113#else
114# define Dprint(cond, args) if (cond) {fprintf args;} else {}
115# define DprintQ(cond, args, query, size) if (cond) {\
116 fprintf args;\
117 __fp_nquery(query, size, stdout);\
118 } else {}
119 static void
120 Aerror(file, string, error, address)
121 FILE *file;
122 char *string;
123 int error;
124 struct sockaddr_in address;
125 {
126 int save = errno;
127
128 if (_res.options & RES_DEBUG) {
129 fprintf(file, "res_send: %s ([%s].%u): %s\n",
130 string,
131 inet_ntoa(address.sin_addr),
132 ntohs(address.sin_port),
133 strerror(error));
134 }
135 errno = save;
136 }
137 static void
138 Perror(file, string, error)
139 FILE *file;
140 char *string;
141 int error;
142 {
143 int save = errno;
144
145 if (_res.options & RES_DEBUG) {
146 fprintf(file, "res_send: %s: %s\n",
147 string, strerror(error));
148 }
149 errno = save;
150 }
92#endif 151#endif
93 152
94res_send(buf, buflen, answer, anslen) 153static res_send_qhook Qhook = NULL;
95 const char *buf; 154static res_send_rhook Rhook = NULL;
155
156void
157res_send_setqhook(hook)
158 res_send_qhook hook;
159{
160
161 Qhook = hook;
162}
163
164void
165res_send_setrhook(hook)
166 res_send_rhook hook;
167{
168
169 Rhook = hook;
170}
171
172/* int
173 * res_isourserver(ina)
174 * looks up "ina" in _res.ns_addr_list[]
175 * returns:
176 * 0 : not found
177 * >0 : found
178 * author:
179 * paul vixie, 29may94
180 */
181int
182res_isourserver(inp)
183 const struct sockaddr_in *inp;
184{
185 struct sockaddr_in ina;
186 register int ns, ret;
187
188 ina = *inp;
189 ret = 0;
190 for (ns = 0; ns < _res.nscount; ns++) {
191 register const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
192
193 if (srv->sin_family == ina.sin_family &&
194 srv->sin_port == ina.sin_port &&
195 (srv->sin_addr.s_addr == INADDR_ANY ||
196 srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
197 ret++;
198 break;
199 }
200 }
201 return (ret);
202}
203
204/* int
205 * res_nameinquery(name, type, class, buf, eom)
206 * look for (name,type,class) in the query section of packet (buf,eom)
207 * returns:
208 * -1 : format error
209 * 0 : not found
210 * >0 : found
211 * author:
212 * paul vixie, 29may94
213 */
214int
215res_nameinquery(name, type, class, buf, eom)
216 const char *name;
217 register int type, class;
218 const u_char *buf, *eom;
219{
220 register const u_char *cp = buf + HFIXEDSZ;
221 int qdcount = ntohs(((HEADER*)buf)->qdcount);
222
223 while (qdcount-- > 0) {
224 char tname[MAXDNAME+1];
225 register int n, ttype, tclass;
226
227 n = dn_expand(buf, eom, cp, tname, sizeof tname);
228 if (n < 0)
229 return (-1);
230 cp += n;
231 ttype = _getshort(cp); cp += INT16SZ;
232 tclass = _getshort(cp); cp += INT16SZ;
233 if (ttype == type &&
234 tclass == class &&
235 strcasecmp(tname, name) == 0)
236 return (1);
237 }
238 return (0);
239}
240
241/* int
242 * res_queriesmatch(buf1, eom1, buf2, eom2)
243 * is there a 1:1 mapping of (name,type,class)
244 * in (buf1,eom1) and (buf2,eom2)?
245 * returns:
246 * -1 : format error
247 * 0 : not a 1:1 mapping
248 * >0 : is a 1:1 mapping
249 * author:
250 * paul vixie, 29may94
251 */
252int
253res_queriesmatch(buf1, eom1, buf2, eom2)
254 const u_char *buf1, *eom1;
255 const u_char *buf2, *eom2;
256{
257 register const u_char *cp = buf1 + HFIXEDSZ;
258 int qdcount = ntohs(((HEADER*)buf1)->qdcount);
259
260 if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
261 return (0);
262 while (qdcount-- > 0) {
263 char tname[MAXDNAME+1];
264 register int n, ttype, tclass;
265
266 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
267 if (n < 0)
268 return (-1);
269 cp += n;
270 ttype = _getshort(cp); cp += INT16SZ;
271 tclass = _getshort(cp); cp += INT16SZ;
272 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
273 return (0);
274 }
275 return (1);
276}
277
278int
279res_send(buf, buflen, ans, anssiz)
280 const u_char *buf;
96 int buflen; 281 int buflen;
97 char *answer; 282 u_char *ans;
98 int anslen; 283 int anssiz;
99{ 284{
100 register int n;
101 int try, v_circuit, resplen, ns;
102 int gotsomewhere = 0, connected = 0;
103 int connreset = 0;
104 u_short id, len;
105 char *cp;
106 fd_set dsmask;
107 struct timeval timeout;
108 HEADER *hp = (HEADER *) buf; 285 HEADER *hp = (HEADER *) buf;
109 HEADER *anhp = (HEADER *) answer; 286 HEADER *anhp = (HEADER *) ans;
110 u_int badns; /* XXX NSMAX can't exceed #/bits per this */ 287 int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
111 struct iovec iov[2]; 288 register int n;
112 int terrno = ETIMEDOUT; 289 u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
113 char junk[512]; 290
114 291 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
115#ifdef DEBUG 292 /* errno should have been set by res_init() in this case. */
116 if ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY)) { 293 return (-1);
117 printf(";; res_send()\n");
118 __p_query(buf);
119 } 294 }
120#endif 295 DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
121 if (!(_res.options & RES_INIT)) 296 (stdout, ";; res_send()\n"), buf, buflen);
122 if (res_init() == -1) {
123 return(-1);
124 }
125 v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; 297 v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
126 id = hp->id; 298 gotsomewhere = 0;
299 connreset = 0;
300 terrno = ETIMEDOUT;
127 badns = 0; 301 badns = 0;
302
128 /* 303 /*
129 * Send request, RETRY times, or until successful 304 * Send request, RETRY times, or until successful
130 */ 305 */
131 for (try = 0; try < _res.retry; try++) { 306 for (try = 0; try < _res.retry; try++) {
132 for (ns = 0; ns < _res.nscount; ns++) { 307 for (ns = 0; ns < _res.nscount; ns++) {
133 if (badns & (1<<ns)) 308 struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
134 continue; 309 same_ns:
135#ifdef DEBUG 310 if (badns & (1 << ns)) {
136 if (_res.options & RES_DEBUG) 311 _res_close();
137 printf(";; Querying server (# %d) address = %s\n", 312 goto next_ns;
138 ns+1, 313 }
139 inet_ntoa(_res.nsaddr_list[ns].sin_addr)); 314
140#endif 315 if (Qhook) {
141 usevc: 316 int done = 0, loops = 0;
317
318 do {
319 res_sendhookact act;
320
321 act = (*Qhook)(&nsap, &buf, &buflen,
322 ans, anssiz, &resplen);
323 switch (act) {
324 case res_goahead:
325 done = 1;
326 break;
327 case res_nextns:
328 _res_close();
329 goto next_ns;
330 case res_done:
331 return (resplen);
332 case res_modified:
333 /* give the hook another try */
334 if (++loops < 42) /*doug adams*/
335 break;
336 /*FALLTHROUGH*/
337 case res_error:
338 /*FALLTHROUGH*/
339 default:
340 return (-1);
341 }
342 } while (!done);
343 }
344
345 Dprint(_res.options & RES_DEBUG,
346 (stdout, ";; Querying server (# %d) address = %s\n",
347 ns + 1, inet_ntoa(nsap->sin_addr)));
348
142 if (v_circuit) { 349 if (v_circuit) {
143 int truncated = 0; 350 int truncated;
351 struct iovec iov[2];
352 u_short len;
353 u_char *cp;
144 354
145 /* 355 /*
146 * Use virtual circuit; 356 * Use virtual circuit;
147 * at most one attempt per server. 357 * at most one attempt per server.
148 */ 358 */
149 try = _res.retry; 359 try = _res.retry;
150 if (s < 0) { 360 truncated = 0;
151 s = socket(AF_INET, SOCK_STREAM, 0); 361 if ((s < 0) || (!vc)) {
362 if (s >= 0)
363 _res_close();
364
365 s = socket(PF_INET, SOCK_STREAM, 0);
152 if (s < 0) { 366 if (s < 0) {
153 terrno = errno; 367 terrno = errno;
154#ifdef DEBUG 368 Perror(stderr, "socket(vc)", errno);
155 if (_res.options & RES_DEBUG) 369 return (-1);
156 perror("socket (vc) failed");
157#endif
158 continue;
159 } 370 }
160 if (connect(s, 371 errno = 0;
161 (struct sockaddr *)&(_res.nsaddr_list[ns]), 372 if (connect(s, (struct sockaddr *)nsap,
162 sizeof(struct sockaddr)) < 0) { 373 sizeof(struct sockaddr)) < 0) {
163 terrno = errno; 374 terrno = errno;
164#ifdef DEBUG 375 Aerror(stderr, "connect/vc",
165 if (_res.options & RES_DEBUG) 376 errno, *nsap);
166 perror("connect failed"); 377 badns |= (1 << ns);
167#endif 378 _res_close();
168 (void) close(s); 379 goto next_ns;
169 s = -1;
170 continue;
171 } 380 }
381 vc = 1;
172 } 382 }
173 /* 383 /*
174 * Send length & message 384 * Send length & message
175 */ 385 */
176 len = htons((u_short)buflen); 386 putshort((u_short)buflen, (u_char*)&len);
177 iov[0].iov_base = (caddr_t)&len; 387 iov[0].iov_base = (caddr_t)&len;
178 iov[0].iov_len = sizeof(len); 388 iov[0].iov_len = INT16SZ;
179 iov[1].iov_base = (char *)buf; 389 iov[1].iov_base = (caddr_t)buf;
180 iov[1].iov_len = buflen; 390 iov[1].iov_len = buflen;
181 if (writev(s, iov, 2) != sizeof(len) + buflen) { 391 if (writev(s, iov, 2) != (INT16SZ + buflen)) {
182 terrno = errno; 392 terrno = errno;
183#ifdef DEBUG 393 Perror(stderr, "write failed", errno);
184 if (_res.options & RES_DEBUG) 394 badns |= (1 << ns);
185 perror("write failed"); 395 _res_close();
186#endif 396 goto next_ns;
187 (void) close(s);
188 s = -1;
189 continue;
190 } 397 }
191 /* 398 /*
192 * Receive length & response 399 * Receive length & response
193 */ 400 */
194 cp = answer; 401 cp = ans;
195 len = sizeof(short); 402 len = INT16SZ;
196 while (len != 0 && 403 while ((n = read(s, (char *)cp, (int)len)) > 0) {
197 (n = read(s, (char *)cp, (int)len)) > 0) {
198 cp += n; 404 cp += n;
199 len -= n; 405 if ((len -= n) <= 0)
406 break;
200 } 407 }
201 if (n <= 0) { 408 if (n <= 0) {
202 terrno = errno; 409 terrno = errno;
203#ifdef DEBUG 410 Perror(stderr, "read failed", errno);
204 if (_res.options & RES_DEBUG) 411 _res_close();
205 perror("read failed");
206#endif
207 (void) close(s);
208 s = -1;
209 /* 412 /*
210 * A long running process might get its TCP 413 * A long running process might get its TCP
211 * connection reset if the remote server was 414 * connection reset if the remote server was
@@ -217,35 +420,32 @@ res_send(buf, buflen, answer, anslen)
217 */ 420 */
218 if (terrno == ECONNRESET && !connreset) { 421 if (terrno == ECONNRESET && !connreset) {
219 connreset = 1; 422 connreset = 1;
220 ns--; 423 _res_close();
424 goto same_ns;
221 } 425 }
222 continue; 426 _res_close();
427 goto next_ns;
223 } 428 }
224 cp = answer; 429 resplen = _getshort(ans);
225 if ((resplen = ntohs(*(u_short *)cp)) > anslen) { 430 if (resplen > anssiz) {
226#ifdef DEBUG 431 Dprint(_res.options & RES_DEBUG,
227 if (_res.options & RES_DEBUG) 432 (stdout, ";; response truncated\n")
228 fprintf(stderr, 433 );
229 ";; response truncated\n");
230#endif
231 len = anslen;
232 truncated = 1; 434 truncated = 1;
435 len = anssiz;
233 } else 436 } else
234 len = resplen; 437 len = resplen;
438 cp = ans;
235 while (len != 0 && 439 while (len != 0 &&
236 (n = read(s, (char *)cp, (int)len)) > 0) { 440 (n = read(s, (char *)cp, (int)len)) > 0) {
237 cp += n; 441 cp += n;
238 len -= n; 442 len -= n;
239 } 443 }
240 if (n <= 0) { 444 if (n <= 0) {
241 terrno = errno; 445 terrno = errno;
242#ifdef DEBUG 446 Perror(stderr, "read(vc)", errno);
243 if (_res.options & RES_DEBUG) 447 _res_close();
244 perror("read failed"); 448 goto next_ns;
245#endif
246 (void) close(s);
247 s = -1;
248 continue;
249 } 449 }
250 if (truncated) { 450 if (truncated) {
251 /* 451 /*
@@ -253,10 +453,13 @@ res_send(buf, buflen, answer, anslen)
253 * so connection stays in synch. 453 * so connection stays in synch.
254 */ 454 */
255 anhp->tc = 1; 455 anhp->tc = 1;
256 len = resplen - anslen; 456 len = resplen - anssiz;
257 while (len != 0) { 457 while (len != 0) {
258 n = (len > sizeof(junk) ? 458 char junk[PACKETSZ];
259 sizeof(junk) : len); 459
460 n = (len > sizeof(junk)
461 ? sizeof(junk)
462 : len);
260 if ((n = read(s, junk, n)) > 0) 463 if ((n = read(s, junk, n)) > 0)
261 len -= n; 464 len -= n;
262 else 465 else
@@ -267,19 +470,26 @@ res_send(buf, buflen, answer, anslen)
267 /* 470 /*
268 * Use datagrams. 471 * Use datagrams.
269 */ 472 */
270 if (s < 0) { 473 struct timeval timeout;
271 s = socket(AF_INET, SOCK_DGRAM, 0); 474 fd_set dsmask;
475 struct sockaddr_in from;
476 int fromlen;
477
478 if ((s < 0) || vc) {
479 if (vc)
480 _res_close();
481 s = socket(PF_INET, SOCK_DGRAM, 0);
272 if (s < 0) { 482 if (s < 0) {
273 terrno = errno; 483#if !CAN_RECONNECT
274#ifdef DEBUG 484 bad_dg_sock:
275 if (_res.options & RES_DEBUG)
276 perror("socket (dg) failed");
277#endif 485#endif
278 continue; 486 terrno = errno;
487 Perror(stderr, "socket(dg)", errno);
488 return (-1);
279 } 489 }
490 connected = 0;
280 } 491 }
281 /* 492 /*
282 * I'm tired of answering this question, so:
283 * On a 4.3BSD+ machine (client and server, 493 * On a 4.3BSD+ machine (client and server,
284 * actually), sending to a nameserver datagram 494 * actually), sending to a nameserver datagram
285 * port with no nameserver will cause an 495 * port with no nameserver will cause an
@@ -296,29 +506,27 @@ res_send(buf, buflen, answer, anslen)
296 */ 506 */
297 if (_res.nscount == 1 || (try == 0 && ns == 0)) { 507 if (_res.nscount == 1 || (try == 0 && ns == 0)) {
298 /* 508 /*
299 * Don't use connect if we might 509 * Connect only if we are sure we won't
300 * still receive a response 510 * receive a response from another server.
301 * from another server.
302 */ 511 */
303 if (connected == 0) { 512 if (!connected) {
304 if (connect(s, 513 if (connect(s, (struct sockaddr *)nsap,
305 (struct sockaddr *) 514 sizeof(struct sockaddr)
306 &_res.nsaddr_list[ns], 515 ) < 0) {
307 sizeof(struct sockaddr)) < 0) { 516 Aerror(stderr,
308#ifdef DEBUG 517 "connect(dg)",
309 if (_res.options & RES_DEBUG) 518 errno, *nsap);
310 perror("connect"); 519 badns |= (1 << ns);
311#endif 520 _res_close();
312 continue; 521 goto next_ns;
313 } 522 }
314 connected = 1; 523 connected = 1;
315 } 524 }
316 if (send(s, buf, buflen, 0) != buflen) { 525 if (send(s, (char*)buf, buflen, 0) != buflen) {
317#ifdef DEBUG 526 Perror(stderr, "send", errno);
318 if (_res.options & RES_DEBUG) 527 badns |= (1 << ns);
319 perror("send"); 528 _res_close();
320#endif 529 goto next_ns;
321 continue;
322 } 530 }
323 } else { 531 } else {
324 /* 532 /*
@@ -326,18 +534,36 @@ res_send(buf, buflen, answer, anslen)
326 * for responses from more than one server. 534 * for responses from more than one server.
327 */ 535 */
328 if (connected) { 536 if (connected) {
329 (void) connect(s, &no_addr, 537#if CAN_RECONNECT
330 sizeof(no_addr)); 538 struct sockaddr_in no_addr;
539
540 no_addr.sin_family = AF_INET;
541 no_addr.sin_addr.s_addr = INADDR_ANY;
542 no_addr.sin_port = 0;
543 (void) connect(s,
544 (struct sockaddr *)
545 &no_addr,
546 sizeof(no_addr));
547#else
548 int s1 = socket(PF_INET, SOCK_DGRAM,0);
549 if (s1 < 0)
550 goto bad_dg_sock;
551 (void) dup2(s1, s);
552 (void) close(s1);
553 Dprint(_res.options & RES_DEBUG,
554 (stdout, ";; new DG socket\n"))
555#endif
331 connected = 0; 556 connected = 0;
557 errno = 0;
332 } 558 }
333 if (sendto(s, buf, buflen, 0, 559 if (sendto(s, (char*)buf, buflen, 0,
334 (struct sockaddr *)&_res.nsaddr_list[ns], 560 (struct sockaddr *)nsap,
335 sizeof(struct sockaddr)) != buflen) { 561 sizeof(struct sockaddr))
336#ifdef DEBUG 562 != buflen) {
337 if (_res.options & RES_DEBUG) 563 Aerror(stderr, "sendto", errno, *nsap);
338 perror("sendto"); 564 badns |= (1 << ns);
339#endif 565 _res_close();
340 continue; 566 goto next_ns;
341 } 567 }
342 } 568 }
343 569
@@ -350,106 +576,157 @@ res_send(buf, buflen, answer, anslen)
350 if ((long) timeout.tv_sec <= 0) 576 if ((long) timeout.tv_sec <= 0)
351 timeout.tv_sec = 1; 577 timeout.tv_sec = 1;
352 timeout.tv_usec = 0; 578 timeout.tv_usec = 0;
353wait: 579 wait:
354 FD_ZERO(&dsmask); 580 FD_ZERO(&dsmask);
355 FD_SET(s, &dsmask); 581 FD_SET(s, &dsmask);
356 n = select(s+1, &dsmask, (fd_set *)NULL, 582 n = select(s+1, &dsmask, (fd_set *)NULL,
357 (fd_set *)NULL, &timeout); 583 (fd_set *)NULL, &timeout);
358 if (n < 0) { 584 if (n < 0) {
359#ifdef DEBUG 585 Perror(stderr, "select", errno);
360 if (_res.options & RES_DEBUG) 586 _res_close();
361 perror("select"); 587 goto next_ns;
362#endif
363 continue;
364 } 588 }
365 if (n == 0) { 589 if (n == 0) {
366 /* 590 /*
367 * timeout 591 * timeout
368 */ 592 */
369#ifdef DEBUG 593 Dprint(_res.options & RES_DEBUG,
370 if (_res.options & RES_DEBUG) 594 (stdout, ";; timeout\n"));
371 printf(";; timeout\n");
372#endif
373 gotsomewhere = 1; 595 gotsomewhere = 1;
374 continue; 596 _res_close();
597 goto next_ns;
375 } 598 }
376 if ((resplen = recv(s, answer, anslen, 0)) <= 0) { 599 errno = 0;
377#ifdef DEBUG 600 fromlen = sizeof(struct sockaddr_in);
378 if (_res.options & RES_DEBUG) 601 resplen = recvfrom(s, (char*)ans, anssiz, 0,
379 perror("recvfrom"); 602 (struct sockaddr *)&from, &fromlen);
380#endif 603 if (resplen <= 0) {
381 continue; 604 Perror(stderr, "recvfrom", errno);
605 _res_close();
606 goto next_ns;
382 } 607 }
383 gotsomewhere = 1; 608 gotsomewhere = 1;
384 if (id != anhp->id) { 609 if (hp->id != anhp->id) {
385 /* 610 /*
386 * response from old query, ignore it 611 * response from old query, ignore it.
612 * XXX - potential security hazard could
613 * be detected here.
387 */ 614 */
388#ifdef DEBUG 615 DprintQ((_res.options & RES_DEBUG) ||
389 if ((_res.options & RES_DEBUG) || 616 (_res.pfcode & RES_PRF_REPLY),
390 (_res.pfcode & RES_PRF_REPLY)) { 617 (stdout, ";; old answer:\n"),
391 printf(";; old answer:\n"); 618 ans, resplen);
392 __p_query(answer); 619 goto wait;
393 } 620 }
621#if CHECK_SRVR_ADDR
622 if (!(_res.options & RES_INSECURE1) &&
623 !res_isourserver(&from)) {
624 /*
625 * response from wrong server? ignore it.
626 * XXX - potential security hazard could
627 * be detected here.
628 */
629 DprintQ((_res.options & RES_DEBUG) ||
630 (_res.pfcode & RES_PRF_REPLY),
631 (stdout, ";; not our server:\n"),
632 ans, resplen);
633 goto wait;
634 }
394#endif 635#endif
636 if (!(_res.options & RES_INSECURE2) &&
637 !res_queriesmatch(buf, buf + buflen,
638 ans, ans + anssiz)) {
639 /*
640 * response contains wrong query? ignore it.
641 * XXX - potential security hazard could
642 * be detected here.
643 */
644 DprintQ((_res.options & RES_DEBUG) ||
645 (_res.pfcode & RES_PRF_REPLY),
646 (stdout, ";; wrong query name:\n"),
647 ans, resplen);
395 goto wait; 648 goto wait;
396 } 649 }
397 if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || 650 if (anhp->rcode == SERVFAIL ||
651 anhp->rcode == NOTIMP ||
398 anhp->rcode == REFUSED) { 652 anhp->rcode == REFUSED) {
399#ifdef DEBUG 653 DprintQ(_res.options & RES_DEBUG,
400 if (_res.options & RES_DEBUG) { 654 (stdout, "server rejected query:\n"),
401 printf("server rejected query:\n"); 655 ans, resplen);
402 __p_query(answer); 656 badns |= (1 << ns);
403 } 657 _res_close();
404#endif 658 /* don't retry if called from dig */
405 badns |= (1<<ns); 659 if (!_res.pfcode)
406 continue; 660 goto next_ns;
407 } 661 }
408 if (!(_res.options & RES_IGNTC) && anhp->tc) { 662 if (!(_res.options & RES_IGNTC) && anhp->tc) {
409 /* 663 /*
410 * get rest of answer; 664 * get rest of answer;
411 * use TCP with same server. 665 * use TCP with same server.
412 */ 666 */
413#ifdef DEBUG 667 Dprint(_res.options & RES_DEBUG,
414 if (_res.options & RES_DEBUG) 668 (stdout, ";; truncated answer\n"));
415 printf(";; truncated answer\n");
416#endif
417 (void) close(s);
418 s = -1;
419 v_circuit = 1; 669 v_circuit = 1;
420 goto usevc; 670 _res_close();
671 goto same_ns;
421 } 672 }
422 } 673 } /*if vc/dg*/
423#ifdef DEBUG 674 Dprint((_res.options & RES_DEBUG) ||
424 if (_res.options & RES_DEBUG) 675 ((_res.pfcode & RES_PRF_REPLY) &&
425 printf(";; got answer:\n"); 676 (_res.pfcode & RES_PRF_HEAD1)),
426 if ((_res.options & RES_DEBUG) || 677 (stdout, ";; got answer:\n"));
427 (_res.pfcode & RES_PRF_REPLY)) 678 DprintQ((_res.options & RES_DEBUG) ||
428 __p_query(answer); 679 (_res.pfcode & RES_PRF_REPLY),
429#endif 680 (stdout, ""),
681 ans, resplen);
430 /* 682 /*
431 * If using virtual circuits, we assume that the first server 683 * If using virtual circuits, we assume that the first server
432 * is preferred * over the rest (i.e. it is on the local 684 * is preferred over the rest (i.e. it is on the local
433 * machine) and only keep that one open. 685 * machine) and only keep that one open.
434 * If we have temporarily opened a virtual circuit, 686 * If we have temporarily opened a virtual circuit,
435 * or if we haven't been asked to keep a socket open, 687 * or if we haven't been asked to keep a socket open,
436 * close the socket. 688 * close the socket.
437 */ 689 */
438 if ((v_circuit && 690 if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
439 ((_res.options & RES_USEVC) == 0 || ns != 0)) || 691 !(_res.options & RES_STAYOPEN)) {
440 (_res.options & RES_STAYOPEN) == 0) { 692 _res_close();
441 (void) close(s); 693 }
442 s = -1; 694 if (Rhook) {
695 int done = 0, loops = 0;
696
697 do {
698 res_sendhookact act;
699
700 act = (*Rhook)(nsap, buf, buflen,
701 ans, anssiz, &resplen);
702 switch (act) {
703 case res_goahead:
704 case res_done:
705 done = 1;
706 break;
707 case res_nextns:
708 _res_close();
709 goto next_ns;
710 case res_modified:
711 /* give the hook another try */
712 if (++loops < 42) /*doug adams*/
713 break;
714 /*FALLTHROUGH*/
715 case res_error:
716 /*FALLTHROUGH*/
717 default:
718 return (-1);
719 }
720 } while (!done);
721
443 } 722 }
444 return (resplen); 723 return (resplen);
445 } 724 next_ns: ;
446 } 725 } /*foreach ns*/
447 if (s >= 0) { 726 } /*foreach retry*/
448 (void) close(s); 727 _res_close();
449 s = -1; 728 if (!v_circuit)
450 } 729 if (!gotsomewhere)
451 if (v_circuit == 0)
452 if (gotsomewhere == 0)
453 errno = ECONNREFUSED; /* no nameservers found */ 730 errno = ECONNREFUSED; /* no nameservers found */
454 else 731 else
455 errno = ETIMEDOUT; /* no answer obtained */ 732 errno = ETIMEDOUT; /* no answer obtained */
@@ -465,10 +742,13 @@ wait:
465 * 742 *
466 * This routine is not expected to be user visible. 743 * This routine is not expected to be user visible.
467 */ 744 */
745void
468_res_close() 746_res_close()
469{ 747{
470 if (s != -1) { 748 if (s >= 0) {
471 (void) close(s); 749 (void) close(s);
472 s = -1; 750 s = -1;
751 connected = 0;
752 vc = 0;
473 } 753 }
474} 754}
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3
index 99abe17f03..07bc10c393 100644
--- a/src/lib/libc/net/resolver.3
+++ b/src/lib/libc/net/resolver.3
@@ -1,4 +1,4 @@
1.\" $NetBSD: resolver.3,v 1.5 1995/02/25 06:21:02 cgd Exp $ 1.\" $NetBSD: resolver.3,v 1.6 1996/02/02 15:22:37 mrg Exp $
2.\" 2.\"
3.\" Copyright (c) 1985, 1991, 1993 3.\" Copyright (c) 1985, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -333,6 +333,7 @@ see
333.%T RFC1033 , 333.%T RFC1033 ,
334.%T RFC1034 , 334.%T RFC1034 ,
335.%T RFC1035 , 335.%T RFC1035 ,
336.%T RFC1535 ,
336.%T RFC974 337.%T RFC974
337.Rs 338.Rs
338.%T "Name Server Operations Guide for BIND" 339.%T "Name Server Operations Guide for BIND"
diff --git a/src/lib/libc/net/sethostent.c b/src/lib/libc/net/sethostent.c
index 00f6499695..df58b1bc92 100644
--- a/src/lib/libc/net/sethostent.c
+++ b/src/lib/libc/net/sethostent.c
@@ -1,4 +1,4 @@
1/* $NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $ */ 1/* $NetBSD: sethostent.c,v 1.5 1996/02/02 15:22:39 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1985, 1993 4 * Copyright (c) 1985, 1993
@@ -36,8 +36,9 @@
36#if defined(LIBC_SCCS) && !defined(lint) 36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0 37#if 0
38static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93"; 38static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93";
39static char rcsid[] = "$Id: sethostent.c,v 8.3 1995/06/29 09:26:28 vixie Exp ";
39#else 40#else
40static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $"; 41static char rcsid[] = "$NetBSD: sethostent.c,v 1.5 1996/02/02 15:22:39 mrg Exp $";
41#endif 42#endif
42#endif /* LIBC_SCCS and not lint */ 43#endif /* LIBC_SCCS and not lint */
43 44
@@ -49,7 +50,11 @@ static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $
49 50
50void 51void
51sethostent(stayopen) 52sethostent(stayopen)
53 int stayopen;
52{ 54{
55
56 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
57 return;
53 if (stayopen) 58 if (stayopen)
54 _res.options |= RES_STAYOPEN | RES_USEVC; 59 _res.options |= RES_STAYOPEN | RES_USEVC;
55} 60}