34 #define NUM_DEFAULT_REQUESTED_OPTS 15 38 static void parse_client_default_duid(
struct parse *cfile);
39 static void parse_client6_lease_statement(
struct parse *cfile);
41 static struct dhc6_ia *parse_client6_ia_na_statement(
struct parse *cfile);
42 static struct dhc6_ia *parse_client6_ia_ta_statement(
struct parse *cfile);
43 static struct dhc6_ia *parse_client6_ia_pd_statement(
struct parse *cfile);
44 static struct dhc6_addr *parse_client6_iaaddr_statement(
struct parse *cfile);
45 static struct dhc6_addr *parse_client6_iaprefix_statement(
struct parse *cfile);
48 static void parse_lease_id_format (
struct parse *cfile);
72 memset(default_requested_options, 0,
sizeof(default_requested_options));
76 option_code_hash_lookup(&default_requested_options[0],
81 option_code_hash_lookup(&default_requested_options[1],
86 option_code_hash_lookup(&default_requested_options[2],
95 option_code_hash_lookup(&default_requested_options[3],
100 option_code_hash_lookup(&default_requested_options[4],
105 option_code_hash_lookup(&default_requested_options[5],
110 option_code_hash_lookup(&default_requested_options[6],
115 option_code_hash_lookup(&default_requested_options[7],
120 option_code_hash_lookup(&default_requested_options[8],
125 option_code_hash_lookup(&default_requested_options[9],
130 option_code_hash_lookup(&default_requested_options[10],
135 option_code_hash_lookup(&default_requested_options[11],
140 option_code_hash_lookup(&default_requested_options[12],
145 option_code_hash_lookup(&default_requested_options[13],
150 option_code_hash_lookup(&default_requested_options[14],
154 if (default_requested_options[code] == NULL)
155 log_fatal(
"Unable to find option definition for " 156 "index %u during default parameter request " 165 option_code_hash_lookup(&default_requested_options[9],
168 if (default_requested_options[9] == NULL) {
169 log_fatal(
"Unable to find option definition for " 170 "index %u during default parameter request " 177 option_code_hash_lookup(&default_requested_options[9],
180 if (default_requested_options[9] == NULL) {
181 log_fatal(
"Unable to find option definition for " 182 "index %u during default parameter request " 186 option_code_hash_lookup(&default_requested_options[10],
189 if (default_requested_options[10] == NULL) {
190 log_fatal(
"Unable to find option definition for " 191 "index %u during default parameter request " 230 log_fatal (
"no memory for top-level on_receipt group");
234 log_fatal (
"no memory for top-level on_transmission group");
240 if (status != ISC_R_SUCCESS) {
244 status =
new_parse(&parse, -1, default_client_config,
245 sizeof(default_client_config) - 1,
246 "default client configuration", 0);
247 if (status != ISC_R_SUCCESS)
248 log_fatal (
"can't begin default client config!");
270 log_fatal (
"no memory for client state.");
271 memset (ip -> client, 0,
sizeof *(ip -> client));
272 ip -> client ->
interface = ip;
275 if (!ip -> client -> config) {
281 log_fatal (
"no memory for client config.");
285 ip -> client -> config = config;
300 if ((file = open (name, O_RDONLY | O_CLOEXEC)) < 0)
305 if (status != ISC_R_SUCCESS || cfile == NULL)
309 token =
peek_token (&val, (
unsigned *)0, cfile);
345 if (status != ISC_R_SUCCESS || cfile == NULL)
355 parse_client_default_duid(cfile);
381 if (status != ISC_R_SUCCESS || cfile == NULL)
385 token =
next_token (&val, (
unsigned *)0, cfile);
391 parse_client_default_duid(cfile);
399 parse_client6_lease_statement(cfile);
403 log_error (
"Corrupt lease file - possible data loss!");
450 struct option ***append_list, **new_list, **cat_list;
452 switch (
peek_token (&val, (
unsigned *)0, cfile)) {
455 token =
next_token (&val, (
unsigned *)0, cfile);
457 parse_warn (cfile,
"filename string expected.");
461 if (status != ISC_R_SUCCESS)
482 parse_warn (cfile,
"key definition not allowed here.");
501 parse_warn(cfile,
"expected REQUEST or REQUIRE list");
507 if (*append_list == NULL) {
513 for (i = 0 ; (*append_list)[i] != NULL ; i++)
524 if (tmp == 0 || new_list == NULL)
528 cat_list =
dmalloc(
sizeof(
struct option *) * (i + tmp + 1),
531 if (cat_list == NULL) {
532 log_error(
"Unable to allocate memory for new " 538 for (i = 0 ; (*append_list)[i] != NULL ; i++)
543 for (i = 0 ; new_list[i] != 0 ; i++)
552 *append_list = cat_list;
560 token =
peek_token (&val, (
unsigned *)0, cfile);
589 token =
next_token (&val, (
unsigned *)0, cfile);
595 "invalid authentication policy.");
599 config -> auth_policy =
policy;
608 config -> bootp_policy =
policy;
610 parse_warn (cfile,
"expecting a policy type.");
618 token =
peek_token (&val, (
unsigned *)0, cfile);
619 if (token ==
SPACE) {
622 "option space definitions %s",
623 " may not be scoped.");
633 if (status != ISC_R_SUCCESS || option == NULL)
636 token =
next_token (&val, (
unsigned *)0, cfile);
638 parse_warn (cfile,
"expecting \"code\" keyword.");
645 "option definitions may only appear in %s",
646 "the outermost scope.");
677 parse_warn (cfile,
"hardware address parameter %s",
678 "not allowed here.");
688 parse_warn(cfile,
"anycast mac address parameter " 689 "not allowed here.");
696 if (config -> requested_options == default_requested_options)
697 config -> requested_options = NULL;
718 token =
next_token (&val, (
unsigned *)0, cfile);
721 "unexpected omapi subtype: %s", val);
725 token =
next_token (&val, (
unsigned *)0, cfile);
727 parse_warn (cfile,
"invalid port number: `%s'", val);
732 if (tmp < 0 || tmp > 65535)
733 parse_warn (cfile,
"invalid omapi port %d.", tmp);
736 "omapi port only works at top level.");
744 token =
next_token (&val, (
unsigned *)0, cfile);
745 if (!strcasecmp (val,
"on") ||
746 !strcasecmp (val,
"true"))
747 config -> do_forward_update = 1;
748 else if (!strcasecmp (val,
"off") ||
749 !strcasecmp (val,
"false"))
750 config -> do_forward_update = 0;
752 parse_warn (cfile,
"expecting boolean value.");
781 parse_string (cfile, &config -> script_name, (
unsigned *)0);
786 token =
next_token (&val, (
unsigned *)0, cfile);
788 parse_warn (cfile,
"expecting 'vendor option space'");
792 token =
next_token (&val, (
unsigned *)0, cfile);
793 if (token !=
SPACE) {
794 parse_warn (cfile,
"expecting 'vendor option space'");
798 token =
next_token (&val, (
unsigned *)0, cfile);
800 parse_warn (cfile,
"expecting an identifier.");
804 config -> vendor_space_name =
dmalloc (strlen (val) + 1,
MDL);
805 if (!config -> vendor_space_name)
806 log_fatal (
"no memory for vendor option space name.");
807 strcpy (config -> vendor_space_name, val);
810 config -> vendor_space_name))
812 if (i == universe_count) {
813 log_error (
"vendor option space %s not found.",
814 config -> vendor_space_name);
822 parse_warn (cfile,
"nested interface declaration.");
828 token =
next_token (&val, (
unsigned *)0, cfile);
831 log_fatal (
"no memory for pseudo interface name");
853 parse_lease_id_format(cfile);
857 token =
next_token(&val, (
unsigned*)0, cfile);
878 eptr = &config -> on_transmission ->
statements;
883 stmt ->
data.on.statements,
MDL);
896 for (; *eptr; eptr = &(*eptr) ->
next)
923 token =
peek_token (&val, (
unsigned *)0, cfile);
925 token =
next_token (&val, (
unsigned *)0, cfile);
929 parse_warn (cfile,
"%s: expected option name.", val);
935 if (status != ISC_R_SUCCESS || option == NULL) {
936 parse_warn (cfile,
"%s: expected option name.", val);
941 log_fatal (
"can't allocate pair for option code.");
943 r->car = (caddr_t)option;
952 token =
next_token (&val, (
unsigned *)0, cfile);
953 }
while (token ==
COMMA);
963 *list =
dmalloc ((ix + 1) *
sizeof(
struct option *),
MDL);
965 log_error (
"no memory for option list.");
968 for (q = p; q; q = q -> cdr)
970 (
struct option *)q->car,
MDL);
996 token =
next_token (&val, (
unsigned *)0, cfile);
998 parse_warn (cfile,
"expecting interface name (in quotes).");
1004 log_fatal (
"Can't allocate interface %s.", val);
1010 client ->
interface = ip;
1011 for (cp = &ip -> client; *cp; cp = &((*cp) -> next))
1015 if (!ip -> client) {
1017 ip -> client ->
interface = ip;
1019 client = ip -> client;
1022 if (!client -> config)
1028 token =
next_token (&val, (
unsigned *)0, cfile);
1036 token =
peek_token (&val, (
unsigned *)0, cfile);
1039 "unterminated interface declaration.");
1053 isc_result_t status;
1057 if (!strcmp (i -> name, name)) {
1058 interface_reference (&ip, i,
MDL);
1066 if (!strcmp (ip -> name, name)) {
1067 interface_reference (&ip, i,
MDL);
1076 if ((status = interface_allocate (&ip,
MDL)) != ISC_R_SUCCESS)
1077 log_fatal (
"Can't record interface %s: %s",
1078 name, isc_result_totext (status));
1080 if (strlen(name) >=
sizeof(ip->
name)) {
1081 interface_dereference(&ip,
MDL);
1084 strcpy(ip->
name, name);
1087 interface_reference (&ip ->
next,
1094 status = interface_reference (pi, ip,
MDL);
1096 status = ISC_R_FAILURE;
1097 interface_dereference (&ip,
MDL);
1098 if (status != ISC_R_SUCCESS)
1108 log_fatal (
"no memory for client state\n");
1109 memset (*state, 0,
sizeof **state);
1118 if (!client -> config)
1119 log_fatal (
"no memory for client config\n");
1120 memcpy (client -> config, config,
sizeof *config);
1125 log_fatal (
"no memory for client state groups.");
1138 struct parse *cfile;
1147 token =
next_token (&val, (
unsigned *)0, cfile);
1158 memset (lease, 0,
sizeof *lease);
1161 log_fatal (
"no memory for lease options.\n");
1164 token =
peek_token (&val, (
unsigned *)0, cfile);
1166 parse_warn (cfile,
"unterminated lease declaration.");
1183 if (!ip -> client) {
1185 ip -> client ->
interface = ip;
1188 client = ip -> client;
1191 if (is_static == 2) {
1192 ip -> client -> alias = lease;
1201 for (lp = client -> leases; lp; lp =
next) {
1209 client -> leases =
next;
1219 lease -> next = client -> leases;
1220 client -> leases = lease;
1235 if (client -> active) {
1245 client -> active -> next = client -> leases;
1246 client -> leases = client -> active;
1249 client -> active = lease;
1267 struct parse *cfile;
1278 switch (
next_token (&val, (
unsigned *)0, cfile)) {
1280 token =
next_token (&val, (
unsigned *)0, cfile);
1292 lease -> is_bootp = 1;
1296 token =
next_token (&val, (
unsigned *)0, cfile);
1299 "expecting interface name (in quotes).");
1304 log_fatal (
"Can't allocate interface %s.", val);
1308 token =
next_token (&val, (
unsigned *)0, cfile);
1311 parse_warn (cfile,
"state name precedes interface.");
1314 for (client = ip -> client; client; client = client ->
next)
1315 if (client ->
name && !strcmp (client ->
name, val))
1319 "lease specified for unknown pseudo.");
1333 parse_string (cfile, &lease -> filename, (
unsigned *)0);
1337 parse_string (cfile, &lease -> server_name, (
unsigned *)0);
1361 parse_warn (cfile,
"expecting lease declaration.");
1365 token =
next_token (&val, (
unsigned *)0, cfile);
1366 if (token !=
SEMI) {
1375 parse_client_default_duid(
struct parse *cfile)
1381 len =
parse_X(cfile, buf,
sizeof(buf));
1388 memset(&new_duid, 0,
sizeof(new_duid));
1390 parse_warn(cfile,
"Out of memory parsing default DUID.");
1415 parse_client6_lease_statement(
struct parse *cfile)
1417 #if !defined(DHCPv6) 1429 int token, has_ia, no_semi, has_name;
1433 parse_warn(cfile,
"Expecting open curly brace.");
1439 if (lease == NULL) {
1440 parse_warn(cfile,
"Unable to allocate lease state.");
1447 parse_warn(cfile,
"Unable to allocate option cache.");
1457 while (token !=
RBRACE) {
1462 *ia = parse_client6_ia_na_statement(cfile);
1473 *ia = parse_client6_ia_ta_statement(cfile);
1484 *ia = parse_client6_ia_pd_statement(cfile);
1495 if (iface != NULL) {
1496 parse_warn(cfile,
"Multiple interface names?");
1512 iface = iface->
next) {
1513 if (strcmp(iface->
name, val) == 0)
1517 if (iface == NULL) {
1527 if (client != NULL) {
1534 if (iface == NULL) {
1546 for (client = iface->
client ; client != NULL ;
1547 client = client->
next) {
1548 if ((client->
name != NULL) &&
1549 (strcmp(client->
name, val) == 0))
1553 if (client == NULL) {
1554 parse_warn(cfile,
"Unknown client state %s.",
1576 parse_warn(cfile,
"Unexpected token, %s.", val);
1588 parse_warn(cfile,
"Unexpected end of file.");
1594 log_debug(
"Lease with no IA's discarded from lease db.");
1600 parse_warn(cfile,
"Lease has no interface designation.");
1601 else if (!has_name && (client == NULL)) {
1602 for (client = iface->
client ; client != NULL ;
1603 client = client->
next) {
1604 if (client->
name == NULL)
1609 if (client == NULL) {
1610 parse_warn(cfile,
"No matching client state.");
1616 memset(&ds, 0,
sizeof(ds));
1622 log_error(
"Invalid length of DHCPv6 Preference option " 1623 "(%d != 1)", ds.
len);
1641 log_error(
"Invalid SERVERID option cache.");
1657 parse_client6_ia_na_statement(
struct parse *cfile)
1663 int token, no_semi, len;
1668 parse_warn(cfile,
"Out of memory allocating IA_NA state.");
1677 memcpy(ia->
iaid, buf, 4);
1679 parse_warn(cfile,
"Expecting IAID of length 4, got %d.", len);
1687 parse_warn(cfile,
"Expecting open curly brace.");
1695 parse_warn(cfile,
"Unable to allocate option state.");
1703 while (token !=
RBRACE) {
1721 ia->
renew = atoi(val);
1741 *addr = parse_client6_iaaddr_statement(cfile);
1744 addr = &(*addr)->
next;
1772 parse_warn(cfile,
"Unexpected end of file.");
1785 parse_client6_ia_ta_statement(
struct parse *cfile)
1791 int token, no_semi, len;
1796 parse_warn(cfile,
"Out of memory allocating IA_TA state.");
1805 memcpy(ia->
iaid, buf, 4);
1807 parse_warn(cfile,
"Expecting IAID of length 4, got %d.", len);
1815 parse_warn(cfile,
"Expecting open curly brace.");
1823 parse_warn(cfile,
"Unable to allocate option state.");
1831 while (token !=
RBRACE) {
1849 *addr = parse_client6_iaaddr_statement(cfile);
1852 addr = &(*addr)->
next;
1880 parse_warn(cfile,
"Unexpected end of file.");
1893 parse_client6_ia_pd_statement(
struct parse *cfile)
1899 int token, no_semi, len;
1904 parse_warn(cfile,
"Out of memory allocating IA_PD state.");
1913 memcpy(ia->
iaid, buf, 4);
1915 parse_warn(cfile,
"Expecting IAID of length 4, got %d.", len);
1923 parse_warn(cfile,
"Expecting open curly brace.");
1931 parse_warn(cfile,
"Unable to allocate option state.");
1939 while (token !=
RBRACE) {
1957 ia->
renew = atoi(val);
1977 *pref = parse_client6_iaprefix_statement(cfile);
1980 pref = &(*pref)->
next;
2008 parse_warn(cfile,
"Unexpected end of file.");
2020 parse_client6_iaaddr_statement(
struct parse *cfile)
2029 parse_warn(cfile,
"Unable to allocate IAADDR state.");
2043 parse_warn(cfile,
"Expecting open curly bracket.");
2051 parse_warn(cfile,
"Unable to allocate option state.");
2058 while (token !=
RBRACE) {
2065 addr->
starts = atoi(val);
2116 parse_warn(cfile,
"Unexpected end of file.");
2128 parse_client6_iaprefix_statement(
struct parse *cfile)
2137 parse_warn(cfile,
"Unable to allocate IAPREFIX state.");
2151 parse_warn(cfile,
"Expecting open curly bracket.");
2159 parse_warn(cfile,
"Unable to allocate option state.");
2166 while (token !=
RBRACE) {
2173 pref->
starts = atoi(val);
2224 parse_warn(cfile,
"Unexpected end of file.");
2234 struct parse *cfile;
2244 for (cur = *lp; cur ->
next; cur = cur ->
next)
2251 token =
next_token (&val, (
unsigned *)0, cfile);
2253 parse_warn (cfile,
"Expecting media options.");
2262 log_fatal (
"no memory for string list entry.");
2264 strcpy (tmp ->
string, val);
2274 token =
next_token (&val, (
unsigned *)0, cfile);
2275 }
while (multiple && token ==
COMMA);
2277 if (token !=
SEMI) {
2284 struct parse *cfile;
2311 for (i=0 ; i < match.
mask.
len ; i++) {
2319 parse_warn(cfile,
"zero-length prefix is not permitted " 2320 "for reject statement");
2327 log_fatal (
"no memory for reject list!");
2333 token =
next_token (&val, (
unsigned *)0, cfile);
2334 }
while (token ==
COMMA);
2336 if (token !=
SEMI) {
2349 struct parse *cfile;
2352 parse_warn (cfile,
"allow/deny/ignore not permitted here.");
2373 void parse_lease_id_format (
struct parse *cfile)
2387 parse_warn(cfile,
"lease-id-format is invalid: " 2388 " it must be octal or hex.");
2395 ?
"octal" :
"hex"));
void parse_option_space_decl(struct parse *cfile)
int parse_X(struct parse *cfile, u_int8_t *buf, unsigned max)
int executable_statement_reference(struct executable_statement **ptr, struct executable_statement *bp, const char *file, int line)
isc_result_t parse_option_name(struct parse *cfile, int allocate, int *known, struct option **opt)
struct binding_scope * global_scope
int parse_option_code_definition(struct parse *cfile, struct option *option)
struct universe * universe
struct group * on_receipt
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
int parse_ip_addr_with_subnet(struct parse *cfile, struct iaddrmatch *match)
#define DHO_DOMAIN_SEARCH
int interface_or_dummy(struct interface_info **pi, const char *name)
isc_result_t end_parse(struct parse **cfile)
const char * path_dhclient_db
int parse_key(struct parse *cfile)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
struct group * on_transmission
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
struct client_state * client
enum executable_statement::statement_op op
void parse_client_lease_statement(struct parse *cfile, int is_static)
isc_result_t omapi_auth_key_lookup_name(omapi_auth_key_t **, const char *)
struct client_state * next
pair new_pair(char *file, int line) const
void parse_interface_declaration(struct parse *cfile, struct client_config *outer_config, char *name)
int option_reference(struct option **dest, struct option *src, const char *file, int line)
struct universe dhcp_universe
struct option_state * options
void data_string_forget(struct data_string *data, const char *file, int line)
#define DHO_INTERFACE_MTU
int parse_allow_deny(struct option_cache **oc, struct parse *cfile, int flag)
int log_error(const char *,...) __attribute__((__format__(__printf__
int parse_semi(struct parse *cfile)
#define D6O_INFORMATION_REFRESH_TIME
struct executable_statement * next
#define NUM_DEFAULT_REQUESTED_OPTS
#define DHO_DOMAIN_NAME_SERVERS
struct dhc6_ia * bindings
void parse_string_list(struct parse *cfile, struct string_list **lp, int multiple)
const char * path_dhclient_duid
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
struct data_string default_duid
void make_client_config(struct client_state *client, struct client_config *config)
int parse_string(struct parse *cfile, char **sptr, unsigned *lptr)
int read_client_conf_file(const char *name, struct interface_info *ip, struct client_config *client)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int parse_option_list(struct parse *cfile, struct option ***list)
#define INTERFACE_AUTOMATIC
void read_client_leases()
struct option_state * options
enum dhcp_token next_token(const char **rval, unsigned *rlen, struct parse *cfile)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
struct iaddrmatchlist * next
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
struct option_state * options
void dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
struct option ** requested_options
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
#define DHO_BROADCAST_ADDRESS
struct data_string server_id
int group_allocate(struct group **ptr, const char *file, int line)
#define skip_token(a, b, c)
option_name_hash_t * name_hash
void parse_client_lease_declaration(struct parse *cfile, struct client_lease *lease, struct interface_info **ipp, struct client_state **clientp)
#define D6O_DOMAIN_SEARCH
TIME parse_date(struct parse *cfile)
void parse_reject_statement(struct parse *cfile, struct client_config *config)
void dfree(void *, const char *, int)
struct client_lease * next
#define DHO_CLASSLESS_STATIC_ROUTES
const char * path_dhclient_conf
int parse_ip6_addr(struct parse *cfile, struct iaddr *addr)
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
isc_result_t uerr2isc(int)
struct option_state * options
int parse_option_decl(struct option_cache **oc, struct parse *cfile)
int bootp_broadcast_always
void skip_to_semi(struct parse *cfile)
void * dmalloc(size_t, const char *, int)
void skip_to_rbrace(struct parse *cfile, int brace_count)
struct interface_info * interfaces
struct client_config top_level_config
struct option ** required_options
union executable_statement::@7 data
void destroy_client_lease(struct client_lease *lease)
char * path_dhclient_script
void parse_client_statement(struct parse *cfile, struct interface_info *ip, struct client_config *config)
struct universe ** universes
void make_client_state(struct client_state **state)
struct interface_info * next
struct universe dhcpv6_universe
void free_pair(pair foo, const char *file, int line)
struct string_list * next
isc_result_t read_client_conf()
struct interface_info * dummy_interfaces
int parse_ip6_prefix(struct parse *cfile, struct iaddr *addr, u_int8_t *plen)
void parse_lease_time(struct parse *cfile, TIME *timep)
#define D6O_DHCP4_O_DHCP6_SERVER
struct executable_statement * statements
struct iaddrmatchlist * reject_list
struct hardware anycast_mac_addr
option_code_hash_t * code_hash
struct string_list * medium
int parse_ip_addr(struct parse *cfile, struct iaddr *addr)
const unsigned char * data
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
int parse_executable_statement(struct executable_statement **result, struct parse *cfile, int *lose, enum expression_context case_context)
struct option * default_requested_options[NUM_DEFAULT_REQUESTED_OPTS+2+1]
void parse_hardware_param(struct parse *cfile, struct hardware *hardware)
u_int32_t requested_lease
int clone_group(struct group **gp, struct group *group, const char *file, int line)
int parse_warn(struct parse *cfile, const char *fmt,...)
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
struct dhc6_lease * active_lease
int option_dereference(struct option **dest, const char *file, int line)
int bootp_broadcast_always