mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-30 13:57:50 +00:00
shared network support; dynamic bootp support; BOOTP sname support; add warning on lease file syntax error; can't warn on duplicate option code anymore
This commit is contained in:
parent
f1c1b29607
commit
1f814ff24f
351
confpars.c
351
confpars.c
@ -98,6 +98,8 @@ void read_leases ()
|
|||||||
lease = parse_lease_statement (cfile,
|
lease = parse_lease_statement (cfile,
|
||||||
jref (bc));
|
jref (bc));
|
||||||
enter_lease (lease);
|
enter_lease (lease);
|
||||||
|
} else {
|
||||||
|
parse_warn ("possibly corrupt lease file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +111,7 @@ void read_leases ()
|
|||||||
void parse_statement (cfile)
|
void parse_statement (cfile)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
{
|
{
|
||||||
|
int token;
|
||||||
char *val;
|
char *val;
|
||||||
jmp_buf bc;
|
jmp_buf bc;
|
||||||
|
|
||||||
@ -134,9 +137,40 @@ void parse_statement (cfile)
|
|||||||
parsed_time = parse_timestamp (cfile, jref (bc));
|
parsed_time = parse_timestamp (cfile, jref (bc));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SHARED_NETWORK:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_shared_net_statement (cfile, jref (bc));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SUBNET:
|
case SUBNET:
|
||||||
if (!setjmp (bc)) {
|
if (!setjmp (bc)) {
|
||||||
parse_subnet_statement (cfile, jref (bc));
|
struct shared_network *share;
|
||||||
|
struct subnet *subnet;
|
||||||
|
char *t, *n;
|
||||||
|
|
||||||
|
share = new_shared_network ("parse_statement");
|
||||||
|
if (!share)
|
||||||
|
error ("No memory for shared subnet");
|
||||||
|
share -> leases = (struct lease *)0;
|
||||||
|
share -> last_lease = (struct lease *)0;
|
||||||
|
share -> insertion_point = (struct lease *)0;
|
||||||
|
share -> next = (struct shared_network *)0;
|
||||||
|
share -> default_lease_time = default_lease_time;
|
||||||
|
share -> max_lease_time = max_lease_time;
|
||||||
|
memcpy (share -> options,
|
||||||
|
global_options, sizeof global_options);
|
||||||
|
|
||||||
|
subnet = parse_subnet_statement (cfile, jref (bc),
|
||||||
|
share);
|
||||||
|
share -> subnets = subnet;
|
||||||
|
n = piaddr (subnet -> net);
|
||||||
|
t = dmalloc (strlen (n) + 1, "parse_statement");
|
||||||
|
if (!t)
|
||||||
|
error ("no memory for subnet name");
|
||||||
|
strcpy (t, n);
|
||||||
|
share -> name = t;
|
||||||
|
enter_shared_network (share);
|
||||||
|
goto need_semi;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VENDOR_CLASS:
|
case VENDOR_CLASS:
|
||||||
@ -149,11 +183,59 @@ void parse_statement (cfile)
|
|||||||
parse_class_statement (cfile, jref (bc), 1);
|
parse_class_statement (cfile, jref (bc), 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_lease_time (cfile, jref (bc),
|
||||||
|
&default_lease_time);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_lease_time (cfile, jref (bc), &max_lease_time);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPTION:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_option_decl (cfile, jref (bc), global_options);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVER_IDENTIFIER:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
struct tree_cache *server_id =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname
|
||||||
|
(cfile, jref (bc), 0));
|
||||||
|
if (!tree_evaluate (server_id))
|
||||||
|
error ("server identifier is not known");
|
||||||
|
if (server_id -> len > 4)
|
||||||
|
warn ("server identifier evaluates to more %s"
|
||||||
|
"than one IP address");
|
||||||
|
server_identifier.len = 4;
|
||||||
|
memcpy (server_identifier.iabuf,
|
||||||
|
server_id -> value, server_identifier.len);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
parse_warn ("expecting a declaration.");
|
parse_warn ("expecting a declaration.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
need_semi:
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn ("semicolon expected");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip_to_semi (cfile)
|
void skip_to_semi (cfile)
|
||||||
@ -317,13 +399,122 @@ void parse_class_decl (cfile, bc, class)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subnet_statement :== SUBNET net NETMASK netmask declarations SEMI
|
/* lease_time :== NUMBER */
|
||||||
|
|
||||||
|
void parse_lease_time (cfile, bc, timep)
|
||||||
|
FILE *cfile;
|
||||||
|
jbp_decl (bc);
|
||||||
|
TIME *timep;
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn ("Expecting numeric lease time");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
convert_num ((unsigned char *)timep, val, 10, 32);
|
||||||
|
/* Unswap the number - convert_num returns stuff in NBO. */
|
||||||
|
*timep = ntohl (*timep); /* XXX */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shared_network_statement :== SHARED_NETWORK subnet_statements SEMI
|
||||||
|
subnet_statements :== subnet_statement |
|
||||||
|
subnet_statements subnet_statement */
|
||||||
|
|
||||||
|
void parse_shared_net_statement (cfile, bc)
|
||||||
|
FILE *cfile;
|
||||||
|
jbp_decl (bc);
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
struct shared_network *share;
|
||||||
|
struct subnet *first_net = (struct subnet *)0;
|
||||||
|
struct subnet *last_net = (struct subnet *)0;
|
||||||
|
struct subnet *next_net;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
share = new_shared_network ("parse_shared_net_statement");
|
||||||
|
if (!share)
|
||||||
|
error ("No memory for shared subnet");
|
||||||
|
share -> leases = (struct lease *)0;
|
||||||
|
share -> last_lease = (struct lease *)0;
|
||||||
|
share -> insertion_point = (struct lease *)0;
|
||||||
|
share -> next = (struct shared_network *)0;
|
||||||
|
share -> default_lease_time = default_lease_time;
|
||||||
|
share -> max_lease_time = max_lease_time;
|
||||||
|
memcpy (share -> options, global_options, sizeof global_options);
|
||||||
|
|
||||||
|
/* Get the name of the shared network... */
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (!is_identifier (token) && token != STRING) {
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
parse_warn ("expecting shared network name");
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
if (val [0] == 0) {
|
||||||
|
parse_warn ("zero-length shared network name");
|
||||||
|
val = "<no-name-given>";
|
||||||
|
}
|
||||||
|
name = dmalloc (strlen (val), "parse_shared_net_statement");
|
||||||
|
if (!name)
|
||||||
|
error ("no memory for shared network name");
|
||||||
|
strcpy (name, val);
|
||||||
|
share -> name = name;
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
switch (token) {
|
||||||
|
case SEMI:
|
||||||
|
if (!first_net) {
|
||||||
|
parse_warn ("empty shared-network decl");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
share -> subnets = first_net;
|
||||||
|
enter_shared_network (share);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SUBNET:
|
||||||
|
next_net = parse_subnet_statement (cfile, bc, share);
|
||||||
|
if (!first_net)
|
||||||
|
first_net = next_net;
|
||||||
|
if (last_net)
|
||||||
|
last_net -> next_sibling = next_net;
|
||||||
|
last_net = next_net;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPTION:
|
||||||
|
parse_option_decl (cfile, bc, share -> options);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&share -> default_lease_time);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&share -> max_lease_time);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
parse_warn ("expecting subnet declaration");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subnet_statement :== SUBNET net NETMASK netmask declarations
|
||||||
host_declarations :== <nil> | host_declaration
|
host_declarations :== <nil> | host_declaration
|
||||||
| host_declarations host_declaration SEMI */
|
| host_declarations host_declaration SEMI */
|
||||||
|
|
||||||
struct subnet *parse_subnet_statement (cfile, bc)
|
struct subnet *parse_subnet_statement (cfile, bc, share)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jbp_decl (bc);
|
jbp_decl (bc);
|
||||||
|
struct shared_network *share;
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
int token;
|
int token;
|
||||||
@ -335,11 +526,11 @@ struct subnet *parse_subnet_statement (cfile, bc)
|
|||||||
subnet = new_subnet ("parse_subnet_statement");
|
subnet = new_subnet ("parse_subnet_statement");
|
||||||
if (!subnet)
|
if (!subnet)
|
||||||
error ("No memory for new subnet");
|
error ("No memory for new subnet");
|
||||||
subnet -> leases = (struct lease *)0;
|
subnet -> next_subnet = subnet -> next_sibling = (struct subnet *)0;
|
||||||
subnet -> last_lease = (struct lease *)0;
|
subnet -> shared_network = share;
|
||||||
subnet -> next = (struct subnet *)0;
|
subnet -> default_lease_time = share -> default_lease_time;
|
||||||
subnet -> default_lease_time = default_lease_time;
|
subnet -> max_lease_time = share -> max_lease_time;
|
||||||
subnet -> max_lease_time = max_lease_time;
|
memcpy (subnet -> options, share -> options, sizeof subnet -> options);
|
||||||
|
|
||||||
/* Get the network number... */
|
/* Get the network number... */
|
||||||
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
@ -364,12 +555,15 @@ struct subnet *parse_subnet_statement (cfile, bc)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
token = peek_token (&val, cfile);
|
token = peek_token (&val, cfile);
|
||||||
if (token == SEMI) {
|
if (token == SEMI || token == SUBNET)
|
||||||
token = next_token (&val, cfile);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
parse_subnet_decl (cfile, bc, subnet);
|
parse_subnet_decl (cfile, bc, subnet);
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
|
/* If this subnet supports dynamic bootp, flag it so in the
|
||||||
|
shared_network containing it. */
|
||||||
|
if (subnet -> dynamic_bootp)
|
||||||
|
share -> dynamic_bootp = 1;
|
||||||
return subnet;
|
return subnet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,31 +589,13 @@ void parse_subnet_decl (cfile, bc, decl)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DEFAULT_LEASE_TIME:
|
case DEFAULT_LEASE_TIME:
|
||||||
token = next_token (&val, cfile);
|
parse_lease_time (cfile, bc,
|
||||||
if (token != NUMBER) {
|
&decl -> default_lease_time);
|
||||||
parse_warn ("Expecting numeric default lease time");
|
|
||||||
skip_to_semi (cfile);
|
|
||||||
longjmp (jdref (bc), 1);
|
|
||||||
}
|
|
||||||
convert_num ((unsigned char *)&decl -> default_lease_time,
|
|
||||||
val, 10, 32);
|
|
||||||
/* Unswap the number - convert_num returns stuff in NBO. */
|
|
||||||
decl -> default_lease_time =
|
|
||||||
ntohl (decl -> default_lease_time);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAX_LEASE_TIME:
|
case MAX_LEASE_TIME:
|
||||||
token = next_token (&val, cfile);
|
parse_lease_time (cfile, bc,
|
||||||
if (token != NUMBER) {
|
&decl -> max_lease_time);
|
||||||
parse_warn ("Expecting numeric max lease time");
|
|
||||||
skip_to_semi (cfile);
|
|
||||||
longjmp (jdref (bc), 1);
|
|
||||||
}
|
|
||||||
convert_num ((unsigned char *)&decl -> max_lease_time,
|
|
||||||
val, 10, 32);
|
|
||||||
/* Unswap the number - convert_num returns stuff in NBO. */
|
|
||||||
decl -> max_lease_time =
|
|
||||||
ntohl (decl -> max_lease_time);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -431,7 +607,8 @@ void parse_subnet_decl (cfile, bc, decl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* host_declaration :== hardware_declaration | filename_declaration
|
/* host_declaration :== hardware_declaration | filename_declaration
|
||||||
| fixed_addr_declaration | option_declaration */
|
| fixed_addr_declaration | option_declaration
|
||||||
|
| max_lease_declaration | default_lease_declaration */
|
||||||
|
|
||||||
void parse_host_decl (cfile, bc, decl)
|
void parse_host_decl (cfile, bc, decl)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
@ -449,12 +626,23 @@ void parse_host_decl (cfile, bc, decl)
|
|||||||
case FILENAME:
|
case FILENAME:
|
||||||
decl -> filename = parse_filename_decl (cfile, bc);
|
decl -> filename = parse_filename_decl (cfile, bc);
|
||||||
break;
|
break;
|
||||||
|
case SERVER_NAME:
|
||||||
|
decl -> server_name = parse_servername_decl (cfile, bc);
|
||||||
|
break;
|
||||||
case FIXED_ADDR:
|
case FIXED_ADDR:
|
||||||
parse_fixed_addr_decl (cfile, bc, decl);
|
parse_fixed_addr_decl (cfile, bc, decl);
|
||||||
break;
|
break;
|
||||||
case OPTION:
|
case OPTION:
|
||||||
parse_option_decl (cfile, bc, decl -> options);
|
parse_option_decl (cfile, bc, decl -> options);
|
||||||
break;
|
break;
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&decl -> default_lease_time);
|
||||||
|
break;
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&decl -> max_lease_time);
|
||||||
|
break;
|
||||||
case CIADDR:
|
case CIADDR:
|
||||||
decl -> ciaddr =
|
decl -> ciaddr =
|
||||||
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
@ -493,25 +681,10 @@ void parse_hardware_decl (cfile, bc, decl)
|
|||||||
|
|
||||||
hw = parse_hardware_addr (cfile, bc);
|
hw = parse_hardware_addr (cfile, bc);
|
||||||
|
|
||||||
/* Find space for the new interface... */
|
|
||||||
if (decl -> interfaces) {
|
|
||||||
decl -> interfaces =
|
|
||||||
(struct hardware *)realloc (decl -> interfaces,
|
|
||||||
++decl -> interface_count *
|
|
||||||
sizeof (struct hardware));
|
|
||||||
} else {
|
|
||||||
decl -> interfaces =
|
|
||||||
(struct hardware *)malloc (sizeof (struct hardware));
|
|
||||||
decl -> interface_count = 1;
|
|
||||||
}
|
|
||||||
if (!decl -> interfaces)
|
|
||||||
error ("no memory for hardware interface info.");
|
|
||||||
|
|
||||||
/* Copy out the information... */
|
/* Copy out the information... */
|
||||||
decl -> interfaces [decl -> interface_count - 1].htype = hw.htype;
|
decl -> interface.htype = hw.htype;
|
||||||
decl -> interfaces [decl -> interface_count - 1].hlen = hw.hlen;
|
decl -> interface.hlen = hw.hlen;
|
||||||
memcpy (decl -> interfaces [decl -> interface_count - 1].haddr,
|
memcpy (decl -> interface.haddr, &hw.haddr [0], hw.hlen);
|
||||||
&hw.haddr [0], hw.hlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hardware parse_hardware_addr (cfile, bc)
|
struct hardware parse_hardware_addr (cfile, bc)
|
||||||
@ -564,6 +737,29 @@ char *parse_filename_decl (cfile, bc)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* servername_decl :== SERVER_NAME STRING */
|
||||||
|
|
||||||
|
char *parse_servername_decl (cfile, bc)
|
||||||
|
FILE *cfile;
|
||||||
|
jbp_decl (bc);
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != STRING) {
|
||||||
|
parse_warn ("server name must be a string");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
s = (char *)malloc (strlen (val));
|
||||||
|
if (!s)
|
||||||
|
error ("no memory for server name.");
|
||||||
|
strcpy (s, val);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/* ip_addr_or_hostname :== ip_address | hostname
|
/* ip_addr_or_hostname :== ip_address | hostname
|
||||||
ip_address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
|
ip_address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
|
||||||
|
|
||||||
@ -602,15 +798,33 @@ struct tree *parse_ip_addr_or_hostname (cfile, bc, uniform)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fixed_addr_declaration :== FIXED_ADDR ip_addr_or_hostname */
|
/* fixed_addr_clause :==
|
||||||
|
FIXED_ADDR fixed_addr_decls
|
||||||
|
|
||||||
|
fixed_addr_decls :== ip_addr_or_hostname |
|
||||||
|
fixed_addr_decls ip_addr_or_hostname */
|
||||||
|
|
||||||
void parse_fixed_addr_decl (cfile, bc, decl)
|
void parse_fixed_addr_decl (cfile, bc, decl)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jbp_decl (bc);
|
jbp_decl (bc);
|
||||||
struct host_decl *decl;
|
struct host_decl *decl;
|
||||||
{
|
{
|
||||||
decl -> fixed_addr =
|
char *val;
|
||||||
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
int token;
|
||||||
|
struct tree *tree = (struct tree *)0;
|
||||||
|
struct tree *tmp;
|
||||||
|
|
||||||
|
do {
|
||||||
|
tmp = parse_ip_addr_or_hostname (cfile, bc, 0);
|
||||||
|
if (tree)
|
||||||
|
tree = tree_concat (tree, tmp);
|
||||||
|
else
|
||||||
|
tree = tmp;
|
||||||
|
token = peek_token (&val, cfile);
|
||||||
|
if (token == COMMA)
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
} while (token == COMMA);
|
||||||
|
decl -> fixed_addr = tree_cache (tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* option_declaration :== OPTION identifier DOT identifier <syntax> |
|
/* option_declaration :== OPTION identifier DOT identifier <syntax> |
|
||||||
@ -790,10 +1004,6 @@ void parse_option_decl (cfile, bc, options)
|
|||||||
}
|
}
|
||||||
} while (*fmt == 'A');
|
} while (*fmt == 'A');
|
||||||
|
|
||||||
if (options [option -> code]) {
|
|
||||||
parse_warn ("duplicate option code %d (%s).",
|
|
||||||
option -> code, option -> name);
|
|
||||||
}
|
|
||||||
options [option -> code] = tree_cache (tree);
|
options [option -> code] = tree_cache (tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,7 +1039,8 @@ TIME parse_timestamp (cfile, bc)
|
|||||||
| UID hex_numbers
|
| UID hex_numbers
|
||||||
| HOST identifier
|
| HOST identifier
|
||||||
| CLASS identifier
|
| CLASS identifier
|
||||||
| TIMESTAMP number */
|
| TIMESTAMP number
|
||||||
|
| DYNAMIC_BOOTP */
|
||||||
|
|
||||||
struct lease *parse_lease_statement (cfile, bc)
|
struct lease *parse_lease_statement (cfile, bc)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
@ -912,6 +1123,7 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
memcpy (lease.uid, s, lease.uid_len);
|
memcpy (lease.uid, s, lease.uid_len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
case HOST:
|
case HOST:
|
||||||
seenbit = 16;
|
seenbit = 16;
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@ -927,6 +1139,7 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
val,
|
val,
|
||||||
"no longer known.");
|
"no longer known.");
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case CLASS:
|
case CLASS:
|
||||||
seenbit = 32;
|
seenbit = 32;
|
||||||
@ -945,6 +1158,11 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
= parse_hardware_addr (cfile, bc);
|
= parse_hardware_addr (cfile, bc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DYNAMIC_BOOTP:
|
||||||
|
seenbit = 128;
|
||||||
|
lease.flags |= BOOTP_LEASE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
@ -960,7 +1178,8 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
return &lease;
|
return &lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* address_range :== RANGE ip_address ip_address */
|
/* address_range :== RANGE ip_address ip_address |
|
||||||
|
RANGE dynamic_bootp_statement ip_address ip_address */
|
||||||
|
|
||||||
void parse_address_range (cfile, bc, subnet)
|
void parse_address_range (cfile, bc, subnet)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
@ -972,6 +1191,12 @@ void parse_address_range (cfile, bc, subnet)
|
|||||||
int len = sizeof addr;
|
int len = sizeof addr;
|
||||||
int token;
|
int token;
|
||||||
char *val;
|
char *val;
|
||||||
|
int dynamic = 0;
|
||||||
|
|
||||||
|
if ((token = peek_token (&val, cfile)) == DYNAMIC_BOOTP) {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
subnet -> dynamic_bootp = dynamic = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the bottom address in the range... */
|
/* Get the bottom address in the range... */
|
||||||
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
@ -984,7 +1209,7 @@ void parse_address_range (cfile, bc, subnet)
|
|||||||
high.len = len;
|
high.len = len;
|
||||||
|
|
||||||
/* Create the new address range... */
|
/* Create the new address range... */
|
||||||
new_address_range (low, high, subnet);
|
new_address_range (low, high, subnet, dynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
||||||
|
@ -98,6 +98,8 @@ void read_leases ()
|
|||||||
lease = parse_lease_statement (cfile,
|
lease = parse_lease_statement (cfile,
|
||||||
jref (bc));
|
jref (bc));
|
||||||
enter_lease (lease);
|
enter_lease (lease);
|
||||||
|
} else {
|
||||||
|
parse_warn ("possibly corrupt lease file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +111,7 @@ void read_leases ()
|
|||||||
void parse_statement (cfile)
|
void parse_statement (cfile)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
{
|
{
|
||||||
|
int token;
|
||||||
char *val;
|
char *val;
|
||||||
jmp_buf bc;
|
jmp_buf bc;
|
||||||
|
|
||||||
@ -134,9 +137,40 @@ void parse_statement (cfile)
|
|||||||
parsed_time = parse_timestamp (cfile, jref (bc));
|
parsed_time = parse_timestamp (cfile, jref (bc));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SHARED_NETWORK:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_shared_net_statement (cfile, jref (bc));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SUBNET:
|
case SUBNET:
|
||||||
if (!setjmp (bc)) {
|
if (!setjmp (bc)) {
|
||||||
parse_subnet_statement (cfile, jref (bc));
|
struct shared_network *share;
|
||||||
|
struct subnet *subnet;
|
||||||
|
char *t, *n;
|
||||||
|
|
||||||
|
share = new_shared_network ("parse_statement");
|
||||||
|
if (!share)
|
||||||
|
error ("No memory for shared subnet");
|
||||||
|
share -> leases = (struct lease *)0;
|
||||||
|
share -> last_lease = (struct lease *)0;
|
||||||
|
share -> insertion_point = (struct lease *)0;
|
||||||
|
share -> next = (struct shared_network *)0;
|
||||||
|
share -> default_lease_time = default_lease_time;
|
||||||
|
share -> max_lease_time = max_lease_time;
|
||||||
|
memcpy (share -> options,
|
||||||
|
global_options, sizeof global_options);
|
||||||
|
|
||||||
|
subnet = parse_subnet_statement (cfile, jref (bc),
|
||||||
|
share);
|
||||||
|
share -> subnets = subnet;
|
||||||
|
n = piaddr (subnet -> net);
|
||||||
|
t = dmalloc (strlen (n) + 1, "parse_statement");
|
||||||
|
if (!t)
|
||||||
|
error ("no memory for subnet name");
|
||||||
|
strcpy (t, n);
|
||||||
|
share -> name = t;
|
||||||
|
enter_shared_network (share);
|
||||||
|
goto need_semi;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VENDOR_CLASS:
|
case VENDOR_CLASS:
|
||||||
@ -149,11 +183,59 @@ void parse_statement (cfile)
|
|||||||
parse_class_statement (cfile, jref (bc), 1);
|
parse_class_statement (cfile, jref (bc), 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_lease_time (cfile, jref (bc),
|
||||||
|
&default_lease_time);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_lease_time (cfile, jref (bc), &max_lease_time);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPTION:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
parse_option_decl (cfile, jref (bc), global_options);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVER_IDENTIFIER:
|
||||||
|
if (!setjmp (bc)) {
|
||||||
|
struct tree_cache *server_id =
|
||||||
|
tree_cache (parse_ip_addr_or_hostname
|
||||||
|
(cfile, jref (bc), 0));
|
||||||
|
if (!tree_evaluate (server_id))
|
||||||
|
error ("server identifier is not known");
|
||||||
|
if (server_id -> len > 4)
|
||||||
|
warn ("server identifier evaluates to more %s"
|
||||||
|
"than one IP address");
|
||||||
|
server_identifier.len = 4;
|
||||||
|
memcpy (server_identifier.iabuf,
|
||||||
|
server_id -> value, server_identifier.len);
|
||||||
|
goto need_semi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
parse_warn ("expecting a declaration.");
|
parse_warn ("expecting a declaration.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
need_semi:
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn ("semicolon expected");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip_to_semi (cfile)
|
void skip_to_semi (cfile)
|
||||||
@ -317,13 +399,122 @@ void parse_class_decl (cfile, bc, class)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subnet_statement :== SUBNET net NETMASK netmask declarations SEMI
|
/* lease_time :== NUMBER */
|
||||||
|
|
||||||
|
void parse_lease_time (cfile, bc, timep)
|
||||||
|
FILE *cfile;
|
||||||
|
jbp_decl (bc);
|
||||||
|
TIME *timep;
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn ("Expecting numeric lease time");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
convert_num ((unsigned char *)timep, val, 10, 32);
|
||||||
|
/* Unswap the number - convert_num returns stuff in NBO. */
|
||||||
|
*timep = ntohl (*timep); /* XXX */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shared_network_statement :== SHARED_NETWORK subnet_statements SEMI
|
||||||
|
subnet_statements :== subnet_statement |
|
||||||
|
subnet_statements subnet_statement */
|
||||||
|
|
||||||
|
void parse_shared_net_statement (cfile, bc)
|
||||||
|
FILE *cfile;
|
||||||
|
jbp_decl (bc);
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
struct shared_network *share;
|
||||||
|
struct subnet *first_net = (struct subnet *)0;
|
||||||
|
struct subnet *last_net = (struct subnet *)0;
|
||||||
|
struct subnet *next_net;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
share = new_shared_network ("parse_shared_net_statement");
|
||||||
|
if (!share)
|
||||||
|
error ("No memory for shared subnet");
|
||||||
|
share -> leases = (struct lease *)0;
|
||||||
|
share -> last_lease = (struct lease *)0;
|
||||||
|
share -> insertion_point = (struct lease *)0;
|
||||||
|
share -> next = (struct shared_network *)0;
|
||||||
|
share -> default_lease_time = default_lease_time;
|
||||||
|
share -> max_lease_time = max_lease_time;
|
||||||
|
memcpy (share -> options, global_options, sizeof global_options);
|
||||||
|
|
||||||
|
/* Get the name of the shared network... */
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (!is_identifier (token) && token != STRING) {
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
parse_warn ("expecting shared network name");
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
if (val [0] == 0) {
|
||||||
|
parse_warn ("zero-length shared network name");
|
||||||
|
val = "<no-name-given>";
|
||||||
|
}
|
||||||
|
name = dmalloc (strlen (val), "parse_shared_net_statement");
|
||||||
|
if (!name)
|
||||||
|
error ("no memory for shared network name");
|
||||||
|
strcpy (name, val);
|
||||||
|
share -> name = name;
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
switch (token) {
|
||||||
|
case SEMI:
|
||||||
|
if (!first_net) {
|
||||||
|
parse_warn ("empty shared-network decl");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
share -> subnets = first_net;
|
||||||
|
enter_shared_network (share);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SUBNET:
|
||||||
|
next_net = parse_subnet_statement (cfile, bc, share);
|
||||||
|
if (!first_net)
|
||||||
|
first_net = next_net;
|
||||||
|
if (last_net)
|
||||||
|
last_net -> next_sibling = next_net;
|
||||||
|
last_net = next_net;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPTION:
|
||||||
|
parse_option_decl (cfile, bc, share -> options);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&share -> default_lease_time);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&share -> max_lease_time);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
parse_warn ("expecting subnet declaration");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subnet_statement :== SUBNET net NETMASK netmask declarations
|
||||||
host_declarations :== <nil> | host_declaration
|
host_declarations :== <nil> | host_declaration
|
||||||
| host_declarations host_declaration SEMI */
|
| host_declarations host_declaration SEMI */
|
||||||
|
|
||||||
struct subnet *parse_subnet_statement (cfile, bc)
|
struct subnet *parse_subnet_statement (cfile, bc, share)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jbp_decl (bc);
|
jbp_decl (bc);
|
||||||
|
struct shared_network *share;
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
int token;
|
int token;
|
||||||
@ -335,11 +526,11 @@ struct subnet *parse_subnet_statement (cfile, bc)
|
|||||||
subnet = new_subnet ("parse_subnet_statement");
|
subnet = new_subnet ("parse_subnet_statement");
|
||||||
if (!subnet)
|
if (!subnet)
|
||||||
error ("No memory for new subnet");
|
error ("No memory for new subnet");
|
||||||
subnet -> leases = (struct lease *)0;
|
subnet -> next_subnet = subnet -> next_sibling = (struct subnet *)0;
|
||||||
subnet -> last_lease = (struct lease *)0;
|
subnet -> shared_network = share;
|
||||||
subnet -> next = (struct subnet *)0;
|
subnet -> default_lease_time = share -> default_lease_time;
|
||||||
subnet -> default_lease_time = default_lease_time;
|
subnet -> max_lease_time = share -> max_lease_time;
|
||||||
subnet -> max_lease_time = max_lease_time;
|
memcpy (subnet -> options, share -> options, sizeof subnet -> options);
|
||||||
|
|
||||||
/* Get the network number... */
|
/* Get the network number... */
|
||||||
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
@ -364,12 +555,15 @@ struct subnet *parse_subnet_statement (cfile, bc)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
token = peek_token (&val, cfile);
|
token = peek_token (&val, cfile);
|
||||||
if (token == SEMI) {
|
if (token == SEMI || token == SUBNET)
|
||||||
token = next_token (&val, cfile);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
parse_subnet_decl (cfile, bc, subnet);
|
parse_subnet_decl (cfile, bc, subnet);
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
|
/* If this subnet supports dynamic bootp, flag it so in the
|
||||||
|
shared_network containing it. */
|
||||||
|
if (subnet -> dynamic_bootp)
|
||||||
|
share -> dynamic_bootp = 1;
|
||||||
return subnet;
|
return subnet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,31 +589,13 @@ void parse_subnet_decl (cfile, bc, decl)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DEFAULT_LEASE_TIME:
|
case DEFAULT_LEASE_TIME:
|
||||||
token = next_token (&val, cfile);
|
parse_lease_time (cfile, bc,
|
||||||
if (token != NUMBER) {
|
&decl -> default_lease_time);
|
||||||
parse_warn ("Expecting numeric default lease time");
|
|
||||||
skip_to_semi (cfile);
|
|
||||||
longjmp (jdref (bc), 1);
|
|
||||||
}
|
|
||||||
convert_num ((unsigned char *)&decl -> default_lease_time,
|
|
||||||
val, 10, 32);
|
|
||||||
/* Unswap the number - convert_num returns stuff in NBO. */
|
|
||||||
decl -> default_lease_time =
|
|
||||||
ntohl (decl -> default_lease_time);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAX_LEASE_TIME:
|
case MAX_LEASE_TIME:
|
||||||
token = next_token (&val, cfile);
|
parse_lease_time (cfile, bc,
|
||||||
if (token != NUMBER) {
|
&decl -> max_lease_time);
|
||||||
parse_warn ("Expecting numeric max lease time");
|
|
||||||
skip_to_semi (cfile);
|
|
||||||
longjmp (jdref (bc), 1);
|
|
||||||
}
|
|
||||||
convert_num ((unsigned char *)&decl -> max_lease_time,
|
|
||||||
val, 10, 32);
|
|
||||||
/* Unswap the number - convert_num returns stuff in NBO. */
|
|
||||||
decl -> max_lease_time =
|
|
||||||
ntohl (decl -> max_lease_time);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -431,7 +607,8 @@ void parse_subnet_decl (cfile, bc, decl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* host_declaration :== hardware_declaration | filename_declaration
|
/* host_declaration :== hardware_declaration | filename_declaration
|
||||||
| fixed_addr_declaration | option_declaration */
|
| fixed_addr_declaration | option_declaration
|
||||||
|
| max_lease_declaration | default_lease_declaration */
|
||||||
|
|
||||||
void parse_host_decl (cfile, bc, decl)
|
void parse_host_decl (cfile, bc, decl)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
@ -449,12 +626,23 @@ void parse_host_decl (cfile, bc, decl)
|
|||||||
case FILENAME:
|
case FILENAME:
|
||||||
decl -> filename = parse_filename_decl (cfile, bc);
|
decl -> filename = parse_filename_decl (cfile, bc);
|
||||||
break;
|
break;
|
||||||
|
case SERVER_NAME:
|
||||||
|
decl -> server_name = parse_servername_decl (cfile, bc);
|
||||||
|
break;
|
||||||
case FIXED_ADDR:
|
case FIXED_ADDR:
|
||||||
parse_fixed_addr_decl (cfile, bc, decl);
|
parse_fixed_addr_decl (cfile, bc, decl);
|
||||||
break;
|
break;
|
||||||
case OPTION:
|
case OPTION:
|
||||||
parse_option_decl (cfile, bc, decl -> options);
|
parse_option_decl (cfile, bc, decl -> options);
|
||||||
break;
|
break;
|
||||||
|
case DEFAULT_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&decl -> default_lease_time);
|
||||||
|
break;
|
||||||
|
case MAX_LEASE_TIME:
|
||||||
|
parse_lease_time (cfile, bc,
|
||||||
|
&decl -> max_lease_time);
|
||||||
|
break;
|
||||||
case CIADDR:
|
case CIADDR:
|
||||||
decl -> ciaddr =
|
decl -> ciaddr =
|
||||||
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
||||||
@ -493,25 +681,10 @@ void parse_hardware_decl (cfile, bc, decl)
|
|||||||
|
|
||||||
hw = parse_hardware_addr (cfile, bc);
|
hw = parse_hardware_addr (cfile, bc);
|
||||||
|
|
||||||
/* Find space for the new interface... */
|
|
||||||
if (decl -> interfaces) {
|
|
||||||
decl -> interfaces =
|
|
||||||
(struct hardware *)realloc (decl -> interfaces,
|
|
||||||
++decl -> interface_count *
|
|
||||||
sizeof (struct hardware));
|
|
||||||
} else {
|
|
||||||
decl -> interfaces =
|
|
||||||
(struct hardware *)malloc (sizeof (struct hardware));
|
|
||||||
decl -> interface_count = 1;
|
|
||||||
}
|
|
||||||
if (!decl -> interfaces)
|
|
||||||
error ("no memory for hardware interface info.");
|
|
||||||
|
|
||||||
/* Copy out the information... */
|
/* Copy out the information... */
|
||||||
decl -> interfaces [decl -> interface_count - 1].htype = hw.htype;
|
decl -> interface.htype = hw.htype;
|
||||||
decl -> interfaces [decl -> interface_count - 1].hlen = hw.hlen;
|
decl -> interface.hlen = hw.hlen;
|
||||||
memcpy (decl -> interfaces [decl -> interface_count - 1].haddr,
|
memcpy (decl -> interface.haddr, &hw.haddr [0], hw.hlen);
|
||||||
&hw.haddr [0], hw.hlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hardware parse_hardware_addr (cfile, bc)
|
struct hardware parse_hardware_addr (cfile, bc)
|
||||||
@ -564,6 +737,29 @@ char *parse_filename_decl (cfile, bc)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* servername_decl :== SERVER_NAME STRING */
|
||||||
|
|
||||||
|
char *parse_servername_decl (cfile, bc)
|
||||||
|
FILE *cfile;
|
||||||
|
jbp_decl (bc);
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != STRING) {
|
||||||
|
parse_warn ("server name must be a string");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
longjmp (jdref (bc), 1);
|
||||||
|
}
|
||||||
|
s = (char *)malloc (strlen (val));
|
||||||
|
if (!s)
|
||||||
|
error ("no memory for server name.");
|
||||||
|
strcpy (s, val);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/* ip_addr_or_hostname :== ip_address | hostname
|
/* ip_addr_or_hostname :== ip_address | hostname
|
||||||
ip_address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
|
ip_address :== NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
|
||||||
|
|
||||||
@ -602,15 +798,33 @@ struct tree *parse_ip_addr_or_hostname (cfile, bc, uniform)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fixed_addr_declaration :== FIXED_ADDR ip_addr_or_hostname */
|
/* fixed_addr_clause :==
|
||||||
|
FIXED_ADDR fixed_addr_decls
|
||||||
|
|
||||||
|
fixed_addr_decls :== ip_addr_or_hostname |
|
||||||
|
fixed_addr_decls ip_addr_or_hostname */
|
||||||
|
|
||||||
void parse_fixed_addr_decl (cfile, bc, decl)
|
void parse_fixed_addr_decl (cfile, bc, decl)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
jbp_decl (bc);
|
jbp_decl (bc);
|
||||||
struct host_decl *decl;
|
struct host_decl *decl;
|
||||||
{
|
{
|
||||||
decl -> fixed_addr =
|
char *val;
|
||||||
tree_cache (parse_ip_addr_or_hostname (cfile, bc, 0));
|
int token;
|
||||||
|
struct tree *tree = (struct tree *)0;
|
||||||
|
struct tree *tmp;
|
||||||
|
|
||||||
|
do {
|
||||||
|
tmp = parse_ip_addr_or_hostname (cfile, bc, 0);
|
||||||
|
if (tree)
|
||||||
|
tree = tree_concat (tree, tmp);
|
||||||
|
else
|
||||||
|
tree = tmp;
|
||||||
|
token = peek_token (&val, cfile);
|
||||||
|
if (token == COMMA)
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
} while (token == COMMA);
|
||||||
|
decl -> fixed_addr = tree_cache (tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* option_declaration :== OPTION identifier DOT identifier <syntax> |
|
/* option_declaration :== OPTION identifier DOT identifier <syntax> |
|
||||||
@ -790,10 +1004,6 @@ void parse_option_decl (cfile, bc, options)
|
|||||||
}
|
}
|
||||||
} while (*fmt == 'A');
|
} while (*fmt == 'A');
|
||||||
|
|
||||||
if (options [option -> code]) {
|
|
||||||
parse_warn ("duplicate option code %d (%s).",
|
|
||||||
option -> code, option -> name);
|
|
||||||
}
|
|
||||||
options [option -> code] = tree_cache (tree);
|
options [option -> code] = tree_cache (tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,7 +1039,8 @@ TIME parse_timestamp (cfile, bc)
|
|||||||
| UID hex_numbers
|
| UID hex_numbers
|
||||||
| HOST identifier
|
| HOST identifier
|
||||||
| CLASS identifier
|
| CLASS identifier
|
||||||
| TIMESTAMP number */
|
| TIMESTAMP number
|
||||||
|
| DYNAMIC_BOOTP */
|
||||||
|
|
||||||
struct lease *parse_lease_statement (cfile, bc)
|
struct lease *parse_lease_statement (cfile, bc)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
@ -912,6 +1123,7 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
memcpy (lease.uid, s, lease.uid_len);
|
memcpy (lease.uid, s, lease.uid_len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
case HOST:
|
case HOST:
|
||||||
seenbit = 16;
|
seenbit = 16;
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@ -927,6 +1139,7 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
val,
|
val,
|
||||||
"no longer known.");
|
"no longer known.");
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case CLASS:
|
case CLASS:
|
||||||
seenbit = 32;
|
seenbit = 32;
|
||||||
@ -945,6 +1158,11 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
= parse_hardware_addr (cfile, bc);
|
= parse_hardware_addr (cfile, bc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DYNAMIC_BOOTP:
|
||||||
|
seenbit = 128;
|
||||||
|
lease.flags |= BOOTP_LEASE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
@ -960,7 +1178,8 @@ struct lease *parse_lease_statement (cfile, bc)
|
|||||||
return &lease;
|
return &lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* address_range :== RANGE ip_address ip_address */
|
/* address_range :== RANGE ip_address ip_address |
|
||||||
|
RANGE dynamic_bootp_statement ip_address ip_address */
|
||||||
|
|
||||||
void parse_address_range (cfile, bc, subnet)
|
void parse_address_range (cfile, bc, subnet)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
@ -972,6 +1191,12 @@ void parse_address_range (cfile, bc, subnet)
|
|||||||
int len = sizeof addr;
|
int len = sizeof addr;
|
||||||
int token;
|
int token;
|
||||||
char *val;
|
char *val;
|
||||||
|
int dynamic = 0;
|
||||||
|
|
||||||
|
if ((token = peek_token (&val, cfile)) == DYNAMIC_BOOTP) {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
subnet -> dynamic_bootp = dynamic = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the bottom address in the range... */
|
/* Get the bottom address in the range... */
|
||||||
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
parse_numeric_aggregate (cfile, bc, addr, &len, DOT, 10, 8);
|
||||||
@ -984,7 +1209,7 @@ void parse_address_range (cfile, bc, subnet)
|
|||||||
high.len = len;
|
high.len = len;
|
||||||
|
|
||||||
/* Create the new address range... */
|
/* Create the new address range... */
|
||||||
new_address_range (low, high, subnet);
|
new_address_range (low, high, subnet, dynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
/* date :== NUMBER NUMBER/NUMBER/NUMBER NUMBER:NUMBER:NUMBER
|
||||||
|
Loading…
x
Reference in New Issue
Block a user