33 static unsigned char global_host_once = 1;
35 static int parse_binding_value(
struct parse *cfile,
62 #if defined(LDAP_CONFIGURATION)
63 if (res != ISC_R_SUCCESS)
66 return ldap_read_config ();
73 int group_type,
int leasep)
86 ttype = trace_readleases_type;
88 ttype = trace_readconf_type;
97 if (status != ISC_R_SUCCESS)
107 tflen = strlen (dbuf);
108 ulen = ulen - tflen - 1;
109 fbuf = dbuf + tflen + 1;
114 if ((file = open (filename, O_RDONLY | O_CLOEXEC)) < 0) {
116 log_error (
"Can't open lease database %s: %m --",
118 log_error (
" check for failed database %s!",
120 log_error (
"Please read the dhcpd.leases manual%s",
122 log_fatal (
"don't know what to do about this.");
124 log_fatal (
"Can't open %s: %m", filename);
128 cfile = (
struct parse *)0;
129 #if defined (TRACING)
130 flen = lseek (file, (off_t)0, SEEK_END);
133 log_fatal (
"Can't lseek on %s: %m", filename);
135 if (lseek (file, (off_t)0, SEEK_SET) < 0)
138 if (flen > 0x7FFFFFFFUL)
139 log_fatal (
"%s: file is too long to buffer.", filename);
144 tflen = strlen (filename);
147 log_fatal (
"No memory for %s (%d bytes)",
151 strcpy (dbuf, filename);
154 fbuf = dbuf + tflen + 1;
155 result = read (file, fbuf, ulen);
157 log_fatal (
"Can't read in %s: %m", filename);
159 log_fatal (
"%s: short read of %d bytes instead of %d.",
160 filename, ulen, result);
166 status =
new_parse(&cfile, -1, fbuf, ulen, filename, 0);
168 status =
new_parse(&cfile, file, NULL, 0, filename, 0);
170 if (status != ISC_R_SUCCESS || cfile == NULL)
178 #if defined (TRACING)
184 #if defined (TRACING)
191 static int postconf_initialized;
192 static int leaseconf_initialized;
197 tflen = strlen (data);
198 flen = len - tflen - 1;
199 fbuf = data + tflen + 1;
205 status =
new_parse(&cfile, -1, fbuf, flen, data, 0);
206 if (status == ISC_R_SUCCESS || cfile != NULL) {
207 if (ttype == trace_readleases_type)
216 if (!postconf_initialized && ttype == trace_readconf_type) {
218 postconf_initialized = 1;
221 if (!leaseconf_initialized && ttype == trace_readleases_type) {
223 leaseconf_initialized = 1;
244 token =
peek_token (&val, (
unsigned *)0, cfile);
269 token =
next_token (&val, (
unsigned *)0, cfile);
272 if (token ==
LEASE) {
276 lease_dereference (&lease,
MDL);
279 "possibly corrupt lease file");
280 }
else if (token ==
IA_NA) {
282 }
else if (token ==
IA_TA) {
284 }
else if (token ==
IA_PD) {
286 }
else if (token ==
CLASS) {
292 }
else if (token ==
HOST) {
294 }
else if (token ==
GROUP) {
296 #if defined (FAILOVER_PROTOCOL)
299 (cfile, (dhcp_failover_state_t *)0);
306 log_error (
"Corrupt lease file - possible data loss!");
367 token =
peek_token (&val, (
unsigned *)0, cfile);
372 token =
next_token (&val, (
unsigned *)0, cfile);
374 parse_warn (cfile,
"filename string expected.");
378 if (status != ISC_R_SUCCESS)
387 if (global_host_once &&
389 global_host_once = 0;
390 log_error(
"WARNING: Host declarations are "
391 "global. They are not limited to "
392 "the scope you declared them in.");
398 "host declarations not allowed here.");
409 "group declarations not allowed here.");
420 parse_warn (cfile,
"shared-network parameters not %s.",
435 "subnet declarations not allowed here.");
461 status = shared_network_allocate (&share,
MDL);
462 if (status != ISC_R_SUCCESS)
463 log_fatal (
"Can't allocate shared subnet: %s",
464 isc_result_totext (status));
466 log_fatal (
"Can't allocate group for shared net");
497 share->
name = strdup(n);
499 if (share->
name == NULL)
500 log_fatal(
"Out of memory allocating default "
501 "shared network name (\"%s\").", n);
509 shared_network_dereference(&share,
MDL);
516 "class declarations not allowed here.");
527 "class declarations not allowed here.");
538 "class declarations not allowed here.");
549 "class declarations not allowed here.");
559 memset (&hardware, 0,
sizeof hardware);
560 if (host_decl && memcmp(&hardware, &(host_decl->
interface),
561 sizeof(hardware)) != 0) {
562 parse_warn(cfile,
"Host %s hardware address already "
563 "configured.", host_decl->
name);
569 host_decl ->
interface = hardware;
571 parse_warn (cfile,
"hardware address parameter %s",
572 "not allowed here.");
584 "Only one fixed address "
585 "declaration per host.");
591 "fixed-address parameter not "
601 parse_warn (cfile,
"pool declared within pool.");
604 parse_warn (cfile,
"pool declared outside of network");
615 "range declaration not allowed here.");
628 "range6 declaration not allowed here.");
639 "prefix6 declaration not allowed here.");
650 "fixed-prefix6 declaration not "
661 parse_warn (cfile,
"pool6 declared within pool.");
664 parse_warn (cfile,
"pool6 declared outside of network");
675 token =
next_token (&val, (
unsigned *)0, cfile);
678 group -> authoritative = 0;
688 group -> authoritative = 1;
691 parse_warn (cfile,
"authority makes no sense here.");
701 log_fatal(
"Server identifier not in hash (%s:%d).",
708 token =
peek_token (&val, (
unsigned *)0, cfile);
709 if (token ==
SPACE) {
712 "option space definitions %s",
713 "may not be scoped.");
723 if (status == ISC_R_SUCCESS) {
724 token =
peek_token (&val, (
unsigned *)0, cfile);
728 "option definitions%s",
729 " may not be scoped.");
741 option_name_hash_delete(
744 option_code_hash_delete(
768 (&et, cfile, 1, option,
772 goto insert_statement;
780 parse_warn (cfile,
"failover peers may only be %s",
781 "defined in shared-network");
782 log_error (
"declarations and the outer scope.");
786 token =
next_token (&val, (
unsigned *)0, cfile);
787 #if defined (FAILOVER_PROTOCOL)
809 "expecting a declaration");
812 "expecting a parameter %s",
865 #if defined (FAILOVER_PROTOCOL)
873 dhcp_failover_state_t *peer;
878 unsigned hba_len =
sizeof hba;
882 dhcp_failover_config_t *cp;
884 token =
next_token (&val, (
unsigned *)0, cfile);
891 token =
next_token (&val, (
unsigned *)0, cfile);
895 log_fatal (
"no memory for peer name %s", name);
898 parse_warn (cfile,
"expecting failover peer name.");
904 peer = (dhcp_failover_state_t *)0;
907 token =
next_token (&val, (
unsigned *)0, cfile);
910 parse_warn (cfile,
"failover peer reference not %s",
911 "in shared-network declaration");
914 parse_warn (cfile,
"reference to unknown%s%s",
915 " failover peer ", name);
919 dhcp_failover_state_reference
923 dhcp_failover_state_dereference (&peer,
MDL);
926 }
else if (token ==
STATE) {
928 parse_warn (cfile,
"state declaration for unknown%s%s",
929 " failover peer ", name);
934 dhcp_failover_state_dereference (&peer,
MDL);
937 }
else if (token !=
LBRACE) {
944 parse_warn (cfile,
"redeclaration of failover peer %s", name);
946 dhcp_failover_state_dereference (&peer,
MDL);
951 status = dhcp_failover_state_allocate (&peer,
MDL);
952 if (status != ISC_R_SUCCESS)
953 log_fatal (
"Can't allocate failover peer %s: %s",
954 name, isc_result_totext (status));
962 token =
next_token (&val, (
unsigned *)0, cfile);
968 peer -> i_am = primary;
972 peer -> i_am = secondary;
975 "secondary may not define %s",
976 "load balance settings.");
980 cp = &peer -> partner;
987 dhcp_failover_state_dereference (&peer,
MDL);
997 token =
next_token (&val, (
unsigned *)0, cfile);
1002 cp -> port = atoi (val);
1006 tp = &peer->max_lease_misbalance;
1010 tp = &peer->max_lease_ownership;
1014 tp = &peer->max_balance;
1018 tp = &peer->min_balance;
1022 tp = &peer->auto_partner_down;
1026 tp = &cp -> max_response_delay;
1028 token =
next_token (&val, (
unsigned *)0, cfile);
1032 dhcp_failover_state_dereference (&peer,
MDL);
1039 tp = &cp -> max_flying_updates;
1048 if (peer -> i_am == secondary)
1050 "secondary may not define %s",
1051 "load balance settings.");
1055 dhcp_failover_state_dereference (&peer,
MDL);
1058 if (hba_len != 32) {
1060 "HBA must be exactly 32 bytes.");
1069 memcpy (peer -> hba, hba, 32);
1073 token =
next_token (&val, (
unsigned *)0, cfile);
1074 if (peer -> i_am == secondary)
1076 "secondary may not define %s",
1077 "load balance settings.");
1081 dhcp_failover_state_dereference (&peer,
MDL);
1087 "0 and 256, inclusive");
1089 memset (hba, 0,
sizeof hba);
1090 for (i = 0; i < split; i++) {
1092 hba [i / 8] |= (1 << (i & 7));
1099 token =
next_token (&val, (
unsigned *)0, cfile);
1106 token =
next_token (&val, (
unsigned *)0, cfile);
1111 token =
next_token (&val, (
unsigned *)0, cfile);
1116 token =
next_token (&val, (
unsigned *)0, cfile);
1121 peer -> load_balance_max_secs = atoi (val);
1126 "invalid statement in peer declaration");
1128 dhcp_failover_state_dereference (&peer,
MDL);
1133 dhcp_failover_state_dereference (&peer,
MDL);
1136 }
while (token !=
RBRACE);
1141 if (!peer -> partner.address)
1142 parse_warn (cfile,
"peer address may not be omitted");
1145 peer->me.port = DEFAULT_FAILOVER_PORT;
1146 if (!peer->partner.port)
1147 peer->partner.port = DEFAULT_FAILOVER_PORT;
1149 if (peer -> i_am == primary) {
1152 "primary failover server must have hba or split.");
1153 }
else if (!peer -> mclt) {
1155 "primary failover server must have mclt.");
1159 if (!peer->max_lease_misbalance)
1160 peer->max_lease_misbalance = DEFAULT_MAX_LEASE_MISBALANCE;
1161 if (!peer->max_lease_ownership)
1162 peer->max_lease_ownership = DEFAULT_MAX_LEASE_OWNERSHIP;
1163 if (!peer->max_balance)
1164 peer->max_balance = DEFAULT_MAX_BALANCE_TIME;
1165 if (!peer->min_balance)
1166 peer->min_balance = DEFAULT_MIN_BALANCE_TIME;
1167 if (!peer->me.max_flying_updates)
1168 peer->me.max_flying_updates = DEFAULT_MAX_FLYING_UPDATES;
1169 if (!peer->me.max_response_delay)
1170 peer->me.max_response_delay = DEFAULT_MAX_RESPONSE_DELAY;
1176 if (peer -> i_am == primary) {
1189 if (status != ISC_R_SUCCESS)
1191 peer -> name, isc_result_totext (status));
1192 dhcp_failover_state_dereference (&peer,
MDL);
1196 dhcp_failover_state_t *peer)
1201 dhcp_failover_state_t *state;
1202 dhcp_failover_config_t *cp;
1205 token =
next_token (&val, (
unsigned *)0, cfile);
1206 if (token !=
PEER) {
1212 token =
next_token (&val, (
unsigned *)0, cfile);
1216 log_fatal (
"failover peer name %s: no memory",
1220 parse_warn (cfile,
"expecting failover peer name.");
1226 state = (dhcp_failover_state_t *)0;
1229 parse_warn (cfile,
"unknown failover peer: %s", name);
1234 token =
next_token (&val, (
unsigned *)0, cfile);
1235 if (token !=
STATE) {
1242 state = (dhcp_failover_state_t *)0;
1243 dhcp_failover_state_reference (&state, peer,
MDL);
1245 token =
next_token (&val, (
unsigned *)0, cfile);
1250 dhcp_failover_state_dereference (&state,
MDL);
1254 token =
next_token (&val, (
unsigned *)0, cfile);
1261 token =
next_token (&val, (
unsigned *)0, cfile);
1262 if (token !=
STATE) {
1267 &cp -> state, &cp -> stos);
1271 cp = &state -> partner;
1275 if (state -> i_am == primary) {
1277 "mclt not valid for primary");
1280 token =
next_token (&val, (
unsigned *)0, cfile);
1285 state -> mclt = atoi (val);
1290 parse_warn (cfile,
"expecting state setting.");
1293 dhcp_failover_state_dereference (&state,
MDL);
1296 }
while (token !=
RBRACE);
1297 dhcp_failover_state_dereference (&state,
MDL);
1301 struct
parse *cfile;
1310 token =
next_token (&val, (
unsigned *)0, cfile);
1365 parse_warn (cfile,
"unknown failover state");
1370 token =
next_token (&val, (
unsigned *)0, cfile);
1371 if (token ==
SEMI) {
1425 void get_permit(cfile, permit_head, is_allow, valid_from, valid_until)
1426 struct
parse *cfile;
1427 struct
permit **permit_head;
1429 TIME *valid_from, *valid_until;
1434 int need_clients = 1;
1499 permit->
class = NULL;
1507 if (*valid_from || *valid_until) {
1508 parse_warn(cfile,
"duplicate \"after\" clause.");
1524 parse_warn (cfile,
"expecting permit type.");
1534 if ((need_clients != 0) &&
1542 while (*permit_head)
1543 permit_head = &((*permit_head)->next);
1544 *permit_head = permit;
1557 struct permit *plp, *prp;
1564 for (plp = lhs; plp; plp = plp ->
next) {
1566 for (prp = rhs; prp; prp = prp ->
next) {
1567 if (prp -> type == plp -> type &&
1569 prp ->
class == plp ->
class)) {
1600 struct
parse *cfile;
1601 struct group *group;
1608 int declaration = 0;
1609 isc_result_t status;
1610 struct lease *lpchain = NULL, *lp;
1613 status = pool_allocate(&pool,
MDL);
1614 if (status != ISC_R_SUCCESS)
1616 isc_result_totext (status));
1626 parse_warn(cfile,
"Dynamic pools are only valid inside "
1627 "subnet or shared-network statements.");
1636 #if defined (FAILOVER_PROTOCOL)
1639 dhcp_failover_state_reference
1645 pool_dereference(&pool,
MDL);
1658 "expecting \"failover peer\".");
1662 #if defined (FAILOVER_PROTOCOL)
1664 dhcp_failover_state_dereference
1669 #if defined (FAILOVER_PROTOCOL)
1673 if (token !=
PEER) {
1685 dhcp_failover_state_dereference
1689 if (status != ISC_R_SUCCESS)
1691 "failover peer %s: %s", val,
1692 isc_result_totext (status));
1742 #if defined (FAILOVER_PROTOCOL)
1758 for (lp = lpchain; lp; lp = lp->
next) {
1759 pool_dereference(&lp->pool,
MDL);
1760 pool_reference(&lp->pool, pp,
MDL);
1763 #if defined (BINARY_LEASES)
1777 for (; *p; p = &((*p)->next))
1779 pool_reference(p, pool,
MDL);
1785 parse_warn(cfile,
"Pool declaration with no address range.");
1786 log_error(
"Pool declarations must always contain at least");
1794 lease_reference(&lp, lpchain,
MDL);
1795 lease_dereference(&lpchain,
MDL);
1797 lease_reference(&lpchain, lp->
next,
MDL);
1798 lease_dereference(&lp->next,
MDL);
1799 lease_dereference(&lp,
MDL);
1802 pool_dereference(&pool,
MDL);
1809 struct
parse *cfile;
1814 token =
next_token (&val, (
unsigned *)0, cfile);
1827 struct
parse *cfile;
1828 struct group *group;
1834 int declaration = 0;
1837 isc_result_t status;
1844 parse_warn (cfile,
"expecting a name for host declaration.");
1850 status = host_allocate (&host,
MDL);
1851 if (status != ISC_R_SUCCESS)
1852 log_fatal (
"can't allocate host decl struct %s: %s",
1853 name, isc_result_totext (status));
1854 host -> name =
name;
1856 log_fatal (
"can't clone group for host %s", name);
1858 host_dereference (&host,
MDL);
1866 token =
peek_token (&val, (
unsigned *)0, cfile);
1873 parse_warn (cfile,
"unexpected end of file");
1895 if (token ==
GROUP) {
1898 token =
next_token (&val, (
unsigned *)0, cfile);
1901 "expecting string or identifier.");
1907 val, strlen (val),
MDL)) {
1908 parse_warn (cfile,
"unknown group %s in host %s",
1911 if (host -> named_group)
1912 group_object_dereference
1913 (&host -> named_group,
MDL);
1914 group_object_reference (&host -> named_group,
1916 group_object_dereference (&go,
MDL);
1925 unsigned char *t = 0;
1933 "client identifier.",
1939 token =
peek_token (&val, (
unsigned *)0, cfile);
1943 host -> client_identifier.terminated = 1;
1948 (
unsigned char *)0, &len,
':', 16, 8);
1951 "expecting hex list.");
1954 s = (
const char *)t;
1957 (&host -> client_identifier.buffer,
1958 len + host -> client_identifier.terminated,
MDL))
1959 log_fatal (
"no memory for uid for host %s.",
1961 host -> client_identifier.data =
1962 host -> client_identifier.buffer -> data;
1963 host -> client_identifier.len = len;
1964 memcpy (host -> client_identifier.buffer -> data, s,
1965 len + host -> client_identifier.terminated);
1977 "only one host-identifier allowed "
1988 "host-identifier v6relopt "
1989 "must have a number");
1993 host->
relays = atoi(val);
1996 "host-identifier v6relopt "
1997 "must have a number >= 0");
2001 }
else if (token !=
OPTION) {
2003 "host-identifier must be an option"
2011 if ((status != ISC_R_SUCCESS) || (option == NULL)) {
2050 (
unsigned char *)host -> name,
2051 strlen (host -> name),
MDL)) {
2053 host_dereference (&hp,
MDL);
2057 if (host -> group -> statements ||
2058 (host -> group -> authoritative !=
2060 if (host -> group -> next)
2080 if (status != ISC_R_SUCCESS)
2081 parse_warn (cfile,
"host %s: %s", host -> name,
2082 isc_result_totext (status));
2084 host_dereference (&host,
MDL);
2092 struct
parse *cfile;
2093 struct group *group;
2098 struct class *
class = NULL, *pc = NULL;
2099 int declaration = 0;
2106 isc_result_t status = ISC_R_FAILURE;
2107 int matchedonce = 0;
2108 int submatchedonce = 0;
2126 class_reference(&
class, pc,
MDL);
2128 class_dereference(&pc,
MDL);
2143 data.
len = strlen (val);
2146 log_fatal (
"no memory for class name.");
2150 tname = type ?
"implicit-vendor-class" :
"implicit-user-class";
2160 log_fatal (
"No memory for class name %s.", tname);
2175 class_dereference (&pc,
MDL);
2181 memcpy ((
char *)data.
buffer -> data, val,
2184 memset (&data, 0,
sizeof data);
2187 class_dereference (&pc,
MDL);
2191 parse_warn (cfile,
"Expecting string or hex list.");
2193 class_dereference (&pc,
MDL);
2201 class_hash_lookup (&
class, pc -> hash,
2208 status = subclass_allocate (&
class,
MDL);
2210 status = class_allocate (&
class,
MDL);
2214 class_reference (&
class -> superclass, pc,
MDL);
2215 class -> lease_limit = pc -> lease_limit;
2216 if (
class -> lease_limit) {
2217 class -> billed_leases =
2218 dmalloc (
class -> lease_limit *
2220 if (!
class -> billed_leases)
2222 memset (
class -> billed_leases, 0,
2223 (
class -> lease_limit *
2224 sizeof (
struct lease *)));
2229 log_fatal (
"No memory for subclass hash.");
2230 class_hash_add (pc -> hash,
2231 (
const char *)
class -> hash_string.data,
2232 class -> hash_string.len,
2233 (
void *)
class,
MDL);
2238 log_fatal (
"no memory to clone class group.");
2247 log_fatal (
"no memory for class statement.");
2248 stmt -> op = supersede_option_statement;
2251 stmt -> data.option -> data = data;
2255 option_code_hash_lookup(
2260 class -> statements = stmt;
2273 if (
class -> superclass) {
2275 if (token ==
SEMI) {
2279 status = class_reference (cp,
class,
MDL);
2280 class_dereference (&
class,
MDL);
2282 class_dereference (&pc,
MDL);
2283 return cp ? (status == ISC_R_SUCCESS) : 1;
2292 class_dereference (&
class,
MDL);
2294 class_dereference (&pc,
MDL);
2305 parse_warn (cfile,
"unexpected end of file");
2307 }
else if (token ==
DYNAMIC) {
2319 }
else if (token ==
MATCH) {
2322 "invalid match in subclass.");
2333 "one 'match if' clause.");
2344 "expecting boolean expr.");
2348 #if defined (DEBUG_EXPRESSION_PARSE)
2354 }
else if (token ==
SPAWN) {
2358 "invalid spawn in subclass.");
2362 class -> spawning = 1;
2364 if (token !=
WITH) {
2366 "expecting with after spawn");
2371 if (submatchedonce) {
2373 "can't override existing %s.",
2385 "expecting data expr.");
2389 #if defined (DEBUG_EXPRESSION_PARSE)
2395 }
else if (token ==
LEASE) {
2398 if (token !=
LIMIT) {
2411 class -> lease_limit = atoi (val);
2414 class -> billed_leases =
2415 dmalloc (
class -> lease_limit *
2417 if (!
class -> billed_leases)
2418 log_fatal (
"no memory for billed leases.");
2419 memset (
class -> billed_leases, 0,
2420 (
class -> lease_limit *
2421 sizeof (
struct lease *)));
2433 struct class *theclass = NULL;
2436 if (status == ISC_R_SUCCESS) {
2438 class_dereference(&theclass,
MDL);
2441 class_hash_delete(pc->hash,
2453 class_reference (&c ->
nic,
class,
MDL);
2458 status = class_reference (cp,
class,
MDL);
2459 class_dereference (&
class,
MDL);
2461 class_dereference (&pc,
MDL);
2462 return cp ? (status == ISC_R_SUCCESS) : 1;
2469 struct
parse *cfile;
2470 struct group *group;
2476 int declaration = 0;
2477 isc_result_t status;
2480 status = shared_network_allocate (&share,
MDL);
2481 if (status != ISC_R_SUCCESS)
2482 log_fatal (
"Can't allocate shared subnet: %s",
2483 isc_result_totext (status));
2485 log_fatal (
"Can't clone group for shared net");
2491 token =
peek_token (&val, (
unsigned *)0, cfile);
2496 parse_warn (cfile,
"zero-length shared network name");
2497 val =
"<no-name-given>";
2501 log_fatal (
"no memory for shared network name");
2507 "expecting a name for shared-network");
2509 shared_network_dereference (&share,
MDL);
2513 share -> name =
name;
2516 shared_network_dereference (&share,
MDL);
2521 token =
peek_token (&val, (
unsigned *)0, cfile);
2526 "empty shared-network decl");
2529 shared_network_dereference (&share,
MDL);
2533 parse_warn (cfile,
"unexpected end of file");
2537 token =
next_token (&val, (
unsigned *)0, cfile);
2549 shared_network_dereference (&share,
MDL);
2554 common_subnet_parsing(
struct parse *cfile,
2558 struct subnet *t, *u;
2560 int declaration = 0;
2565 subnet_dereference(&subnet,
MDL);
2576 parse_warn (cfile,
"unexpected end of file");
2594 subnet_reference(&share->
subnets, subnet,
MDL);
2606 subnet_dereference(&share->
subnets,
2608 subnet_reference(&share->
subnets,
2611 subnet_dereference(&subnet,
MDL);
2618 subnet_dereference(&subnet,
MDL);
2626 struct
parse *cfile;
2631 struct subnet *subnet;
2633 unsigned char addr [4];
2634 unsigned len =
sizeof addr;
2635 isc_result_t status;
2637 subnet = (
struct subnet *)0;
2638 status = subnet_allocate (&subnet,
MDL);
2639 if (status != ISC_R_SUCCESS)
2640 log_fatal (
"Allocation of new subnet failed: %s",
2641 isc_result_totext (status));
2656 log_fatal(
"Allocation of group for new subnet failed.");
2659 subnet_reference (&subnet -> group -> subnet, subnet,
MDL);
2663 subnet_dereference (&subnet,
MDL);
2666 memcpy (iaddr.
iabuf, addr, len);
2668 subnet ->
net = iaddr;
2670 token =
next_token (&val, (
unsigned *)0, cfile);
2679 subnet_dereference (&subnet,
MDL);
2682 memcpy (iaddr.
iabuf, addr, len);
2692 "subnet %s netmask %s: bad subnet number/mask combination.",
2695 subnet_dereference (&subnet,
MDL);
2700 common_subnet_parsing(cfile, share, subnet);
2708 #if !defined(DHCPv6)
2712 struct subnet *subnet;
2713 isc_result_t status;
2718 const static int mask[] = { 0x00, 0x80, 0xC0, 0xE0,
2719 0xF0, 0xF8, 0xFC, 0xFE };
2723 parse_warn(cfile,
"subnet6 statement is only supported "
2730 status = subnet_allocate(&subnet,
MDL);
2731 if (status != ISC_R_SUCCESS) {
2732 log_fatal(
"Allocation of new subnet failed: %s",
2733 isc_result_totext(status));
2749 log_fatal(
"Allocation of group for new subnet failed.");
2755 subnet_dereference(&subnet,
MDL);
2760 if (token !=
SLASH) {
2777 parse_warn(cfile,
"Expecting a number between 0 and 128.");
2783 parse_warn(cfile,
"New subnet mask too short.");
2793 if (ofs < subnet->netmask.len) {
2796 while (--ofs >= 0) {
2802 if (memcmp(&iaddr, &subnet->
net, 16) != 0) {
2804 "subnet %s/%d: prefix not long enough for address.",
2806 subnet_dereference(&subnet,
MDL);
2811 if (!common_subnet_parsing(cfile, share, subnet)) {
2820 struct
parse *cfile;
2821 struct group *group;
2826 int declaration = 0;
2828 isc_result_t status;
2836 log_fatal(
"no memory for explicit group.");
2844 log_fatal(
"no memory for group decl name %s", val);
2866 }
else if (token ==
DYNAMIC) {
2870 }
else if (token ==
STATIC) {
2885 strlen(name),
MDL)) {
2891 status = group_object_allocate(&t,
MDL);
2892 if (status != ISC_R_SUCCESS)
2893 log_fatal(
"no memory for group decl %s: %s",
2894 val, isc_result_totext(status));
2903 group_object_dereference(&t,
MDL);
2913 struct parse *cfile,
2950 if (token ==
COMMA) {
2953 }
while (token ==
COMMA);
2987 unsigned char addr [4];
2988 unsigned len =
sizeof addr;
2996 int noequal, newbinding;
2999 isc_result_t status;
3003 unsigned buflen = 0;
3004 struct class *
class;
3006 lease = (
struct lease *)0;
3007 status = lease_allocate (&lease,
MDL);
3008 if (status != ISC_R_SUCCESS)
3013 lease_dereference (&lease,
MDL);
3020 lease_dereference (&lease,
MDL);
3025 token =
next_token (&val, (
unsigned *)0, cfile);
3029 parse_warn (cfile,
"unexpected end of file");
3032 strncpy (tbuf, val,
sizeof tbuf);
3033 tbuf [(
sizeof tbuf) - 1] = 0;
3085 token =
peek_token (&val, (
unsigned *)0, cfile);
3087 unsigned char *tuid;
3089 if (buflen < sizeof lease ->
uid_buf) {
3094 tuid = ((
unsigned char *)
3098 lease_dereference (&lease,
3105 memcpy (tuid, val, lease ->
uid_len);
3106 lease ->
uid = tuid;
3110 (cfile, (
unsigned char *)0,
3111 &buflen,
':', 16, 8));
3112 if (!lease ->
uid) {
3113 lease_dereference (&lease,
MDL);
3119 lease ->
uid = (
unsigned char *)0;
3127 if (!lease ->
uid) {
3134 token =
next_token (&val, (
unsigned *)0, cfile);
3138 lease_dereference (&lease,
MDL);
3173 token =
next_token (&val, (
unsigned *)0, cfile);
3179 goto do_binding_state;
3189 goto do_binding_state;
3195 token =
next_token (&val, (
unsigned *)0, cfile);
3196 if (token !=
STATE) {
3201 token =
next_token (&val, (
unsigned *)0, cfile);
3239 "%s: expecting a binding state.",
3245 if (seenbit == 256) {
3254 if (!(seenmask & 128))
3258 if (!(seenmask & 512))
3260 }
else if (seenbit == 128)
3262 else if (seenbit == 512)
3265 log_fatal(
"Impossible condition at %s:%d.",
3273 token =
peek_token (&val, (
unsigned *)0, cfile);
3278 lease_dereference (&lease,
MDL);
3288 "expecting a hostname.");
3290 lease_dereference (&lease,
MDL);
3298 class = (struct class *)0;
3299 token =
next_token (&val, (
unsigned *)0, cfile);
3300 if (token ==
CLASS) {
3302 (
unsigned *)0, cfile);
3310 if (lease -> billing_class)
3311 class_dereference (&lease -> billing_class,
3316 "unknown class %s", val);
3319 if (lease -> billing_class)
3320 class_dereference (&lease -> billing_class,
3330 class_reference (&lease -> billing_class,
3332 class_dereference (&
class,
MDL);
3341 lease_dereference (&lease,
MDL);
3346 on->
data.
on.statements) {
3353 on->
data.
on.statements) {
3371 "agent option expected.");
3378 log_error (
"no memory to stash agent option");
3382 *p; p = &((*p) -> cdr))
3386 &((*p) -> car)), oc,
MDL);
3394 token =
next_token (&val, (
unsigned *)0, cfile);
3397 "%s can't be a variable name",
3401 lease_dereference (&lease,
MDL);
3410 binding = (
struct binding *)0;
3413 if (!lease -> scope)
3415 (&lease -> scope,
MDL)))
3421 memset (binding, 0,
sizeof *binding);
3424 if (!binding -> name)
3427 strcpy (binding -> name, val);
3435 log_fatal(
"no memory for binding value.");
3438 token =
next_token (&val, (
unsigned *)0, cfile);
3439 if (token !=
EQUAL) {
3441 "expecting '=' in set statement.");
3446 if (!parse_binding_value(cfile, nv)) {
3448 lease_dereference(&lease,
MDL);
3469 if (!strcasecmp (val,
"ddns-fwd-name")) {
3473 }
else if (!strcasecmp (val,
"ddns-rev-name")) {
3478 parse_warn(cfile,
"Unexpected configuration "
3482 lease_dereference (&lease,
MDL);
3486 if (seenmask & seenbit) {
3488 "Too many %s parameters in lease %s\n",
3491 seenmask |= seenbit;
3496 if (!(seenmask & 256)) {
3500 #if defined (FAILOVER_PROTOCOL)
3507 #if defined (FAILOVER_PROTOCOL)
3520 if (!(seenmask & 65536))
3523 lease_reference (lp, lease,
MDL);
3524 lease_dereference (&lease,
MDL);
3543 if ((cfile == NULL) || (value == NULL))
3550 value->
type = binding_data;
3563 value->
type = binding_data;
3583 }
else if (token ==
PERCENT) {
3587 parse_warn(cfile,
"expecting decimal number.");
3592 value->
type = binding_numeric;
3594 }
else if (token ==
NAME) {
3596 value->
type = binding_boolean;
3597 if (!strcasecmp(val,
"true"))
3599 else if (!strcasecmp(val,
"false"))
3602 parse_warn(cfile,
"expecting true or false");
3608 parse_warn (cfile,
"expecting a constant value.");
3621 struct
parse *cfile;
3622 struct group *group;
3624 struct
pool *inpool;
3625 struct
lease **lpchain;
3627 struct iaddr low, high, net;
3628 unsigned char addr [4];
3629 unsigned len =
sizeof addr;
3633 struct subnet *subnet;
3636 isc_result_t status;
3647 memcpy (low.
iabuf, addr, len);
3651 token =
peek_token (&val, (
unsigned *)0, cfile);
3658 memcpy (high.
iabuf, addr, len);
3662 token =
next_token (&val, (
unsigned *)0, cfile);
3663 if (token !=
SEMI) {
3670 subnet = group -> subnet;
3674 for (subnet = share ->
subnets;
3675 subnet; subnet = subnet -> next_sibling) {
3677 if (
addr_eq (net, subnet -> net))
3681 parse_warn (cfile,
"address range not on network %s",
3683 log_error (
"Be sure to place pool statement after %s",
3684 "related subnet declarations.");
3690 struct pool *last = (
struct pool *)0;
3695 for (pool = share ->
pools; pool; pool = pool ->
next) {
3700 permit_dynamic_bootp_clients)) ||
3705 permit_all_clients))) {
3714 status = pool_allocate (&pool,
MDL);
3715 if (status != ISC_R_SUCCESS)
3716 log_fatal (
"no memory for ad-hoc pool: %s",
3717 isc_result_totext (status));
3720 log_fatal (
"no memory for ad-hoc permit.");
3726 pool -> permit_list = p;
3729 pool -> prohibit_list = p;
3733 pool_reference (&last ->
next, pool,
MDL);
3735 pool_reference (&share ->
pools, pool,
MDL);
3739 log_fatal (
"no memory for anon pool group.");
3741 pool = (
struct pool *)0;
3743 pool_reference (&pool, last,
MDL);
3745 pool_reference (&pool, share ->
pools,
MDL);
3748 pool = (
struct pool *)0;
3749 pool_reference (&pool, inpool,
MDL);
3752 #if defined (FAILOVER_PROTOCOL)
3756 parse_warn (cfile,
"dynamic-bootp flag is %s",
3757 "not permitted for address");
3758 log_error (
"range declarations where there is a failover");
3759 log_error (
"peer in scope. If you wish to declare an");
3760 log_error (
"address range from which dynamic bootp leases");
3761 log_error (
"can be allocated, please declare it within a");
3762 log_error (
"pool declaration that also contains the \"no");
3763 log_error (
"failover\" statement. The failover protocol");
3764 log_error (
"itself does not permit dynamic bootp - this");
3765 log_error (
"is not a limitation specific to the ISC DHCP");
3766 log_error (
"server. Please don't ask me to defend this");
3767 log_error (
"until you have read and really tried %s",
3769 log_error (
"the failover protocol specification.");
3779 pool_dereference (&pool,
MDL);
3784 add_ipv6_pool_to_subnet(
struct subnet *subnet, u_int16_t type,
3785 struct iaddr *lo_addr,
int bits,
int units,
3788 struct in6_addr tmp_in6_addr;
3795 if (lo_addr->
len !=
sizeof(tmp_in6_addr)) {
3796 log_fatal(
"Internal error: Attempt to add non-IPv6 address "
3797 "to IPv6 shared network.");
3799 memcpy(&tmp_in6_addr, lo_addr->
iabuf,
sizeof(tmp_in6_addr));
3802 bits, units,
MDL) != ISC_R_SUCCESS) {
3817 subnet_reference(&pool->
subnet, subnet,
MDL);
3831 while (pond->
ipv6_pools[num_pools] != NULL) {
3839 if (num_pools > 0) {
3841 sizeof(
struct ipv6_pool *) * num_pools);
3869 if ((units - bits) > (
sizeof(isc_uint64_t) * 8)) {
3874 isc_uint64_t space_left
3877 = (isc_uint64_t)(1) << (units -
bits);
3879 if (addon > space_left) {
3916 add_ipv6_pond_to_network(
struct group *group,
3919 struct ipv6_pond *pond = NULL, *last = NULL;
3921 isc_result_t status;
3938 if (status != ISC_R_SUCCESS)
3939 log_fatal (
"no memory for ad-hoc ipv6 pond: %s",
3940 isc_result_totext (status));
3943 log_fatal (
"no memory for ad-hoc ipv6 permit.");
3946 p->
type = permit_all_clients;
3959 log_fatal (
"no memory for anon pool group.");
3972 struct group *group,
3974 struct iaddr lo, hi;
3984 parse_warn(cfile,
"range6 statement is only supported "
3991 if (group->
subnet == NULL)
4004 parse_warn(cfile,
"range6 start address is outside the subnet");
4012 memset(&net, 0,
sizeof(net));
4019 if (token ==
SLASH) {
4032 if ((bits < 0) || (bits > 128)) {
4033 parse_warn(cfile,
"networks have 0 to 128 bits");
4039 "network mask smaller than subnet mask");
4054 parse_warn(cfile,
"temporary mask too short");
4092 "range6 end address is outside the subnet");
4101 if (
range2cidr(&nets, &lo, &hi) != ISC_R_SUCCESS) {
4102 log_fatal(
"Error converting range to CIDR networks");
4113 if (inpond != NULL) {
4116 add_ipv6_pond_to_network(group, &pond);
4120 for (p=nets; p != NULL; p=p->
next) {
4121 add_ipv6_pool_to_subnet(group->
subnet, type,
4133 if (token !=
SEMI) {
4144 struct group *group,
4146 struct iaddr lo, hi;
4155 parse_warn(cfile,
"prefix6 statement is only supported "
4162 if (group->
subnet == NULL)
4182 " is outside the subnet");
4202 " is outside the subnet");
4212 if (token !=
SLASH) {
4226 if ((bits <= 0) || (bits >= 128)) {
4227 parse_warn(cfile,
"networks have 0 to 128 bits (exclusive)");
4238 parse_warn(cfile,
"network mask smaller than subnet mask");
4251 if (token !=
SEMI) {
4261 if (
range2cidr(&nets, &lo, &hi) != ISC_R_SUCCESS) {
4262 log_fatal(
"Error converting prefix to CIDR");
4271 if (inpond != NULL) {
4274 add_ipv6_pond_to_network(group, &pond);
4277 for (p = nets; p != NULL; p = p->
next) {
4310 while (*h != NULL) {
4330 if (token !=
SLASH) {
4346 if (token !=
SEMI) {
4359 parse_warn(cfile,
"networks have 0 to 128 bits");
4395 struct
parse *cfile;
4396 struct group *group;
4403 int declaration = 0;
4404 isc_result_t status;
4408 if (status != ISC_R_SUCCESS)
4410 isc_result_totext (status));
4417 parse_warn(cfile,
"pool6s are only valid inside "
4418 "subnet statements.");
4491 for (; *p; p = &((*p)->next))
4498 parse_warn (cfile,
"Pool6 declaration with no %s.",
4499 "address range6 or prefix6");
4500 log_error (
"Pool6 declarations must always contain at least");
4501 log_error (
"one range6 or prefix6 statement.");
4519 struct
parse *cfile;
4524 unsigned char rf = flag;
4533 token =
next_token (&val, (
unsigned *)0, cfile);
4568 parse_warn (cfile,
"expecting allow/deny key");
4576 log_fatal(
"Unable to find server option %u (%s:%d).",
4586 #if !defined(DHCPv6)
4593 struct ia_xx *old_ia;
4603 char addr_buf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
4604 isc_boolean_t newbinding;
4612 parse_warn(cfile,
"IA_NA is only supported in DHCPv6 mode.");
4620 "expecting an iaid+ia_na string");
4626 "iaid+ia_na string too short");
4631 memcpy(&iaid, val, 4);
4633 if (
ia_allocate(&ia, iaid, val+4, len-4,
MDL) != ISC_R_SUCCESS) {
4640 parse_warn(cfile,
"corrupt lease file; expecting left brace");
4647 if (token ==
RBRACE)
break;
4649 if (token ==
CLTT) {
4656 "expecting IAADDR or right brace");
4663 "expecting IPv6 address");
4671 "expecting left brace");
4681 if (token ==
RBRACE)
break;
4690 "unexpected end of file");
4696 if (token !=
STATE) {
4730 if (token !=
SEMI) {
4747 prefer = atoi (val);
4756 if (token ==
SEMI) {
4760 "corrupt lease file; "
4761 "expecting semicolon.");
4784 if (token ==
SEMI) {
4788 "corrupt lease file; "
4789 "expecting semicolon.");
4801 if ((token !=
NAME) &&
4833 if (bnd->
name == NULL) {
4837 strcpy(bnd->
name, val);
4839 newbinding = ISC_TRUE;
4841 newbinding = ISC_FALSE;
4850 if (token !=
EQUAL) {
4856 if (!parse_binding_value(cfile, nv)) {
4888 if (on_star[0] == NULL) {
4916 "expecting ia_na contents, "
4925 "missing state in iaaddr");
4928 if (end_time == -1) {
4930 "missing end time in iaaddr");
4935 if (iasubopt_allocate(&iaaddr,
MDL) != ISC_R_SUCCESS) {
4940 iaaddr->
state = state;
4942 iaaddr->
valid = valid;
4946 if (scope != NULL) {
4958 (i < 2) && on_star[i] != NULL ;
4960 if ((on_star[i]->data.on.evtypes &
ON_EXPIRY) &&
4961 on_star[i]->
data.
on.statements) {
4966 if ((on_star[i]->data.on.evtypes &
ON_RELEASE) &&
4967 on_star[i]->
data.
on.statements) {
4978 &iaaddr->
addr) != ISC_R_SUCCESS) {
4979 inet_ntop(AF_INET6, &iaaddr->
addr,
4980 addr_buf,
sizeof(addr_buf));
4981 log_error(
"No pool found for IA_NA address %s",
4989 iaaddr, ia) != ISC_R_SUCCESS) {
4990 inet_ntop(AF_INET6, &iaaddr->
addr,
4991 addr_buf,
sizeof(addr_buf));
4992 parse_warn(cfile,
"duplicate na lease for address %s",
5038 #if !defined(DHCPv6)
5045 struct ia_xx *old_ia;
5055 char addr_buf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5056 isc_boolean_t newbinding;
5064 parse_warn(cfile,
"IA_TA is only supported in DHCPv6 mode.");
5072 "expecting an iaid+ia_ta string");
5078 "iaid+ia_ta string too short");
5083 memcpy(&iaid, val, 4);
5085 if (
ia_allocate(&ia, iaid, val+4, len-4,
MDL) != ISC_R_SUCCESS) {
5092 parse_warn(cfile,
"corrupt lease file; expecting left brace");
5099 if (token ==
RBRACE)
break;
5101 if (token ==
CLTT) {
5108 "expecting IAADDR or right brace");
5115 "expecting IPv6 address");
5123 "expecting left brace");
5133 if (token ==
RBRACE)
break;
5142 "unexpected end of file");
5148 if (token !=
STATE) {
5182 if (token !=
SEMI) {
5199 prefer = atoi (val);
5208 if (token ==
SEMI) {
5212 "corrupt lease file; "
5213 "expecting semicolon.");
5236 if (token ==
SEMI) {
5240 "corrupt lease file; "
5241 "expecting semicolon.");
5253 if ((token !=
NAME) &&
5285 if (bnd->
name == NULL) {
5289 strcpy(bnd->
name, val);
5291 newbinding = ISC_TRUE;
5293 newbinding = ISC_FALSE;
5302 if (token !=
EQUAL) {
5308 if (!parse_binding_value(cfile, nv)) {
5340 if (on_star[0] == NULL) {
5368 "expecting ia_ta contents, "
5377 "missing state in iaaddr");
5380 if (end_time == -1) {
5382 "missing end time in iaaddr");
5387 if (iasubopt_allocate(&iaaddr,
MDL) != ISC_R_SUCCESS) {
5392 iaaddr->
state = state;
5394 iaaddr->
valid = valid;
5398 if (scope != NULL) {
5410 (i < 2) && on_star[i] != NULL ;
5412 if ((on_star[i]->data.on.evtypes &
ON_EXPIRY) &&
5413 on_star[i]->
data.
on.statements) {
5418 if ((on_star[i]->data.on.evtypes &
ON_RELEASE) &&
5419 on_star[i]->
data.
on.statements) {
5430 &iaaddr->
addr) != ISC_R_SUCCESS) {
5431 inet_ntop(AF_INET6, &iaaddr->
addr,
5432 addr_buf,
sizeof(addr_buf));
5433 log_error(
"No pool found for IA_TA address %s",
5441 iaaddr, ia) != ISC_R_SUCCESS) {
5442 inet_ntop(AF_INET6, &iaaddr->
addr,
5443 addr_buf,
sizeof(addr_buf));
5444 parse_warn(cfile,
"duplicate ta lease for address %s",
5490 #if !defined(DHCPv6)
5497 struct ia_xx *old_ia;
5508 char addr_buf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
5509 isc_boolean_t newbinding;
5517 parse_warn(cfile,
"IA_PD is only supported in DHCPv6 mode.");
5525 "expecting an iaid+ia_pd string");
5531 "iaid+ia_pd string too short");
5536 memcpy(&iaid, val, 4);
5538 if (
ia_allocate(&ia, iaid, val+4, len-4,
MDL) != ISC_R_SUCCESS) {
5545 parse_warn(cfile,
"corrupt lease file; expecting left brace");
5552 if (token ==
RBRACE)
break;
5554 if (token ==
CLTT) {
5560 parse_warn(cfile,
"corrupt lease file; expecting "
5561 "IAPREFIX or right brace");
5568 "expecting IPv6 prefix");
5576 "expecting left brace");
5586 if (token ==
RBRACE)
break;
5595 "unexpected end of file");
5601 if (token !=
STATE) {
5635 if (token !=
SEMI) {
5652 prefer = atoi (val);
5661 if (token ==
SEMI) {
5665 "corrupt lease file; "
5666 "expecting semicolon.");
5689 if (token ==
SEMI) {
5693 "corrupt lease file; "
5694 "expecting semicolon.");
5706 if ((token !=
NAME) &&
5738 if (bnd->
name == NULL) {
5742 strcpy(bnd->
name, val);
5744 newbinding = ISC_TRUE;
5746 newbinding = ISC_FALSE;
5755 if (token !=
EQUAL) {
5761 if (!parse_binding_value(cfile, nv)) {
5793 if (on_star[0] == NULL) {
5821 "expecting ia_pd contents, "
5830 "missing state in iaprefix");
5833 if (end_time == -1) {
5835 "missing end time in iaprefix");
5840 if (iasubopt_allocate(&iapref,
MDL) != ISC_R_SUCCESS) {
5844 iapref->
plen = plen;
5845 iapref->
state = state;
5847 iapref->
valid = valid;
5851 if (scope != NULL) {
5863 (i < 2) && on_star[i] != NULL ;
5865 if ((on_star[i]->data.on.evtypes &
ON_EXPIRY) &&
5866 on_star[i]->
data.
on.statements) {
5871 if ((on_star[i]->data.on.evtypes &
ON_RELEASE) &&
5872 on_star[i]->
data.
on.statements) {
5883 &iapref->
addr) != ISC_R_SUCCESS) {
5884 inet_ntop(AF_INET6, &iapref->
addr,
5885 addr_buf,
sizeof(addr_buf));
5886 log_error(
"No pool found for prefix %s", addr_buf);
5893 iapref, ia) != ISC_R_SUCCESS) {
5894 inet_ntop(AF_INET6, &iapref->
addr,
5895 addr_buf,
sizeof(addr_buf));
5896 parse_warn(cfile,
"duplicate pd lease for address %s",
5958 parse_warn(cfile,
"corrupt lease file; expecting a DUID");
5963 memset(&duid, 0,
sizeof(duid));
5966 log_fatal(
"Out of memory storing DUID");
5968 duid.data = (
unsigned char *)duid.buffer->data;
5969 memcpy(duid.buffer->data, val, len);
5976 if (token !=
SEMI) {
5977 parse_warn(cfile,
"corrupt lease file; expecting a semicolon");
5999 u_int32_t enterprise_number;
6026 parse_warn(cfile,
"enterprise number expected");
6030 enterprise_number = atoi(val);
6042 memset(&duid, 0,
sizeof(duid));
6043 duid.len = 2 + 4 +
len;
6045 log_fatal(
"Out of memory storing DUID");
6047 duid.data = (
unsigned char *)duid.buffer->data;
6049 putULong(duid.buffer->data + 2, enterprise_number);
6050 memcpy(duid.buffer->data + 6, val, len);
6063 else if (token ==
LL) {
6086 memset(&ll_addr, 0,
sizeof(ll_addr));
6094 memset(&duid, 0,
sizeof(duid));
6095 duid.len = 2 + 2 + ll_addr.len;
6097 log_fatal(
"Out of memory storing DUID");
6099 duid.data = (
unsigned char *)duid.buffer->data;
6101 putUShort(duid.buffer->data + 2, ll_type);
6102 memcpy(duid.buffer->data + 4,
6103 ll_addr.data, ll_addr.len);
6118 else if (token ==
LLT) {
6148 llt_time = atoi(val);
6150 memset(&ll_addr, 0,
sizeof(ll_addr));
6158 memset(&duid, 0,
sizeof(duid));
6159 duid.len = 2 + 2 + 4 + ll_addr.len;
6161 log_fatal(
"Out of memory storing DUID");
6163 duid.data = (
unsigned char *)duid.buffer->data;
6165 putUShort(duid.buffer->data + 2, ll_type);
6166 putULong(duid.buffer->data + 4, llt_time);
6167 memcpy(duid.buffer->data + 8,
6168 ll_addr.data, ll_addr.len);
6185 else if (token ==
NUMBER) {
6186 duid_type_num = atoi(val);
6198 memset(&duid, 0,
sizeof(duid));
6201 log_fatal(
"Out of memory storing DUID");
6203 duid.data = (
unsigned char *)duid.buffer->data;
6204 putUShort(duid.buffer->data, duid_type_num);
6205 memcpy(duid.buffer->data + 2, val, len);
6215 parse_warn(cfile,
"DUID type of LLT, EN, or LL expected");
6224 if (token !=
SEMI) {
struct iaddrcidrnet cidrnet
#define GROUP_OBJECT_DYNAMIC
void parse_option_space_decl(struct parse *cfile)
int executable_statement_reference(struct executable_statement **ptr, struct executable_statement *bp, const char *file, int line)
int executable_statement_allocate(struct executable_statement **ptr, const char *file, int line)
int parse_lease_declaration(struct lease **lp, struct parse *cfile)
void parse_server_duid_conf(struct parse *cfile)
isc_result_t parse_option_name(struct parse *cfile, int allocate, int *known, struct option **opt)
void parse_trace_setup(void)
void trace_conf_input(trace_type_t *, unsigned, char *)
int parse_option_code_definition(struct parse *cfile, struct option *option)
isc_result_t read_conf_file(const char *filename, struct group *group, int group_type, int leasep)
struct universe * universe
int binding_value_dereference(struct binding_value **v, const char *file, int line)
isc_result_t delete_group(struct group_object *group, int writep)
isc_result_t add_lease6(struct ipv6_pool *pool, struct iasubopt *lease, time_t valid_lifetime_end_time)
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
const char * piaddr(const struct iaddr addr)
#define CLASS_TYPE_VENDOR
void parse_fixed_prefix6(struct parse *cfile, struct host_decl *host_decl)
struct permit * new_permit(const char *, int)
isc_result_t end_parse(struct parse **cfile)
int parse_statement(struct parse *cfile, struct group *group, int type, struct host_decl *host_decl, int declaration)
int permit_list_match(struct permit *lhs, struct permit *rhs)
void * dmalloc(unsigned, const char *, int)
char * piaddrmask(struct iaddr *addr, struct iaddr *mask)
isc_result_t ia_dereference(struct ia_xx **ia, const char *file, int line)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
void parse_pool6_statement(struct parse *, struct group *, int)
struct universe server_universe
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
int parse_data_expression(struct expression **expr, struct parse *cfile, int *lose)
struct ipv6_pond * ipv6_pond
int binding_value_reference(struct binding_value **ptr, struct binding_value *src, const char *file, int line)
#define HOST_DECL_DYNAMIC
#define CLASS_DECL_DELETED
enum executable_statement::statement_op op
struct executable_statement * on_release
int option_reference(struct option **dest, struct option *src, const char *file, int line)
void print_expression(char *name, struct expression *expr) const
struct universe dhcp_universe
int group_reference(struct group **ptr, struct group *bp, const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
struct shared_network * shared_network
isc_result_t ipv6_pond_reference(struct ipv6_pond **pond, struct ipv6_pond *src, const char *file, int line)
reference an IPv6 pond structure.
int option_cache_reference(struct option_cache **ptr, struct option_cache *src, const char *file, int line)
struct option_cache * fixed_addr
struct group * root_group
enum binding_value::@15 type
struct data_string hash_string
const char * path_dhcpd_db
int log_error(const char *,...) __attribute__((__format__(__printf__
struct collection * collections
trace_type_t * trace_type_register(const char *, void *, void(*)(trace_type_t *, unsigned, char *), void(*)(trace_type_t *), const char *, int)
int binding_scope_dereference(struct binding_scope **ptr, const char *file, int line)
void free_permit(struct permit *, const char *, int)
struct binding_scope * scope
dhcp_failover_state_t * failover_peer
int parse_semi(struct parse *cfile)
struct ipv6_pond * ipv6_pond
struct executable_statement * next
dhcp_failover_state_t * failover_peer
int parse_fixed_addr_param(struct option_cache **oc, struct parse *cfile, enum dhcp_token type)
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
isc_result_t lease_file_subparse(struct parse *cfile)
struct data_string client_identifier
struct permit * prohibit_list
int parse_string(struct parse *cfile, char **sptr, unsigned *lptr)
void parse_failover_state_declaration(struct parse *, dhcp_failover_state_t *)
void expression_dereference(struct expression **eptr, const char *file, int line)
#define DHO_DHCP_SERVER_IDENTIFIER
void log_fatal(const char *,...) __attribute__((__format__(__printf__
void get_permit(struct parse *cfile, struct permit **permit_head, int is_allow, TIME *valid_from, TIME *valid_until)
Parse allow and deny statements.
void parse_ia_ta_declaration(struct parse *cfile)
int binding_value_allocate(struct binding_value **cptr, const char *file, int line)
struct executable_statement * statements
int parse_cshl(struct data_string *data, struct parse *cfile)
void parse_group_declaration(struct parse *cfile, struct group *group)
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
union expression::expr_union data
#define CLASS_DECL_DYNAMIC
struct hardware hardware_addr
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
void postdb_startup(void)
isc_result_t ipv6_pool_allocate(struct ipv6_pool **pool, u_int16_t type, const struct in6_addr *start_addr, int bits, int units, const char *file, int line)
Create a new IPv6 lease pool structure.
enum dhcp_token next_token(const char **rval, unsigned *rlen, struct parse *cfile)
int subnet_inner_than(const struct subnet *, const struct subnet *, int)
time_t hard_lifetime_end_time
struct permit * prohibit_list
host_hash_t * host_name_hash
void parse_ia_na_declaration(struct parse *cfile)
#define CLASS_TYPE_SUBCLASS
isc_result_t delete_host(struct host_decl *, int)
void enter_shared_network(struct shared_network *)
isc_result_t cleanup_lease6(ia_hash_t *ia_table, struct ipv6_pool *pool, struct iasubopt *lease, struct ia_xx *ia)
Cleans up leases when reading from a lease file.
binding_state_t binding_state
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
struct option_cache * option
void postconf_initialization(int)
int binding_scope_allocate(struct binding_scope **ptr, const char *file, int line)
void putULong(unsigned char *, u_int32_t)
int group_dereference(struct group **ptr, const char *file, int line)
#define skip_token(a, b, c)
void enter_lease(struct lease *)
int parse_boolean_expression(struct expression **expr, struct parse *cfile, int *lose)
struct iaddrcidrnetlist * next
option_name_hash_t * name_hash
unsigned char * parse_numeric_aggregate(struct parse *cfile, unsigned char *buf, unsigned *max, int separator, int base, unsigned size)
struct data_string iaid_duid
isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result)
int parse_lbrace(struct parse *cfile)
void parse_subnet6_declaration(struct parse *cfile, struct shared_network *share)
int make_concat(struct expression **expr, struct expression *left, struct expression *right)
TIME parse_date(struct parse *cfile)
struct expression * submatch
void dfree(void *, const char *, int)
void set_server_duid(struct data_string *new_duid)
isc_result_t add_ipv6_pool(struct ipv6_pool *pool)
int parse_ip6_addr(struct parse *cfile, struct iaddr *addr)
struct data_string host_id
int parse_ip_addr_or_hostname(struct expression **expr, struct parse *cfile, int uniform)
void set_server_duid_type(int type)
int parse_option_decl(struct option_cache **oc, struct parse *cfile)
isc_result_t conf_file_subparse(struct parse *cfile, struct group *group, int group_type)
struct ipv6_pool ** ipv6_pools
void skip_to_semi(struct parse *cfile)
int option_cache(struct option_cache **oc, struct data_string *dp, struct expression *expr, struct option *option, const char *file, int line)
void skip_to_rbrace(struct parse *cfile, int brace_count)
void new_address_range(struct parse *, struct iaddr, struct iaddr, struct subnet *, struct pool *, struct lease **)
isc_result_t find_failover_peer(dhcp_failover_state_t **, const char *, const char *, int)
int parse_on_statement(struct executable_statement **result, struct parse *cfile, int *lose)
struct shared_network * shared_network
isc_result_t ipv6_pool_dereference(struct ipv6_pool **pool, const char *file, int line)
de-reference an IPv6 pool structure.
isc_result_t find_ipv6_pool(struct ipv6_pool **pool, u_int16_t type, const struct in6_addr *addr)
int addr_eq(struct iaddr addr1, struct iaddr addr2)
struct executable_statement::@7::@9 on
char * parse_host_name(struct parse *cfile)
int parse_option_statement(struct executable_statement **result, struct parse *cfile, int lookups, struct option *option, enum statement_op op)
isc_result_t delete_class(struct class *, int)
isc_result_t enter_failover_peer(dhcp_failover_state_t *)
union executable_statement::@7 data
void parse_shared_net_declaration(struct parse *cfile, struct group *group)
void db_startup(int testp)
int parse_option_data(struct expression **expr, struct parse *cfile, int lookups, struct option *option)
union binding_value::value value
struct shared_network * shared_network
struct lease ** billed_leases
const char * path_dhcpd_conf
struct data_string const_data
u_int32_t host_addr(struct iaddr addr, struct iaddr mask)
void parse_address_range(struct parse *cfile, struct group *group, int type, struct pool *inpool, struct lease **lpchain)
int parse_ip6_addr_expr(struct expression **expr, struct parse *cfile)
struct iaddrcidrnetlist * fixed_prefix
struct group_object * named_group
struct binding * bindings
isc_result_t ipv6_pond_allocate(struct ipv6_pond **pond, const char *file, int line)
Create a new IPv6 pond structure.
isc_boolean_t is_cidr_mask_valid(const struct iaddr *addr, int bits)
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
binding_state_t rewind_binding_state
void parse_failover_state(struct parse *, enum failover_state *, TIME *)
void parse_host_declaration(struct parse *cfile, struct group *group)
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
void parse_subnet_declaration(struct parse *cfile, struct shared_network *share)
void parse_failover_peer(struct parse *, struct group *, int)
void parse_address_range6(struct parse *cfile, struct group *group, struct ipv6_pond *)
#define SV_BOOT_UNKNOWN_CLIENTS
TIME parse_date_core(struct parse *cfile)
isc_result_t iasubopt_dereference(struct iasubopt **iasubopt, const char *file, int line)
struct binding_value * value
isc_result_t supersede_group(struct group_object *group, int writep)
isc_result_t find_class(struct class **c, const char *s, const char *file, int line)
void parse_prefix6(struct parse *cfile, struct group *group, struct ipv6_pond *)
struct option * host_id_option
isc_result_t ia_allocate(struct ia_xx **ia, u_int32_t iaid, const char *duid, unsigned int duid_len, const char *file, int line)
int option_chain_head_allocate(struct option_chain_head **ptr, const char *file, int line)
int parse_ip6_prefix(struct parse *cfile, struct iaddr *addr, u_int8_t *plen)
isc_result_t trace_get_file(trace_type_t *, const char *, unsigned *, char **)
struct subnet * next_sibling
isc_result_t ia_add_iasubopt(struct ia_xx *ia, struct iasubopt *iasubopt, const char *file, int line)
struct interface_info * interface
isc_result_t trace_write_packet(trace_type_t *, unsigned, const char *, const char *, int)
isc_result_t ipv6_pond_dereference(struct ipv6_pond **pond, const char *file, int line)
de-reference an IPv6 pond structure.
void enter_subnet(struct subnet *)
isc_result_t enter_host(struct host_decl *, int, int)
void parse_ia_pd_declaration(struct parse *cfile)
group_hash_t * group_name_hash
struct executable_statement * statements
#define DHO_VENDOR_CLASS_IDENTIFIER
struct universe agent_universe
struct ipv6_pool ** pools
char * piaddrcidr(const struct iaddr *addr, unsigned int bits)
option_code_hash_t * code_hash
void parse_server_duid(struct parse *cfile)
pair cons(caddr_t car, pair cdr)
struct executable_statement * on_expiry
struct binding * find_binding(struct binding_scope *scope, const char *name)
struct shared_network * shared_network
int parse_class_declaration(struct class **cp, struct parse *cfile, struct group *group, int type)
void new_shared_network_interface(struct parse *, struct shared_network *, const char *)
struct permit * permit_list
void putUShort(unsigned char *, u_int32_t)
isc_result_t range2cidr(struct iaddrcidrnetlist **result, const struct iaddr *lo, const struct iaddr *hi)
struct shared_network * shared_network
void trace_conf_stop(trace_type_t *ttype)
int parse_allow_deny(struct option_cache **oc, struct parse *cfile, int flag)
isc_result_t ia_reference(struct ia_xx **ia, struct ia_xx *src, const char *file, int line)
const unsigned char * data
struct binding_scope * scope
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
isc_result_t ipv6_pool_reference(struct ipv6_pool **pool, struct ipv6_pool *src, const char *file, int line)
reference an IPv6 pool structure.
struct hardware interface
struct permit * permit_list
int parse_executable_statement(struct executable_statement **result, struct parse *cfile, int *lose, enum expression_context case_context)
void parse_hardware_param(struct parse *cfile, struct hardware *hardware)
int clone_group(struct group **gp, struct group *group, const char *file, int line)
int parse_warn(struct parse *cfile, const char *fmt,...)
binding_state_t next_binding_state
struct interface_info * interface
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
void parse_pool_statement(struct parse *cfile, struct group *group, int type)
Parse a pool statement.
#define GROUP_OBJECT_STATIC
int option_dereference(struct option **dest, const char *file, int line)
#define SV_CLIENT_UPDATES