Changes since 4.0.0
+- Added explicit parser support for zero-length DHCP options, such as
+ rapid-commit, via format code 'Z'
+
- Exit with warning when DHCPv6-specific statements are used in the
config file but -6 is not specified.
return NS_YXRRSET;
break;
case 'z':
+ if (!strcasecmp (atom + 1, "erolen"))
+ return ZEROLEN;
if (!strcasecmp (atom + 1, "one"))
return ZONE;
break;
{
struct data_string tmp;
- if (src->len == 0)
+ if (src->len == 0 && option->format[0] != 'Z')
return 0;
memset(&tmp, 0, sizeof(tmp));
has_encapsulation = 1;
break;
+ case ZEROLEN:
+ type = 'Z';
+ if (arrayp) {
+ parse_warn (cfile, "array incompatible with zerolen.");
+ skip_to_rbrace (cfile, recordp);
+ if (recordp)
+ skip_to_semi (cfile);
+ return 0;
+ }
+ no_more_in_record = 1;
+ break;
+
default:
parse_warn (cfile, "unknown data type %s", val);
skip_to_rbrace (cfile, recordp);
fmt = option->format;
/* 'a' means always uniform */
- if ((fmt[0] != '\0') && (tolower((int)fmt[1]) == 'a'))
+ if ((fmt[0] != 'Z') && (tolower((int)fmt[1]) == 'a'))
uniform = 1;
do {
tmp = *expr;
*expr = NULL;
+
if (!parse_option_token(expr, cfile, &fmt, tmp,
- uniform, lookups)) {
+ uniform, lookups)) {
if (fmt [1] != 'o') {
if (tmp)
expression_dereference (&tmp,
*expr = tmp;
tmp = NULL;
}
- if (tmp)
+ if (tmp)
expression_dereference (&tmp, MDL);
- if (*fmt != '\0')
- fmt++;
-
+ fmt++;
} while (*fmt != '\0');
if ((*fmt == 'A') || (*fmt == 'a')) {
int lose;
token = peek_token (&val, (unsigned *)0, cfile);
- if ((token == SEMI) && (option->format[0] != '\0')) {
+ if ((token == SEMI) && (option->format[0] != 'Z')) {
/* Eat the semicolon... */
/*
* XXXSK: I'm not sure why we should ever get here, but we
return 0;
break;
- case '\0': /* Zero-length option. */
- buf[0] = '\0';
+ case 'Z': /* Zero-length option. */
+ token = peek_token (&val, (unsigned *)0, cfile);
+ if (token != SEMI) {
+ parse_warn(cfile, "semicolon expected.");
+ skip_to_semi(cfile);
+ }
+ buf[0] = '\0';
if (!make_const_data(&t, /* expression */
buf, /* buffer */
0, /* length */
break;
default:
- parse_warn (cfile, "Bad format %c in parse_option_token.",
+ parse_warn (cfile, "Bad format '%c' in parse_option_token.",
**fmt);
skip_to_semi (cfile);
return 0;
dp = buf;
goto alloc;
+ case 'Z': /* Zero-length option */
+ token = next_token(&val, (unsigned *)0, cfile);
+ if (token != SEMI) {
+ parse_warn(cfile,
+ "semicolon expected.");
+ goto parse_exit;
+ }
+ len = 0;
+ buf[0] = '\0';
+ break;
+
default:
log_error ("parse_option_param: Bad format %c",
*fmt);
d - Domain name (i.e., FOO or FOO.BAR).
D - Domain list (i.e., example.com eng.example.com)
c - When following a 'D' atom, enables compression pointers.
+ Z - Zero-length option
*/
struct universe dhcp_universe;
#endif
{ "unicast", "6", &dhcpv6_universe, 12, 1 },
{ "status-code", "Nstatus-codes.to", &dhcpv6_universe, 13, 1 },
- { "rapid-commit", "", &dhcpv6_universe, 14, 1 },
+ { "rapid-commit", "Z", &dhcpv6_universe, 14, 1 },
#if 0
/* XXX: user-class contents are of the form "StA" where the
* integer describes the length of the text field. We don't have
{ "vendor-opts", "Evsio.", &dhcpv6_universe, 17, 1 },
{ "interface-id", "X", &dhcpv6_universe, 18, 1 },
{ "reconf-msg", "Ndhcpv6-messages.", &dhcpv6_universe, 19, 1 },
- { "reconf-accept", "", &dhcpv6_universe, 20, 1 },
+ { "reconf-accept", "Z", &dhcpv6_universe, 20, 1 },
/* RFC3319 OPTIONS */
RANGE6 = 651,
WHITESPACE = 652,
TOKEN_ALSO = 653,
- AFTER = 654
+ AFTER = 654,
+ ZEROLEN = 655
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \