33static void config_min_valid_lifetime(
struct element *,
struct parse *);
34static void config_def_valid_lifetime(
struct element *,
struct parse *);
35static void config_max_valid_lifetime(
struct element *,
struct parse *);
36static void config_file(
struct element *,
struct parse *);
37static void config_sname(
struct element *,
struct parse *);
38static void config_next_server(
struct element *,
struct parse *);
39static void config_vendor_option_space(
struct element *,
struct parse *);
40static void config_site_option_space(
struct element *,
struct parse *);
41static struct element *default_qualifying_suffix(
void);
42static void config_qualifying_suffix(
struct element *,
struct parse *);
43static void config_enable_updates(
struct element *,
struct parse *);
44static void config_ddns_update_style(
struct element *,
struct parse *);
45static void config_preferred_lifetime(
struct element *,
struct parse *);
46static void config_match_client_id(
struct element *,
struct parse *);
47static void config_echo_client_id(
struct element *,
struct parse *);
56static void putULong(
unsigned char *obuf, uint32_t val);
57static void putLong(
unsigned char *obuf, int32_t val);
58static void putUShort(
unsigned char *obuf, uint32_t val);
59static void putShort(
unsigned char *obuf, int32_t val);
102 if (brace_count > 0) {
106 if (brace_count == 0) {
111 }
else if (token ==
LBRACE) {
113 }
else if (token ==
SEMI && (brace_count == 0)) {
117 }
else if (token ==
EOL) {
154 s = (
char *)malloc(len + 1);
155 parse_error(cfile,
"no memory for string %s.", val);
156 memcpy(s, val, len + 1);
200 }
while (token ==
DOT);
219 unsigned char addr[4];
220 unsigned len =
sizeof(addr);
222 struct string *bin = NULL;
260 h = gethostbyname(name->
content);
261 if ((h == NULL) || (h->h_addr_list[0] == NULL))
263 if (check_multi && h->h_addr_list[1]) {
267 snprintf(msg,
sizeof(msg),
268 "/// %s resolves into multiple addresses",
279 parse_error(cfile,
"%s (%d): expecting IP address or hostname",
293 unsigned char addr[4];
294 unsigned len =
sizeof(addr);
303is_hex_string(
const char *s)
306 if (!isxdigit((
int)*s)) {
331 char v6[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
346 is_hex_string(val)) ||
353 val_len = strlen(val);
354 if ((v6_len + val_len) >=
sizeof(v6))
356 memcpy(v6+v6_len, val, val_len);
369 if (inet_pton(AF_INET6, v6, addr) <= 0)
437 if (!ether || (hlen != 6)) {
466 unsigned *max,
int separator,
467 int base,
unsigned size)
471 unsigned char *bufp = buf, *s;
473 struct string *r = NULL, *t = NULL;
476 bufp = (
unsigned char *)malloc(*max * size / 8);
478 parse_error(cfile,
"no space for numeric aggregate");
483 t =
makeString(size / 8,
"bigger than needed");
489 if (token != separator) {
517 }
while (++count != *max);
521 r =
makeString(count * size / 8, (
char *)bufp);
528 int base,
unsigned size)
530 const unsigned char *ptr = (
const unsigned char *)str;
547 }
else if (isascii(ptr[1]) && isdigit(ptr[1])) {
562 tval = tval -
'a' + 10;
563 else if (tval >=
'A')
564 tval = tval -
'A' + 10;
565 else if (tval >=
'0')
571 "Bogus number %s: digit %d not in base %d",
573 val = val * base + tval;
577 max = (1 << (size - 1));
579 max = (1 << (size - 1)) + ((1 << (size - 1)) - 1);
584 "%s%lo exceeds max (%d) for precision.",
586 (
unsigned long)val, max);
590 "%s%lx exceeds max (%d) for precision.",
592 (
unsigned long)val, max);
596 "%s%lu exceeds max (%d) for precision.",
598 (
unsigned long)val, max);
606 *buf = -(
unsigned long)val;
616 "Unexpected integer size: %d\n", size);
632 "Unexpected integer size: %d\n", size);
657 "expecting identifier after option keyword.");
661 parse_error(cfile,
"no memory for uname information.");
670 parse_error(cfile,
"expecting identifier after '.'");
676 parse_error(cfile,
"no option space named %s.", uname);
690 parse_error(cfile,
"unknown server option %s.", val);
698 else if (strncasecmp(val,
"unknown-", 8) == 0) {
699 code = atoi(val + 8);
736 snprintf(msg,
sizeof(msg),
737 "/// option %s.%s redefinition",
747 }
else if (allocate) {
757 parse_error(cfile,
"no option named %s in space %s",
776 int tsize = 1, lsize = 1;
790 parse_error(cfile,
"No memory for new option space.");
817 "expecting number 1, 2, 4.");
838 mapSet(nu, p,
"code-width");
878 mapSet(nu, p,
"length-width");
889 "expecting a 10base number");
895 }
while (token !=
SEMI);
949 struct string *encapsulated;
971 parse_error(cfile,
"expecting option code number.");
978 struct option *from_code = NULL;
982 if (from_code != NULL) {
1009 if (token ==
ARRAY) {
1034 if (has_encapsulation)
1036 "encapsulate must always be the last item.");
1054 arrayp = recordp + 1;
1056 if ((recordp) && (token ==
LBRACE))
1058 "only uniform array inside record.");
1081 switch (atoi(val)) {
1111 "%s bit precision is not supported.", val);
1119 parse_error(cfile,
"expecting \"integer\" keyword.");
1126 type =
"ipv4-address";
1130 type =
"ipv6-address";
1146 "MUST NOT be compressed");
1158 parse_error(cfile,
"arrays of text strings not %s",
1172 "expecting option space identifier");
1180 if (datatype->
length == 0)
1188 parse_error(cfile,
"array incompatible with zerolen.");
1200 if (arrayp > recordp) {
1205 if (token ==
COMMA) {
1206 if (no_more_in_record) {
1211 "%s must be at end of record.",
1212 last ==
't' ?
"text" :
"string");
1224 if (has_encapsulation && arrayp)
1226 "Arrays of encapsulations don't make sense.");
1229 if (is_array || arrayp) {
1235 mapSet(def, array_def,
"array");
1238 if (not_supported) {
1245 mapSet(def, saved_def,
"definition");
1248 "compatible with Kea");
1252 mapSet(def, type_def,
"type");
1253 }
else if (recordp) {
1264 if (has_encapsulation)
1268 if (optdef == NULL) {
1299 parse_error(cfile,
"expecting option code number.");
1312 parse_error(cfile,
"expecting option space identifier");
1315 parse_error(cfile,
"unknown option space %s", val);
1344 if ((strchr(fmt,
'A') != NULL) || (strchr(fmt,
'a') != NULL) ||
1345 (strchr(fmt,
'D') != NULL))
1348 if (strchr(fmt,
'E') != NULL)
1351 if ((strchr(fmt,
'Y') != NULL) || (strchr(fmt,
'A') != NULL) ||
1352 (strchr(fmt,
'E') != NULL) || (strchr(fmt,
'o') != NULL) ||
1353 (*fmt ==
'X') || (*fmt ==
'u'))
1359 if (datatype->
length != 0)
1398 g = strchr(fmt,
'.');
1424 }
while (*fmt !=
'\0');
1438 static unsigned char
1439 from64[] = {64, 64, 64, 64, 64, 64, 64, 64,
1440 64, 64, 64, 62, 64, 64, 64, 63,
1441 52, 53, 54, 55, 56, 57, 58, 59,
1442 60, 61, 64, 64, 64, 64, 64, 64,
1443 64, 0, 1, 2, 3, 4, 5, 6,
1444 7, 8, 9, 10, 11, 12, 13, 14,
1445 15, 16, 17, 18, 19, 20, 21, 22,
1446 23, 24, 25, 64, 64, 64, 64, 64,
1447 64, 26, 27, 28, 29, 30, 31, 32,
1448 33, 34, 35, 36, 37, 38, 39, 40,
1449 41, 42, 43, 44, 45, 46, 47, 48,
1450 49, 50, 51, 64, 64, 64, 64, 64};
1468 for (i = 0; val[i]; i++) {
1472 if (((val[i] <
' ') || (val[i] >
'z')) ||
1473 ((from64[val[i] -
' '] > 63) && (val[i] !=
'='))) {
1478 }
while (valid_base64);
1503 parse_error(cfile,
"expecting hexadecimal number.");
1506 snprintf(tbuf,
sizeof(tbuf),
"%02hhx", ibuf);
1508 snprintf(tbuf,
sizeof(tbuf),
":%02hhx", ibuf);
1537 parse_error(cfile,
"expecting hexadecimal number.");
1539 snprintf(tbuf,
sizeof(tbuf),
"%02hhx", ibuf);
1617 else if (token ==
LOCAL)
1620 parse_error(cfile,
"Expecting 'local' or 'default'.");
1628 mapSet(result, st,
"db-time-format");
1647 mapSet(result, st,
"add-class");
1657 mapSet(result, st,
"break");
1694 mapSet(result, st,
"config");
1701 goto switch_default;
1743 "case statement in inappropriate scope.");
1745 cfile, lose, case_context);
1750 parse_error(cfile,
"switch default statement in %s",
1751 "inappropriate scope.");
1756 mapSet(result, st,
"default");
1770 "%s can't be a variable name", val);
1774 mapSet(result, st, flag ?
"define" :
"set");
1791 "expecting argument name");
1796 }
while (token ==
COMMA);
1813 lose, case_context)) {
1817 mapSet(func, expr,
"body");
1818 mapSet(st, func,
"function");
1826 "expecting '=' in %s statement.",
1827 flag ?
"define" :
"set");
1834 "expecting expression.");
1840 mapSet(st, expr,
"value");
1849 parse_error(cfile,
"%s can't be a variable name", val);
1854 mapSet(result, st,
"unset");
1869 "expecting data expression.");
1875 mapSet(result, expr,
"eval");
1899 "expecting expression.");
1906 mapSet(expr, st,
"arguments");
1909 parse_error(cfile,
"right parenthesis expected.");
1911 mapSet(result, expr,
"execute");
1923 "expecting data expression.");
1929 mapSet(result, expr,
"return");
1939 mapSet(result, st,
"log");
1944 "yet log statements");
1959 else if (token ==
ERROR)
1963 else if (token ==
INFO)
1976 mapSet(st, pri,
"priority");
1984 mapSet(st, expr,
"message");
1988 parse_error(cfile,
"right parenthesis expected.");
2015 mapSet(result, zone,
"zone");
2051 (direct ? NULL : result,
2072 mapSet(result, expr,
"eval");
2117 mapSet(zone, values,
"primary");
2124 mapSet(zone, values,
"secondary");
2134 "expecting IP addr or "
2138 }
while (token ==
COMMA);
2147 mapSet(zone, values,
"primary6");
2154 mapSet(zone, values,
"secondary6");
2165 }
while (token ==
COMMA);
2251 "expecting key algorithm name.");
2255 s = strrchr(alg->
content,
'.');
2292 keys =
mapGet(result,
"tsig-keys");
2295 mapSet(result, keys,
"tsig-keys");
2310 struct parse *cfile,
2322 mapSet(result, statement,
"on");
2336 parse_error(cfile,
"expecting a lease event type");
2341 }
while (token ==
OR);
2362 mapSet(statement, body,
"body");
2376 struct parse *cfile,
2388 mapSet(result, statement,
"switch");
2403 "expecting data or numeric expression.");
2406 mapSet(statement, cond,
"condition");
2424 mapSet(statement, body,
"body");
2438 struct parse *cfile,
2453 ?
"data" :
"numeric"));
2462 mapSet(result, expr,
"case");
2478 struct parse *cfile,
2492 mapSet(result, statement,
"if");
2504 parse_error(cfile,
"boolean expression expected.");
2508 mapSet(statement, cond,
"condition");
2527 mapSet(statement, branch,
"then");
2532 if (token ==
ELSE) {
2541 "expecting if statement");
2545 }
else if (token !=
LBRACE)
2557 mapSet(statement, branch,
"else");
2558 }
else if (token ==
ELSIF) {
2564 "expecting conditional.");
2568 mapSet(statement, branch,
"else");
2587 struct parse *cfile,
2598 parse_error(cfile,
"Expecting a boolean expression.");
2611 if (!strcasecmp (val,
"true")
2612 || !strcasecmp (val,
"on"))
2614 else if (!strcasecmp (val,
"false")
2615 || !strcasecmp (val,
"off"))
2619 "boolean value (true/false/on/off) expected");
2646 struct parse *cfile,
2657 parse_error(cfile,
"Expecting a data expression.");
2669 struct parse *cfile,
2680 parse_error(cfile,
"Expecting a numeric expression.");
2688 struct parse *cfile,
2715 mapSet(expr, nexp,
"check");
2729 parse_error(cfile,
"boolean expression expected");
2734 mapSet(expr, nexp,
"not");
2770 mapSet(expr, nexp,
"exists");
2778 mapSet(expr, nexp,
"static");
2786 mapSet(expr, nexp,
"known");
2794 mapSet(expr, nexp,
"substring");
2807 "expecting data expression.");
2810 mapSet(nexp, arg,
"expression");
2813 if (token !=
COMMA) {
2823 "expecting numeric expression.");
2826 mapSet(nexp, arg,
"offset");
2835 mapSet(nexp, arg,
"length");
2840 parse_error(cfile,
"right parenthesis expected.");
2849 mapSet(expr, nexp,
"suffix");
2858 mapSet(nexp, arg,
"expression");
2867 mapSet(nexp, arg,
"length");
2892 mapSet(expr, nexp,
"lowercase");
2913 mapSet(expr, nexp,
"uppercase");
2921 mapSet(expr, nexp,
"concat");
2930 mapSet(nexp, arg,
"left");
2943 if (token ==
COMMA) {
2945 mapSet(nexp, chain,
"right");
2947 mapSet(chain, nexp,
"concat");
2948 mapSet(nexp, arg,
"left");
2949 goto concat_another;
2951 mapSet(nexp, arg,
"right");
2962 mapSet(expr, nexp,
"binary-to-ascii");
2971 mapSet(nexp, arg,
"base");
2980 mapSet(nexp, arg,
"width");
2989 mapSet(nexp, arg,
"separator");
2998 mapSet(nexp, arg,
"buffer");
3010 mapSet(expr, nexp,
"reverse");
3019 mapSet(nexp, arg,
"width");
3028 mapSet(nexp, arg,
"buffer");
3042 mapSet(expr, nexp,
"pick-first-value");
3055 }
while (token ==
COMMA);
3081 mapSet(expr, nexp,
"option");
3084 "not supported by Kea");
3086 mapSet(expr, nexp,
"config-option");
3095 mapSet(expr, nexp,
"hardware");
3103 mapSet(expr, nexp,
"leased-address");
3111 mapSet(expr, nexp,
"client-state");
3119 mapSet(expr, nexp,
"filename");
3127 mapSet(expr, nexp,
"server-name");
3135 mapSet(expr, nexp,
"lease-time");
3144 mapSet(expr, nexp,
"null");
3152 mapSet(expr, nexp,
"host-decl-name");
3160 mapSet(expr, nexp,
"packet");
3169 mapSet(nexp, arg,
"offset");
3178 mapSet(nexp, arg,
"length");
3203 "expecting data expression.");
3214 switch (atoi(val)) {
3216 mapSet(expr, nexp,
"extract-int8");
3220 mapSet(expr, nexp,
"extract-int16");
3224 mapSet(expr, nexp,
"extract-int32");
3228 parse_error(cfile,
"unsupported integer size %s", val);
3233 parse_error(cfile,
"right parenthesis expected.");
3247 parse_error(cfile,
"expecting numeric expression.");
3256 switch (atoi(val)) {
3258 mapSet(expr, nexp,
"encode-int8");
3262 mapSet(expr, nexp,
"encode-int16");
3266 mapSet(expr, nexp,
"encode-int32");
3270 parse_error(cfile,
"unsupported integer size %s", val);
3275 parse_error(cfile,
"right parenthesis expected.");
3307#ifndef ISC_R_SUCCESS
3308#define ISC_R_SUCCESS 0
3317#ifndef DHCP_R_NOTAUTH
3318#define DHCP_R_NOTAUTH ((6 << 16) + 21)
3327#ifndef ISC_R_NOTIMPLEMENTED
3328#define ISC_R_NOTIMPLEMENTED 27
3337#ifndef DHCP_R_NOTZONE
3338#define DHCP_R_NOTZONE ((6 << 16) + 22)
3347#ifndef DHCP_R_NXDOMAIN
3348#define DHCP_R_NXDOMAIN ((6 << 16) + 15)
3357#ifndef DHCP_R_NXRRSET
3358#define DHCP_R_NXRRSET ((6 << 16) + 20)
3367#ifndef DHCP_R_REFUSED
3368#define DHCP_R_REFUSED ((6 << 16) + 17)
3377#ifndef DHCP_R_SERVFAIL
3378#define DHCP_R_SERVFAIL ((6 << 16) + 14)
3387#ifndef DHCP_R_YXDOMAIN
3388#define DHCP_R_YXDOMAIN ((6 << 16) + 18)
3397#ifndef DHCP_R_YXRRSET
3398#define DHCP_R_YXRRSET ((6 << 16) + 19)
3418#define S_REBOOTING 1
3428#define S_SELECTING 3
3438#define S_REQUESTING 4
3468#define S_REBINDING 7
3483 parse_error(cfile,
"%s can't be a variable name", val);
3488 mapSet(expr, nexp,
"variable-exists");
3500 mapSet(expr, nexp,
"gethostname");
3521 "\"foo.example.com\"");
3525 mapSet(expr, nexp,
"gethostbyname");
3537 mapSet(expr, nexp,
"v6relay");
3546 mapSet(nexp, arg,
"relay");
3555 mapSet(nexp, arg,
"relay-option");
3579 mapSet(expr, nexp,
"variable-reference");
3587 mapSet(expr, nexp,
"funcall");
3589 mapSet(nexp, chain,
"name");
3599 "expecting expression.");
3605 }
while (token ==
COMMA);
3607 parse_error(cfile,
"Right parenthesis expected.");
3608 mapSet(nexp, chain,
"arguments");
3628 const char *binop_name;
3639 "expecting right-hand side.");
3653 parse_error(cfile,
"! in boolean context without =");
3669 else if (token ==
EQUAL)
3672 parse_error(cfile,
"expecting ~= or ~~ operator");
3767 "expecting a subexpression");
3773 binop_name =
"none";
3780 (rhs_context != lhs_context))
3786 binop_name =
"not-equal";
3789 binop_name =
"equal";
3800 binop_name =
"iregex-match";
3804 binop_name =
"regex-match";
3807 "expecting data expression");
3819 "expecting boolean expressions");
3827 binop_name =
"subtract";
3830 binop_name =
"divide";
3833 binop_name =
"multiply";
3836 binop_name =
"remainder";
3839 binop_name =
"binary-and";
3842 binop_name =
"binary-or";
3845 binop_name =
"binary-xor";
3850 "expecting numeric expressions");
3864 mapSet(expr, tmp, binop_name);
3868 mapSet(tmp, lhs,
"left");
3869 mapSet(tmp, rhs,
"right");
3881 mapSet(tmp, lhs,
"left");
3882 mapSet(tmp, rhs,
"right");
3885 mapSet(lhs, tmp, binop_name);
3907 if ((len > 0) && (isspace(val[0]) || isspace(val[len - 1]))) {
3911 for (i = 0; i < len; i++) {
3912 if (val[i] ==
',') {
3930 struct parse *cfile,
3965 mapSet(expr, elem,
"original-data");
3971 if ((fmt == NULL) || (*fmt == 0))
3972 parse_error(cfile,
"unknown format for option %s.%s\n",
3975 if ((strchr(fmt,
'Y') != NULL) || (strchr(fmt,
'A') != NULL) ||
3976 (strchr(fmt,
'E') != NULL) || (strchr(fmt,
'o') != NULL) ||
3977 (*fmt ==
'X') || (*fmt ==
'u'))
3980 if (strchr(fmt,
'N') != NULL)
3981 parse_error(cfile,
"unsupported format %s for option %s.%s\n",
3999 &canon_bool, &modified);
4000 if ((*fmt ==
'D') && (fmt[1] ==
'c'))
4002 if (require_binary) {
4011 }
while (*fmt !=
'\0');
4016 if (token ==
COMMA) {
4030 }
while (*fmt ==
'a');
4032 if (!modified ||
eqString(saved, data))
4038 "lowercase true or false");
4041 mapSet(expr, elem,
"data");
4071 else if (*fmt ==
'A')
4075 if ((*fmt ==
'A') || (*fmt ==
'a'))
4083 if (fmt[1] ==
'o') {
4093 if (token ==
SEMI) {
4102 g = strchr(fmt,
'.');
4105 "malformed encapsulation "
4114 g = strchr(fmt,
'.');
4117 "malformed enumeration "
4124 else if (fmt[1] !=
'o')
4128 }
while (*fmt !=
'\0');
4130 if ((*fmt ==
'A') || (*fmt ==
'a')) {
4133 if (token ==
COMMA) {
4139 if ((*fmt ==
'A') || (fmt[1] ==
'\0'))
4147 }
while ((*fmt ==
'A') || (*fmt ==
'a'));
4149 elem =
mapGet(expr,
"original-data");
4156 "last type in the record to binary");
4163 mapSet(expr, elem,
"data");
4178 if ((fmt == NULL) || (*fmt == 0))
4179 parse_error(cfile,
"unknown format for option %s.%s\n",
4182 if (strcmp(fmt,
"t") != 0) {
4184 parse_error(cfile,
"can't parse binary option data");
4185 data =
mapGet(expr,
"data");
4187 parse_error(cfile,
"can't get binary option data");
4194 parse_error(cfile,
"can't parse text option data");
4195 data =
mapGet(expr,
"data");
4199 parse_error(cfile,
"option data must be a string");
4212 struct parse *cfile,
4220 struct element *opt_data_list;
4241 msg =
makeString(-1,
"/// Kea does not support option data ");
4276 "to true when setting data "
4277 "for relevant options, cf Kea #250");
4289 "to true when setting data "
4290 "for relevant options, cf Kea #250");
4305 }
else if (token ==
EQUAL) {
4320 "expecting a data expression.");
4334 mapSet(opt_data, expr,
"original-data");
4338 mapSet(opt_data, data,
"data");
4349 mapSet(opt_data, data,
"data");
4353 mapSet(opt_data, expr,
"expression");
4362 if (result != NULL) {
4364 mapSet(result, opt_data,
"option");
4368 for (where = cfile->
stack_top; where > 0; --where) {
4373 opt_data_list =
mapGet(cfile->
stack[where],
"option-data");
4374 if (opt_data_list == NULL) {
4376 mapSet(cfile->
stack[where], opt_data_list,
"option-data");
4413 "or hexadecimal data.");
4425 "or hexadecimal data.");
4472 if (val[0] ==
'0' && isascii(val[1]) && isdigit(val[1]))
4480 if (strcasecmp(val,
"true") == 0)
4482 if (strcasecmp(val,
"on") == 0) {
4487 if (strcasecmp(val,
"false") == 0)
4489 if (strcasecmp(val,
"off") == 0) {
4503 parse_error(cfile,
"Bad format '%c' in parse_option_token.",
4540 "or hexadecimal data.");
4621 if ((strcasecmp(val,
"true") == 0) ||
4622 (strcasecmp(val,
"on") == 0))
4624 if ((strcasecmp(val,
"false") == 0) ||
4625 (strcasecmp(val,
"off") == 0))
4627 if (strcasecmp(val,
"ignore") == 0)
4640 parse_error(cfile,
"Bad format '%c' in parse_option_token.",
4658 if (token ==
COMMA) {
4683 }
while (token ==
COMMA);
4693 struct parse *cfile,
4712 parse_error(cfile,
"multiple value config option");
4728 else if (token ==
STRING)
4732 "or hexadecimal data.");
4758 parse_error(cfile,
"expecting IP address of hostname");
4781 convert_num(cfile, (
unsigned char *)&u32, val, 0, 32);
4789 convert_num(cfile, (
unsigned char *)&u16, val, 0, 16);
4797 convert_num(cfile, (
unsigned char *)&u8, val, 0, 8);
4805 if ((strcasecmp(val,
"true") == 0) ||
4806 (strcasecmp(val,
"on") == 0))
4808 else if ((strcasecmp(val,
"false") == 0) ||
4809 (strcasecmp(val,
"off") == 0))
4811 else if (strcasecmp(val,
"ignore") == 0) {
4819 parse_error(cfile,
"Bad format '%c' in parse_config_data.",
4823 mapSet(expr, elem,
"value");
4832 struct parse *cfile,
4838 struct comments *comments;
4859 msg =
makeString(-1,
"/// Kea does not support option data ");
4897 }
else if (token ==
EQUAL) {
4909 "expecting a data expression.");
4912 mapSet(config, expr,
"value");
4920 if (result != NULL) {
4922 mapSet(result, config,
"config");
4926 for (where = cfile->
stack_top; where > 0; --where) {
4934 config_list =
mapGet(cfile->
stack[where],
"config");
4935 if (config_list == NULL) {
4938 mapSet(cfile->
stack[where], config_list,
"config");
4948 config_def_valid_lifetime(config, cfile);
4951 config_max_valid_lifetime(config, cfile);
4954 config_min_valid_lifetime(config, cfile);
4957 config_file(config, cfile);
4960 config_sname(config, cfile);
4963 config_next_server(config, cfile);
4966 parse_error(cfile,
"authoritative is a statement, "
4967 "here it is used as a config option");
4969 config_vendor_option_space(config, cfile);
4972 config_site_option_space(config, cfile);
4975 config_qualifying_suffix(config, cfile);
4978 config_enable_updates(config, cfile);
4981 config_ddns_update_style(config, cfile);
4984 config_preferred_lifetime(config, cfile);
4987 config_match_client_id(config, cfile);
4990 config_echo_client_id(config, cfile);
4993 parse_error(cfile,
"unsupported config option %s (%u)",
5001config_def_valid_lifetime(
struct element *config,
struct parse *cfile)
5010 for (scope = cfile->
stack_top; scope > 0; --scope) {
5025 "unsupported scope");
5031 if (pop_from_pool) {
5033 "an internal pool scope");
5040config_min_valid_lifetime(
struct element *config,
struct parse *cfile)
5049 for (scope = cfile->
stack_top; scope > 0; --scope) {
5064 "unsupported scope");
5070 if (pop_from_pool) {
5072 "an internal pool scope");
5079config_max_valid_lifetime(
struct element *config,
struct parse *cfile)
5088 for (scope = cfile->
stack_top; scope > 0; --scope) {
5103 "unsupported scope");
5109 if (pop_from_pool) {
5111 "an internal pool scope");
5118config_file(
struct element *config,
struct parse *cfile)
5126 parse_error(cfile,
"boot-file-name is DHCPv4 only");
5130 for (scope = cfile->
stack_top; scope > 0; --scope) {
5146 "an unsupported scope");
5155config_sname(
struct element *config,
struct parse *cfile)
5163 parse_error(cfile,
"server-hostname is DHCPv4 only");
5167 for (scope = cfile->
stack_top; scope > 0; --scope) {
5183 "an unsupported scope");
5192config_next_server(
struct element *config,
struct parse *cfile)
5204 for (scope = cfile->
stack_top; scope > 0; --scope) {
5219 "an internal unsupported scope");
5226config_vendor_option_space(
struct element *config,
struct parse *cfile)
5235 parse_error(cfile,
"vendor-option-space is DHCPv4 only");
5246 parse_error(cfile,
"vendor-option-space has no value");
5249 "vendor-option-space value is not a string");
5261 for (i = 0; i <
listSize(defs); i++) {
5269 code =
mapGet(item,
"code");
5270 if ((code == NULL) ||
5274 old =
mapGet(item,
"encapsulate");
5298config_site_option_space(
struct element *config,
struct parse *cfile)
5306 parse_error(cfile,
"site-option-space is DHCPv4 only");
5310 parse_error(cfile,
"site-option-space has no value");
5312 parse_error(cfile,
"site-option-space value is not a string");
5320 msg =
makeString(-1,
"/// site-option-space '");
5325 msg =
makeString(-1,
"/// Please to move private (code 224..254)");
5334default_qualifying_suffix(
void)
5341 "domain-name option value)");
5351config_qualifying_suffix(
struct element *config,
struct parse *cfile)
5358 for (scope = cfile->
stack_top; scope > 0; --scope)
5386config_enable_updates(
struct element *config,
struct parse *cfile)
5393 for (scope = cfile->
stack_top; scope > 0; --scope)
5416 qs = default_qualifying_suffix();
5417 mapSet(d2, qs,
"qualifying-suffix");
5426config_ddns_update_style(
struct element *config,
struct parse *cfile)
5441 for (scope = cfile->
stack_top; scope > 0; --scope)
5445 msg =
makeString(-1,
"/// Unsupported ddns-update-style ");
5454 for (scope = cfile->
stack_top; scope > 0; --scope)
5479 qs = default_qualifying_suffix();
5480 mapSet(d2, qs,
"qualifying-suffix");
5489config_preferred_lifetime(
struct element *config,
struct parse *cfile)
5498 parse_error(cfile,
"preferred-lifetime is DHCPv6 only");
5502 for (scope = cfile->
stack_top; scope > 0; --scope) {
5517 "unsupported scope");
5523 if (pop_from_pool) {
5525 "an internal pool scope");
5531 "current value...");
5540 mapSet(cfile->
stack[scope], child,
"renew-timer");
5543 mapSet(cfile->
stack[scope], child,
"rebind-timer");
5547config_match_client_id(
struct element *config,
struct parse *cfile)
5555 parse_error(cfile,
"ignore-client-uids is DHCPv4 only");
5561 for (scope = cfile->
stack_top; scope > 0; --scope) {
5582 if (pop_from_pool) {
5584 "an internal pool scope");
5591config_echo_client_id(
struct element *config,
struct parse *cfile)
5598 parse_error(cfile,
"echo-client-id is DHCPv4 only");
5602 for (scope = cfile->
stack_top; scope > 0; --scope) {
5665putULong(
unsigned char *obuf, uint32_t val)
5667 uint32_t tmp = htonl(val);
5668 memcpy(obuf, &tmp,
sizeof(tmp));
5674 int32_t tmp = htonl(val);
5675 memcpy(obuf, &tmp,
sizeof(tmp));
5679putUShort(
unsigned char *obuf, uint32_t val)
5681 uint16_t tmp = htons(val);
5682 memcpy(obuf, &tmp,
sizeof(tmp));
5688 int16_t tmp = htons(val);
5689 memcpy(obuf, &tmp,
sizeof(tmp));
5904#ifdef keep_expr_const_data_precedence
5964#ifndef keep_expr_const_data_precedence
5975 return op_val(op1) - op_val(op2);
6110 fprintf(stderr,
"empty expression");
6111 if (expr->
key != NULL)
6112 fprintf(stderr,
" for %s", expr->
key);
6124 fprintf(stderr,
": %s",
key);
6126 fprintf(stderr,
", %s",
key);
6130 fputs(
"\n", stderr);
6139 return op_val(op) - op_val(
expression(expr));
int parse_allow_deny(struct option_cache **oc, struct parse *cfile, int flag)
enum dhcp_token next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile)
enum dhcp_token peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile)
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
enum dhcp_token next_token(const char **rval, unsigned *rlen, struct parse *cfile)
isc_result_t save_parse_state(struct parse *cfile)
isc_result_t restore_parse_state(struct parse *cfile)
int parse_boolean(struct parse *cfile)
unsigned char * parse_numeric_aggregate(struct parse *cfile, unsigned char *buf, unsigned *max, int separator, int base, unsigned size)
int parse_string(struct parse *cfile, char **sptr, unsigned *lptr)
int parse_option_token(struct expression **rv, struct parse *cfile, const char **fmt, struct expression *expr, int uniform, int lookups)
int parse_boolean_expression(struct expression **expr, struct parse *cfile, int *lose)
void skip_to_semi(struct parse *cfile)
int parse_option_statement(struct executable_statement **result, struct parse *cfile, int lookups, struct option *option, enum statement_op op)
int parse_expression(struct expression **expr, struct parse *cfile, int *lose, enum expression_context context, struct expression **plhs, enum expr_op binop)
int parse_semi(struct parse *cfile)
int parse_key(struct parse *cfile)
int parse_switch_statement(struct executable_statement **result, struct parse *cfile, int *lose)
int parse_option_code_definition(struct parse *cfile, struct option *option)
int parse_ip6_addr(struct parse *cfile, struct iaddr *addr)
int parse_zone(struct dns_zone *zone, struct parse *cfile)
void skip_to_rbrace(struct parse *cfile, int brace_count)
int parse_if_statement(struct executable_statement **result, struct parse *cfile, int *lose)
int parse_numeric_expression(struct expression **expr, struct parse *cfile, int *lose)
int parse_data_expression(struct expression **expr, struct parse *cfile, int *lose)
void convert_num(struct parse *cfile, unsigned char *buf, const char *str, int base, unsigned size)
int parse_executable_statements(struct executable_statement **statements, struct parse *cfile, int *lose, enum expression_context case_context)
struct expression * parse_domain_list(struct parse *cfile, int compress)
int parse_non_binary(struct expression **expr, struct parse *cfile, int *lose, enum expression_context context)
int parse_base64(struct data_string *data, struct parse *cfile)
char * parse_host_name(struct parse *cfile)
int parse_ip_addr_or_hostname(struct expression **expr, struct parse *cfile, int uniform)
int parse_cshl(struct data_string *data, struct parse *cfile)
void parse_hardware_param(struct parse *cfile, struct hardware *hardware)
int parse_on_statement(struct executable_statement **result, struct parse *cfile, int *lose)
int parse_option_data(struct expression **expr, struct parse *cfile, int lookups, struct option *option)
void parse_option_space_decl(struct parse *cfile)
int parse_ip_addr(struct parse *cfile, struct iaddr *addr)
int parse_executable_statement(struct executable_statement **result, struct parse *cfile, int *lose, enum expression_context case_context)
int parse_case_statement(struct executable_statement **result, struct parse *cfile, int *lose, enum expression_context case_context)
isc_result_t parse_option_name(struct parse *cfile, int allocate, int *known, struct option **opt)
void putShort(unsigned char *, int32_t)
void putLong(unsigned char *, int32_t)
void putUShort(unsigned char *, u_int32_t)
void putULong(unsigned char *, u_int32_t)
void concatString(struct string *s, const struct string *a)
void listPush(struct element *l, struct element *e)
struct comment * createComment(const char *line)
void resetInt(struct element *e, int64_t i)
isc_boolean_t eqString(const struct string *s, const struct string *o)
struct string * makeString(int l, const char *s)
isc_boolean_t boolValue(const struct element *e)
struct element * createHexa(struct string *h)
struct element * createList(void)
struct element * createBool(isc_boolean_t b)
struct string * allocString(void)
size_t mapSize(const struct element *m)
void appendString(struct string *s, const char *a)
struct element * listGet(struct element *l, int i)
struct string * stringValue(struct element *e)
struct element * createNull(void)
isc_boolean_t mapContains(const struct element *m, const char *k)
struct string * quote(struct string *s)
struct string * hexaValue(struct element *s)
struct element * createInt(int64_t i)
void mapSet(struct element *m, struct element *e, const char *k)
size_t listSize(const struct element *l)
void resetString(struct element *e, const struct string *s)
struct element * createMap(void)
struct element * createString(const struct string *s)
void resetBy(struct element *e, struct element *o)
void mapRemove(struct element *m, const char *k)
struct element * mapGet(struct element *m, const char *k)
int64_t intValue(const struct element *e)
struct string * makeStringExt(int l, const char *s, char fmt)
#define TAILQ_INSERT_TAIL(head, elm)
#define TAILQ_FOREACH(var, head)
#define TAILQ_CONCAT(head1, head2)
#define TAILQ_EMPTY(head)
#define DHO_VIVSO_SUBOPTIONS
#define skip_token(a, b, c)
#define HARDWARE_ADDR_LEN
struct element * eval_data_expression(struct element *expr, isc_boolean_t *modifiedp)
#define ISC_R_NOTIMPLEMENTED
isc_boolean_t is_data_expression(struct element *expr)
void parse_vendor_code_definition(struct parse *cfile, struct option *option)
isc_boolean_t is_boolean_expression(struct element *expr)
isc_boolean_t is_numeric_expression(struct element *expr)
struct string * escape_option_string(unsigned len, const char *val, isc_boolean_t *require_binary, isc_boolean_t *modified)
int expr_precedence(enum expr_op op, struct element *expr)
struct string * parse_ip6_addr_txt(struct parse *cfile)
isc_boolean_t parse_option_binary(struct element *expr, struct parse *cfile, struct option *option, isc_boolean_t ambiguous)
isc_boolean_t parse_config_statement(struct element *result, struct parse *cfile, struct option *option, enum statement_op op)
isc_boolean_t parse_config_data(struct element *expr, struct parse *cfile, struct option *option)
struct string * parse_hexa(struct parse *cfile)
struct string * parse_option_token_binary(struct parse *cfile, const char *fmt)
struct string * parse_option_textbin(struct parse *cfile, struct option *option)
struct string * convert_format(const char *fmt, isc_boolean_t *is_array, isc_boolean_t *encapsulate)
void parse_error(struct parse *cfile, const char *fmt,...)
struct option * option_lookup_code(const char *, unsigned)
void add_option_data(struct element *, struct element *)
struct option * option_lookup_name(const char *, const char *)
struct comments * get_config_comments(unsigned)
void push_option(struct option *)
@ supersede_option_statement
@ default_option_statement
@ prepend_option_statement
@ append_option_statement
struct space * space_lookup(const char *)
void push_space(struct space *)
enum option_status status
const struct space * space
enum option_status status
enum expression_context op_context(enum expr_op op)
int op_precedence(enum expr_op op1, enum expr_op op2)
@ context_data_or_numeric
@ expr_variable_reference