2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-28 12:57:42 +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, for a different name. In essence, this lets the client do as it will,
ignoring this aspect of their request. 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 Changes since 3.0.4
- A warning that host statements declared within subnet or shared-network - 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 - Some manual pages were clarified pursuant to discussion on the dhcp-server
mailing list. 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 Changes since 3.0.4b2
- Null-termination sensing for certain clients that unfortunatley require - Null-termination sensing for certain clients that unfortunatley require

View File

@ -1,11 +1,21 @@
#!/bin/sh #!/bin/sh
make_resolv_conf() { make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then if [ 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 for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf echo nameserver $nameserver >> /etc/resolv.conf.dhclient
done done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi fi
} }

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/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$ # $FreeBSD$
@ -12,24 +12,38 @@ fi
make_resolv_conf() { make_resolv_conf() {
if [ x"$new_domain_name_servers" != x ]; then if [ x"$new_domain_name_servers" != x ]; then
if [ "x$new_domain_name" != x ]; then ( cat /dev/null > /etc/resolv.conf.dhclient )
( echo search $new_domain_name >/etc/resolv.conf )
exit_status=$? exit_status=$?
else
if [ -e /etc/resolv.conf ] ; then
( rm /etc/resolv.conf )
exit_status=$?
else
( touch /etc/resolv.conf )
exit_status=$?
fi
fi
if [ $exit_status -ne 0 ]; then if [ $exit_status -ne 0 ]; then
$LOGGER "WARNING: Unable to update resolv.conf: Error $exit_status" $LOGGER "Unable to create /etc/resolv.conf.dhclient: Error $exit_status"
else else
if [ "x$new_domain_search" != x ]; then
( echo search $new_domain_search >> /etc/resolv.conf.dhclient )
exit_status=$?
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
for nameserver in $new_domain_name_servers; do 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 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
fi fi
} }

View File

@ -23,12 +23,22 @@
# of the $1 in its args. # of the $1 in its args.
make_resolv_conf() { make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then if [ x"$new_domain_name_servers" != x ]; then
echo search $new_domain_name >/etc/resolv.conf cat /dev/null > /etc/resolv.conf.dhclient
chmod 644 /etc/resolv.conf 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 for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi fi
} }

View File

@ -2,10 +2,20 @@
make_resolv_conf() { make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then 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 for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi fi
} }

View File

@ -31,11 +31,21 @@ if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
route add default $router 1 >/dev/null 2>&1 route add default $router 1 >/dev/null 2>&1
done done
fi fi
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then if [ 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 for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi fi
exit 0 exit 0
fi fi

View File

@ -1,11 +1,21 @@
#!/bin/sh #!/bin/sh
make_resolv_conf() { make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then if 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 for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done done
mv /etc/ersolv.conf.dhclient /etc/resolv.conf
fi fi
} }

View File

