#endif
char *h_errlist[] = {
- "Error 0",
+ "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;
v->iov_len = 2;
v++;
}
- v->iov_base = (u_int)h_errno < h_nerr ?
- h_errlist[h_errno] : "Unknown error";
+ v->iov_base = hstrerror(h_errno);
v->iov_len = strlen(v->iov_base);
v++;
v->iov_base = "\n";
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");
}
}
*dn++ = c;
if (cp >= eomorig) /* out of range */
- return(-1);
+ return (-1);
}
break;
len = cp - comp_dn + 1;
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;
cp++;
break;
default: /* illegal type */
- return -1;
+ return (-1);
}
break;
}
if (cp > eom)
- return -1;
+ return (-1);
return (cp - comp_dn);
}
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')
return (u);
}
+#ifdef NeXT
+/*
+ * nExt machines have some funky library conventions, which we must maintain.
+ */
+u_int16_t
+res_getshort(msgp)
+ register const u_char *msgp;
+{
+ return (_getshort(msgp));
+}
+#endif
+
u_int32_t
_getlong(msgp)
register const u_char *msgp;
dn_skipname(comp_dn, eom)
const u_char *comp_dn, *eom;
{
- return __dn_skipname(comp_dn, eom);
+ return (__dn_skipname(comp_dn, eom));
}
#endif /* Ultrix 4.0 hackery */
"QUERY",
"IQUERY",
"CQUERYM",
- "CQUERYU",
- "4",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
"5",
"6",
"7",
((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
fprintf(file, hs);
while (--n >= 0) {
- cp = p_rr(cp, msg, file);
+ if ((!_res.pfcode) || sflag) {
+ cp = p_rr(cp, msg, file);
+ } 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) > PACKETSZ)
return (NULL);
}
}
putc(';', file);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
- fprintf(file,"; flags:");
+ fprintf(file, "; flags:");
if (hp->qr)
fprintf(file, " qr");
if (hp->aa)
*/
if (n = ntohs(hp->qdcount)) {
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file,";; QUESTIONS:\n");
+ fprintf(file, ";; QUESTIONS:\n");
while (--n >= 0) {
- fprintf(file,";;\t");
+ fprintf(file, ";;\t");
TruncTest(cp);
cp = p_cdname(cp, msg, file);
ErrorTest(cp);
case C_HS:
bcopy(cp, (char *)&inaddr, INADDRSZ);
if (dlen == 4) {
- fprintf(file,"\t%s", inet_ntoa(inaddr));
+ fprintf(file, "\t%s", inet_ntoa(inaddr));
cp += dlen;
} else if (dlen == 7) {
char *address;
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);
+ fprintf(file, "\t%.*s", n, cp);
cp += n;
}
- if (n = *cp++) {
- fprintf(file,"\t%.*s", 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", 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", 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", 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", 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)", t, __p_time(t));
break;
case T_MX:
case T_AFSDB:
case T_RT:
- fprintf(file,"\t%d ", _getshort((u_char*)cp));
+ 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_TXT:
+ 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:
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
}
}
putc('"', file);
- break;
+ break;
- case T_NSAP:
+ case T_NSAP:
(void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
cp += dlen;
- break;
+ 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:
case T_UID:
case T_GID:
if (dlen == 4) {
- fprintf(file,"\t%u", _getlong((u_char*)cp));
+ fprintf(file, "\t%u", _getlong((u_char*)cp));
cp += INT32SZ;
}
break;
while (cp < cp1 + dlen) {
c = *cp++;
do {
- if (c & 0200) {
+ if (c & 0200) {
if (lcnt == 0) {
fputs("\n\t\t\t", file);
lcnt = 5;
putc(' ', file);
lcnt--;
}
- c <<= 1;
+ c <<= 1;
} while (++n & 07);
}
putc(')', file);
#endif /* ALLOW_T_UNSPEC */
default:
- fprintf(file,"\t?%d?", type);
+ fprintf(file, "\t?%d?", type);
cp += dlen;
}
#if 0
putc('\n', file);
#endif
if (cp - cp1 != dlen) {
- fprintf(file,";; packet size error (found %d, dlen was %d)\n",
+ fprintf(file, ";; packet size error (found %d, dlen was %d)\n",
cp - cp1, dlen);
cp = NULL;
}
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";
int class;
{
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);
}
}
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%x?", option); return (nbuf);
}
}
# include "../conf/portability.h"
#endif
+/*
+ * Marc Majka 1994/04/16
+ * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
+ *
+ * NetInfo resolver configuration directory support.
+ *
+ * Allow a NetInfo directory to be created in the hierarchy which
+ * contains the same information as the resolver configuration file.
+ *
+ * - The local domain name is stored as the value of the "domain" property.
+ * - The Internet address(es) of the name server(s) are stored as values
+ * of the "nameserver" property.
+ * - The name server addresses are stored as values of the "nameserver"
+ * property.
+ * - The search list for host-name lookup is stored as values of the
+ * "search" property.
+ * - The sortlist comprised of IP address netmask pairs are stored as
+ * values of the "sortlist" property. The IP address and optional netmask
+ * should be seperated by a slash (/) character.
+ * - Internal resolver variables can be set from the value of the "options"
+ * property.
+ *
+ */
+#if defined(NeXT)
+# include <netinfo/ni.h>
+# define NI_PATH_RESCONF "/locations/resolver"
+# define NI_TIMEOUT 10
+static int netinfo_res_init __P((int *haveenv, int *havesearch));
+#endif
+
#if defined(USE_OPTIONS_H)
# include "../conf/options.h"
#endif
#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
*pp++ = 0;
}
+#define MATCH(line, name) \
+ (!strncmp(line, name, sizeof(name) - 1) && \
+ (line[sizeof(name) - 1] == ' ' || \
+ line[sizeof(name) - 1] == '\t'))
+
+#ifdef NeXT
+ if (netinfo_res_init(&haveenv, &havesearch) == 0)
+#endif
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;
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
- (void)strncpy(_res.defdname, cp,
- sizeof(_res.defdname) - 1);
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
*cp = '\0';
havesearch = 0;
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;
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
- (void)strncpy(_res.defdname, cp,
- sizeof(_res.defdname) - 1);
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
if ((cp = strchr(_res.defdname, '\n')) != NULL)
*cp = '\0';
/*
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;
continue;
}
/* read nameservers to query */
- if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
- nserv < MAXNS) {
- struct in_addr a;
+ if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+ struct in_addr a;
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
continue;
}
#ifdef RESOLVSORT
- if (!strncmp(buf, "sortlist", sizeof("sortlist") -1)) {
+ if (MATCH(buf, "sortlist")) {
struct in_addr a;
cp = buf + sizeof("sortlist") - 1;
break;
net = cp;
while (*cp && *cp != '/' &&
- isascii(*cp) && !isspace(*cp))
+ isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
continue;
}
#endif
- if (!strncmp(buf, "options", sizeof("options") -1)) {
+ if (MATCH(buf, "options")) {
res_setoptions(buf + sizeof("options") - 1, "conf");
continue;
}
_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) {
#ifndef RFC1535
dots = 0;
- for (cp = _res.defdname; *cp; cp++)
+ for (cp = _res.defdname; *cp; cp++)
dots += (*cp == '.');
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--;
#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*/
+#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;
int i;
#ifdef DEBUG
- if (_res.options & RES_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')
cp++;
/* search for and process individual options */
- if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) {
+ if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
i = atoi(cp + sizeof("ndots:") - 1);
if (i <= RES_MAXNDOTS)
_res.ndots = i;
else
_res.ndots = RES_MAXNDOTS;
#ifdef DEBUG
- if (_res.options & RES_DEBUG) {
+ if (_res.options & RES_DEBUG)
printf(";;\tndots=%d\n", _res.ndots);
- }
#endif
- } else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
+ } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
#ifdef DEBUG
if (!(_res.options & RES_DEBUG)) {
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
net_mask(in) /* XXX - should really use system's version of this */
struct in_addr in;
{
- register u_int32_t i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return (htonl(IN_CLASSA_NET));
- else if (IN_CLASSB(i))
- return (htonl(IN_CLASSB_NET));
- else
- return (htonl(IN_CLASSC_NET));
+ register u_int32_t i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return (htonl(IN_CLASSA_NET));
+ else if (IN_CLASSB(i))
+ return (htonl(IN_CLASSB_NET));
+ return (htonl(IN_CLASSC_NET));
}
#endif
+
+#ifdef NeXT
+static int
+netinfo_res_init(haveenv, havesearch)
+ int *haveenv;
+ int *havesearch;
+{
+ register int n;
+ void *domain, *parent;
+ ni_id dir;
+ ni_status status;
+ ni_namelist nl;
+ int nserv = 0;
+#ifdef RESOLVSORT
+ int nsort = 0;
+#endif
+
+ status = ni_open(NULL, ".", &domain);
+ if (status == NI_OK) {
+ ni_setreadtimeout(domain, NI_TIMEOUT);
+ ni_setabort(domain, 1);
+
+ /* climb the NetInfo hierarchy to find a resolver directory */
+ while (status == NI_OK) {
+ status = ni_pathsearch(domain, &dir, NI_PATH_RESCONF);
+ if (status == NI_OK) {
+ /* found a resolver directory */
+
+ if (*haveenv == 0) {
+ /* get the default domain name */
+ status = ni_lookupprop(domain, &dir, "domain", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ (void)strncpy(_res.defdname,
+ nl.ni_namelist_val[0],
+ sizeof(_res.defdname) - 1);
+ _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+ ni_namelist_free(&nl);
+ *havesearch = 0;
+ }
+
+ /* get search list */
+ status = ni_lookupprop(domain, &dir, "search", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ (void)strncpy(_res.defdname,
+ nl.ni_namelist_val[0],
+ sizeof(_res.defdname) - 1);
+ _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+ /* copy */
+ for (n = 0;
+ n < nl.ni_namelist_len && n < MAXDNSRCH;
+ n++) {
+ /* duplicate up to MAXDNSRCH servers */
+ char *cp = nl.ni_namelist_val[n];
+ _res.dnsrch[n] =
+ strcpy((char *)malloc(strlen(cp) + 1), cp);
+ }
+ ni_namelist_free(&nl);
+ *havesearch = 1;
+ }
+ }
+
+ /* get list of nameservers */
+ status = ni_lookupprop(domain, &dir, "nameserver", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ /* copy up to MAXNS servers */
+ for (n = 0;
+ n < nl.ni_namelist_len && nserv < MAXNS;
+ n++) {
+ struct in_addr a;
+
+ if (inet_aton(nl.ni_namelist_val[n], &a)) {
+ _res.nsaddr_list[nserv].sin_addr = a;
+ _res.nsaddr_list[nserv].sin_family = AF_INET;
+ _res.nsaddr_list[nserv].sin_port =
+ htons(NAMESERVER_PORT);
+ nserv++;
+ }
+ }
+ ni_namelist_free(&nl);
+ }
+
+ if (nserv > 1)
+ _res.nscount = nserv;
+
+#ifdef RESOLVSORT
+ /* get sort order */
+ status = ni_lookupprop(domain, &dir, "sortlist", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+
+ /* copy up to MAXRESOLVSORT address/netmask pairs */
+ for (n = 0;
+ n < nl.ni_namelist_len && nsort < MAXRESOLVSORT;
+ n++) {
+ char ch;
+ char *cp;
+ struct in_addr a;
+
+ cp = strchr(nl.ni_namelist_val[n], '/');
+ if (cp != NULL) {
+ ch = *cp;
+ *cp = '\0';
+ }
+
+ if (inet_aton(nl.ni_namelist_val[n], &a)) {
+ _res.sort_list[nsort].addr = a;
+ if (*cp && ch == '/') {
+ *cp++ = ch;
+ if (inet_aton(cp, &a)) {
+ _res.sort_list[nsort].mask = a.s_addr;
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ nsort++;
+ }
+ }
+ ni_namelist_free(&nl);
+ }
+
+ _res.nsort = nsort;
+#endif
+
+ /* get resolver options */
+ status = ni_lookupprop(domain, &dir, "options", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ res_setoptions(nl.ni_namelist_val[0], "conf");
+ ni_namelist_free(&nl);
+ }
+
+ ni_free(domain);
+ return(1); /* using DNS configuration from NetInfo */
+ }
+
+ status = ni_open(domain, "..", &parent);
+ ni_free(domain);
+ if (status == NI_OK)
+ domain = parent;
+ }
+ }
+ return(0); /* if not using DNS configuration from NetInfo */
+}
+#endif /* NeXT */
printf(";; res_mkquery(%d, %s, %d, %d)\n",
op, dname, class, type);
#endif
+ if (!(_res.options & RES_INIT)) {
+ if (res_init() == -1)
+ return (-1);
+ }
/*
* Initialize header fields.
*/
if ((buf == NULL) || (buflen < HFIXEDSZ))
- return(-1);
+ return (-1);
bzero(buf, HFIXEDSZ);
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
* perform opcode specific processing
*/
switch (op) {
- case QUERY:
+ case QUERY: /*FALLTHROUGH*/
+ case NS_NOTIFY_OP:
if ((buflen -= QFIXEDSZ) < 0)
- return(-1);
+ return (-1);
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
return (-1);
cp += n;
__putshort(type, cp);
- cp += INT16SZ;
- __putshort(class, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
__putlong(0, cp);
cp += INT32SZ;
__putshort(datalen, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
if (datalen) {
bcopy(data, cp, datalen);
cp += datalen;
return (-1);
cp += n;
__putshort(newrr->r_type, cp);
- cp += INT16SZ;
- __putshort(newrr->r_class, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
+ __putshort(newrr->r_class, cp);
+ cp += INT16SZ;
__putlong(0, cp);
cp += INT32SZ;
__putshort(newrr->r_size, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
if (newrr->r_size) {
bcopy(newrr->r_data, cp, newrr->r_size);
cp += newrr->r_size;
}
hp->ancount = htons(0);
break;
-
#endif /* ALLOW_UPDATES */
+ default:
+ return (-1);
}
return (cp - buf);
}
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;
res_send_setqhook(hook)
res_send_qhook hook;
{
+
Qhook = hook;
}
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
* author:
* paul vixie, 29may94
*/
-static int
-our_server(inp)
+int
+res_isourserver(inp)
const struct sockaddr_in *inp;
{
struct sockaddr_in ina;
}
/* 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;
}
/* 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;
{
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);
int
res_send(buf, buflen, ans, anssiz)
- const u_char *buf;
- int buflen;
- u_char *ans;
- int anssiz;
+ const u_char *buf;
+ int buflen;
+ u_char *ans;
+ int anssiz;
{
- HEADER *hp = (HEADER *) buf;
- HEADER *anhp = (HEADER *) ans;
- int gotsomewhere = 0,
- connreset = 0,
- terrno = ETIMEDOUT;
-
- register int n;
- int try, v_circuit, resplen, ns;
- u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
+ HEADER *hp = (HEADER *) 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 */
DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
(stdout, ";; res_send()\n"), buf);
- if (!(_res.options & RES_INIT)) {
- if (res_init() == -1)
- return (-1);
- }
+ if (!(_res.options & RES_INIT) && res_init() == -1)
+ return (-1);
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ gotsomewhere = 0;
+ connreset = 0;
+ terrno = ETIMEDOUT;
badns = 0;
/*
for (ns = 0; ns < _res.nscount; ns++) {
struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
same_ns:
- if (badns & (1<<ns)) {
+ if (badns & (1 << ns)) {
_res_close();
goto next_ns;
}
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;
Dprint(_res.options & RES_DEBUG,
(stdout, ";; Querying server (# %d) address = %s\n",
- ns+1, inet_ntoa(nsap->sin_addr)));
+ ns + 1, inet_ntoa(nsap->sin_addr)));
if (v_circuit) {
- int truncated;
- struct iovec iov[2];
- u_short len;
- u_char *cp;
+ int truncated;
+ struct iovec iov[2];
+ u_short len;
+ u_char *cp;
/*
* Use virtual circuit;
Perror(stderr, "socket(vc)", errno);
return (-1);
}
- if (connect(s,
- (struct sockaddr *)nsap,
- sizeof(struct sockaddr))
- < 0) {
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof(struct sockaddr)) < 0) {
terrno = errno;
Aerror(stderr, "connect/vc",
errno, *nsap);
- badns |= (1<<ns);
+ badns |= (1 << ns);
_res_close();
goto next_ns;
}
if (writev(s, iov, 2) != (INT16SZ + buflen)) {
terrno = errno;
Perror(stderr, "write failed", errno);
- badns |= (1<<ns);
+ badns |= (1 << ns);
_res_close();
goto next_ns;
}
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;
}
anhp->tc = 1;
len = resplen - anssiz;
while (len != 0) {
- char junk[512];
+ char junk[PACKETSZ];
n = (len > sizeof(junk)
? sizeof(junk)
/*
* Use datagrams.
*/
- struct timeval timeout;
- fd_set dsmask;
+ struct timeval timeout;
+ fd_set dsmask;
struct sockaddr_in from;
- int fromlen;
+ int fromlen;
if ((s < 0) || vc) {
if (vc)
* 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);
- badns |= (1<<ns);
+ badns |= (1 << ns);
_res_close();
goto next_ns;
}
connected = 1;
}
- if (send(s, buf, buflen, 0) != buflen) {
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
Perror(stderr, "send", errno);
- badns |= (1<<ns);
+ badns |= (1 << ns);
_res_close();
goto next_ns;
}
connected = 0;
errno = 0;
}
- if (sendto(s, buf, buflen, 0,
+ if (sendto(s, (char*)buf, buflen, 0,
(struct sockaddr *)nsap,
sizeof(struct sockaddr))
!= buflen) {
Aerror(stderr, "sendto", errno, *nsap);
- badns |= (1<<ns);
+ badns |= (1 << ns);
_res_close();
goto next_ns;
}
* timeout
*/
Dprint(_res.options & RES_DEBUG,
- (stdout, ";; timeout\n")
- );
+ (stdout, ";; timeout\n"));
gotsomewhere = 1;
_res_close();
goto next_ns;
}
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);
}
#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
}
#endif
if (!(_res.options & RES_INSECURE2) &&
- !queries_match(buf, buf + buflen,
- ans, ans + anssiz)) {
+ !res_queriesmatch(buf, buf + buflen,
+ ans, ans + anssiz)) {
/*
* response contains wrong query? ignore it.
* XXX - potential security hazard could
DprintQ(_res.options & RES_DEBUG,
(stdout, "server rejected query:\n"),
ans);
- badns |= (1<<ns);
+ badns |= (1 << ns);
_res_close();
- goto next_ns;
+ /* don't retry if called from dig */
+ if (!_res.pfcode)
+ goto next_ns;
}
if (!(_res.options & RES_IGNTC) && anhp->tc) {
/*
* 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;
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:
} /*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);
}