34 #define NUM_DEFAULT_REQUESTED_OPTS 15 37 static void parse_client_default_duid(
struct parse *cfile);
38 static void parse_client6_lease_statement(
struct parse *cfile);
40 static struct dhc6_ia *parse_client6_ia_na_statement(
struct parse *cfile);
41 static struct dhc6_ia *parse_client6_ia_ta_statement(
struct parse *cfile);
42 static struct dhc6_ia *parse_client6_ia_pd_statement(
struct parse *cfile);
43 static struct dhc6_addr *parse_client6_iaaddr_statement(
struct parse *cfile);
44 static struct dhc6_addr *parse_client6_iaprefix_statement(
struct parse *cfile);
69 memset(default_requested_options, 0,
sizeof(default_requested_options));
73 option_code_hash_lookup(&default_requested_options[0],
78 option_code_hash_lookup(&default_requested_options[1],
83 option_code_hash_lookup(&default_requested_options[2],
92 option_code_hash_lookup(&default_requested_options[3],
97 option_code_hash_lookup(&default_requested_options[4],
102 option_code_hash_lookup(&default_requested_options[5],
107 option_code_hash_lookup(&default_requested_options[6],
112 option_code_hash_lookup(&default_requested_options[7],
117 option_code_hash_lookup(&default_requested_options[8],
122 option_code_hash_lookup(&default_requested_options[9],
127 option_code_hash_lookup(&default_requested_options[10],
132 option_code_hash_lookup(&default_requested_options[11],
137 option_code_hash_lookup(&default_requested_options[12],
142 option_code_hash_lookup(&default_requested_options[13],
147 option_code_hash_lookup(&default_requested_options[14],
151 if (default_requested_options[code] == NULL)
152 log_fatal(
"Unable to find option definition for " 153 "index %u during default parameter request " 189 log_fatal (
"no memory for top-level on_receipt group");
193 log_fatal (
"no memory for top-level on_transmission group");
199 if (status != ISC_R_SUCCESS) {
203 status =
new_parse(&parse, -1, default_client_config,
204 sizeof(default_client_config) - 1,
205 "default client configuration", 0);
206 if (status != ISC_R_SUCCESS)
207 log_fatal (
"can't begin default client config!");
229 log_fatal (
"no memory for client state.");
230 memset (ip -> client, 0,
sizeof *(ip -> client));
231 ip -> client ->
interface = ip;
234 if (!ip -> client -> config) {
240 log_fatal (
"no memory for client config.");
244 ip -> client -> config = config;
259 if ((file = open (name, O_RDONLY | O_CLOEXEC)) < 0)
264 if (status != ISC_R_SUCCESS || cfile == NULL)
268 token =
peek_token (&val, (
unsigned *)0, cfile);
301 if (status != ISC_R_SUCCESS || cfile == NULL)
305 token =
next_token (&val, (
unsigned *)0, cfile);
311 parse_client_default_duid(cfile);
319 parse_client6_lease_statement(cfile);
323 log_error (
"Corrupt lease file - possible data loss!");
370 struct option ***append_list, **new_list, **cat_list;
372 switch (
peek_token (&val, (
unsigned *)0, cfile)) {
375 token =
next_token (&val, (
unsigned *)0, cfile);
377 parse_warn (cfile,
"filename string expected.");
381 if (status != ISC_R_SUCCESS)
402 parse_warn (cfile,
"key definition not allowed here.");
421 parse_warn(cfile,
"expected REQUEST or REQUIRE list");
427 if (*append_list == NULL) {
433 for (i = 0 ; (*append_list)[i] != NULL ; i++)
444 if (tmp == 0 || new_list == NULL)
448 cat_list =
dmalloc(
sizeof(
struct option *) * (i + tmp + 1),
451 if (cat_list == NULL) {
452 log_error(
"Unable to allocate memory for new " 458 for (i = 0 ; (*append_list)[i] != NULL ; i++)
463 for (i = 0 ; new_list[i] != 0 ; i++)
472 *append_list = cat_list;
480 token =
peek_token (&val, (
unsigned *)0, cfile);
509 token =
next_token (&val, (
unsigned *)0, cfile);
515 "invalid authentication policy.");
519 config -> auth_policy =
policy;
528 config -> bootp_policy =
policy;
530 parse_warn (cfile,
"expecting a policy type.");
538 token =
peek_token (&val, (
unsigned *)0, cfile);
539 if (token ==
SPACE) {
542 "option space definitions %s",
543 " may not be scoped.");
553 if (status != ISC_R_SUCCESS || option == NULL)
556 token =
next_token (&val, (
unsigned *)0, cfile);
558 parse_warn (cfile,
"expecting \"code\" keyword.");
565 "option definitions may only appear in %s",
566 "the outermost scope.");
597 parse_warn (cfile,
"hardware address parameter %s",
598 "not allowed here.");
608 parse_warn(cfile,
"anycast mac address parameter " 609 "not allowed here.");
616 if (config -> requested_options == default_requested_options)
617 config -> requested_options = NULL;
638 token =
next_token (&val, (
unsigned *)0, cfile);
641 "unexpected omapi subtype: %s", val);
645 token =
next_token (&val, (
unsigned *)0, cfile);
647 parse_warn (cfile,
"invalid port number: `%s'", val);
652 if (tmp < 0 || tmp > 65535)
653 parse_warn (cfile,
"invalid omapi port %d.", tmp);
656 "omapi port only works at top level.");
664 token =
next_token (&val, (
unsigned *)0, cfile);
665 if (!strcasecmp (val,
"on") ||
666 !strcasecmp (val,
"true"))
667 config -> do_forward_update = 1;
668 else if (!strcasecmp (val,
"off") ||
669 !strcasecmp (val,
"false"))
670 config -> do_forward_update = 0;
672 parse_warn (cfile,
"expecting boolean value.");
701 parse_string (cfile, &config -> script_name, (
unsigned *)0);
706 token =
next_token (&val, (
unsigned *)0, cfile);
708 parse_warn (cfile,
"expecting 'vendor option space'");
712 token =
next_token (&val, (
unsigned *)0, cfile);
713 if (token !=
SPACE) {
714 parse_warn (cfile,
"expecting 'vendor option space'");
718 token =
next_token (&val, (
unsigned *)0, cfile);
720 parse_warn (cfile,
"expecting an identifier.");
724 config -> vendor_space_name =
dmalloc (strlen (val) + 1,
MDL);
725 if (!config -> vendor_space_name)
726 log_fatal (
"no memory for vendor option space name.");
727 strcpy (config -> vendor_space_name, val);
730 config -> vendor_space_name))
732 if (i == universe_count) {
733 log_error (
"vendor option space %s not found.",
734 config -> vendor_space_name);
742 parse_warn (cfile,
"nested interface declaration.");
748 token =
next_token (&val, (
unsigned *)0, cfile);
751 log_fatal (
"no memory for pseudo interface name");
772 token =
next_token(&val, (
unsigned*)0, cfile);
792 eptr = &config -> on_transmission ->
statements;
797 stmt ->
data.on.statements,
MDL);
810 for (; *eptr; eptr = &(*eptr) ->
next)
837 token =
peek_token (&val, (
unsigned *)0, cfile);
839 token =
next_token (&val, (
unsigned *)0, cfile);
843 parse_warn (cfile,
"%s: expected option name.", val);
849 if (status != ISC_R_SUCCESS || option == NULL) {
850 parse_warn (cfile,
"%s: expected option name.", val);
855 log_fatal (
"can't allocate pair for option code.");
857 r->car = (caddr_t)option;
866 token =
next_token (&val, (
unsigned *)0, cfile);
867 }
while (token ==
COMMA);
877 *list =
dmalloc ((ix + 1) *
sizeof(
struct option *),
MDL);
879 log_error (
"no memory for option list.");
882 for (q = p; q; q = q -> cdr)
884 (
struct option *)q->car,
MDL);
910 token =
next_token (&val, (
unsigned *)0, cfile);
912 parse_warn (cfile,
"expecting interface name (in quotes).");
918 log_fatal (
"Can't allocate interface %s.", val);
924 client ->
interface = ip;
925 for (cp = &ip -> client; *cp; cp = &((*cp) -> next))
931 ip -> client ->
interface = ip;
933 client = ip -> client;
936 if (!client -> config)
942 token =
next_token (&val, (
unsigned *)0, cfile);
950 token =
peek_token (&val, (
unsigned *)0, cfile);
953 "unterminated interface declaration.");
971 if (!strcmp (i -> name, name)) {
972 interface_reference (&ip, i,
MDL);
980 if (!strcmp (ip -> name, name)) {
981 interface_reference (&ip, i,
MDL);
990 if ((status = interface_allocate (&ip,
MDL)) != ISC_R_SUCCESS)
991 log_fatal (
"Can't record interface %s: %s",
992 name, isc_result_totext (status));
994 if (strlen(name) >=
sizeof(ip->
name)) {
995 interface_dereference(&ip,
MDL);
998 strcpy(ip->
name, name);
1001 interface_reference (&ip ->
next,
1008 status = interface_reference (pi, ip,
MDL);
1010 status = ISC_R_FAILURE;
1011 interface_dereference (&ip,
MDL);
1012 if (status != ISC_R_SUCCESS)
1022 log_fatal (
"no memory for client state\n");
1023 memset (*state, 0,
sizeof **state);
1032 if (!client -> config)
1033 log_fatal (
"no memory for client config\n");
1034 memcpy (client -> config, config,
sizeof *config);
1039 log_fatal (
"no memory for client state groups.");
1052 struct parse *cfile;
1061 token =
next_token (&val, (
unsigned *)0, cfile);
1072 memset (lease, 0,
sizeof *lease);
1075 log_fatal (
"no memory for lease options.\n");
1078 token =
peek_token (&val, (
unsigned *)0, cfile);
1080 parse_warn (cfile,
"unterminated lease declaration.");
1097 if (!ip -> client) {
1099 ip -> client ->
interface = ip;
1102 client = ip -> client;
1105 if (is_static == 2) {
1106 ip -> client -> alias = lease;
1115 for (lp = client -> leases; lp; lp =
next) {
1123 client -> leases =
next;
1133 lease -> next = client -> leases;
1134 client -> leases = lease;
1149 if (client -> active) {
1159 client -> active -> next = client -> leases;
1160 client -> leases = client -> active;
1163 client -> active = lease;
1181 struct parse *cfile;
1192 switch (
next_token (&val, (
unsigned *)0, cfile)) {
1194 token =
next_token (&val, (
unsigned *)0, cfile);
1206 lease -> is_bootp = 1;
1210 token =
next_token (&val, (
unsigned *)0, cfile);
1213 "expecting interface name (in quotes).");
1218 log_fatal (
"Can't allocate interface %s.", val);
1222 token =
next_token (&val, (
unsigned *)0, cfile);
1225 parse_warn (cfile,
"state name precedes interface.");
1228 for (client = ip -> client; client; client = client ->
next)
1229 if (client ->
name && !strcmp (client ->
name, val))
1233 "lease specified for unknown pseudo.");
1247 parse_string (cfile, &lease -> filename, (
unsigned *)0);
1251 parse_string (cfile, &lease -> server_name, (
unsigned *)0);
1275 parse_warn (cfile,
"expecting lease declaration.");
1279 token =
next_token (&val, (
unsigned *)0, cfile);
1280 if (token !=
SEMI) {
1289 parse_client_default_duid(
struct parse *cfile)
1292 const char *val = NULL;
1296 memset(&new_duid, 0,
sizeof(new_duid));
1312 parse_warn(cfile,
"Out of memory parsing default DUID.");
1337 parse_client6_lease_statement(
struct parse *cfile)
1339 #if !defined(DHCPv6) 1351 int token, has_ia, no_semi, has_name;
1355 parse_warn(cfile,
"Expecting open curly brace.");
1361 if (lease == NULL) {
1362 parse_warn(cfile,
"Unable to allocate lease state.");
1369 parse_warn(cfile,
"Unable to allocate option cache.");
1379 while (token !=
RBRACE) {
1384 *ia = parse_client6_ia_na_statement(cfile);
1395 *ia = parse_client6_ia_ta_statement(cfile);
1406 *ia = parse_client6_ia_pd_statement(cfile);
1417 if (iface != NULL) {
1418 parse_warn(cfile,
"Multiple interface names?");
1434 iface = iface->
next) {
1435 if (strcmp(iface->
name, val) == 0)
1439 if (iface == NULL) {
1449 if (client != NULL) {
1456 if (iface == NULL) {
1468 for (client = iface->
client ; client != NULL ;
1469 client = client->
next) {
1470 if ((client->
name != NULL) &&
1471 (strcmp(client->
name, val) == 0))
1475 if (client == NULL) {
1476 parse_warn(cfile,
"Unknown client state %s.",
1498 parse_warn(cfile,
"Unexpected token, %s.", val);
1510 parse_warn(cfile,
"Unexpected end of file.");
1516 log_debug(
"Lease with no IA's discarded from lease db.");
1522 parse_warn(cfile,
"Lease has no interface designation.");
1523 else if (!has_name && (client == NULL)) {
1524 for (client = iface->
client ; client != NULL ;
1525 client = client->
next) {
1526 if (client->
name == NULL)
1531 if (client == NULL) {
1532 parse_warn(cfile,
"No matching client state.");
1538 memset(&ds, 0,
sizeof(ds));
1544 log_error(
"Invalid length of DHCPv6 Preference option " 1545 "(%d != 1)", ds.
len);
1563 log_error(
"Invalid SERVERID option cache.");
1579 parse_client6_ia_na_statement(
struct parse *cfile)
1585 int token, no_semi, len;
1590 parse_warn(cfile,
"Out of memory allocating IA_NA state.");
1599 memcpy(ia->
iaid, buf, 4);
1601 parse_warn(cfile,
"Expecting IAID of length 4, got %d.", len);
1609 parse_warn(cfile,
"Expecting open curly brace.");
1617 parse_warn(cfile,
"Unable to allocate option state.");
1625 while (token !=
RBRACE) {
1643 ia->
renew = atoi(val);
1663 *addr = parse_client6_iaaddr_statement(cfile);
1666 addr = &(*addr)->
next;
1694 parse_warn(cfile,
"Unexpected end of file.");
1707 parse_client6_ia_ta_statement(
struct parse *cfile)
1713 int token, no_semi, len;
1718 parse_warn(cfile,
"Out of memory allocating IA_TA state.");
1727 memcpy(ia->
iaid, buf, 4);
1729 parse_warn(cfile,
"Expecting IAID of length 4, got %d.", len);
1737 parse_warn(cfile,
"Expecting open curly brace.");
1745 parse_warn(cfile,
"Unable to allocate option state.");
1753 while (token !=
RBRACE) {
1771 *addr = parse_client6_iaaddr_statement(cfile);
1774 addr = &(*addr)->
next;
1802 parse_warn(cfile,
"Unexpected end of file.");
1815 parse_client6_ia_pd_statement(
struct parse *cfile)
1821 int token, no_semi, len;
1826 parse_warn(cfile,
"Out of memory allocating IA_PD state.");
1835 memcpy(ia->
iaid, buf, 4);
1837 parse_warn(cfile,
"Expecting IAID of length 4, got %d.", len);
1845 parse_warn(cfile,
"Expecting open curly brace.");
1853 parse_warn(cfile,
"Unable to allocate option state.");
1861 while (token !=
RBRACE) {
1879 ia->
renew = atoi(val);
1899 *pref = parse_client6_iaprefix_statement(cfile);
1902 pref = &(*pref)->
next;
1930 parse_warn(cfile,
"Unexpected end of file.");
1942 parse_client6_iaaddr_statement(
struct parse *cfile)
1951 parse_warn(cfile,
"Unable to allocate IAADDR state.");
1965 parse_warn(cfile,
"Expecting open curly bracket.");
1973 parse_warn(cfile,
"Unable to allocate option state.");
1980 while (token !=
RBRACE) {
1987 addr->
starts = atoi(val);
2038 parse_warn(cfile,
"Unexpected end of file.");
2050 parse_client6_iaprefix_statement(
struct parse *cfile)
2059 parse_warn(cfile,
"Unable to allocate IAPREFIX state.");
2073 parse_warn(cfile,
"Expecting open curly bracket.");
2081 parse_warn(cfile,
"Unable to allocate option state.");
2088 while (token !=
RBRACE) {
2095 pref->
starts = atoi(val);
2146 parse_warn(cfile,
"Unexpected end of file.");
2156 struct parse *cfile;
2166 for (cur = *lp; cur ->
next; cur = cur ->
next)
2173 token =
next_token (&val, (
unsigned *)0, cfile);
2175 parse_warn (cfile,
"Expecting media options.");
2184 log_fatal (
"no memory for string list entry.");
2186 strcpy (tmp ->
string, val);
2196 token =
next_token (&val, (
unsigned *)0, cfile);
2197 }
while (multiple && token ==
COMMA);
2199 if (token !=
SEMI) {
2206 struct parse *cfile;
2233 for (i=0 ; i < match.
mask.
len ; i++) {
2241 parse_warn(cfile,
"zero-length prefix is not permitted " 2242 "for reject statement");
2249 log_fatal (
"no memory for reject list!");
2255 token =
next_token (&val, (
unsigned *)0, cfile);
2256 }
while (token ==
COMMA);
2258 if (token !=
SEMI) {
2271 struct parse *cfile;
2274 parse_warn (cfile,
"allow/deny/ignore not permitted here.");
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)
void * dmalloc(unsigned, const char *, int)
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)
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)
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 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)
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)
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
struct option * default_requested_options[NUM_DEFAULT_REQUESTED_OPTS+1]
int option_dereference(struct option **dest, const char *file, int line)
int bootp_broadcast_always