@ -1,11 +1,21 @@
#!/bin/sh #!/bin/sh
make_resolv_conf() { make_resolv_conf() {
if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then if [ 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 for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf echo nameserver $nameserver >>/etc/resolv.conf.dhclient
done done
mv /etc/resolv.conf.dhclient /etc/resolv.conf
fi fi
} }

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -655,8 +655,12 @@ static enum dhcp_token intern (atom, dfv)
return DNS_DELETE; return DNS_DELETE;
if (!strcasecmp (atom + 1, "omain")) if (!strcasecmp (atom + 1, "omain"))
return DOMAIN; return DOMAIN;
if (!strcasecmp (atom + 1, "omain-name")) if (!strncasecmp (atom + 1, "omain-", 6)) {
if (!strcasecmp(atom + 7, "name"))
return DOMAIN_NAME; return DOMAIN_NAME;
if (!strcasecmp(atom + 7, "list"))
return DOMAIN_LIST;
}
if (!strcasecmp (atom + 1, "o-forward-update")) if (!strcasecmp (atom + 1, "o-forward-update"))
return DO_FORWARD_UPDATE; return DO_FORWARD_UPDATE;
if (!strcasecmp (atom + 1, "ebug")) 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) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium .\" 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. a text option.
.PP .PP
The 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 .B flag
data type specifies a boolean value. Booleans can be either true or data type specifies a boolean value. Booleans can be either true or
false (or on or off, if that makes more sense to you). 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. should be listed in order of preference.
.RE .RE
.PP .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 .B option \fBextensions-path\fR \fItext\fR\fB;\fR
.RS 0.25i .RS 0.25i
.PP .PP

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#define DHCP_OPTION_DATA #define DHCP_OPTION_DATA
@ -46,6 +46,12 @@ struct option *vendor_cfg_option;
static void do_option_set PROTO ((pair *, static void do_option_set PROTO ((pair *,
struct option_cache *, struct option_cache *,
enum statement_op)); 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. */ /* Parse all available options out of the specified packet. */
@ -1146,6 +1152,7 @@ format_has_text(format)
case 'a': case 'a':
case 'X': case 'X':
case 'x': case 'x':
case 'D':
return 0; return 0;
/* 'E' is variable length, but not arbitrary...you /* 'E' is variable length, but not arbitrary...you
@ -1264,6 +1271,7 @@ format_min_length(format, oc)
break; break;
case 'd': /* "Domain name" */ case 'd': /* "Domain name" */
case 'D': /* "rfc1035 compressed names" */
case 't': /* "ASCII Text" */ case 't': /* "ASCII Text" */
case 'X': /* "ASCII or Hex Conditional */ case 'X': /* "ASCII or Hex Conditional */
case 'x': /* "Hex" */ case 'x': /* "Hex" */
@ -1293,14 +1301,16 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
int emit_quotes; int emit_quotes;
{ {
static char optbuf [32768]; /* XXX */ static char optbuf [32768]; /* XXX */
static char *endbuf = &optbuf[sizeof(optbuf)];
int hunksize = 0; int hunksize = 0;
int opthunk = 0; int opthunk = 0;
int hunkinc = 0; int hunkinc = 0;
int numhunk = -1; int numhunk = -1;
int numelem = 0; int numelem = 0;
int count;
int i, j, k, l;
char fmtbuf [32]; char fmtbuf [32];
struct enumeration *enumbuf [32]; struct enumeration *enumbuf [32];
int i, j, k, l;
char *op = optbuf; char *op = optbuf;
const unsigned char *dp = data; const unsigned char *dp = data;
struct in_addr foo; 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++) { for (j = 0; j < numelem; j++) {
switch (fmtbuf [j]) { switch (fmtbuf [j]) {
case 't': case 't':
if (emit_quotes) /* endbuf-1 leaves room for NULL. */
*op++ = '"'; k = pretty_text(&op, endbuf - 1, &dp,
for (; dp < data + len; dp++) { data + len, emit_quotes);
if (!isascii (*dp) || if (k == -1) {
!isprint (*dp)) { log_error("Error printing text.");
/* Skip trailing NUL. */ break;
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;
}
if (emit_quotes)
*op++ = '"';
*op = 0; *op = 0;
break; 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 /* pretty-printing an array of enums is
going to get ugly. */ going to get ugly. */
case 'N': case 'N':
@ -1478,7 +1529,6 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
break; break;
} }
strcpy (op, enumbuf [j] -> values [i].name); strcpy (op, enumbuf [j] -> values [i].name);
op += strlen (op);
break; break;
case 'I': case 'I':
foo.s_addr = htonl (getULong (dp)); foo.s_addr = htonl (getULong (dp));
@ -2642,3 +2692,142 @@ void do_packet (interface, packet, len, from_port, from, hfrom)
dump_rc_history (0); dump_rc_history (0);
#endif #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 #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -1391,6 +1391,9 @@ int parse_option_code_definition (cfile, option)
case DOMAIN_NAME: case DOMAIN_NAME:
type = 'd'; type = 'd';
goto no_arrays; goto no_arrays;
case DOMAIN_LIST:
type = 'D';
goto no_arrays;
case TEXT: case TEXT:
type = 't'; type = 't';
no_arrays: no_arrays:
@ -4705,6 +4708,17 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
} }
break; 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... */ case 'd': /* Domain name... */
val = parse_host_name (cfile); val = parse_host_name (cfile);
if (!val) { if (!val) {
@ -5188,3 +5202,54 @@ int parse_warn (struct parse *cfile, const char *fmt, ...)
return 0; 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 #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #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 followed by a '.'. The width of the data is specified in the
named enumeration. Named enumerations are tracked in parse.c. named enumeration. Named enumerations are tracked in parse.c.
d - Domain name (i.e., FOO or FOO.BAR). d - Domain name (i.e., FOO or FOO.BAR).
D - Domain list (i.e., example.com eng.example.com)
*/ */
struct universe dhcp_universe; struct universe dhcp_universe;
@ -185,6 +186,7 @@ static struct option dhcp_options[] = {
{ "nds-context", "t", &dhcp_universe, 87, 1 }, { "nds-context", "t", &dhcp_universe, 87, 1 },
{ "uap-servers", "t", &dhcp_universe, 98, 1 }, { "uap-servers", "t", &dhcp_universe, 98, 1 },
{ "subnet-selection", "I", &dhcp_universe, 118, 1 }, { "subnet-selection", "I", &dhcp_universe, 118, 1 },
{ "domain-search", "D", &dhcp_universe, 119, 1 },
{ "vivco", "Evendor-class.", &dhcp_universe, 124, 1 }, { "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
{ "vivso", "Evendor.", &dhcp_universe, 125, 1 }, { "vivso", "Evendor.", &dhcp_universe, 125, 1 },
{ NULL, NULL, NULL, 0, 0 } { NULL, NULL, NULL, 0, 0 }

View File

@ -149,6 +149,7 @@ struct dhcp_packet {
#define DHO_FQDN 81 #define DHO_FQDN 81
#define DHO_DHCP_AGENT_OPTIONS 82 #define DHO_DHCP_AGENT_OPTIONS 82
#define DHO_SUBNET_SELECTION 118 /* RFC3011! */ #define DHO_SUBNET_SELECTION 118 /* RFC3011! */
#define DHO_DOMAIN_SEARCH 119 /* RFC3397 */
#define DHO_VIVCO_SUBOPTIONS 124 #define DHO_VIVCO_SUBOPTIONS 124
#define DHO_VIVSO_SUBOPTIONS 125 #define DHO_VIVSO_SUBOPTIONS 125
/* The DHO_AUTHENTICATE option is not a standard yet, so I've /* 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_auth_key PROTO ((struct data_string *, struct parse *));
int parse_warn (struct parse *, const char *, ...) int parse_warn (struct parse *, const char *, ...)
__attribute__((__format__(__printf__,2,3))); __attribute__((__format__(__printf__,2,3)));
struct expression *parse_domain_list (struct parse *cfile);
/* tree.c */ /* tree.c */
#if defined (NSUPDATE) #if defined (NSUPDATE)

View File

@ -322,7 +322,8 @@ enum dhcp_token {
MAX_LEASE_MISBALANCE = 626, MAX_LEASE_MISBALANCE = 626,
MAX_LEASE_OWNERSHIP = 627, MAX_LEASE_OWNERSHIP = 627,
MAX_BALANCE = 628, MAX_BALANCE = 628,
MIN_BALANCE = 629 MIN_BALANCE = 629,
DOMAIN_LIST = 630
}; };
#define is_identifier(x) ((x) >= FIRST_TOKEN && \ #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); int minires_ninit (res_state);
ns_rcode isc_rcode_to_ns (isc_result_t); 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) #if defined (MINIRES_LIB)
#define res_update minires_update #define res_update minires_update
#define res_mkupdate minires_mkupdate #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 *); unsigned, ns_tcp_tsig_state *);
isc_result_t ns_sign_tcp (unsigned char *, isc_result_t ns_sign_tcp (unsigned char *,
unsigned *, unsigned, int, ns_tcp_tsig_state *, int); 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_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 *, int ns_name_pack (const unsigned char *, unsigned char *,
unsigned, const unsigned char **, const unsigned char **); unsigned, const unsigned char **, const unsigned char **);
int ns_name_compress (const char *, unsigned char *, int ns_name_compress (const char *, unsigned char *,