2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 01:49:35 +00:00

- Support for compressed 'domain name list' style DHCP option contents, and

in particular the domain search option (#119) was added. [ISC-Bugs #15934]
This commit is contained in:
David Hankins 2006-07-22 02:24:16 +00:00
parent 8f4c32a101
commit dba5803b95
17 changed files with 431 additions and 68 deletions

View File

@ -143,6 +143,9 @@ and for prodding me into improving it.
for a different name. In essence, this lets the client do as it will,
ignoring this aspect of their request.
- Support for compressed 'domain name list' style DHCP option contents, and
in particular the domain search option (#119) was added.
Changes since 3.0.4
- A warning that host statements declared within subnet or shared-network
@ -208,6 +211,9 @@ and for prodding me into improving it.
- Some manual pages were clarified pursuant to discussion on the dhcp-server
mailing list.
- Support for compressed 'domain name list' style DHCP option contents, and
in particular the domain search option (#119) was added.
Changes since 3.0.4b2
- Null-termination sensing for certain clients that unfortunatley require

View File

@ -1,11 +1,21 @@
#!/bin/sh
make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
echo search $new_domain_name >/etc/resolv.conf
if [ x"$new_domain_name_servers" != x ]; then
cat /dev/null > /etc/resolv.conf.dhclient
if [ "x$new_domain_search" != x ]; then
echo search $new_domain_search >> /etc/resolv.conf.dhclient
elif [ "x$new_domain_name" != x ]; then
# Note that the DHCP 'Domain Name Option' is really just a domain
# name, and that this practice of using the domain name option as
# a search path is both nonstandard and deprecated.
echo search $new_domain_name >> /etc/resolv.conf.dhclient
fi
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
echo nameserver $nameserver >> /etc/resolv.conf.dhclient
done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi
}

View File

@ -1,6 +1,6 @@
#!/bin/sh
#
# $Id: freebsd,v 1.16 2005/03/17 20:14:56 dhankins Exp $
# $Id: freebsd,v 1.17 2006/07/22 02:24:16 dhankins Exp $
#
# $FreeBSD$
@ -12,24 +12,38 @@ fi
make_resolv_conf() {
if [ x"$new_domain_name_servers" != x ]; then
if [ "x$new_domain_name" != x ]; then
( echo search $new_domain_name >/etc/resolv.conf )
exit_status=$?
( cat /dev/null > /etc/resolv.conf.dhclient )
exit_status=$?
if [ $exit_status -ne 0 ]; then
$LOGGER "Unable to create /etc/resolv.conf.dhclient: Error $exit_status"
else
if [ -e /etc/resolv.conf ] ; then
( rm /etc/resolv.conf )
if [ "x$new_domain_search" != x ]; then
( echo search $new_domain_search >> /etc/resolv.conf.dhclient )
exit_status=$?
else
( touch /etc/resolv.conf )
elif [ "x$new_domain_name" != x ]; then
# Note that the DHCP 'Domain Name Option' is really just a domain
# name, and that this practice of using the domain name option as
# a search path is both nonstandard and deprecated.
( echo search $new_domain_name >> /etc/resolv.conf.dhclient )
exit_status=$?
fi
fi
if [ $exit_status -ne 0 ]; then
$LOGGER "WARNING: Unable to update resolv.conf: Error $exit_status"
else
for nameserver in $new_domain_name_servers; do
( echo nameserver $nameserver >>/etc/resolv.conf )
if [ $exit_status -ne 0 ]; then
break
fi
( echo nameserver $nameserver >>/etc/resolv.conf.dhclient )
exit_status=$?
done
# If there were no errors, attempt to mv the new file into place.
if [ $exit_status -eq 0 ]; then
( mv /etc/resolv.conf.dhclient /etc/resolv.conf )
exit_status = $?
fi
if [ $exit_status -ne 0 ]; then
$LOGGER "Error while writing new /etc/resolv.conf."
fi
fi
fi
}

View File

@ -23,12 +23,22 @@
# of the $1 in its args.
make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
echo search $new_domain_name >/etc/resolv.conf
chmod 644 /etc/resolv.conf
if [ x"$new_domain_name_servers" != x ]; then
cat /dev/null > /etc/resolv.conf.dhclient
chmod 644 /etc/resolv.conf.dhclient
if [ x"$new_domain_search" != x ]; then
echo search $new_domain_search >> /etc/resolv.conf.dhclient
elif [ x"$new_domain_name" != x ]; then
# Note that the DHCP 'Domain Name Option' is really just a domain
# name, and that this practice of using the domain name option as
# a search path is both nonstandard and deprecated.
echo search $new_domain_name >> /etc/resolv.conf.dhclient
fi
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi
}

View File

@ -2,10 +2,20 @@
make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
echo search $new_domain_name >/etc/resolv.conf
cat /dev/null > /etc/resolv.conf.dhclient
if [ "x$new_domain_search != x ]; then
echo search $new_domain_search >> /etc/resolv.conf.dhclient
elif [ "x$new_domain_name != x ]; then
# Note that the DHCP 'Domain Name Option' is really just a domain
# name, and that this practice of using the domain name option as
# a search path is both nonstandard and deprecated.
echo search $new_domain_name >> /etc/resolv.conf.dhclient
fi
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi
}

View File

@ -31,11 +31,21 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
route add default $router 1 >/dev/null 2>&1
done
fi
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
echo search $new_domain_name >/etc/resolv.conf
if [ x"$new_domain_name_servers" != x ]; then
cat /dev/null > /etc/resolv.conf.dhclient
if [ "x$new_domain_search != x ]; then
echo search $new_domain_search >> /etc/resolv.conf.dhclient
elif [ "x$new_domain_name != x ]; then
# Note that the DHCP 'Domain Name Option' is really just a domain
# name, and that this practice of using the domain name option as
# a search path is both nonstandard and deprecated.
echo search $new_domain_name >> /etc/resolv.conf.dhclient
fi
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi
exit 0
fi

View File

@ -1,11 +1,21 @@
#!/bin/sh
make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
echo search $new_domain_name >/etc/resolv.conf
if x"$new_domain_name_servers" != x ]; then
cat /dev/null > /etc/resolv.conf.dhclient
if [ x"$new_domain_search" != x ]; then
echo search $new_domain_search >> /etc/resolv.conf.dhclient
elif [ x"$new_domain_name" != x ]; then
# Note that the DHCP 'Domain Name Option' is really just a domain
# name, and that this practice of using the domain name option as
# a search path is both nonstandard and deprecated.
echo search $new_domain_name >> /etc/resolv.conf.dhclient
fi
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done
mv /etc/ersolv.conf.dhclient /etc/resolv.conf
fi
}

View File

@ -1,11 +1,21 @@
#!/bin/sh
make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
echo search $new_domain_name >/etc/resolv.conf
if [ x"$new_domain_name_servers" != x ]; then
cat /dev/null > /etc/resolv.conf.dhclient
if [ x"$new_domain_search" != x ]; then
echo search $new_domain_search >> /etc/resolv.conf.dhclient
elif [ x"$new_domain_name" != x ]; then
# Note that the DHCP 'Domain Name Option' is really just a domain
# name, and that this practice of using the domain name option as
# a search path is both nonstandard and deprecated.
echo search $new_domain_name >> /etc/resolv.conf.dhclient
fi
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi
}

View File

@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
"$Id: conflex.c,v 1.100 2006/06/16 19:26:44 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
"$Id: conflex.c,v 1.101 2006/07/22 02:24:16 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -655,8 +655,12 @@ static enum dhcp_token intern (atom, dfv)
return DNS_DELETE;
if (!strcasecmp (atom + 1, "omain"))
return DOMAIN;
if (!strcasecmp (atom + 1, "omain-name"))
return DOMAIN_NAME;
if (!strncasecmp (atom + 1, "omain-", 6)) {
if (!strcasecmp(atom + 7, "name"))
return DOMAIN_NAME;
if (!strcasecmp(atom + 7, "list"))
return DOMAIN_LIST;
}
if (!strcasecmp (atom + 1, "o-forward-update"))
return DO_FORWARD_UPDATE;
if (!strcasecmp (atom + 1, "ebug"))

View File

@ -1,4 +1,4 @@
.\" $Id: dhcp-options.5,v 1.29 2006/06/01 20:23:17 dhankins Exp $
.\" $Id: dhcp-options.5,v 1.30 2006/07/22 02:24:16 dhankins Exp $
.\"
.\" Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium
@ -91,6 +91,13 @@ existing DHCP options. The domain name is stored just as if it were
a text option.
.PP
The
.B domain-list
data type specifies a list of domain names, a space between each name and
the entire string enclosed in double quotes. These types of data are used
for the domain-search option for example, and encodes an RFC1035 compressed
DNS label list on the wire.
.PP
The
.B flag
data type specifies a boolean value. Booleans can be either true or
false (or on or off, if that makes more sense to you).
@ -389,6 +396,15 @@ The domain-name-servers option specifies a list of Domain Name System
should be listed in order of preference.
.RE
.PP
.B option \fBdomain-search\fR \fIstring\fR\fB;\fR
.RS 0.25i
.PP
The domain-search option specifies a 'search list' of Domain Names to be
used by the client to locate not-fully-qualified domain names. The difference
between this option and historic use of the domain-name option for the same
ends is that this option is encoded in RFC1035 compressed labels on the wire.
.RE
.PP
.B option \fBextensions-path\fR \fItext\fR\fB;\fR
.RS 0.25i
.PP

View File

@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
"$Id: options.c,v 1.91 2006/06/01 20:23:17 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
"$Id: options.c,v 1.92 2006/07/22 02:24:16 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
@ -46,6 +46,12 @@ struct option *vendor_cfg_option;
static void do_option_set PROTO ((pair *,
struct option_cache *,
enum statement_op));
static int pretty_escape(char **, char *, const unsigned char **,
const unsigned char *);
static int pretty_text(char **, char *, const unsigned char **,
const unsigned char *, int);
static int pretty_domain(char **, char *, const unsigned char **,
const unsigned char *);
/* Parse all available options out of the specified packet. */
@ -1146,6 +1152,7 @@ format_has_text(format)
case 'a':
case 'X':
case 'x':
case 'D':
return 0;
/* 'E' is variable length, but not arbitrary...you
@ -1264,6 +1271,7 @@ format_min_length(format, oc)
break;
case 'd': /* "Domain name" */
case 'D': /* "rfc1035 compressed names" */
case 't': /* "ASCII Text" */
case 'X': /* "ASCII or Hex Conditional */
case 'x': /* "Hex" */
@ -1293,14 +1301,16 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
int emit_quotes;
{
static char optbuf [32768]; /* XXX */
static char *endbuf = &optbuf[sizeof(optbuf)];
int hunksize = 0;
int opthunk = 0;
int hunkinc = 0;
int numhunk = -1;
int numelem = 0;
int count;
int i, j, k, l;
char fmtbuf [32];
struct enumeration *enumbuf [32];
int i, j, k, l;
char *op = optbuf;
const unsigned char *dp = data;
struct in_addr foo;
@ -1439,32 +1449,73 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
for (j = 0; j < numelem; j++) {
switch (fmtbuf [j]) {
case 't':
if (emit_quotes)
*op++ = '"';
for (; dp < data + len; dp++) {
if (!isascii (*dp) ||
!isprint (*dp)) {
/* Skip trailing NUL. */
if (dp + 1 != data + len ||
*dp != 0) {
sprintf (op, "\\%03o",
*dp);
op += 4;
}
} else if (*dp == '"' ||
*dp == '\'' ||
*dp == '$' ||
*dp == '`' ||
*dp == '\\') {
*op++ = '\\';
*op++ = *dp;
} else
*op++ = *dp;
/* endbuf-1 leaves room for NULL. */
k = pretty_text(&op, endbuf - 1, &dp,
data + len, emit_quotes);
if (k == -1) {
log_error("Error printing text.");
break;
}
if (emit_quotes)
*op++ = '"';
*op = 0;
break;
case 'D': /* RFC1035 format name list */
for( ; dp < (data + len) ; dp += k) {
unsigned char nbuff[NS_MAXCDNAME];
const unsigned char *nbp, *nend;
nend = &nbuff[sizeof(nbuff)];
/* If this is for ISC DHCP consumption
* (emit_quotes), lay it out as a list
* of STRING tokens. Otherwise, it is
* a space-separated list of DNS-
* escaped names as /etc/resolv.conf
* might digest.
*/
if (dp != data) {
if (op + 2 > endbuf)
break;
if (emit_quotes)
*op++ = ',';
*op++ = ' ';
}
k = MRns_name_unpack(data,
data + len,
dp, nbuff,
sizeof(nbuff));
if (k == -1) {
log_error("Invalid domain "
"list.");
break;
}
/* If emit_quotes, then use ISC DHCP
* escapes. Otherwise, rely only on
* ns_name_ntop().
*/
if (emit_quotes) {
nbp = nbuff;
pretty_domain(&op, endbuf-1,
&nbp, nend);
} else {
count = MRns_name_ntop(
nbuff, op,
(endbuf-op)-1);
if (count == -1) {
log_error("Invalid "
"domain name.");
break;
}
op += count;
}
}
*op = '\0';
break;
/* pretty-printing an array of enums is
going to get ugly. */
case 'N':
@ -1478,7 +1529,6 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
break;
}
strcpy (op, enumbuf [j] -> values [i].name);
op += strlen (op);
break;
case 'I':
foo.s_addr = htonl (getULong (dp));
@ -2642,3 +2692,142 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
dump_rc_history (0);
#endif
}
static int
pretty_escape(char **dst, char *dend, const unsigned char **src,
const unsigned char *send)
{
int count = 0;
/* If there aren't as many bytes left as there are in the source
* buffer, don't even bother entering the loop.
*/
if (dst == NULL || src == NULL || (*dst >= dend) || (*src > send) ||
*dst == NULL || *src == NULL ||
((send - *src) > (dend - *dst)))
return -1;
for ( ; *src < send ; *src++) {
if (!isascii (**src) || !isprint (**src)) {
/* Skip trailing NUL. */
if ((*src + 1) != send || **src != '\0') {
if (*dst + 4 > dend)
return -1;
sprintf(*dst, "\\%03o",
**src);
*dst += 4;
count += 4;
}
} else if (**src == '"' || **src == '\'' || **src == '$' ||
**src == '`' || **src == '\\') {
if (*dst + 2 > dend)
return -1;
**dst = '\\';
*dst++;
**dst = **src;
*dst++;
count += 2;
} else {
if (*dst + 1 > dend)
return -1;
**dst = **src;
*dst++;
count++;
}
}
return count;
}
static int
pretty_text(char **dst, char *dend, const unsigned char **src,
const unsigned char *send, int emit_quotes)
{
int count;
if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
*dst == NULL || *src == NULL ||
((*dst + (emit_quotes ? 2 : 0)) > dend) || (*src > send))
return -1;
if (emit_quotes) {
**dst = '"';
*dst++;
}
/* dend-1 leaves 1 byte for the closing quote. */
count = pretty_escape(dst, dend - (emit_quotes ? 1 : 0), src, send);
if (count == -1)
return -1;
if (emit_quotes && (*dst < dend)) {
**dst = '"';
*dst++;
/* Includes quote prior to pretty_escape(); */
count += 2;
}
return count;
}
static int
pretty_domain(char **dst, char *dend, const unsigned char **src,
const unsigned char *send)
{
const unsigned char *tend;
int count = 2;
int tsiz, status;
if (dst == NULL || dend == NULL || src == NULL || send == NULL ||
*dst == NULL || *src == NULL ||
((*dst + 2) > dend) || (*src >= send))
return -1;
**dst = '"';
*dst++;
do {
/* Continue loop until end of src buffer. */
if (*src >= send)
break;
/* Consume tag size. */
tsiz = **src;
*src++;
/* At root, finis. */
if (tsiz == 0)
break;
tend = *src + tsiz;
/* If the tag exceeds the source buffer, it's illegal.
* This should also trap compression pointers (which should
* not be in these buffers).
*/
if (tend > send)
return -1;
/* dend-2 leaves room for a trailing dot and quote. */
status = pretty_escape(dst, dend-2, src, tend);
if ((status == -1) || ((*dst + 2) > dend))
return -1;
**dst = '.';
*dst++;
count += status + 1;
}
while(1);
**dst = '"';
*dst++;
return count;
}

View File

@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
"$Id: parse.c,v 1.112 2006/06/06 16:35:18 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
"$Id: parse.c,v 1.113 2006/07/22 02:24:16 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -1391,6 +1391,9 @@ int parse_option_code_definition (cfile, option)
case DOMAIN_NAME:
type = 'd';
goto no_arrays;
case DOMAIN_LIST:
type = 'D';
goto no_arrays;
case TEXT:
type = 't';
no_arrays:
@ -4704,7 +4707,18 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
}
}
break;
case 'D': /* Domain list... */
t = parse_domain_list(cfile);
if (!t) {
if ((*fmt)[1] != 'o')
skip_to_semi(cfile);
return 0;
}
break;
case 'd': /* Domain name... */
val = parse_host_name (cfile);
if (!val) {
@ -5188,3 +5202,54 @@ int parse_warn (struct parse *cfile, const char *fmt, ...)
return 0;
}
struct expression *
parse_domain_list (cfile)
struct parse *cfile;
{
const char *val;
enum dhcp_token token = SEMI;
struct expression *t = NULL;
unsigned len, clen = 0;
int result;
unsigned char compbuf[256 * NS_MAXCDNAME];
const unsigned char *dnptrs[256], **lastdnptr;
memset(compbuf, 0, sizeof(compbuf));
memset(dnptrs, 0, sizeof(dnptrs));
dnptrs[0] = compbuf;
lastdnptr = &dnptrs[255];
do {
/* Consume the COMMA token if peeked. */
if (token == COMMA)
next_token(&val, NULL, cfile);
/* Get next (or first) value. */
token = next_token(&val, &len, cfile);
if (token != STRING) {
parse_warn(cfile, "Expecting a domain string.");
return NULL;
}
result = MRns_name_compress(val, compbuf + clen,
sizeof(compbuf) - clen,
dnptrs, lastdnptr);
if (result < 0) {
parse_warn(cfile, "Error compressing domain list: %m");
return NULL;
}
clen += result;
token = peek_token(&val, NULL, cfile);
} while (token == COMMA);
if (!make_const_data(&t, compbuf, clen, 1, 1, MDL))
log_fatal("No memory for domain list object.");
return t;
}

