summaryrefslogtreecommitdiff
path: root/lib/libc/net
diff options
context:
space:
mode:
authordm <dm@cvs.openbsd.org>1996-02-19 19:54:44 +0000
committerdm <dm@cvs.openbsd.org>1996-02-19 19:54:44 +0000
commit34dfcd3c571a64de57872aa758d1b228d7b22a02 (patch)
tree22b14dd50dff4fc41ec5c5f2ee3e20f4b7f1d141 /lib/libc/net
parentd134390523f594c4e7f1b453b8026b993a1aeebb (diff)
netbsd: bind 4.9.3
Diffstat (limited to 'lib/libc/net')
-rw-r--r--lib/libc/net/Makefile.inc8
-rw-r--r--lib/libc/net/gethostnamadr.c2
-rw-r--r--lib/libc/net/getnetbyname.c10
-rw-r--r--lib/libc/net/getnetent.c25
-rw-r--r--lib/libc/net/herror.c23
-rw-r--r--lib/libc/net/inet_addr.c7
-rw-r--r--lib/libc/net/nsap_addr.c130
-rw-r--r--lib/libc/net/res_comp.c63
-rw-r--r--lib/libc/net/res_debug.c513
-rw-r--r--lib/libc/net/res_init.c32
-rw-r--r--lib/libc/net/res_mkquery.c46
-rw-r--r--lib/libc/net/res_query.c73
-rw-r--r--lib/libc/net/res_send.c718
-rw-r--r--lib/libc/net/resolver.33
-rw-r--r--lib/libc/net/sethostent.c9
15 files changed, 1120 insertions, 542 deletions
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc
index 2d220067e40..054d9a74927 100644
--- a/lib/libc/net/Makefile.inc
+++ b/lib/libc/net/Makefile.inc
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.23 1995/03/02 09:09:07 chopps Exp $
+# $NetBSD: Makefile.inc,v 1.24 1996/02/02 15:22:14 mrg Exp $
# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
# net sources
@@ -8,9 +8,9 @@ SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \
getproto.c getprotoent.c getprotoname.c getservbyname.c \
getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \
inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \
- iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c rcmd.c recv.c res_comp.c \
- res_debug.c res_init.c res_mkquery.c res_query.c res_send.c \
- send.c sethostent.c ethers.c
+ iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \
+ res_comp.c res_debug.c res_init.c res_mkquery.c res_query.c \
+ res_send.c send.c sethostent.c ethers.c
# machine-dependent net sources
# m-d Makefile.inc must include sources for:
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
index 2c0595803b7..ec3f14a9002 100644
--- a/lib/libc/net/gethostnamadr.c
+++ b/lib/libc/net/gethostnamadr.c
@@ -270,7 +270,6 @@ gethostbyname(name)
register struct hostent *hp;
char lookups[MAXDNSLUS];
-#ifdef insecure
/*
* disallow names consisting only of digits/dots, unless
* they end in a dot.
@@ -302,7 +301,6 @@ gethostbyname(name)
if (!isdigit(*cp) && *cp != '.')
break;
}
-#endif
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
return (_gethtbyname(name));
diff --git a/lib/libc/net/getnetbyname.c b/lib/libc/net/getnetbyname.c
index 93a2e1256cd..f660f79b20e 100644
--- a/lib/libc/net/getnetbyname.c
+++ b/lib/libc/net/getnetbyname.c
@@ -1,4 +1,4 @@
-/* $NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $ */
+/* $NetBSD: getnetbyname.c,v 1.5 1996/02/02 15:22:20 mrg Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -35,9 +35,11 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
+static char sccsid_[] = "from getnetbyname.c 1.1 (Coimbra) 93/06/02";
+static char rcsid[] = "=Id: getnetbyname.c,v 1.6 1994/05/31 01:49:35 vixie Exp =";
static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93";
#else
-static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $";
+static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.5 1996/02/02 15:22:20 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -55,10 +57,10 @@ getnetbyname(name)
setnetent(_net_stayopen);
while (p = getnetent()) {
- if (strcmp(p->n_name, name) == 0)
+ if (strcasecmp(p->n_name, name) == 0)
break;
for (cp = p->n_aliases; *cp != 0; cp++)
- if (strcmp(*cp, name) == 0)
+ if (strcasecmp(*cp, name) == 0)
goto found;
}
found:
diff --git a/lib/libc/net/getnetent.c b/lib/libc/net/getnetent.c
index 8ecdf6c5a36..2e897201a82 100644
--- a/lib/libc/net/getnetent.c
+++ b/lib/libc/net/getnetent.c
@@ -1,4 +1,4 @@
-/* $NetBSD: getnetent.c,v 1.5 1996/01/14 05:02:41 ghudson Exp $ */
+/* $NetBSD: getnetent.c,v 1.6 1996/02/02 15:22:21 mrg Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
#else
-static char rcsid[] = "$NetBSD: getnetent.c,v 1.5 1996/01/14 05:02:41 ghudson Exp $";
+static char rcsid[] = "$NetBSD: getnetent.c,v 1.6 1996/02/02 15:22:21 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -109,19 +109,18 @@ again:
net.n_net = inet_network(cp);
net.n_addrtype = AF_INET;
q = net.n_aliases = net_aliases;
- if (p != NULL) {
+ if (p != NULL)
cp = p;
- while (cp && *cp) {
- if (*cp == ' ' || *cp == '\t') {
- cp++;
- continue;
- }
- if (q < &net_aliases[MAXALIASES - 1])
- *q++ = cp;
- cp = strpbrk(cp, " \t");
- if (cp != NULL)
- *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
}
+ if (q < &net_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
}
*q = NULL;
return (&net);
diff --git a/lib/libc/net/herror.c b/lib/libc/net/herror.c
index 41adbf10554..f2d241385da 100644
--- a/lib/libc/net/herror.c
+++ b/lib/libc/net/herror.c
@@ -1,4 +1,4 @@
-/* $NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $ */
+/* $NetBSD: herror.c,v 1.6 1996/02/02 15:22:22 mrg Exp $ */
/*-
* Copyright (c) 1987, 1993
@@ -56,9 +56,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: herror.c,v 4.9.1.1 1993/05/02 23:14:35 vixie Rel ";
+static char rcsid[] = "$Id: herror.c,v 8.2 1995/06/19 08:35:01 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $";
+static char rcsid[] = "$NetBSD: herror.c,v 1.6 1996/02/02 15:22:22 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -68,14 +68,14 @@ static char rcsid[] = "$NetBSD: herror.c,v 1.5 1995/02/25 06:20:39 cgd Exp $";
#include <unistd.h>
#include <string.h>
-char *h_errlist[] = {
- "Error 0",
+const char *h_errlist[] = {
+ "Resolver Error 0 (no error)",
"Unknown host", /* 1 HOST_NOT_FOUND */
"Host name lookup failure", /* 2 TRY_AGAIN */
"Unknown server error", /* 3 NO_RECOVERY */
"No address associated with name", /* 4 NO_ADDRESS */
};
-int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
+int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
extern int h_errno;
@@ -98,8 +98,7 @@ herror(s)
v->iov_len = 2;
v++;
}
- v->iov_base = (u_int)h_errno < h_nerr ?
- h_errlist[h_errno] : "Unknown error";
+ v->iov_base = (char *)hstrerror(h_errno);
v->iov_len = strlen(v->iov_base);
v++;
v->iov_base = "\n";
@@ -107,9 +106,13 @@ herror(s)
writev(STDERR_FILENO, iov, (v - iov) + 1);
}
-char *
+const char *
hstrerror(err)
int err;
{
- return (u_int)err < h_nerr ? h_errlist[err] : "Unknown resolver error";
+ if (err < 0)
+ return ("Resolver internal error");
+ else if (err < h_nerr)
+ return (h_errlist[err]);
+ return ("Unknown resolver error");
}
diff --git a/lib/libc/net/inet_addr.c b/lib/libc/net/inet_addr.c
index b5b9d8302fa..e527c6b384b 100644
--- a/lib/libc/net/inet_addr.c
+++ b/lib/libc/net/inet_addr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $ */
+/* $NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $ */
/*
* Copyright (c) 1983, 1990, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
#else
-static char rcsid[] = "$NetBSD: inet_addr.c,v 1.5 1995/02/25 06:20:41 cgd Exp $";
+static char rcsid[] = "$NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -131,6 +131,9 @@ inet_aton(cp, addr)
n = pp - parts + 1;
switch (n) {
+ case 0:
+ return (0); /* initial nondigit */
+
case 1: /* a -- 32 bits */
break;
diff --git a/lib/libc/net/nsap_addr.c b/lib/libc/net/nsap_addr.c
new file mode 100644
index 00000000000..e4583a3db80
--- /dev/null
+++ b/lib/libc/net/nsap_addr.c
@@ -0,0 +1,130 @@
+/* $NetBSD: nsap_addr.c,v 1.1 1996/02/02 15:22:24 mrg Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char rcsid[] = "$Id: lib-libc-net,v 8.1 1995/12/22 21:59:52 vixie Exp ";
+#else
+static char rcsid[] = "$NetBSD: nsap_addr.c,v 1.1 1996/02/02 15:22:24 mrg Exp $";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+
+static char
+xtob(c)
+ register int c;
+{
+ return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
+}
+
+/* These have to be here for BIND and its utilities (DiG, nslookup, et al)
+ * but should not be promulgated since the calling interface is not pretty.
+ * (They do, however, implement the RFC standard way of representing ISO NSAPs
+ * and as such, are preferred over the more general iso_addr.c routines.
+ */
+
+u_int
+inet_nsap_addr(ascii, binary, maxlen)
+ const char *ascii;
+ u_char *binary;
+ int maxlen;
+{
+ register u_char c, nib;
+ u_int len = 0;
+
+ while ((c = *ascii++) != '\0' && len < maxlen) {
+ if (c == '.' || c == '+' || c == '/')
+ continue;
+ if (!isascii(c))
+ return (0);
+ if (islower(c))
+ c = toupper(c);
+ if (isxdigit(c)) {
+ nib = xtob(c);
+ if (c = *ascii++) {
+ c = toupper(c);
+ if (isxdigit(c)) {
+ *binary++ = (nib << 4) | xtob(c);
+ len++;
+ } else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ return (len);
+}
+
+char *
+inet_nsap_ntoa(binlen, binary, ascii)
+ int binlen;
+ register const u_char *binary;
+ register char *ascii;
+{
+ register int nib;
+ int i;
+ static char tmpbuf[255*3];
+ char *start;
+
+ if (ascii)
+ start = ascii;
+ else {
+ ascii = tmpbuf;
+ start = tmpbuf;
+ }
+
+ if (binlen > 255)
+ binlen = 255;
+
+ for (i = 0; i < binlen; i++) {
+ nib = *binary >> 4;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ nib = *binary++ & 0x0f;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ if (((i % 2) == 0 && (i + 1) < binlen))
+ *ascii++ = '.';
+ }
+ *ascii = '\0';
+ return (start);
+}
diff --git a/lib/libc/net/res_comp.c b/lib/libc/net/res_comp.c
index 9d7bbecdda5..2d81327aafd 100644
--- a/lib/libc/net/res_comp.c
+++ b/lib/libc/net/res_comp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $ */
+/* $NetBSD: res_comp.c,v 1.7 1996/02/02 15:22:26 mrg Exp $ */
/*-
* Copyright (c) 1985, 1993
@@ -56,9 +56,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_comp.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
+static char rcsid[] = "$Id: res_comp.c,v 8.3 1995/12/06 20:34:50 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $";
+static char rcsid[] = "$NetBSD: res_comp.c,v 1.7 1996/02/02 15:22:26 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -67,8 +67,11 @@ static char rcsid[] = "$NetBSD: res_comp.c,v 1.6 1995/02/25 06:20:55 cgd Exp $";
#include <netinet/in.h>
#include <resolv.h>
#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
-static int dn_find();
+static int dn_find __P((u_char *, u_char *, u_char **, u_char **));
/*
* Expand compressed domain name 'comp_dn' to full domain name.
@@ -77,18 +80,20 @@ static int dn_find();
* 'exp_dn' is a pointer to a buffer of size 'length' for the result.
* Return size of compressed name or -1 if there was an error.
*/
+int
dn_expand(msg, eomorig, comp_dn, exp_dn, length)
const u_char *msg, *eomorig, *comp_dn;
- u_char *exp_dn;
+ char *exp_dn;
int length;
{
- register u_char *cp, *dn;
+ register const u_char *cp;
+ register char *dn;
register int n, c;
- u_char *eom;
+ char *eom;
int len = -1, checked = 0;
dn = exp_dn;
- cp = (u_char *)comp_dn;
+ cp = comp_dn;
eom = exp_dn + length;
/*
* fetch next label in domain name
@@ -108,23 +113,23 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
return (-1);
checked += n + 1;
while (--n >= 0) {
- if ((c = *cp++) == '.') {
+ if ((c = *cp++) == '.' || c == '\\') {
if (dn + n + 2 >= eom)
return (-1);
*dn++ = '\\';
}
*dn++ = c;
if (cp >= eomorig) /* out of range */
- return(-1);
+ return (-1);
}
break;
case INDIR_MASK:
if (len < 0)
len = cp - comp_dn + 1;
- cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
+ cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
if (cp < msg || cp >= eomorig) /* out of range */
- return(-1);
+ return (-1);
checked += 2;
/*
* Check for loops in the compressed name;
@@ -140,6 +145,9 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
}
}
*dn = '\0';
+ for (dn = exp_dn; (c = *dn) != '\0'; dn++)
+ if (isascii(c) && isspace(c))
+ return (-1);
if (len < 0)
len = cp - comp_dn;
return (len);
@@ -157,8 +165,9 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
* If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
* is NULL, we don't update the list.
*/
+int
dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
- const u_char *exp_dn;
+ const char *exp_dn;
u_char *comp_dn, **dnptrs, **lastdnptr;
int length;
{
@@ -170,6 +179,7 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
dn = (u_char *)exp_dn;
cp = comp_dn;
eob = cp + length;
+ lpp = cpp = NULL;
if (dnptrs != NULL) {
if ((msg = *dnptrs++) != NULL) {
for (cpp = dnptrs; *cpp != NULL; cpp++)
@@ -235,13 +245,14 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
/*
* Skip over a compressed domain name. Return the size or -1.
*/
+int
__dn_skipname(comp_dn, eom)
const u_char *comp_dn, *eom;
{
- register u_char *cp;
+ register const u_char *cp;
register int n;
- cp = (u_char *)comp_dn;
+ cp = comp_dn;
while (cp < eom && (n = *cp++)) {
/*
* check for indirection
@@ -263,6 +274,15 @@ __dn_skipname(comp_dn, eom)
return (cp - comp_dn);
}
+static int
+mklower(ch)
+ register int ch;
+{
+ if (isascii(ch) && isupper(ch))
+ return (tolower(ch));
+ return (ch);
+}
+
/*
* Search for expanded name from a list of previously compressed names.
* Return the offset from msg if found or -1.
@@ -292,7 +312,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
goto next;
if (*dn == '\\')
dn++;
- if (*dn++ != *cp++)
+ if (mklower(*dn++) != mklower(*cp++))
goto next;
}
if ((n = *dn++) == '\0' && *cp == '\0')
@@ -301,11 +321,12 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
continue;
goto next;
- default: /* illegal type */
- return (-1);
-
case INDIR_MASK: /* indirection */
cp = msg + (((n & 0x3f) << 8) | *cp);
+ break;
+
+ default: /* illegal type */
+ return (-1);
}
}
if (*dn == '\0')
@@ -325,7 +346,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
u_short
_getshort(msgp)
- register u_char *msgp;
+ register const u_char *msgp;
{
register u_int16_t u;
@@ -335,7 +356,7 @@ _getshort(msgp)
u_int32_t
_getlong(msgp)
- register u_char *msgp;
+ register const u_char *msgp;
{
register u_int32_t u;
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
index d841293f18d..14e5ddf790d 100644
--- a/lib/libc/net/res_debug.c
+++ b/lib/libc/net/res_debug.c
@@ -1,4 +1,4 @@
-/* $NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $ */
+/* $NetBSD: res_debug.c,v 1.8 1996/02/02 15:22:27 mrg Exp $ */
/*-
* Copyright (c) 1985, 1990, 1993
@@ -56,8 +56,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_debug.c,v 8.7 1995/12/22 10:20:39 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $";
+static char rcsid[] = "$NetBSD: res_debug.c,v 1.8 1996/02/02 15:22:27 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -68,18 +69,16 @@ static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $"
#include <resolv.h>
#include <stdio.h>
#include <string.h>
+#include <netdb.h>
void __fp_query();
-char *__p_class(), *__p_time(), *__p_type();
-char *p_cdname(), *p_fqname(), *p_rr();
-static char *p_option __P((u_int32_t));
char *_res_opcodes[] = {
"QUERY",
"IQUERY",
"CQUERYM",
- "CQUERYU",
- "4",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
"5",
"6",
"7",
@@ -112,102 +111,118 @@ char *_res_resultcodes[] = {
"NOCHANGE",
};
-static char retbuf[16];
-
static char *
dewks(wks)
int wks;
{
+ static char nbuf[20];
+
switch (wks) {
- case 5: return("rje");
- case 7: return("echo");
- case 9: return("discard");
- case 11: return("systat");
- case 13: return("daytime");
- case 15: return("netstat");
- case 17: return("qotd");
- case 19: return("chargen");
- case 20: return("ftp-data");
- case 21: return("ftp");
- case 23: return("telnet");
- case 25: return("smtp");
- case 37: return("time");
- case 39: return("rlp");
- case 42: return("name");
- case 43: return("whois");
- case 53: return("domain");
- case 57: return("apts");
- case 59: return("apfs");
- case 67: return("bootps");
- case 68: return("bootpc");
- case 69: return("tftp");
- case 77: return("rje");
- case 79: return("finger");
- case 87: return("link");
- case 95: return("supdup");
- case 100: return("newacct");
- case 101: return("hostnames");
- case 102: return("iso-tsap");
- case 103: return("x400");
- case 104: return("x400-snd");
- case 105: return("csnet-ns");
- case 109: return("pop-2");
- case 111: return("sunrpc");
- case 113: return("auth");
- case 115: return("sftp");
- case 117: return("uucp-path");
- case 119: return("nntp");
- case 121: return("erpc");
- case 123: return("ntp");
- case 133: return("statsrv");
- case 136: return("profile");
- case 144: return("NeWS");
- case 161: return("snmp");
- case 162: return("snmp-trap");
- case 170: return("print-srv");
- default: (void) sprintf(retbuf, "%d", wks); return(retbuf);
+ case 5: return "rje";
+ case 7: return "echo";
+ case 9: return "discard";
+ case 11: return "systat";
+ case 13: return "daytime";
+ case 15: return "netstat";
+ case 17: return "qotd";
+ case 19: return "chargen";
+ case 20: return "ftp-data";
+ case 21: return "ftp";
+ case 23: return "telnet";
+ case 25: return "smtp";
+ case 37: return "time";
+ case 39: return "rlp";
+ case 42: return "name";
+ case 43: return "whois";
+ case 53: return "domain";
+ case 57: return "apts";
+ case 59: return "apfs";
+ case 67: return "bootps";
+ case 68: return "bootpc";
+ case 69: return "tftp";
+ case 77: return "rje";
+ case 79: return "finger";
+ case 87: return "link";
+ case 95: return "supdup";
+ case 100: return "newacct";
+ case 101: return "hostnames";
+ case 102: return "iso-tsap";
+ case 103: return "x400";
+ case 104: return "x400-snd";
+ case 105: return "csnet-ns";
+ case 109: return "pop-2";
+ case 111: return "sunrpc";
+ case 113: return "auth";
+ case 115: return "sftp";
+ case 117: return "uucp-path";
+ case 119: return "nntp";
+ case 121: return "erpc";
+ case 123: return "ntp";
+ case 133: return "statsrv";
+ case 136: return "profile";
+ case 144: return "NeWS";
+ case 161: return "snmp";
+ case 162: return "snmp-trap";
+ case 170: return "print-srv";
+ default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
}
}
-static char *
+/* XXX: we should use getprotobynumber() instead. */
+static const char *
deproto(protonum)
int protonum;
{
+ static char nbuf[20];
+
switch (protonum) {
- case 1: return("icmp");
- case 2: return("igmp");
- case 3: return("ggp");
- case 5: return("st");
- case 6: return("tcp");
- case 7: return("ucl");
- case 8: return("egp");
- case 9: return("igp");
- case 11: return("nvp-II");
- case 12: return("pup");
- case 16: return("chaos");
- case 17: return("udp");
- default: (void) sprintf(retbuf, "%d", protonum); return(retbuf);
+ case 1: return "icmp";
+ case 2: return "igmp";
+ case 3: return "ggp";
+ case 5: return "st";
+ case 6: return "tcp";
+ case 7: return "ucl";
+ case 8: return "egp";
+ case 9: return "igp";
+ case 11: return "nvp-II";
+ case 12: return "pup";
+ case 16: return "chaos";
+ case 17: return "udp";
+ default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
}
}
-static char *
-do_rrset(msg, cp, cnt, pflag, file, hs)
- int cnt, pflag;
- char *cp,*msg, *hs;
+static const u_char *
+do_rrset(msg, len, cp, cnt, pflag, file, hs)
+ int cnt, pflag, len;
+ const u_char *cp, *msg;
+ const char *hs;
FILE *file;
{
int n;
int sflag;
+
/*
- * Print answer records
+ * Print answer records.
*/
sflag = (_res.pfcode & pflag);
if (n = ntohs(cnt)) {
if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
fprintf(file, hs);
while (--n >= 0) {
- cp = p_rr(cp, msg, file);
- if ((cp-msg) > PACKETSZ)
+ if ((!_res.pfcode) || sflag) {
+ cp = p_rr(cp, msg, file);
+ } else {
+ unsigned int dlen;
+ cp += __dn_skipname(cp, cp + MAXCDNAME);
+ cp += sizeof(u_int16_t);
+ cp += sizeof(u_int16_t);
+ cp += sizeof(u_int32_t);
+ dlen = _getshort((u_char*)cp);
+ cp += sizeof(u_int16_t);
+ cp += dlen;
+ }
+ if ((cp - msg) > len)
return (NULL);
}
if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
@@ -216,8 +231,9 @@ do_rrset(msg, cp, cnt, pflag, file, hs)
return(cp);
}
+void
__p_query(msg)
- char *msg;
+ const u_char *msg;
{
__fp_query(msg, stdout);
}
@@ -231,15 +247,14 @@ __fp_resstat(statp, file)
struct __res_state *statp;
FILE *file;
{
- int bit;
+ register u_long mask;
fprintf(file, ";; res options:");
if (!statp)
statp = &_res;
- for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */
- if (statp->options & (1<<bit))
- fprintf(file, " %s", p_option(1<<bit));
- }
+ for (mask = 1; mask != 0; mask <<= 1)
+ if (statp->options & mask)
+ fprintf(file, " %s", p_option(mask));
putc('\n', file);
}
@@ -248,19 +263,27 @@ __fp_resstat(statp, file)
* This is intended to be primarily a debugging routine.
*/
void
-__fp_query(msg,file)
- char *msg;
+__fp_nquery(msg, len, file)
+ const u_char *msg;
+ int len;
FILE *file;
{
- register char *cp;
- register HEADER *hp;
+ register const u_char *cp, *endMark;
+ register const HEADER *hp;
register int n;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+
+#define TruncTest(x) if (x >= endMark) goto trunc
+#define ErrorTest(x) if (x == NULL) goto error
+
/*
* Print header fields.
*/
hp = (HEADER *)msg;
- cp = msg + sizeof(HEADER);
+ cp = msg + HFIXEDSZ;
+ endMark = cp + len;
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
_res_opcodes[hp->opcode],
@@ -268,7 +291,8 @@ __fp_query(msg,file)
ntohs(hp->id));
putc('\n', file);
}
- putc(';', file);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
+ putc(';', file);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
fprintf(file,"; flags:");
if (hp->qr)
@@ -281,20 +305,17 @@ __fp_query(msg,file)
fprintf(file," rd");
if (hp->ra)
fprintf(file," ra");
- if (hp->pr)
- fprintf(file," pr");
}
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
fprintf(file,"; Ques: %d", ntohs(hp->qdcount));
fprintf(file,", Ans: %d", ntohs(hp->ancount));
fprintf(file,", Auth: %d", ntohs(hp->nscount));
- fprintf(file,", Addit: %d\n", ntohs(hp->arcount));
+ fprintf(file, ", Addit: %d", ntohs(hp->arcount));
}
-#if 0
- if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) {
+ if ((!_res.pfcode) || (_res.pfcode &
+ (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
putc('\n',file);
}
-#endif
/*
* Print question records.
*/
@@ -302,55 +323,85 @@ __fp_query(msg,file)
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
fprintf(file,";; QUESTIONS:\n");
while (--n >= 0) {
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
fprintf(file,";;\t");
- cp = p_cdname(cp, msg, file);
- if (cp == NULL)
- return;
+ TruncTest(cp);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ cp = p_cdnname(cp, msg, len, file);
+ else {
+ int n;
+ char name[MAXDNAME];
+
+ if ((n = dn_expand(msg, msg+len, cp, name,
+ sizeof name)) < 0)
+ cp = NULL;
+ else
+ cp += n;
+ }
+ ErrorTest(cp);
+ TruncTest(cp);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
fprintf(file, ", type = %s",
- __p_type(_getshort(cp)));
- cp += sizeof(u_int16_t);
+ __p_type(_getshort((u_char*)cp)));
+ cp += INT16SZ;
+ TruncTest(cp);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ", class = %s\n\n",
- __p_class(_getshort(cp)));
- cp += sizeof(u_int16_t);
+ fprintf(file, ", class = %s\n",
+ __p_class(_getshort((u_char*)cp)));
+ cp += INT16SZ;
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ putc('\n', file);
}
}
/*
* Print authoritative answer records
*/
- cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
+ TruncTest(cp);
+ cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
";; ANSWERS:\n");
- if (cp == NULL)
- return;
+ ErrorTest(cp);
/*
* print name server records
*/
- cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
+ TruncTest(cp);
+ cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
";; AUTHORITY RECORDS:\n");
- if (!cp)
- return;
+ ErrorTest(cp);
+ TruncTest(cp);
/*
* print additional records
*/
- cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
+ cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
";; ADDITIONAL RECORDS:\n");
- if (!cp)
+ ErrorTest(cp);
+ return;
+ trunc:
+ fprintf(file, "\n;; ...truncated\n");
return;
+ error:
+ fprintf(file, "\n;; ...malformed\n");
}
-char *
-p_cdname(cp, msg, file)
- char *cp, *msg;
+void
+__fp_query(msg, file)
+ const u_char *msg;
+ FILE *file;
+{
+ fp_nquery(msg, PACKETSZ, file);
+}
+
+const u_char *
+__p_cdnname(cp, msg, len, file)
+ const u_char *cp, *msg;
+ int len;
FILE *file;
{
char name[MAXDNAME];
int n;
- if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
- (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
+ if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
return (NULL);
if (name[0] == '\0')
putc('.', file);
@@ -359,16 +410,26 @@ p_cdname(cp, msg, file)
return (cp + n);
}
-char *
-p_fqname(cp, msg, file)
- char *cp, *msg;
+const u_char *
+__p_cdname(cp, msg, file)
+ const u_char *cp, *msg;
+ FILE *file;
+{
+ return (p_cdnname(cp, msg, PACKETSZ, file));
+}
+
+/* XXX: the rest of these functions need to become length-limited, too. (vix)
+ */
+
+const u_char *
+__p_fqname(cp, msg, file)
+ const u_char *cp, *msg;
FILE *file;
{
char name[MAXDNAME];
- int n, len;
+ int n;
- if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
- (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
+ if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
return (NULL);
if (name[0] == '\0') {
putc('.', file);
@@ -383,17 +444,21 @@ p_fqname(cp, msg, file)
/*
* Print resource record fields in human readable form.
*/
-char *
-p_rr(cp, msg, file)
- char *cp, *msg;
+const u_char *
+__p_rr(cp, msg, file)
+ const u_char *cp, *msg;
FILE *file;
{
int type, class, dlen, n, c;
struct in_addr inaddr;
- char *cp1, *cp2;
+ const u_char *cp1, *cp2;
u_int32_t tmpttl, t;
int lcnt;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL); /* compression error */
type = _getshort(cp);
@@ -406,7 +471,7 @@ p_rr(cp, msg, file)
cp += sizeof(u_int16_t);
cp1 = cp;
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
- fprintf(file, "\t%lu", tmpttl);
+ fprintf(file, "\t%lu", (u_long)tmpttl);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
fprintf(file, "\t%s", __p_class(class));
fprintf(file, "\t%s", __p_type(type));
@@ -429,7 +494,7 @@ p_rr(cp, msg, file)
address = inet_ntoa(inaddr);
cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
+ protocol = *cp;
cp += sizeof(u_char);
port = _getshort(cp);
cp += sizeof(u_int16_t);
@@ -448,52 +513,75 @@ p_rr(cp, msg, file)
case T_NS:
case T_PTR:
putc('\t', file);
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
break;
case T_HINFO:
+ case T_ISDN:
+ cp2 = cp + dlen;
if (n = *cp++) {
fprintf(file,"\t%.*s", n, cp);
cp += n;
}
- if (n = *cp++) {
+ if ((cp < cp2) && (n = *cp++)) {
fprintf(file,"\t%.*s", n, cp);
cp += n;
- }
+ } else if (type == T_HINFO)
+ fprintf(file, "\n;; *** Warning *** OS-type missing");
break;
case T_SOA:
putc('\t', file);
- cp = p_fqname(cp, msg, file); /* origin */
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
putc(' ', file);
- cp = p_fqname(cp, msg, file); /* mail addr */
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
fputs(" (\n", file);
t = _getlong(cp); cp += sizeof(u_int32_t);
- fprintf(file,"\t\t\t%lu\t; serial\n", t);
+ fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
t = _getlong(cp); cp += sizeof(u_int32_t);
- fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
+ (u_long)t, __p_time(t));
t = _getlong(cp); cp += sizeof(u_int32_t);
- fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
+ (u_long)t, __p_time(t));
t = _getlong(cp); cp += sizeof(u_int32_t);
- fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
+ (u_long)t, __p_time(t));
t = _getlong(cp); cp += sizeof(u_int32_t);
- fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
+ (u_long)t, __p_time(t));
break;
case T_MX:
case T_AFSDB:
- fprintf(file,"\t%d ", _getshort(cp));
- cp += sizeof(u_int16_t);
- cp = p_fqname(cp, msg, file);
+ case T_RT:
+ fprintf(file, "\t%d ", _getshort(cp));
+ cp += INT16SZ;
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ break;
+
+ case T_PX:
+ fprintf(file, "\t%d ", _getshort(cp));
+ cp += INT16SZ;
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ putc(' ', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
break;
case T_TXT:
+ case T_X25:
(void) fputs("\t\"", file);
cp2 = cp1 + dlen;
while (cp < cp2) {
if (n = (unsigned char) *cp++) {
for (c = n; c > 0 && cp < cp2; c--)
- if (*cp == '\n') {
+ if ((*cp == '\n') || (*cp == '"')) {
(void) putc('\\', file);
(void) putc(*cp++, file);
} else
@@ -503,12 +591,19 @@ p_rr(cp, msg, file)
putc('"', file);
break;
+ case T_NSAP:
+ (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
+ cp += dlen;
+ break;
+
case T_MINFO:
case T_RP:
putc('\t', file);
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
putc(' ', file);
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
break;
case T_UINFO:
@@ -558,7 +653,7 @@ p_rr(cp, msg, file)
case T_UNSPEC:
{
int NumBytes = 8;
- char *DataPtr;
+ u_char *DataPtr;
int i;
if (dlen < NumBytes) NumBytes = dlen;
@@ -588,113 +683,98 @@ p_rr(cp, msg, file)
return (cp);
}
-static char nbuf[40];
-
/*
* Return a string for the type
*/
-char *
+const char *
__p_type(type)
int type;
{
+ static char nbuf[20];
+
switch (type) {
- case T_A:
- return("A");
- case T_NS: /* authoritative server */
- return("NS");
- case T_CNAME: /* canonical name */
- return("CNAME");
- case T_SOA: /* start of authority zone */
- return("SOA");
- case T_MB: /* mailbox domain name */
- return("MB");
- case T_MG: /* mail group member */
- return("MG");
- case T_MR: /* mail rename name */
- return("MR");
- case T_NULL: /* null resource record */
- return("NULL");
- case T_WKS: /* well known service */
- return("WKS");
- case T_PTR: /* domain name pointer */
- return("PTR");
- case T_HINFO: /* host information */
- return("HINFO");
- case T_MINFO: /* mailbox information */
- return("MINFO");
- case T_MX: /* mail routing info */
- return("MX");
- case T_TXT: /* text */
- return("TXT");
- case T_RP: /* responsible person */
- return("RP");
- case T_AFSDB: /* AFS cell database */
- return("AFSDB");
- case T_AXFR: /* zone transfer */
- return("AXFR");
- case T_MAILB: /* mail box */
- return("MAILB");
- case T_MAILA: /* mail address */
- return("MAILA");
- case T_ANY: /* matches any type */
- return("ANY");
- case T_UINFO:
- return("UINFO");
- case T_UID:
- return("UID");
- case T_GID:
- return("GID");
+ case T_A: return "A";
+ case T_NS: return "NS";
+ case T_CNAME: return "CNAME";
+ case T_SOA: return "SOA";
+ case T_MB: return "MB";
+ case T_MG: return "MG";
+ case T_MR: return "MR";
+ case T_NULL: return "NULL";
+ case T_WKS: return "WKS";
+ case T_PTR: return "PTR";
+ case T_HINFO: return "HINFO";
+ case T_MINFO: return "MINFO";
+ case T_MX: return "MX";
+ case T_TXT: return "TXT";
+ case T_RP: return "RP";
+ case T_AFSDB: return "AFSDB";
+ case T_X25: return "X25";
+ case T_ISDN: return "ISDN";
+ case T_RT: return "RT";
+ case T_NSAP: return "NSAP";
+ case T_NSAP_PTR: return "NSAP_PTR";
+ case T_SIG: return "SIG";
+ case T_KEY: return "KEY";
+ case T_PX: return "PX";
+ case T_GPOS: return "GPOS";
+ case T_AAAA: return "AAAA";
+ case T_LOC: return "LOC";
+ case T_AXFR: return "AXFR";
+ case T_MAILB: return "MAILB";
+ case T_MAILA: return "MAILA";
+ case T_ANY: return "ANY";
+ case T_UINFO: return "UINFO";
+ case T_UID: return "UID";
+ case T_GID: return "GID";
#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- return("UNSPEC");
+ case T_UNSPEC: return "UNSPEC";
#endif /* ALLOW_T_UNSPEC */
-
- default:
- (void)sprintf(nbuf, "%d", type);
- return(nbuf);
+ default: (void)sprintf(nbuf, "%d", type); return (nbuf);
}
}
/*
* Return a mnemonic for class
*/
-char *
+const char *
__p_class(class)
int class;
{
+ static char nbuf[20];
switch (class) {
- case C_IN: /* internet class */
- return("IN");
- case C_HS: /* hesiod class */
- return("HS");
- case C_ANY: /* matches any class */
- return("ANY");
- default:
- (void)sprintf(nbuf, "%d", class);
- return(nbuf);
+ case C_IN: return "IN";
+ case C_HS: return "HS";
+ case C_ANY: return "ANY";
+ default: (void)sprintf(nbuf, "%d", class); return (nbuf);
}
}
/*
* Return a mnemonic for an option
*/
-static char *
-p_option(option)
- u_int32_t option;
+const char *
+__p_option(option)
+ u_long option;
{
+ static char nbuf[40];
+
switch (option) {
case RES_INIT: return "init";
case RES_DEBUG: return "debug";
- case RES_AAONLY: return "aaonly";
+ case RES_AAONLY: return "aaonly(unimpl)";
case RES_USEVC: return "usevc";
- case RES_PRIMARY: return "primry";
+ case RES_PRIMARY: return "primry(unimpl)";
case RES_IGNTC: return "igntc";
case RES_RECURSE: return "recurs";
case RES_DEFNAMES: return "defnam";
case RES_STAYOPEN: return "styopn";
case RES_DNSRCH: return "dnsrch";
- default: sprintf(nbuf, "?0x%x?", option); return nbuf;
+ case RES_INSECURE1: return "insecure1";
+ case RES_INSECURE2: return "insecure2";
+ default: sprintf(nbuf, "?0x%lx?", (u_long)option);
+ return (nbuf);
}
}
@@ -705,6 +785,7 @@ char *
__p_time(value)
u_int32_t value;
{
+ static char nbuf[40];
int secs, mins, hours, days;
register char *p;
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
index 33cc8d39f1d..ff8e1b1e5e6 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -1,4 +1,4 @@
-/* $NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $ */
+/* $NetBSD: res_init.c,v 1.9 1996/02/02 15:22:30 mrg Exp $ */
/*-
* Copyright (c) 1985, 1989, 1993
@@ -56,9 +56,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
-static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
+static char rcsid[] = "$Id: res_init.c,v 8.3 1995/06/29 09:26:28 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $";
+static char rcsid[] = "$NetBSD: res_init.c,v 1.9 1996/02/02 15:22:30 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -92,11 +92,23 @@ struct __res_state _res = {
* there will have precedence. Otherwise, the server address is set to
* INADDR_ANY and the default domain name comes from the gethostname().
*
- * The configuration file should only be used if you want to redefine your
- * domain or run without a server on your machine.
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address
+ * since it was noted that INADDR_ANY actually meant ``the first interface
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
+ * it had to be "up" in order for you to reach your own name server. It
+ * was later decided that since the recommended practice is to always
+ * install local static routes through 127.0.0.1 for all your network
+ * interfaces, that we could solve this problem without a code change.
+ *
+ * The configuration file should always be used, since it is the only way
+ * to specify a default domain. If you are running a server on your local
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
+ * in the configuration file.
*
* Return 0 if completes successfully, -1 on error
*/
+int
res_init()
{
register FILE *fp;
@@ -107,6 +119,7 @@ res_init()
int haveenv = 0;
int havesearch = 0;
int nsort = 0;
+ int dots;
u_long mask;
_res.nsaddr.sin_len = sizeof(struct sockaddr_in);
@@ -392,3 +405,12 @@ net_mask(in) /* XXX - should really use system's version of this */
return (htonl(IN_CLASSB_NET));
return (htonl(IN_CLASSC_NET));
}
+
+u_int16_t
+res_randomid()
+{
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
+}
diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c
index 25f025e147f..1f04c962720 100644
--- a/lib/libc/net/res_mkquery.c
+++ b/lib/libc/net/res_mkquery.c
@@ -1,4 +1,4 @@
-/* $NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $ */
+/* $NetBSD: res_mkquery.c,v 1.6 1996/02/02 15:22:32 mrg Exp $ */
/*-
* Copyright (c) 1985, 1993
@@ -56,9 +56,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp ";
+static char rcsid[] = "$Id: res_mkquery.c,v 8.3 1995/06/29 09:26:28 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $";
+static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.6 1996/02/02 15:22:32 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -73,21 +73,22 @@ static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp
* Form all types of queries.
* Returns the size of the result or -1.
*/
+int
res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
int op; /* opcode of query */
const char *dname; /* domain name */
int class, type; /* class and type of query */
- const char *data; /* resource record data */
+ const u_char *data; /* resource record data */
int datalen; /* length of data */
- const char *newrr_in; /* new rr for modify or append */
- char *buf; /* buffer to put query */
+ const u_char *newrr_in; /* new rr for modify or append */
+ u_char *buf; /* buffer to put query */
int buflen; /* size of buffer */
{
register HEADER *hp;
- register char *cp;
+ register u_char *cp;
register int n;
struct rrec *newrr = (struct rrec *) newrr_in;
- char *dnptrs[10], **dpp, **lastdnptr;
+ u_char *dnptrs[10], **dpp, **lastdnptr;
#ifdef DEBUG
if (_res.options & RES_DEBUG)
@@ -117,16 +118,16 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
*/
switch (op) {
case QUERY:
+ case NS_NOTIFY_OP:
if ((buflen -= QFIXEDSZ) < 0)
return(-1);
- if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
- (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
+ if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
buflen -= n;
- __putshort(type, (u_char *)cp);
+ __putshort(type, cp);
cp += sizeof(u_int16_t);
- __putshort(class, (u_char *)cp);
+ __putshort(class, cp);
cp += sizeof(u_int16_t);
hp->qdcount = htons(1);
if (op == QUERY || data == NULL)
@@ -135,18 +136,17 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
* Make an additional record for completion domain.
*/
buflen -= RRFIXEDSZ;
- if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
- (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
+ if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
buflen -= n;
- __putshort(T_NULL, (u_char *)cp);
+ __putshort(T_NULL, cp);
cp += sizeof(u_int16_t);
- __putshort(class, (u_char *)cp);
+ __putshort(class, cp);
cp += sizeof(u_int16_t);
- __putlong(0, (u_char *)cp);
+ __putlong(0, cp);
cp += sizeof(u_int32_t);
- __putshort(0, (u_char *)cp);
+ __putshort(0, cp);
cp += sizeof(u_int16_t);
hp->arcount = htons(1);
break;
@@ -158,13 +158,13 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
if (buflen < 1 + RRFIXEDSZ + datalen)
return (-1);
*cp++ = '\0'; /* no domain name */
- __putshort(type, (u_char *)cp);
+ __putshort(type, cp);
cp += sizeof(u_int16_t);
- __putshort(class, (u_char *)cp);
+ __putshort(class, cp);
cp += sizeof(u_int16_t);
- __putlong(0, (u_char *)cp);
+ __putlong(0, cp);
cp += sizeof(u_int32_t);
- __putshort(datalen, (u_char *)cp);
+ __putshort(datalen, cp);
cp += sizeof(u_int16_t);
if (datalen) {
bcopy(data, cp, datalen);
@@ -231,6 +231,8 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
break;
#endif /* ALLOW_UPDATES */
+ default:
+ return (-1);
}
return (cp - buf);
}
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c
index 7649462e563..81c4d3194d3 100644
--- a/lib/libc/net/res_query.c
+++ b/lib/libc/net/res_query.c
@@ -1,4 +1,4 @@
-/* $NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $ */
+/* $NetBSD: res_query.c,v 1.10 1996/02/02 15:22:34 mrg Exp $ */
/*-
* Copyright (c) 1988, 1993
@@ -56,9 +56,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_query.c,v 1.1 1993/06/01 09:42:14 vixie Exp vixie ";
+static char rcsid[] = "$Id: res_query.c,v 8.6 1995/06/29 09:26:28 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $";
+static char rcsid[] = "$NetBSD: res_query.c,v 1.10 1996/02/02 15:22:34 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -90,27 +90,33 @@ int h_errno;
* if no error is indicated and the answer count is nonzero.
* Return the size of the response on success, -1 on error.
* Error number is left in h_errno.
+ *
* Caller must parse answer and determine whether it answers the question.
*/
+int
res_query(name, class, type, answer, anslen)
- char *name; /* domain name */
+ const char *name; /* domain name */
int class, type; /* class and type of query */
u_char *answer; /* buffer to put answer */
int anslen; /* size of answer buffer */
{
- char buf[MAXPACKET];
- HEADER *hp;
+ u_char buf[MAXPACKET];
+ register HEADER *hp = (HEADER *) answer;
int n;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ hp->rcode = NOERROR; /* default */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
return (-1);
+ }
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query(%s, %d, %d)\n", name, class, type);
#endif
- n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL,
- buf, sizeof(buf));
+ n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
+ buf, sizeof(buf));
if (n <= 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
@@ -119,7 +125,7 @@ res_query(name, class, type, answer, anslen)
h_errno = NO_RECOVERY;
return (n);
}
- n = res_send(buf, n, (char *)answer, anslen);
+ n = res_send(buf, n, answer, anslen);
if (n < 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
@@ -174,10 +180,15 @@ res_search(name, class, type, answer, anslen)
int anslen; /* size of answer */
{
register char *cp, **domain;
- int dots, trailing_dot, ret, got_nodata, saved_herrno, tried_as_is;
+ HEADER *hp = (HEADER *) answer;
+ u_int dots;
+ int trailing_dot, ret, saved_herrno;
+ int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
return (-1);
+ }
got_nodata = 0;
errno = 0;
@@ -188,13 +199,13 @@ res_search(name, class, type, answer, anslen)
dots++;
}
trailing_dot = 0;
- if ((cp > name) && (*--cp == '.'))
+ if (cp > name && *--cp == '.')
trailing_dot++;
/*
* if there aren't any dots, it could be a user-level alias
*/
- if (!dots && (cp = __hostalias(name)))
+ if (!dots && (cp = __hostalias(name)) != NULL)
return (res_query(cp, class, type, answer, anslen));
/*
@@ -251,6 +262,13 @@ res_search(name, class, type, answer, anslen)
case HOST_NOT_FOUND:
/* keep trying */
break;
+ case TRY_AGAIN:
+ if (hp->rcode == SERVFAIL) {
+ /* try next search element, if any */
+ got_servfail++;
+ break;
+ }
+ /* FALLTHROUGH */
default:
/* anything else implies that we're done */
done++;
@@ -291,6 +309,8 @@ res_search(name, class, type, answer, anslen)
h_errno = saved_herrno;
else if (got_nodata)
h_errno = NO_DATA;
+ else if (got_servfail)
+ h_errno = TRY_AGAIN;
return (-1);
}
@@ -298,20 +318,25 @@ res_search(name, class, type, answer, anslen)
* Perform a call on res_query on the concatenation of name and domain,
* removing a trailing dot from name if domain is NULL.
*/
+int
res_querydomain(name, domain, class, type, answer, anslen)
- char *name, *domain;
+ const char *name, *domain;
int class, type; /* class and type of query */
u_char *answer; /* buffer to put answer */
int anslen; /* size of answer */
{
char nbuf[2*MAXDNAME+2];
- char *longname = nbuf;
+ const char *longname = nbuf;
int n;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_querydomain(%s, %s, %d, %d)\n",
- name, domain, class, type);
+ name, domain?domain:"<Nil>", class, type);
#endif
if (domain == NULL) {
/*
@@ -337,24 +362,30 @@ __hostalias(name)
{
register char *cp1, *cp2;
FILE *fp;
- char *file, *getenv(), *strcpy(), *strncpy();
+ char *file;
char buf[BUFSIZ];
static char abuf[MAXDNAME];
+ if (_res.options & RES_NOALIASES)
+ return (NULL);
file = getenv("HOSTALIASES");
if (file == NULL || (fp = fopen(file, "r")) == NULL)
return (NULL);
+ setbuf(fp, NULL);
buf[sizeof(buf) - 1] = '\0';
while (fgets(buf, sizeof(buf), fp)) {
- for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1);
+ for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
+ ;
if (!*cp1)
break;
*cp1 = '\0';
if (!strcasecmp(buf, name)) {
- while (isspace(*++cp1));
+ while (isspace(*++cp1))
+ ;
if (!*cp1)
break;
- for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2);
+ for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
+ ;
abuf[sizeof(abuf) - 1] = *cp2 = '\0';
(void)strncpy(abuf, cp1, sizeof(abuf) - 1);
fclose(fp);
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index e6083581805..f0e9b098b6e 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -1,9 +1,9 @@
-/* $NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $ */
+/* $NetBSD: res_send.c,v 1.5 1996/02/02 15:22:36 mrg Exp $ */
/*-
* Copyright (c) 1985, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,12 +14,12 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -56,12 +56,19 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_send.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
+static char rcsid[] = "$Id: res_send.c,v 8.7 1995/12/03 08:31:17 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $";
+static char rcsid[] = "$NetBSD: res_send.c,v 1.5 1996/02/02 15:22:36 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
+ /* change this to "0"
+ * if you talk to a lot
+ * of multi-homed SunOS
+ * ("broken") name servers.
+ */
+#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
+
/*
* Send query to name server and wait for reply.
*/
@@ -73,139 +80,335 @@ static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $";
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
+
#include <stdio.h>
+#include <netdb.h>
#include <errno.h>
#include <resolv.h>
-#include <unistd.h>
-#include <string.h>
+#if defined(BSD) && (BSD >= 199306)
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+#if defined(USE_OPTIONS_H)
+# include <../conf/options.h>
+#endif
+
+void _res_close __P((void));
static int s = -1; /* socket used for communications */
-static struct sockaddr no_addr;
-
-#ifndef FD_SET
-#define NFDBITS 32
-#define FD_SETSIZE 32
-#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
-#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
-#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
+static int connected = 0; /* is the socket connected */
+static int vc = 0; /* is the socket a virtual ciruit? */
+
+#define CAN_RECONNECT 1
+
+#ifndef DEBUG
+# define Dprint(cond, args) /*empty*/
+# define DprintQ(cond, args, query, size) /*empty*/
+# define Aerror(file, string, error, address) /*empty*/
+# define Perror(file, string, error) /*empty*/
+#else
+# define Dprint(cond, args) if (cond) {fprintf args;} else {}
+# define DprintQ(cond, args, query, size) if (cond) {\
+ fprintf args;\
+ __fp_nquery(query, size, stdout);\
+ } else {}
+ static void
+ Aerror(file, string, error, address)
+ FILE *file;
+ char *string;
+ int error;
+ struct sockaddr_in address;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s ([%s].%u): %s\n",
+ string,
+ inet_ntoa(address.sin_addr),
+ ntohs(address.sin_port),
+ strerror(error));
+ }
+ errno = save;
+ }
+ static void
+ Perror(file, string, error)
+ FILE *file;
+ char *string;
+ int error;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s: %s\n",
+ string, strerror(error));
+ }
+ errno = save;
+ }
#endif
-res_send(buf, buflen, answer, anslen)
- const char *buf;
+static res_send_qhook Qhook = NULL;
+static res_send_rhook Rhook = NULL;
+
+void
+res_send_setqhook(hook)
+ res_send_qhook hook;
+{
+
+ Qhook = hook;
+}
+
+void
+res_send_setrhook(hook)
+ res_send_rhook hook;
+{
+
+ Rhook = hook;
+}
+
+/* int
+ * res_isourserver(ina)
+ * looks up "ina" in _res.ns_addr_list[]
+ * returns:
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_isourserver(inp)
+ const struct sockaddr_in *inp;
+{
+ struct sockaddr_in ina;
+ register int ns, ret;
+
+ ina = *inp;
+ ret = 0;
+ for (ns = 0; ns < _res.nscount; ns++) {
+ register const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
+
+ if (srv->sin_family == ina.sin_family &&
+ srv->sin_port == ina.sin_port &&
+ (srv->sin_addr.s_addr == INADDR_ANY ||
+ srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
+ ret++;
+ break;
+ }
+ }
+ return (ret);
+}
+
+/* int
+ * res_nameinquery(name, type, class, buf, eom)
+ * look for (name,type,class) in the query section of packet (buf,eom)
+ * returns:
+ * -1 : format error
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_nameinquery(name, type, class, buf, eom)
+ const char *name;
+ register int type, class;
+ const u_char *buf, *eom;
+{
+ register const u_char *cp = buf + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf)->qdcount);
+
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ register int n, ttype, tclass;
+
+ n = dn_expand(buf, eom, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ttype = _getshort(cp); cp += INT16SZ;
+ tclass = _getshort(cp); cp += INT16SZ;
+ if (ttype == type &&
+ tclass == class &&
+ strcasecmp(tname, name) == 0)
+ return (1);
+ }
+ return (0);
+}
+
+/* int
+ * res_queriesmatch(buf1, eom1, buf2, eom2)
+ * is there a 1:1 mapping of (name,type,class)
+ * in (buf1,eom1) and (buf2,eom2)?
+ * returns:
+ * -1 : format error
+ * 0 : not a 1:1 mapping
+ * >0 : is a 1:1 mapping
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_queriesmatch(buf1, eom1, buf2, eom2)
+ const u_char *buf1, *eom1;
+ const u_char *buf2, *eom2;
+{
+ register const u_char *cp = buf1 + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf1)->qdcount);
+
+ if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
+ return (0);
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ register int n, ttype, tclass;
+
+ n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ttype = _getshort(cp); cp += INT16SZ;
+ tclass = _getshort(cp); cp += INT16SZ;
+ if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
+ return (0);
+ }
+ return (1);
+}
+
+int
+res_send(buf, buflen, ans, anssiz)
+ const u_char *buf;
int buflen;
- char *answer;
- int anslen;
+ u_char *ans;
+ int anssiz;
{
- register int n;
- int try, v_circuit, resplen, ns;
- int gotsomewhere = 0, connected = 0;
- int connreset = 0;
- u_short id, len;
- char *cp;
- fd_set dsmask;
- struct timeval timeout;
HEADER *hp = (HEADER *) buf;
- HEADER *anhp = (HEADER *) answer;
- u_int badns; /* XXX NSMAX can't exceed #/bits per this */
- struct iovec iov[2];
- int terrno = ETIMEDOUT;
- char junk[512];
-
-#ifdef DEBUG
- if ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY)) {
- printf(";; res_send()\n");
- __p_query(buf);
+ HEADER *anhp = (HEADER *) ans;
+ int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
+ register int n;
+ u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ /* errno should have been set by res_init() in this case. */
+ return (-1);
}
-#endif
- if (!(_res.options & RES_INIT))
- if (res_init() == -1) {
- return(-1);
- }
+ DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+ (stdout, ";; res_send()\n"), buf, buflen);
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
- id = hp->id;
+ gotsomewhere = 0;
+ connreset = 0;
+ terrno = ETIMEDOUT;
badns = 0;
+
/*
* Send request, RETRY times, or until successful
*/
for (try = 0; try < _res.retry; try++) {
for (ns = 0; ns < _res.nscount; ns++) {
- if (badns & (1<<ns))
- continue;
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- printf(";; Querying server (# %d) address = %s\n",
- ns+1,
- inet_ntoa(_res.nsaddr_list[ns].sin_addr));
-#endif
- usevc:
+ struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
+ same_ns:
+ if (badns & (1 << ns)) {
+ _res_close();
+ goto next_ns;
+ }
+
+ if (Qhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Qhook)(&nsap, &buf, &buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ done = 1;
+ break;
+ case res_nextns:
+ _res_close();
+ goto next_ns;
+ case res_done:
+ return (resplen);
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+ }
+
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; Querying server (# %d) address = %s\n",
+ ns + 1, inet_ntoa(nsap->sin_addr)));
+
if (v_circuit) {
- int truncated = 0;
+ int truncated;
+ struct iovec iov[2];
+ u_short len;
+ u_char *cp;
/*
* Use virtual circuit;
* at most one attempt per server.
*/
try = _res.retry;
- if (s < 0) {
- s = socket(AF_INET, SOCK_STREAM, 0);
+ truncated = 0;
+ if ((s < 0) || (!vc)) {
+ if (s >= 0)
+ _res_close();
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
terrno = errno;
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("socket (vc) failed");
-#endif
- continue;
+ Perror(stderr, "socket(vc)", errno);
+ return (-1);
}
- if (connect(s,
- (struct sockaddr *)&(_res.nsaddr_list[ns]),
- sizeof(struct sockaddr)) < 0) {
+ errno = 0;
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof(struct sockaddr)) < 0) {
terrno = errno;
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("connect failed");
-#endif
- (void) close(s);
- s = -1;
- continue;
+ Aerror(stderr, "connect/vc",
+ errno, *nsap);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
}
+ vc = 1;
}
/*
* Send length & message
*/
- len = htons((u_short)buflen);
+ putshort((u_short)buflen, (u_char*)&len);
iov[0].iov_base = (caddr_t)&len;
- iov[0].iov_len = sizeof(len);
- iov[1].iov_base = (char *)buf;
+ iov[0].iov_len = INT16SZ;
+ iov[1].iov_base = (caddr_t)buf;
iov[1].iov_len = buflen;
- if (writev(s, iov, 2) != sizeof(len) + buflen) {
+ if (writev(s, iov, 2) != (INT16SZ + buflen)) {
terrno = errno;
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("write failed");
-#endif
- (void) close(s);
- s = -1;
- continue;
+ Perror(stderr, "write failed", errno);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
}
/*
* Receive length & response
*/
- cp = answer;
- len = sizeof(short);
- while (len != 0 &&
- (n = read(s, (char *)cp, (int)len)) > 0) {
+ cp = ans;
+ len = INT16SZ;
+ while ((n = read(s, (char *)cp, (int)len)) > 0) {
cp += n;
- len -= n;
+ if ((len -= n) <= 0)
+ break;
}
if (n <= 0) {
terrno = errno;
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("read failed");
-#endif
- (void) close(s);
- s = -1;
+ Perror(stderr, "read failed", errno);
+ _res_close();
/*
* A long running process might get its TCP
* connection reset if the remote server was
@@ -217,35 +420,32 @@ res_send(buf, buflen, answer, anslen)
*/
if (terrno == ECONNRESET && !connreset) {
connreset = 1;
- ns--;
+ _res_close();
+ goto same_ns;
}
- continue;
+ _res_close();
+ goto next_ns;
}
- cp = answer;
- if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- fprintf(stderr,
- ";; response truncated\n");
-#endif
- len = anslen;
+ resplen = _getshort(ans);
+ if (resplen > anssiz) {
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; response truncated\n")
+ );
truncated = 1;
+ len = anssiz;
} else
len = resplen;
+ cp = ans;
while (len != 0 &&
- (n = read(s, (char *)cp, (int)len)) > 0) {
+ (n = read(s, (char *)cp, (int)len)) > 0) {
cp += n;
len -= n;
}
if (n <= 0) {
terrno = errno;
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("read failed");
-#endif
- (void) close(s);
- s = -1;
- continue;
+ Perror(stderr, "read(vc)", errno);
+ _res_close();
+ goto next_ns;
}
if (truncated) {
/*
@@ -253,10 +453,13 @@ res_send(buf, buflen, answer, anslen)
* so connection stays in synch.
*/
anhp->tc = 1;
- len = resplen - anslen;
+ len = resplen - anssiz;
while (len != 0) {
- n = (len > sizeof(junk) ?
- sizeof(junk) : len);
+ char junk[PACKETSZ];
+
+ n = (len > sizeof(junk)
+ ? sizeof(junk)
+ : len);
if ((n = read(s, junk, n)) > 0)
len -= n;
else
@@ -267,19 +470,26 @@ res_send(buf, buflen, answer, anslen)
/*
* Use datagrams.
*/
- if (s < 0) {
- s = socket(AF_INET, SOCK_DGRAM, 0);
+ struct timeval timeout;
+ fd_set dsmask;
+ struct sockaddr_in from;
+ int fromlen;
+
+ if ((s < 0) || vc) {
+ if (vc)
+ _res_close();
+ s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
- terrno = errno;
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("socket (dg) failed");
+#if !CAN_RECONNECT
+ bad_dg_sock:
#endif
- continue;
+ terrno = errno;
+ Perror(stderr, "socket(dg)", errno);
+ return (-1);
}
+ connected = 0;
}
/*
- * I'm tired of answering this question, so:
* On a 4.3BSD+ machine (client and server,
* actually), sending to a nameserver datagram
* port with no nameserver will cause an
@@ -296,29 +506,27 @@ res_send(buf, buflen, answer, anslen)
*/
if (_res.nscount == 1 || (try == 0 && ns == 0)) {
/*
- * Don't use connect if we might
- * still receive a response
- * from another server.
+ * Connect only if we are sure we won't
+ * receive a response from another server.
*/
- if (connected == 0) {
- if (connect(s,
- (struct sockaddr *)
- &_res.nsaddr_list[ns],
- sizeof(struct sockaddr)) < 0) {
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("connect");
-#endif
- continue;
+ if (!connected) {
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof(struct sockaddr)
+ ) < 0) {
+ Aerror(stderr,
+ "connect(dg)",
+ errno, *nsap);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
}
connected = 1;
}
- if (send(s, buf, buflen, 0) != buflen) {
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("send");
-#endif
- continue;
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
+ Perror(stderr, "send", errno);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
}
} else {
/*
@@ -326,18 +534,36 @@ res_send(buf, buflen, answer, anslen)
* for responses from more than one server.
*/
if (connected) {
- (void) connect(s, &no_addr,
- sizeof(no_addr));
+#if CAN_RECONNECT
+ struct sockaddr_in no_addr;
+
+ no_addr.sin_family = AF_INET;
+ no_addr.sin_addr.s_addr = INADDR_ANY;
+ no_addr.sin_port = 0;
+ (void) connect(s,
+ (struct sockaddr *)
+ &no_addr,
+ sizeof(no_addr));
+#else
+ int s1 = socket(PF_INET, SOCK_DGRAM,0);
+ if (s1 < 0)
+ goto bad_dg_sock;
+ (void) dup2(s1, s);
+ (void) close(s1);
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; new DG socket\n"))
+#endif
connected = 0;
+ errno = 0;
}
- if (sendto(s, buf, buflen, 0,
- (struct sockaddr *)&_res.nsaddr_list[ns],
- sizeof(struct sockaddr)) != buflen) {
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("sendto");
-#endif
- continue;
+ if (sendto(s, (char*)buf, buflen, 0,
+ (struct sockaddr *)nsap,
+ sizeof(struct sockaddr))
+ != buflen) {
+ Aerror(stderr, "sendto", errno, *nsap);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
}
}
@@ -350,106 +576,157 @@ res_send(buf, buflen, answer, anslen)
if ((long) timeout.tv_sec <= 0)
timeout.tv_sec = 1;
timeout.tv_usec = 0;
-wait:
+ wait:
FD_ZERO(&dsmask);
FD_SET(s, &dsmask);
n = select(s+1, &dsmask, (fd_set *)NULL,
- (fd_set *)NULL, &timeout);
+ (fd_set *)NULL, &timeout);
if (n < 0) {
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("select");
-#endif
- continue;
+ Perror(stderr, "select", errno);
+ _res_close();
+ goto next_ns;
}
if (n == 0) {
/*
* timeout
*/
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- printf(";; timeout\n");
-#endif
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; timeout\n"));
gotsomewhere = 1;
- continue;
+ _res_close();
+ goto next_ns;
}
- if ((resplen = recv(s, answer, anslen, 0)) <= 0) {
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- perror("recvfrom");
-#endif
- continue;
+ errno = 0;
+ fromlen = sizeof(struct sockaddr_in);
+ resplen = recvfrom(s, (char*)ans, anssiz, 0,
+ (struct sockaddr *)&from, &fromlen);
+ if (resplen <= 0) {
+ Perror(stderr, "recvfrom", errno);
+ _res_close();
+ goto next_ns;
}
gotsomewhere = 1;
- if (id != anhp->id) {
+ if (hp->id != anhp->id) {
/*
- * response from old query, ignore it
+ * response from old query, ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
*/
-#ifdef DEBUG
- if ((_res.options & RES_DEBUG) ||
- (_res.pfcode & RES_PRF_REPLY)) {
- printf(";; old answer:\n");
- __p_query(answer);
- }
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer:\n"),
+ ans, resplen);
+ goto wait;
+ }
+#if CHECK_SRVR_ADDR
+ if (!(_res.options & RES_INSECURE1) &&
+ !res_isourserver(&from)) {
+ /*
+ * response from wrong server? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; not our server:\n"),
+ ans, resplen);
+ goto wait;
+ }
#endif
+ if (!(_res.options & RES_INSECURE2) &&
+ !res_queriesmatch(buf, buf + buflen,
+ ans, ans + anssiz)) {
+ /*
+ * response contains wrong query? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; wrong query name:\n"),
+ ans, resplen);
goto wait;
}
- if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP ||
+ if (anhp->rcode == SERVFAIL ||
+ anhp->rcode == NOTIMP ||
anhp->rcode == REFUSED) {
-#ifdef DEBUG
- if (_res.options & RES_DEBUG) {
- printf("server rejected query:\n");
- __p_query(answer);
- }
-#endif
- badns |= (1<<ns);
- continue;
+ DprintQ(_res.options & RES_DEBUG,
+ (stdout, "server rejected query:\n"),
+ ans, resplen);
+ badns |= (1 << ns);
+ _res_close();
+ /* don't retry if called from dig */
+ if (!_res.pfcode)
+ goto next_ns;
}
if (!(_res.options & RES_IGNTC) && anhp->tc) {
/*
* get rest of answer;
* use TCP with same server.
*/
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- printf(";; truncated answer\n");
-#endif
- (void) close(s);
- s = -1;
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; truncated answer\n"));
v_circuit = 1;
- goto usevc;
+ _res_close();
+ goto same_ns;
}
- }
-#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- printf(";; got answer:\n");
- if ((_res.options & RES_DEBUG) ||
- (_res.pfcode & RES_PRF_REPLY))
- __p_query(answer);
-#endif
+ } /*if vc/dg*/
+ Dprint((_res.options & RES_DEBUG) ||
+ ((_res.pfcode & RES_PRF_REPLY) &&
+ (_res.pfcode & RES_PRF_HEAD1)),
+ (stdout, ";; got answer:\n"));
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ""),
+ ans, resplen);
/*
* If using virtual circuits, we assume that the first server
- * is preferred * over the rest (i.e. it is on the local
+ * is preferred over the rest (i.e. it is on the local
* machine) and only keep that one open.
* If we have temporarily opened a virtual circuit,
* or if we haven't been asked to keep a socket open,
* close the socket.
*/
- if ((v_circuit &&
- ((_res.options & RES_USEVC) == 0 || ns != 0)) ||
- (_res.options & RES_STAYOPEN) == 0) {
- (void) close(s);
- s = -1;
+ if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
+ !(_res.options & RES_STAYOPEN)) {
+ _res_close();
+ }
+ if (Rhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Rhook)(nsap, buf, buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ case res_done:
+ done = 1;
+ break;
+ case res_nextns:
+ _res_close();
+ goto next_ns;
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+
}
return (resplen);
- }
- }
- if (s >= 0) {
- (void) close(s);
- s = -1;
- }
- if (v_circuit == 0)
- if (gotsomewhere == 0)
+ next_ns: ;
+ } /*foreach ns*/
+ } /*foreach retry*/
+ _res_close();
+ if (!v_circuit)
+ if (!gotsomewhere)
errno = ECONNREFUSED; /* no nameservers found */
else
errno = ETIMEDOUT; /* no answer obtained */
@@ -465,10 +742,13 @@ wait:
*
* This routine is not expected to be user visible.
*/
+void
_res_close()
{
- if (s != -1) {
+ if (s >= 0) {
(void) close(s);
s = -1;
+ connected = 0;
+ vc = 0;
}
}
diff --git a/lib/libc/net/resolver.3 b/lib/libc/net/resolver.3
index 99abe17f036..07bc10c393a 100644
--- a/lib/libc/net/resolver.3
+++ b/lib/libc/net/resolver.3
@@ -1,4 +1,4 @@
-.\" $NetBSD: resolver.3,v 1.5 1995/02/25 06:21:02 cgd Exp $
+.\" $NetBSD: resolver.3,v 1.6 1996/02/02 15:22:37 mrg Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -333,6 +333,7 @@ see
.%T RFC1033 ,
.%T RFC1034 ,
.%T RFC1035 ,
+.%T RFC1535 ,
.%T RFC974
.Rs
.%T "Name Server Operations Guide for BIND"
diff --git a/lib/libc/net/sethostent.c b/lib/libc/net/sethostent.c
index 00f64996950..df58b1bc928 100644
--- a/lib/libc/net/sethostent.c
+++ b/lib/libc/net/sethostent.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $ */
+/* $NetBSD: sethostent.c,v 1.5 1996/02/02 15:22:39 mrg Exp $ */
/*
* Copyright (c) 1985, 1993
@@ -36,8 +36,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: sethostent.c,v 8.3 1995/06/29 09:26:28 vixie Exp ";
#else
-static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $";
+static char rcsid[] = "$NetBSD: sethostent.c,v 1.5 1996/02/02 15:22:39 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -49,7 +50,11 @@ static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $
void
sethostent(stayopen)
+ int stayopen;
{
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
if (stayopen)
_res.options |= RES_STAYOPEN | RES_USEVC;
}