summaryrefslogtreecommitdiffstats
path: root/lib/libc/net
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1995-08-20 20:03:06 +0000
committerpeter <peter@FreeBSD.org>1995-08-20 20:03:06 +0000
commitbbe6ab41603ea223c7c921bd48586ed795917870 (patch)
tree32821775fcd4108257c3d49593dadeb5a5f18b17 /lib/libc/net
parent2dd1919d1c22bd3dc75ab1064352572d401b1ab9 (diff)
downloadFreeBSD-src-bbe6ab41603ea223c7c921bd48586ed795917870.zip
FreeBSD-src-bbe6ab41603ea223c7c921bd48586ed795917870.tar.gz
Update the resolver part of libc to bind-4.9.3-beta24 level (from beta9p1)
Note that this was done by selective patching from diffs, to not conflict with the 4.4bsd base code.. This was *not* a trivial task.. I have been testing this code (apart from cosmetic changes) in my libc for a while now. Obtained from: Paul Vixie <paul@vix.com>
Diffstat (limited to 'lib/libc/net')
-rw-r--r--lib/libc/net/Makefile.inc1
-rw-r--r--lib/libc/net/gethostbydns.c131
-rw-r--r--lib/libc/net/herror.c17
-rw-r--r--lib/libc/net/res_config.h7
-rw-r--r--lib/libc/net/res_debug.c141
-rw-r--r--lib/libc/net/res_init.c108
-rw-r--r--lib/libc/net/res_mkquery.c21
-rw-r--r--lib/libc/net/res_query.c67
-rw-r--r--lib/libc/net/res_send.c142
9 files changed, 420 insertions, 215 deletions
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc
index 4bcd682..a3eda64 100644
--- a/lib/libc/net/Makefile.inc
+++ b/lib/libc/net/Makefile.inc
@@ -3,6 +3,7 @@
# machine-independent net sources
.PATH: ${.CURDIR}/${MACHINE}/net ${.CURDIR}/net
+CFLAGS+= -I${.CURDIR}/net
SRCS+= gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
getproto.c getprotoent.c getprotoname.c getservbyname.c \
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c
index 6db04f9..cf3455a 100644
--- a/lib/libc/net/gethostbydns.c
+++ b/lib/libc/net/gethostbydns.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp $";
+static char rcsid[] = "$Id: gethostbydns.c,v 1.4 1995/05/30 05:40:43 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -61,16 +61,16 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <string.h>
#include <netdb.h>
#include <resolv.h>
-#include <stdio.h>
#include <ctype.h>
#include <errno.h>
-#include <string.h>
#include <syslog.h>
-#define BYADDR 0
-#define BYNAME 1
+#include <res_config.h>
#define MAXALIASES 35
#define MAXADDRS 35
@@ -78,7 +78,7 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp
#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
static const char AskedForGot[] =
- "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
+ "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
static char *h_addr_ptrs[MAXADDRS + 1];
@@ -87,8 +87,6 @@ static char *host_aliases[MAXALIASES];
static char hostbuf[8*1024];
static struct in_addr host_addr;
static FILE *hostf = NULL;
-static char hostaddr[MAXADDRS];
-static char *host_addrs[2];
static int stayopen = 0;
#if PACKETSZ > 1024
@@ -109,6 +107,24 @@ typedef union {
extern int h_errno;
+#ifdef DEBUG
+static void
+dprintf(msg, num)
+ char *msg;
+ int num;
+{
+ if (_res.options & RES_DEBUG) {
+ int save = errno;
+
+ printf(msg, num);
+ errno = save;
+ }
+}
+#else
+# define dprintf(msg, num) /*nada*/
+#endif
+
+
#ifdef RESOLVSORT
static void
addrsort(ap, num)
@@ -122,7 +138,7 @@ addrsort(ap, num)
p = ap;
for (i = 0; i < num; i++, p++) {
- for (j = 0 ; j < _res.nsort; j++)
+ for (j = 0 ; (unsigned)j < _res.nsort; j++)
if (_res.sort_list[j].addr.s_addr ==
(((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
break;
@@ -240,7 +256,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
cp += n;
if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
+ "gethostby*.gethostanswer: asked for \"%s\", got CNAME for \"%s\"",
host.h_name, bp);
continue; /* XXX - had_error++ ? */
}
@@ -262,9 +278,12 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
continue;
}
if (type != qtype) {
+ /* CNAME->PTR should not cause a log message. */
+ if (!(qtype == T_PTR && type == T_CNAME))
syslog(LOG_NOTICE|LOG_AUTH,
- "gethostby*.getanswer: asked for type %d(%s), got %d(%s)",
- qtype, qname, type, bp);
+ "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
+ qname, p_class(qclass), p_type(qtype),
+ p_type(type));
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -297,6 +316,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
break;
#else
host.h_name = bp;
+ h_errno = NETDB_SUCCESS;
return (&host);
#endif
case T_A:
@@ -327,14 +347,13 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
bp += sizeof(align) - ((u_long)bp % sizeof(align));
if (bp + n >= &hostbuf[sizeof hostbuf]) {
- if (_res.options & RES_DEBUG)
- printf("size (%d) too big\n", n);
+ dprintf("size (%d) too big\n", n);
had_error++;
continue;
}
if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
- if (_res.options & RES_DEBUG && !toobig++)
- printf("Too many addresses (%d)\n",
+ if (!toobig++)
+ dprintf("Too many addresses (%d)\n",
MAXADDRS);
cp += n;
continue;
@@ -344,7 +363,9 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
cp += n;
break;
default:
- abort();
+ dprintf("Impossible condition (type=%d)\n", type);
+ h_errno = NO_RECOVERY;
+ return (NULL);
} /*switch*/
if (!had_error)
haveanswer++;
@@ -367,6 +388,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
strcpy(bp, qname);
host.h_name = bp;
}
+ h_errno = NETDB_SUCCESS;
return (&host);
} else {
h_errno = TRY_AGAIN;
@@ -382,6 +404,19 @@ _gethostbydnsname(name)
register const char *cp;
int n;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+
+ /*
+ * if there aren't any dots, it could be a user-level alias.
+ * this is also done in res_query() since we are not the only
+ * function that looks up host names.
+ */
+ if (!strchr(name, '.') && (cp = __hostalias(name)))
+ name = cp;
+
/*
* disallow names consisting only of digits/dots, unless
* they end in a dot.
@@ -400,7 +435,9 @@ _gethostbydnsname(name)
h_errno = HOST_NOT_FOUND;
return (NULL);
}
- host.h_name = (char *)name;
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ host.h_name = hostbuf;
host.h_aliases = host_aliases;
host_aliases[0] = NULL;
host.h_addrtype = AF_INET;
@@ -415,8 +452,7 @@ _gethostbydnsname(name)
}
if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
- if (_res.options & RES_DEBUG)
- printf("res_search failed\n");
+ dprintf("res_search failed (%d)\n", n);
return (NULL);
}
return (gethostanswer(&buf, n, name, C_IN, T_A));
@@ -431,33 +467,70 @@ _gethostbydnsaddr(addr, len, type)
querybuf buf;
register struct hostent *hp;
char qbuf[MAXDNAME+1];
- int o_res_options = _res.options;
+#ifdef SUNSECURITY
+ register struct hostent *rhp;
+ char **haddr;
+ u_long old_options;
+ char hname2[MAXDNAME+1];
+#endif /*SUNSECURITY*/
- if (type != AF_INET)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (type != AF_INET) {
+ errno = EAFNOSUPPORT;
+ h_errno = NETDB_INTERNAL;
return (NULL);
+ }
(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
((unsigned)addr[3] & 0xff),
((unsigned)addr[2] & 0xff),
((unsigned)addr[1] & 0xff),
((unsigned)addr[0] & 0xff));
- _res.options |= RES_RECURSE;
n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
- _res.options = o_res_options;
if (n < 0) {
- if (_res.options & RES_DEBUG)
- printf("res_query failed\n");
+ dprintf("res_query failed (%d)\n", n);
return (NULL);
}
if (!(hp = gethostanswer(&buf, n, qbuf, C_IN, T_PTR)))
+ return (NULL); /* h_errno was set by gethostanswer() */
+#ifdef SUNSECURITY
+ /*
+ * turn off search as the name should be absolute,
+ * 'localhost' should be matched by defnames
+ */
+ strncpy(hname2, hp->h_name, MAXDNAME);
+ hname2[MAXDNAME] = '\0';
+ old_options = _res.options;
+ _res.options &= ~RES_DNSRCH;
+ _res.options |= RES_DEFNAMES;
+ if (!(rhp = gethostbyname(hname2))) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: No A record for %s (verifying [%s])",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ _res.options = old_options;
+ h_errno = HOST_NOT_FOUND;
return (NULL);
+ }
+ _res.options = old_options;
+ for (haddr = rhp->h_addr_list; *haddr; haddr++)
+ if (!memcmp(*haddr, addr, INADDRSZ))
+ break;
+ if (!*haddr) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: A record of %s != PTR record [%s]",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+#endif /*SUNSECURITY*/
hp->h_addrtype = type;
hp->h_length = len;
h_addr_ptrs[0] = (char *)&host_addr;
h_addr_ptrs[1] = NULL;
host_addr = *(struct in_addr *)addr;
-#if BSD < 43 && !defined(h_addr) /* new-style hostent structure */
- hp->h_addr = h_addr_ptrs[0];
-#endif
+ h_errno = NETDB_SUCCESS;
return (hp);
}
diff --git a/lib/libc/net/herror.c b/lib/libc/net/herror.c
index c9135c3..9b94ee4 100644
--- a/lib/libc/net/herror.c
+++ b/lib/libc/net/herror.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: herror.c,v 1.1.1.1 1994/05/27 04:57:15 rgrimes Exp $";
+static char rcsid[] = "$Id: herror.c,v 1.2 1995/05/30 05:40:49 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -62,8 +62,8 @@ static char rcsid[] = "$Id: herror.c,v 1.1.1.1 1994/05/27 04:57:15 rgrimes 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 */
@@ -92,8 +92,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";
@@ -101,9 +100,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/res_config.h b/lib/libc/net/res_config.h
new file mode 100644
index 0000000..3afa321
--- /dev/null
+++ b/lib/libc/net/res_config.h
@@ -0,0 +1,7 @@
+#define DEBUG /* enable debugging code (needed for dig) */
+#undef ALLOW_T_UNSPEC /* enable the "unspec" RR type for old athena */
+#define RESOLVSORT /* allow sorting of addresses in gethostbyname */
+#undef RFC1535 /* comply with RFC1535 */
+#undef ALLOW_UPDATES /* destroy your system security */
+#undef USELOOPBACK /* res_init() bind to localhost */
+#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
index 78b11c9..550f552 100644
--- a/lib/libc/net/res_debug.c
+++ b/lib/libc/net/res_debug.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_debug.c,v 1.2 1994/09/25 02:12:34 pst Exp $";
+static char rcsid[] = "$Id: res_debug.c,v 1.3 1995/05/30 05:40:54 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -65,13 +65,17 @@ static char rcsid[] = "$Id: res_debug.c,v 1.2 1994/09/25 02:12:34 pst Exp $";
#include <stdio.h>
#include <resolv.h>
#include <string.h>
+#include <netdb.h>
+
+#include <res_config.h>
+
const char *_res_opcodes[] = {
"QUERY",
"IQUERY",
"CQUERYM",
- "CQUERYU",
- "4",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
"5",
"6",
"7",
@@ -104,12 +108,13 @@ const char *_res_resultcodes[] = {
"NOCHANGE",
};
-static char retbuf[16];
-
+/* XXX: we should use getservbyport() instead. */
static const char *
dewks(wks)
int wks;
{
+ static char nbuf[20];
+
switch (wks) {
case 5: return "rje";
case 7: return "echo";
@@ -157,14 +162,17 @@ dewks(wks)
case 161: return "snmp";
case 162: return "snmp-trap";
case 170: return "print-srv";
- default: (void) sprintf(retbuf, "%d", wks); return (retbuf);
+ default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
}
}
+/* 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";
@@ -178,13 +186,13 @@ deproto(protonum)
case 12: return "pup";
case 16: return "chaos";
case 17: return "udp";
- default: (void) sprintf(retbuf, "%d", protonum); return (retbuf);
+ default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
}
}
static const u_char *
-do_rrset(msg, cp, cnt, pflag, file, hs)
- int cnt, pflag;
+do_rrset(msg, len, cp, cnt, pflag, file, hs)
+ int cnt, pflag, len;
const u_char *cp, *msg;
const char *hs;
FILE *file;
@@ -201,8 +209,19 @@ do_rrset(msg, cp, cnt, pflag, file, hs)
((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
fprintf(file, hs);
while (--n >= 0) {
+ if ((!_res.pfcode) || sflag) {
cp = p_rr(cp, msg, file);
- if ((cp - msg) > PACKETSZ)
+ } else {
+ unsigned int dlen;
+ cp += __dn_skipname(cp, cp + MAXCDNAME);
+ cp += INT16SZ;
+ cp += INT16SZ;
+ cp += INT32SZ;
+ dlen = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ cp += dlen;
+ }
+ if ((cp - msg) > len)
return (NULL);
}
if ((!_res.pfcode) ||
@@ -253,6 +272,9 @@ __fp_nquery(msg, len, file)
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
@@ -282,8 +304,6 @@ __fp_nquery(msg, len, 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));
@@ -304,7 +324,7 @@ __fp_nquery(msg, len, file)
while (--n >= 0) {
fprintf(file,";;\t");
TruncTest(cp);
- cp = p_cdname(cp, msg, file);
+ cp = p_cdnname(cp, msg, len, file);
ErrorTest(cp);
TruncTest(cp);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
@@ -323,7 +343,7 @@ __fp_nquery(msg, len, file)
* Print authoritative answer records
*/
TruncTest(cp);
- cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
+ cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
";; ANSWERS:\n");
ErrorTest(cp);
@@ -331,7 +351,7 @@ __fp_nquery(msg, len, file)
* print name server records
*/
TruncTest(cp);
- cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
+ cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
";; AUTHORITY RECORDS:\n");
ErrorTest(cp);
@@ -339,7 +359,7 @@ __fp_nquery(msg, len, file)
/*
* 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");
ErrorTest(cp);
return;
@@ -393,7 +413,7 @@ __p_fqname(cp, msg, file)
FILE *file;
{
char name[MAXDNAME];
- int n, len;
+ int n;
if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
return (NULL);
@@ -422,6 +442,10 @@ __p_rr(cp, msg, file)
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((u_char*)cp);
@@ -434,7 +458,7 @@ __p_rr(cp, msg, file)
cp += INT16SZ;
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));
@@ -476,37 +500,46 @@ __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((u_char*)cp); cp += INT32SZ;
- fprintf(file,"\t\t\t%lu\t; serial\n", t);
+ fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
t = _getlong((u_char*)cp); cp += INT32SZ;
- 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((u_char*)cp); cp += INT32SZ;
- 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((u_char*)cp); cp += INT32SZ;
- 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((u_char*)cp); cp += INT32SZ;
- 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:
@@ -514,7 +547,18 @@ __p_rr(cp, msg, file)
case T_RT:
fprintf(file,"\t%d ", _getshort((u_char*)cp));
cp += INT16SZ;
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ break;
+
+ case T_PX:
+ fprintf(file, "\t%d ", _getshort((u_char*)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:
@@ -524,7 +568,7 @@ __p_rr(cp, msg, file)
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
@@ -546,9 +590,11 @@ __p_rr(cp, msg, file)
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:
@@ -628,8 +674,6 @@ __p_rr(cp, msg, file)
return (cp);
}
-static char nbuf[40];
-
/*
* Return a string for the type
*/
@@ -637,6 +681,8 @@ const char *
__p_type(type)
int type;
{
+ static char nbuf[20];
+
switch (type) {
case T_A: return "A";
case T_NS: return "NS";
@@ -652,12 +698,19 @@ __p_type(type)
case T_MINFO: return "MINFO";
case T_MX: return "MX";
case T_TXT: return "TXT";
- case T_NSAP: return "NSAP";
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";
@@ -679,10 +732,12 @@ const char *
__p_class(class)
int class;
{
+ static char nbuf[20];
+
switch (class) {
- case C_IN: return("IN");
- case C_HS: return("HS");
- case C_ANY: return("ANY");
+ case C_IN: return "IN";
+ case C_HS: return "HS";
+ case C_ANY: return "ANY";
default: (void)sprintf(nbuf, "%d", class); return (nbuf);
}
}
@@ -694,12 +749,14 @@ 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";
@@ -707,7 +764,8 @@ __p_option(option)
case RES_DNSRCH: return "dnsrch";
case RES_INSECURE1: return "insecure1";
case RES_INSECURE2: return "insecure2";
- default: sprintf(nbuf, "?0x%x?", option); return nbuf;
+ default: sprintf(nbuf, "?0x%lx?", (u_long)option);
+ return (nbuf);
}
}
@@ -718,6 +776,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 347e5b6..c6292c8 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -53,11 +53,12 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
-static char rcsid[] = "$Id: res_init.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
+static char rcsid[] = "$Id: res_init.c,v 1.4 1995/05/30 05:40:55 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
@@ -69,9 +70,13 @@ static char rcsid[] = "$Id: res_init.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
#include <stdlib.h>
#include <string.h>
+#include <res_config.h>
+
static void res_setoptions __P((char *, char *));
#ifdef RESOLVSORT
+static const char sort_mask[] = "/&";
+#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
static u_int32_t net_mask __P((struct in_addr));
#endif
@@ -102,11 +107,12 @@ struct __res_state _res;
*
* Return 0 if completes successfully, -1 on error
*/
+int
res_init()
{
register FILE *fp;
register char *cp, **pp;
- register int n, dots;
+ register int n;
char buf[BUFSIZ];
int nserv = 0; /* number of nameserver records read from file */
int haveenv = 0;
@@ -115,9 +121,12 @@ res_init()
int nsort = 0;
char *net;
#endif
+#ifndef RFC1535
+ int dots;
+#endif
/*
- * These four fields used to be statically initialized. This made
+ * These three fields used to be statically initialized. This made
* it hard to use this code in a shared library. It is necessary,
* now that we're doing dynamic initialization here, that we preserve
* the old semantics: if an application modifies one of these three
@@ -128,14 +137,27 @@ res_init()
* will follow. Zero for any of these fields would make no sense,
* so one can safely assume that the applications were already getting
* unexpected results.
+ *
+ * _res.options is tricky since some apps were known to diddle the bits
+ * before res_init() was first called. We can't replicate that semantic
+ * with dynamic initialization (they may have turned bits off that are
+ * set in RES_DEFAULT). Our solution is to declare such applications
+ * "broken". They could fool us by setting RES_INIT but none do (yet).
*/
if (!_res.retrans)
_res.retrans = RES_TIMEOUT;
if (!_res.retry)
_res.retry = 4;
- if (!_res.options)
+ if (!(_res.options & RES_INIT))
_res.options = RES_DEFAULT;
+ /*
+ * This one used to initialize implicitly to zero, so unless the app
+ * has set it to something in particular, we can randomize it now.
+ */
+ if (!_res.id)
+ _res.id = res_randomid();
+
#ifdef USELOOPBACK
_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
@@ -181,14 +203,19 @@ res_init()
*pp++ = 0;
}
+#define MATCH(line, name) \
+ (!strncmp(line, name, sizeof(name) - 1) && \
+ (line[sizeof(name) - 1] == ' ' || \
+ line[sizeof(name) - 1] == '\t'))
+
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
- if ((*buf == ';') || (*buf == '#'))
+ if (*buf == ';' || *buf == '#')
continue;
/* read default domain name */
- if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
+ if (MATCH(buf, "domain")) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("domain") - 1;
@@ -204,7 +231,7 @@ res_init()
continue;
}
/* set search list */
- if (!strncmp(buf, "search", sizeof("search") - 1)) {
+ if (MATCH(buf, "search")) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("search") - 1;
@@ -223,9 +250,7 @@ res_init()
cp = _res.defdname;
pp = _res.dnsrch;
*pp++ = cp;
- for (n = 0;
- *cp && pp < _res.dnsrch + MAXDNSRCH;
- cp++) {
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
if (*cp == ' ' || *cp == '\t') {
*cp = 0;
n = 1;
@@ -243,8 +268,7 @@ res_init()
continue;
}
/* read nameservers to query */
- if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
- nserv < MAXNS) {
+ if (MATCH(buf, "nameserver") && nserv < MAXNS) {
struct in_addr a;
cp = buf + sizeof("nameserver") - 1;
@@ -260,7 +284,7 @@ res_init()
continue;
}
#ifdef RESOLVSORT
- if (!strncmp(buf, "sortlist", sizeof("sortlist") -1)) {
+ if (MATCH(buf, "sortlist")) {
struct in_addr a;
cp = buf + sizeof("sortlist") - 1;
@@ -270,17 +294,18 @@ res_init()
if (*cp == '\0' || *cp == '\n' || *cp == ';')
break;
net = cp;
- while (*cp && *cp != '/' &&
+ while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
if (inet_aton(net, &a)) {
_res.sort_list[nsort].addr = a;
- if (n == '/') {
+ if (ISSORTMASK(n)) {
*cp++ = n;
net = cp;
- while (*cp && isascii(*cp) && !isspace(*cp))
+ while (*cp && *cp != ';' &&
+ isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
@@ -296,12 +321,12 @@ res_init()
}
nsort++;
}
- *cp++ = n;
+ *cp = n;
}
continue;
}
#endif
- if (!strncmp(buf, "options", sizeof("options") -1)) {
+ if (MATCH(buf, "options")) {
res_setoptions(buf + sizeof("options") - 1, "conf");
continue;
}
@@ -312,13 +337,11 @@ res_init()
_res.nsort = nsort;
#endif
(void) fclose(fp);
- } /*if(fopen)*/
- if (_res.defdname[0] == 0) {
- if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
- (cp = strchr(buf, '.'))) {
- (void)strcpy(_res.defdname, cp + 1);
- }
}
+ if (_res.defdname[0] == 0 &&
+ gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+ (cp = strchr(buf, '.')) != NULL)
+ strcpy(_res.defdname, cp + 1);
/* find components of local domain that might be searched */
if (havesearch == 0) {
@@ -333,32 +356,30 @@ res_init()
cp = _res.defdname;
while (pp < _res.dnsrch + MAXDFLSRCH) {
- if (dots < LOCALDOMAINPARTS) {
+ if (dots < LOCALDOMAINPARTS)
break;
- }
cp = strchr(cp, '.') + 1; /* we know there is one */
*pp++ = cp;
dots--;
}
*pp = NULL;
+#ifdef DEBUG
if (_res.options & RES_DEBUG) {
printf(";; res_init()... default dnsrch list:\n");
- for (pp = _res.dnsrch; *pp; pp++) {
+ for (pp = _res.dnsrch; *pp; pp++)
printf(";;\t%s\n", *pp);
- }
printf(";;\t..END..\n");
}
+#endif /* DEBUG */
#endif /*!RFC1535*/
}
- if ((cp = getenv("RES_OPTIONS")) != NULL) {
+ if ((cp = getenv("RES_OPTIONS")) != NULL)
res_setoptions(cp, "env");
- }
_res.options |= RES_INIT;
return (0);
}
-
static void
res_setoptions(options, source)
char *options, *source;
@@ -366,10 +387,11 @@ res_setoptions(options, source)
char *cp = options;
int i;
- if (_res.options & RES_DEBUG) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
printf(";; res_setoptions(\"%s\", \"%s\")...\n",
options, source);
- }
+#endif
while (*cp) {
/* skip leading and inner runs of spaces */
while (*cp == ' ' || *cp == '\t')
@@ -381,16 +403,19 @@ res_setoptions(options, source)
_res.ndots = i;
else
_res.ndots = RES_MAXNDOTS;
- if (_res.options & RES_DEBUG) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
printf(";;\tndots=%d\n", _res.ndots);
- }
+#endif
} else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
+#ifdef DEBUG
if (!(_res.options & RES_DEBUG)) {
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
options, source);
_res.options |= RES_DEBUG;
}
printf(";;\tdebug\n");
+#endif
} else {
/* XXX - print a warning here? */
}
@@ -401,6 +426,7 @@ res_setoptions(options, source)
}
#ifdef RESOLVSORT
+/* XXX - should really support CIDR which means explicit masks always. */
static u_int32_t
net_mask(in) /* XXX - should really use system's version of this */
struct in_addr in;
@@ -411,7 +437,15 @@ net_mask(in) /* XXX - should really use system's version of this */
return (htonl(IN_CLASSA_NET));
else if (IN_CLASSB(i))
return (htonl(IN_CLASSB_NET));
- else
- return (htonl(IN_CLASSC_NET));
+ return (htonl(IN_CLASSC_NET));
}
#endif
+
+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 7788d16..979abbd 100644
--- a/lib/libc/net/res_mkquery.c
+++ b/lib/libc/net/res_mkquery.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_mkquery.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
+static char rcsid[] = "$Id: res_mkquery.c,v 1.4 1995/05/30 05:40:56 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -63,6 +63,10 @@ static char rcsid[] = "$Id: res_mkquery.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
#include <stdio.h>
#include <resolv.h>
#include <string.h>
+#include <netdb.h>
+
+#include <res_config.h>
+
/*
* Form all types of queries.
@@ -82,12 +86,20 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
register HEADER *hp;
register u_char *cp;
register int n;
+#ifdef ALLOW_UPDATES
struct rrec *newrr = (struct rrec *) newrr_in;
+#endif
u_char *dnptrs[20], **dpp, **lastdnptr;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_mkquery(%d, %s, %d, %d)\n",
op, dname, class, type);
+#endif
/*
* Initialize header fields.
*/
@@ -97,7 +109,6 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
hp->opcode = op;
- hp->pr = (_res.options & RES_PRIMARY) != 0;
hp->rd = (_res.options & RES_RECURSE) != 0;
hp->rcode = NOERROR;
cp = buf + HFIXEDSZ;
@@ -110,7 +121,8 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
* perform opcode specific processing
*/
switch (op) {
- case QUERY:
+ case QUERY: /*FALLTHROUGH*/
+ case NS_NOTIFY_OP:
if ((buflen -= QFIXEDSZ) < 0)
return(-1);
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
@@ -222,8 +234,9 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
}
hp->ancount = htons(0);
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 ed923eb..33d87f2 100644
--- a/lib/libc/net/res_query.c
+++ b/lib/libc/net/res_query.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_query.c,v 1.3 1994/09/25 17:45:40 pst Exp $";
+static char rcsid[] = "$Id: res_query.c,v 1.4 1995/05/30 05:40:57 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -66,16 +66,10 @@ static char rcsid[] = "$Id: res_query.c,v 1.3 1994/09/25 17:45:40 pst Exp $";
#include <resolv.h>
#include <ctype.h>
#include <errno.h>
-#if defined(BSD) && (BSD >= 199306)
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <stdlib.h>
+#include <string.h>
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+#include <res_config.h>
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
@@ -109,31 +103,41 @@ res_query(name, class, type, answer, anslen)
hp->rcode = NOERROR; /* default */
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
return (-1);
+ }
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query(%s, %d, %d)\n", name, class, type);
+#endif
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
buf, sizeof(buf));
if (n <= 0) {
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query: mkquery failed\n");
+#endif
h_errno = NO_RECOVERY;
return (n);
}
n = res_send(buf, n, answer, anslen);
if (n < 0) {
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query: send error\n");
+#endif
h_errno = TRY_AGAIN;
return (n);
}
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; rcode = %d, ancount=%d\n", hp->rcode,
ntohs(hp->ancount));
+#endif
switch (hp->rcode) {
case NXDOMAIN:
h_errno = HOST_NOT_FOUND;
@@ -175,22 +179,23 @@ res_search(name, class, type, answer, anslen)
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);
-
+ }
errno = 0;
h_errno = HOST_NOT_FOUND; /* default, if we never query */
dots = 0;
for (cp = name; *cp; cp++)
dots += (*cp == '.');
trailing_dot = 0;
- if ((cp > name) && (*--cp == '.'))
+ 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));
/*
@@ -212,9 +217,8 @@ res_search(name, class, type, answer, anslen)
* - there is at least one dot, there is no trailing dot,
* and RES_DNSRCH is set.
*/
- if (((!dots) && _res.options & RES_DEFNAMES) ||
- (dots && (!trailing_dot) && _res.options & RES_DNSRCH)
- ) {
+ if ((!dots && (_res.options & RES_DEFNAMES)) ||
+ (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
int done = 0;
for (domain = (const char * const *)_res.dnsrch;
@@ -279,7 +283,6 @@ res_search(name, class, type, answer, anslen)
ret = res_querydomain(name, NULL, class, type, answer, anslen);
if (ret > 0)
return (ret);
- saved_herrno = h_errno;
}
/* if we got here, we didn't satisfy the search.
@@ -313,9 +316,15 @@ res_querydomain(name, domain, class, type, answer, anslen)
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?domain:"<Nil>", class, type);
+#endif
if (domain == NULL) {
/*
* Check for trailing '.';
@@ -327,10 +336,8 @@ res_querydomain(name, domain, class, type, answer, anslen)
nbuf[n] = '\0';
} else
longname = name;
- } else {
- sprintf(nbuf, "%.*s.%.*s",
- MAXDNAME, name, MAXDNAME, domain);
- }
+ } else
+ sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
return (res_query(longname, class, type, answer, anslen));
}
@@ -345,22 +352,28 @@ __hostalias(name)
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);
+ strncpy(abuf, cp1, sizeof(abuf) - 1);
fclose(fp);
return (abuf);
}
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index 8ee0a92..d5c9c28 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
+static char rcsid[] = "$Id: res_send.c,v 1.4 1995/05/30 05:40:58 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
/* change this to "0"
@@ -61,7 +61,7 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
* of multi-homed SunOS
* ("broken") name servers.
*/
-#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
+#define CHECK_SRVR_ADDR 1 /* XXX - should be in res_config.h */
/*
* Send query to name server and wait for reply.
@@ -78,8 +78,12 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
#include <stdio.h>
#include <errno.h>
#include <resolv.h>
+#include <netdb.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+#include <res_config.h>
void _res_close __P((void));
@@ -87,12 +91,17 @@ static int s = -1; /* socket used for communications */
static int connected = 0; /* is the socket connected */
static int vc = 0; /* is the socket a virtual ciruit? */
+#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) if (cond) {\
+# define DprintQ(cond, args, query, size) if (cond) {\
fprintf args;\
- __p_query(query);\
+ __fp_nquery(query, size, stdout);\
} else {}
-
static void
Aerror(file, string, error, address)
FILE *file;
@@ -103,15 +112,14 @@ Aerror(file, string, error, address)
int save = errno;
if (_res.options & RES_DEBUG) {
- fprintf(file, "res_send: %s ([%s].%d): %s\n",
+ fprintf(file, "res_send: %s ([%s].%u): %s\n",
string,
inet_ntoa(address.sin_addr),
- address.sin_port,
+ ntohs(address.sin_port),
strerror(error));
}
errno = save;
}
-
static void
Perror(file, string, error)
FILE *file;
@@ -126,6 +134,7 @@ Perror(file, string, error)
}
errno = save;
}
+#endif
static res_send_qhook Qhook = NULL;
static res_send_rhook Rhook = NULL;
@@ -134,6 +143,7 @@ void
res_send_setqhook(hook)
res_send_qhook hook;
{
+
Qhook = hook;
}
@@ -141,11 +151,12 @@ void
res_send_setrhook(hook)
res_send_rhook hook;
{
+
Rhook = hook;
}
/* int
- * our_server(ina)
+ * res_isourserver(ina)
* looks up "ina" in _res.ns_addr_list[]
* returns:
* 0 : not found
@@ -153,8 +164,8 @@ res_send_setrhook(hook)
* author:
* paul vixie, 29may94
*/
-static int
-our_server(inp)
+int
+res_isourserver(inp)
const struct sockaddr_in *inp;
{
struct sockaddr_in ina;
@@ -177,15 +188,17 @@ our_server(inp)
}
/* int
- * name_in_query(name, type, class, buf, eom)
+ * 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
*/
-static int
-name_in_query(name, type, class, buf, eom)
+int
+res_nameinquery(name, type, class, buf, eom)
const char *name;
register int type, class;
const u_char *buf, *eom;
@@ -212,16 +225,18 @@ name_in_query(name, type, class, buf, eom)
}
/* int
- * queries_match(buf1, eom1, buf2, eom2)
+ * 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
*/
-static int
-queries_match(buf1, eom1, buf2, eom2)
+int
+res_queriesmatch(buf1, eom1, buf2, eom2)
const u_char *buf1, *eom1;
const u_char *buf2, *eom2;
{
@@ -240,7 +255,7 @@ queries_match(buf1, eom1, buf2, eom2)
cp += n;
ttype = _getshort(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ;
- if (!name_in_query(tname, ttype, tclass, buf2, eom2))
+ if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
return (0);
}
return (1);
@@ -255,21 +270,20 @@ res_send(buf, buflen, ans, anssiz)
{
HEADER *hp = (HEADER *) buf;
HEADER *anhp = (HEADER *) ans;
- int gotsomewhere = 0,
- connreset = 0,
- terrno = ETIMEDOUT;
-
+ int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
register int n;
- int try, v_circuit, resplen, ns;
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
- DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
- (stdout, ";; res_send()\n"), buf);
- if (!(_res.options & RES_INIT)) {
- if (res_init() == -1)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ /* errno should have been set by res_init() in this case. */
return (-1);
}
+ DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+ (stdout, ";; res_send()\n"), buf, buflen);
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ gotsomewhere = 0;
+ connreset = 0;
+ terrno = ETIMEDOUT;
badns = 0;
/*
@@ -290,12 +304,8 @@ res_send(buf, buflen, ans, anssiz)
do {
res_sendhookact act;
- act = (*Qhook)(&nsap,
- &buf,
- &buflen,
- ans,
- anssiz,
- &resplen);
+ act = (*Qhook)(&nsap, &buf, &buflen,
+ ans, anssiz, &resplen);
switch (act) {
case res_goahead:
done = 1;
@@ -338,16 +348,15 @@ res_send(buf, buflen, ans, anssiz)
if (s >= 0)
_res_close();
- s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
+ s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
terrno = errno;
Perror(stderr, "socket(vc)", errno);
return (-1);
}
- if (connect(s,
- (struct sockaddr *)nsap,
- sizeof(struct sockaddr))
- < 0) {
+ errno = 0;
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof(struct sockaddr)) < 0) {
terrno = errno;
Aerror(stderr, "connect/vc",
errno, *nsap);
@@ -414,8 +423,7 @@ res_send(buf, buflen, ans, anssiz)
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;
}
@@ -433,7 +441,7 @@ res_send(buf, buflen, ans, anssiz)
anhp->tc = 1;
len = resplen - anssiz;
while (len != 0) {
- char junk[512];
+ char junk[PACKETSZ];
n = (len > sizeof(junk)
? sizeof(junk)
@@ -456,9 +464,9 @@ res_send(buf, buflen, ans, anssiz)
if ((s < 0) || vc) {
if (vc)
_res_close();
- s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
+ s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
- bad_dg_sock: terrno = errno;
+ terrno = errno;
Perror(stderr, "socket(dg)", errno);
return (-1);
}
@@ -485,11 +493,9 @@ res_send(buf, buflen, ans, anssiz)
* receive a response from another server.
*/
if (!connected) {
- if (connect(s,
- (struct sockaddr *)nsap,
+ if (connect(s, (struct sockaddr *)nsap,
sizeof(struct sockaddr)
- ) < 0
- ) {
+ ) < 0) {
Aerror(stderr,
"connect(dg)",
errno, *nsap);
@@ -499,7 +505,7 @@ res_send(buf, buflen, ans, anssiz)
}
connected = 1;
}
- if (send(s, buf, buflen, 0) != buflen) {
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
Perror(stderr, "send", errno);
badns |= (1<<ns);
_res_close();
@@ -523,7 +529,7 @@ res_send(buf, buflen, ans, anssiz)
connected = 0;
errno = 0;
}
- if (sendto(s, buf, buflen, 0,
+ if (sendto(s, (char*)buf, buflen, 0,
(struct sockaddr *)nsap,
sizeof(struct sockaddr))
!= buflen) {
@@ -558,14 +564,14 @@ res_send(buf, buflen, ans, anssiz)
* timeout
*/
Dprint(_res.options & RES_DEBUG,
- (stdout, ";; timeout\n")
- );
+ (stdout, ";; timeout\n"));
gotsomewhere = 1;
_res_close();
goto next_ns;
}
+ errno = 0;
fromlen = sizeof(struct sockaddr_in);
- resplen = recvfrom(s, ans, anssiz, 0,
+ resplen = recvfrom(s, (char*)ans, anssiz, 0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
Perror(stderr, "recvfrom", errno);
@@ -582,12 +588,12 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; old answer:\n"),
- ans);
+ ans, resplen);
goto wait;
}
#if CHECK_SRVR_ADDR
if (!(_res.options & RES_INSECURE1) &&
- !our_server(&from)) {
+ !res_isourserver(&from)) {
/*
* response from wrong server? ignore it.
* XXX - potential security hazard could
@@ -596,12 +602,12 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; not our server:\n"),
- ans);
+ ans, resplen);
goto wait;
}
#endif
if (!(_res.options & RES_INSECURE2) &&
- !queries_match(buf, buf + buflen,
+ !res_queriesmatch(buf, buf + buflen,
ans, ans + anssiz)) {
/*
* response contains wrong query? ignore it.
@@ -611,7 +617,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; wrong query name:\n"),
- ans);
+ ans, resplen);
goto wait;
}
if (anhp->rcode == SERVFAIL ||
@@ -619,9 +625,11 @@ res_send(buf, buflen, ans, anssiz)
anhp->rcode == REFUSED) {
DprintQ(_res.options & RES_DEBUG,
(stdout, "server rejected query:\n"),
- ans);
+ 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) {
@@ -630,8 +638,7 @@ res_send(buf, buflen, ans, anssiz)
* use TCP with same server.
*/
Dprint(_res.options & RES_DEBUG,
- (stdout, ";; truncated answer\n")
- );
+ (stdout, ";; truncated answer\n"));
v_circuit = 1;
_res_close();
goto same_ns;
@@ -640,7 +647,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; got answer:\n"),
- ans);
+ ans, resplen);
/*
* If using virtual circuits, we assume that the first server
* is preferred over the rest (i.e. it is on the local
@@ -659,12 +666,8 @@ res_send(buf, buflen, ans, anssiz)
do {
res_sendhookact act;
- act = (*Rhook)(nsap,
- buf,
- buflen,
- ans,
- anssiz,
- &resplen);
+ act = (*Rhook)(nsap, buf, buflen,
+ ans, anssiz, &resplen);
switch (act) {
case res_goahead:
case res_done:
@@ -691,14 +694,13 @@ res_send(buf, buflen, ans, anssiz)
} /*foreach ns*/
} /*foreach retry*/
_res_close();
- if (!v_circuit) {
+ if (!v_circuit)
if (!gotsomewhere)
errno = ECONNREFUSED; /* no nameservers found */
else
errno = ETIMEDOUT; /* no answer obtained */
- } else {
+ else
errno = terrno;
- }
return (-1);
}
OpenPOWER on IntegriCloud