View File

@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
"$Id: tables.c,v 1.55 2006/06/01 20:23:17 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
"$Id: tables.c,v 1.56 2006/07/22 02:24:16 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -94,6 +94,7 @@ HASH_FUNCTIONS (option_code, const unsigned *, struct option,
followed by a '.'. The width of the data is specified in the
named enumeration. Named enumerations are tracked in parse.c.
d - Domain name (i.e., FOO or FOO.BAR).
D - Domain list (i.e., example.com eng.example.com)
*/
struct universe dhcp_universe;
@ -185,6 +186,7 @@ static struct option dhcp_options[] = {
{ "nds-context", "t", &dhcp_universe, 87, 1 },
{ "uap-servers", "t", &dhcp_universe, 98, 1 },
{ "subnet-selection", "I", &dhcp_universe, 118, 1 },
{ "domain-search", "D", &dhcp_universe, 119, 1 },
{ "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
{ "vivso", "Evendor.", &dhcp_universe, 125, 1 },
{ NULL, NULL, NULL, 0, 0 }

View File

@ -149,6 +149,7 @@ struct dhcp_packet {
#define DHO_FQDN 81
#define DHO_DHCP_AGENT_OPTIONS 82
#define DHO_SUBNET_SELECTION 118 /* RFC3011! */
#define DHO_DOMAIN_SEARCH 119 /* RFC3397 */
#define DHO_VIVCO_SUBOPTIONS 124
#define DHO_VIVSO_SUBOPTIONS 125
/* The DHO_AUTHENTICATE option is not a standard yet, so I've

View File

@ -1384,6 +1384,8 @@ int parse_allow_deny PROTO ((struct option_cache **, struct parse *, int));
int parse_auth_key PROTO ((struct data_string *, struct parse *));
int parse_warn (struct parse *, const char *, ...)
__attribute__((__format__(__printf__,2,3)));
struct expression *parse_domain_list (struct parse *cfile);
/* tree.c */
#if defined (NSUPDATE)

View File

@ -322,7 +322,8 @@ enum dhcp_token {
MAX_LEASE_MISBALANCE = 626,
MAX_LEASE_OWNERSHIP = 627,
MAX_BALANCE = 628,
MIN_BALANCE = 629
MIN_BALANCE = 629,
DOMAIN_LIST = 630
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \

View File

@ -45,6 +45,12 @@ isc_result_t minires_nupdate (res_state, ns_updrec *);
int minires_ninit (res_state);
ns_rcode isc_rcode_to_ns (isc_result_t);
int MRns_name_compress(const char *, u_char *, size_t, const unsigned char **,
const unsigned char **);
int MRns_name_unpack(const unsigned char *, const unsigned char *,
const unsigned char *, unsigned char *, size_t);
int MRns_name_ntop(const unsigned char *, char *, size_t);
#if defined (MINIRES_LIB)
#define res_update minires_update
#define res_mkupdate minires_mkupdate
@ -187,10 +193,7 @@ isc_result_t ns_sign_tcp_init (void *, const unsigned char *,
unsigned, ns_tcp_tsig_state *);
isc_result_t ns_sign_tcp (unsigned char *,
unsigned *, unsigned, int, ns_tcp_tsig_state *, int);
int ns_name_ntop (const unsigned char *, char *, size_t);
int ns_name_pton (const char *, unsigned char *, size_t);
int ns_name_unpack (const unsigned char *, const unsigned char *,
const unsigned char *, unsigned char *, size_t);
int ns_name_pack (const unsigned char *, unsigned char *,
unsigned, const unsigned char **, const unsigned char **);
int ns_name_compress (const char *, unsigned char *,