mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-01 14:55:30 +00:00
Fix up all the option handling code to use evaluation instead of fixed data.
This commit is contained in:
171
client/clparse.c
171
client/clparse.c
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: clparse.c,v 1.17 1998/10/22 04:52:23 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: clparse.c,v 1.18 1998/11/05 18:38:43 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -52,6 +52,17 @@ static TIME parsed_time;
|
|||||||
|
|
||||||
struct client_config top_level_config;
|
struct client_config top_level_config;
|
||||||
|
|
||||||
|
u_int32_t default_requested_options [] = {
|
||||||
|
DHO_SUBNET_MASK,
|
||||||
|
DHO_BROADCAST_ADDRESS,
|
||||||
|
DHO_TIME_OFFSET,
|
||||||
|
DHO_ROUTERS,
|
||||||
|
DHO_DOMAIN_NAME,
|
||||||
|
DHO_DOMAIN_NAME_SERVERS,
|
||||||
|
DHO_HOST_NAME,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
/* client-conf-file :== client-declarations EOF
|
/* client-conf-file :== client-declarations EOF
|
||||||
client-declarations :== <nil>
|
client-declarations :== <nil>
|
||||||
| client-declaration
|
| client-declaration
|
||||||
@@ -84,32 +95,8 @@ int read_client_conf ()
|
|||||||
top_level_config.initial_interval = 10;
|
top_level_config.initial_interval = 10;
|
||||||
top_level_config.bootp_policy = ACCEPT;
|
top_level_config.bootp_policy = ACCEPT;
|
||||||
top_level_config.script_name = "/etc/dhclient-script";
|
top_level_config.script_name = "/etc/dhclient-script";
|
||||||
top_level_config.requested_options
|
top_level_config.requested_options = default_requested_options;
|
||||||
[top_level_config.requested_option_count++] =
|
top_level_config.requested_lease = 7200;
|
||||||
DHO_SUBNET_MASK;
|
|
||||||
top_level_config.requested_options
|
|
||||||
[top_level_config.requested_option_count++] =
|
|
||||||
DHO_BROADCAST_ADDRESS;
|
|
||||||
top_level_config.requested_options
|
|
||||||
[top_level_config.requested_option_count++] =
|
|
||||||
DHO_TIME_OFFSET;
|
|
||||||
top_level_config.requested_options
|
|
||||||
[top_level_config.requested_option_count++] =
|
|
||||||
DHO_ROUTERS;
|
|
||||||
top_level_config.requested_options
|
|
||||||
[top_level_config.requested_option_count++] =
|
|
||||||
DHO_DOMAIN_NAME;
|
|
||||||
top_level_config.requested_options
|
|
||||||
[top_level_config.requested_option_count++] =
|
|
||||||
DHO_DOMAIN_NAME_SERVERS;
|
|
||||||
top_level_config.requested_options
|
|
||||||
[top_level_config.requested_option_count++] =
|
|
||||||
DHO_HOST_NAME;
|
|
||||||
top_level_config.requested_lease_time = 7200;
|
|
||||||
top_level_config.send_options.dhcp_options [DHO_DHCP_LEASE_TIME].data
|
|
||||||
= (unsigned char *)&top_level_config.requested_lease_time;
|
|
||||||
top_level_config.send_options.dhcp_options [DHO_DHCP_LEASE_TIME].len
|
|
||||||
= sizeof top_level_config.requested_lease_time;
|
|
||||||
|
|
||||||
if ((cfile = fopen (path_dhclient_conf, "r")) != NULL) {
|
if ((cfile = fopen (path_dhclient_conf, "r")) != NULL) {
|
||||||
do {
|
do {
|
||||||
@@ -144,12 +131,6 @@ int read_client_conf ()
|
|||||||
error ("no memory for client config.");
|
error ("no memory for client config.");
|
||||||
memcpy (config, &top_level_config,
|
memcpy (config, &top_level_config,
|
||||||
sizeof top_level_config);
|
sizeof top_level_config);
|
||||||
i = DHO_DHCP_LEASE_TIME;
|
|
||||||
config -> send_options.dhcp_options [i].data =
|
|
||||||
(unsigned char *)&config -> requested_lease_time;
|
|
||||||
top_level_config.send_options.dhcp_options [DHO_DHCP_LEASE_TIME].len
|
|
||||||
= sizeof top_level_config.requested_lease_time;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ip -> client -> config = config;
|
ip -> client -> config = config;
|
||||||
}
|
}
|
||||||
@@ -215,19 +196,17 @@ void parse_client_statement (cfile, ip, config)
|
|||||||
char *val;
|
char *val;
|
||||||
struct option *option;
|
struct option *option;
|
||||||
struct executable_statement *stmt, **p;
|
struct executable_statement *stmt, **p;
|
||||||
enum statement op op;
|
enum statement_op op;
|
||||||
|
|
||||||
switch (next_token (&val, cfile)) {
|
switch (next_token (&val, cfile)) {
|
||||||
case SEND:
|
case SEND:
|
||||||
p = &config -> on_tranmission;
|
p = &config -> on_transmission;
|
||||||
op = send_option_statement;
|
op = send_option_statement;
|
||||||
do_option:
|
do_option:
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
option = parse_option_name (cfile);
|
option = parse_option_name (cfile);
|
||||||
if (!option) {
|
if (!option)
|
||||||
*lose = 1;
|
return;
|
||||||
return (struct executable_statement *)0;
|
|
||||||
}
|
|
||||||
stmt = parse_option_statement (cfile, 1, option,
|
stmt = parse_option_statement (cfile, 1, option,
|
||||||
send_option_statement);
|
send_option_statement);
|
||||||
for (; *p; p = &((*p) -> next))
|
for (; *p; p = &((*p) -> next))
|
||||||
@@ -271,14 +250,11 @@ void parse_client_statement (cfile, ip, config)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case REQUEST:
|
case REQUEST:
|
||||||
config -> requested_option_count =
|
parse_option_list (cfile, &config -> requested_options);
|
||||||
parse_option_list (cfile, config -> requested_options);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REQUIRE:
|
case REQUIRE:
|
||||||
memset (config -> required_options, 0,
|
parse_option_list (cfile, &config -> required_options);
|
||||||
sizeof config -> required_options);
|
|
||||||
parse_option_list (cfile, config -> required_options);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case TIMEOUT:
|
case TIMEOUT:
|
||||||
@@ -390,13 +366,14 @@ int parse_X (cfile, buf, max)
|
|||||||
/* option-list :== option_name |
|
/* option-list :== option_name |
|
||||||
option_list COMMA option_name */
|
option_list COMMA option_name */
|
||||||
|
|
||||||
int parse_option_list (cfile, list)
|
void parse_option_list (cfile, list)
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
u_int8_t *list;
|
u_int32_t **list;
|
||||||
{
|
{
|
||||||
int ix, i;
|
int ix, i;
|
||||||
int token;
|
int token;
|
||||||
char *val;
|
char *val;
|
||||||
|
pair p = (pair)0, q, r;
|
||||||
|
|
||||||
ix = 0;
|
ix = 0;
|
||||||
do {
|
do {
|
||||||
@@ -404,7 +381,7 @@ int parse_option_list (cfile, list)
|
|||||||
if (!is_identifier (token)) {
|
if (!is_identifier (token)) {
|
||||||
parse_warn ("expected option name.");
|
parse_warn ("expected option name.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
if (!strcasecmp (dhcp_options [i].name, val))
|
if (!strcasecmp (dhcp_options [i].name, val))
|
||||||
@@ -413,22 +390,42 @@ int parse_option_list (cfile, list)
|
|||||||
if (i == 256) {
|
if (i == 256) {
|
||||||
parse_warn ("%s: expected option name.");
|
parse_warn ("%s: expected option name.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return 0;
|
return;
|
||||||
}
|
|
||||||
list [ix++] = i;
|
|
||||||
if (ix == 256) {
|
|
||||||
parse_warn ("%s: too many options.", val);
|
|
||||||
skip_to_semi (cfile);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
r = new_pair ("parse_option_list");
|
||||||
|
if (!r)
|
||||||
|
error ("can't allocate pair for option code.");
|
||||||
|
r -> car = (caddr_t)i;
|
||||||
|
r -> cdr = (pair)0;
|
||||||
|
if (p)
|
||||||
|
q -> cdr = r;
|
||||||
|
else
|
||||||
|
p = r;
|
||||||
|
q = r;
|
||||||
|
++ix;
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
} while (token == COMMA);
|
} while (token == COMMA);
|
||||||
if (token != SEMI) {
|
if (token != SEMI) {
|
||||||
parse_warn ("expecting semicolon.");
|
parse_warn ("expecting semicolon.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return 0;
|
return;
|
||||||
|
}
|
||||||
|
if (*list)
|
||||||
|
dfree (*list, "parse_option_list");
|
||||||
|
*list = dmalloc (ix * sizeof **list, "parse_option_list");
|
||||||
|
if (!*list)
|
||||||
|
warn ("no memory for option list.");
|
||||||
|
else {
|
||||||
|
ix = 0;
|
||||||
|
for (q = p; q; q = q -> cdr)
|
||||||
|
(*list) [ix++] = (u_int32_t)q -> car;
|
||||||
|
(*list) [ix] = 0;
|
||||||
|
}
|
||||||
|
while (p) {
|
||||||
|
q = p -> cdr;
|
||||||
|
free_pair (p, "parse_option_list");
|
||||||
|
p = q;
|
||||||
}
|
}
|
||||||
return ix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* interface-declaration :==
|
/* interface-declaration :==
|
||||||
@@ -589,7 +586,7 @@ void parse_client_lease_statement (cfile, is_static)
|
|||||||
/* If the lease declaration didn't include an interface
|
/* If the lease declaration didn't include an interface
|
||||||
declaration that we recognized, it's of no use to us. */
|
declaration that we recognized, it's of no use to us. */
|
||||||
if (!ip) {
|
if (!ip) {
|
||||||
free_client_lease (lease);
|
destroy_client_lease (lease);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,7 +613,7 @@ void parse_client_lease_statement (cfile, is_static)
|
|||||||
pl -> next = lp -> next;
|
pl -> next = lp -> next;
|
||||||
else
|
else
|
||||||
ip -> client -> leases = lp -> next;
|
ip -> client -> leases = lp -> next;
|
||||||
free_client_lease (lp);
|
destroy_client_lease (lp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -642,13 +639,13 @@ void parse_client_lease_statement (cfile, is_static)
|
|||||||
still valid but no longer active. */
|
still valid but no longer active. */
|
||||||
if (ip -> client -> active) {
|
if (ip -> client -> active) {
|
||||||
if (ip -> client -> active -> expiry < cur_time)
|
if (ip -> client -> active -> expiry < cur_time)
|
||||||
free_client_lease (ip -> client -> active);
|
destroy_client_lease (ip -> client -> active);
|
||||||
else if (ip -> client -> active -> address.len ==
|
else if (ip -> client -> active -> address.len ==
|
||||||
lease -> address.len &&
|
lease -> address.len &&
|
||||||
!memcmp (ip -> client -> active -> address.iabuf,
|
!memcmp (ip -> client -> active -> address.iabuf,
|
||||||
lease -> address.iabuf,
|
lease -> address.iabuf,
|
||||||
lease -> address.len))
|
lease -> address.len))
|
||||||
free_client_lease (ip -> client -> active);
|
destroy_client_lease (ip -> client -> active);
|
||||||
else {
|
else {
|
||||||
ip -> client -> active -> next =
|
ip -> client -> active -> next =
|
||||||
ip -> client -> leases;
|
ip -> client -> leases;
|
||||||
@@ -680,6 +677,7 @@ void parse_client_lease_declaration (cfile, lease, ipp)
|
|||||||
char *val;
|
char *val;
|
||||||
char *t, *n;
|
char *t, *n;
|
||||||
struct interface_info *ip;
|
struct interface_info *ip;
|
||||||
|
struct option_cache *oc;
|
||||||
|
|
||||||
switch (next_token (&val, cfile)) {
|
switch (next_token (&val, cfile)) {
|
||||||
case BOOTP:
|
case BOOTP:
|
||||||
@@ -727,7 +725,14 @@ void parse_client_lease_declaration (cfile, lease, ipp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case OPTION:
|
case OPTION:
|
||||||
parse_option_decl (cfile, lease -> options);
|
oc = (struct option_cache *)0;
|
||||||
|
if (parse_option_decl (&oc, cfile)) {
|
||||||
|
/* XXX save_option here ought to account for the
|
||||||
|
XXX correct option universe, but it doesn't. */
|
||||||
|
save_option (lease -> options.dhcp_hash, oc);
|
||||||
|
option_cache_dereference
|
||||||
|
(&oc, "parse_client_lease_declaration");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -742,9 +747,9 @@ void parse_client_lease_declaration (cfile, lease, ipp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct option *parse_option_decl (cfile, options)
|
int parse_option_decl (oc, cfile)
|
||||||
|
struct option_cache **oc;
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
struct option_data *options;
|
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
int token;
|
int token;
|
||||||
@@ -757,10 +762,11 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
u_int8_t *dp;
|
u_int8_t *dp;
|
||||||
int len;
|
int len;
|
||||||
int nul_term = 0;
|
int nul_term = 0;
|
||||||
|
struct buffer *bp;
|
||||||
|
|
||||||
option = parse_option_name (cfile);
|
option = parse_option_name (cfile);
|
||||||
if (!option)
|
if (!option)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
/* Parse the option data... */
|
/* Parse the option data... */
|
||||||
do {
|
do {
|
||||||
@@ -784,14 +790,14 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
if (token != STRING) {
|
if (token != STRING) {
|
||||||
parse_warn ("expecting string.");
|
parse_warn ("expecting string.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
}
|
}
|
||||||
len = strlen (val);
|
len = strlen (val);
|
||||||
if (hunkix + len + 1 > sizeof hunkbuf) {
|
if (hunkix + len + 1 > sizeof hunkbuf) {
|
||||||
parse_warn ("option data buffer %s",
|
parse_warn ("option data buffer %s",
|
||||||
"overflow");
|
"overflow");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy (&hunkbuf [hunkix], val, len + 1);
|
memcpy (&hunkbuf [hunkix], val, len + 1);
|
||||||
nul_term = 1;
|
nul_term = 1;
|
||||||
@@ -800,7 +806,7 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
|
|
||||||
case 'I': /* IP address. */
|
case 'I': /* IP address. */
|
||||||
if (!parse_ip_addr (cfile, &ip_addr))
|
if (!parse_ip_addr (cfile, &ip_addr))
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
len = ip_addr.len;
|
len = ip_addr.len;
|
||||||
dp = ip_addr.iabuf;
|
dp = ip_addr.iabuf;
|
||||||
|
|
||||||
@@ -809,7 +815,7 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
parse_warn ("option data buffer %s",
|
parse_warn ("option data buffer %s",
|
||||||
"overflow");
|
"overflow");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy (&hunkbuf [hunkix], dp, len);
|
memcpy (&hunkbuf [hunkix], dp, len);
|
||||||
hunkix += len;
|
hunkix += len;
|
||||||
@@ -823,7 +829,7 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
parse_warn ("expecting number.");
|
parse_warn ("expecting number.");
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
}
|
}
|
||||||
convert_num (buf, val, 0, 32);
|
convert_num (buf, val, 0, 32);
|
||||||
len = 4;
|
len = 4;
|
||||||
@@ -857,7 +863,7 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
bad_flag:
|
bad_flag:
|
||||||
if (token != SEMI)
|
if (token != SEMI)
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcasecmp (val, "true")
|
if (!strcasecmp (val, "true")
|
||||||
|| !strcasecmp (val, "on"))
|
|| !strcasecmp (val, "on"))
|
||||||
@@ -877,7 +883,7 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
warn ("Bad format %c in parse_option_param.",
|
warn ("Bad format %c in parse_option_param.",
|
||||||
*fmt);
|
*fmt);
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@@ -886,16 +892,25 @@ struct option *parse_option_decl (cfile, options)
|
|||||||
if (token != SEMI) {
|
if (token != SEMI) {
|
||||||
parse_warn ("semicolon expected.");
|
parse_warn ("semicolon expected.");
|
||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (struct option *)0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
options [option -> code].data =
|
bp = (struct buffer *)0;
|
||||||
(unsigned char *)malloc (hunkix + nul_term);
|
if (!buffer_allocate (&bp, hunkix + nul_term, "parse_option_decl"))
|
||||||
if (!options [option -> code].data)
|
error ("no memory to store option declaration.");
|
||||||
|
if (!bp -> data)
|
||||||
error ("out of memory allocating option data.");
|
error ("out of memory allocating option data.");
|
||||||
memcpy (options [option -> code].data, hunkbuf, hunkix + nul_term);
|
memcpy (bp -> data, hunkbuf, hunkix + nul_term);
|
||||||
options [option -> code].len = hunkix;
|
|
||||||
return option;
|
if (!option_cache_allocate (oc, "parse_option_decl"))
|
||||||
|
error ("out of memory allocating option cache.");
|
||||||
|
|
||||||
|
(*oc) -> data.buffer = bp;
|
||||||
|
(*oc) -> data.data = &bp -> data [0];
|
||||||
|
(*oc) -> data.terminated = nul_term;
|
||||||
|
(*oc) -> data.len = hunkix;
|
||||||
|
(*oc) -> option = option;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_string_list (cfile, lp, multiple)
|
void parse_string_list (cfile, lp, multiple)
|
||||||
|
@@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: dhclient.c,v 1.49 1998/04/09 04:26:24 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: dhclient.c,v 1.50 1998/11/05 18:39:04 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -259,6 +259,25 @@ void cleanup ()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct class *find_class (s)
|
||||||
|
char *s;
|
||||||
|
{
|
||||||
|
return (struct class *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_collection (packet, collection)
|
||||||
|
struct packet *packet;
|
||||||
|
struct collection *collection;
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void classify (packet, class)
|
||||||
|
struct packet *packet;
|
||||||
|
struct class *class;
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* Individual States:
|
/* Individual States:
|
||||||
*
|
*
|
||||||
* Each routine is called from the dhclient_state_machine() in one of
|
* Each routine is called from the dhclient_state_machine() in one of
|
||||||
@@ -389,7 +408,7 @@ void state_selecting (ipp)
|
|||||||
picked -> next = (struct client_lease *)0;
|
picked -> next = (struct client_lease *)0;
|
||||||
} else {
|
} else {
|
||||||
freeit:
|
freeit:
|
||||||
free_client_lease (lp);
|
destroy_client_lease (lp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ip -> client -> offered_leases = (struct client_lease *)0;
|
ip -> client -> offered_leases = (struct client_lease *)0;
|
||||||
@@ -403,7 +422,7 @@ void state_selecting (ipp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If it was a BOOTREPLY, we can just take the address right now. */
|
/* If it was a BOOTREPLY, we can just take the address right now. */
|
||||||
if (!picked -> options [DHO_DHCP_MESSAGE_TYPE].len) {
|
if (!picked -> is_bootp) {
|
||||||
ip -> client -> new = picked;
|
ip -> client -> new = picked;
|
||||||
|
|
||||||
/* Make up some lease expiry times
|
/* Make up some lease expiry times
|
||||||
@@ -430,7 +449,7 @@ void state_selecting (ipp)
|
|||||||
ip -> client -> xid = ip -> client -> packet.xid;
|
ip -> client -> xid = ip -> client -> packet.xid;
|
||||||
|
|
||||||
/* Toss the lease we picked - we'll get it back in a DHCPACK. */
|
/* Toss the lease we picked - we'll get it back in a DHCPACK. */
|
||||||
free_client_lease (picked);
|
destroy_client_lease (picked);
|
||||||
|
|
||||||
/* Add an immediate timeout to send the first DHCPREQUEST packet. */
|
/* Add an immediate timeout to send the first DHCPREQUEST packet. */
|
||||||
send_request (ip);
|
send_request (ip);
|
||||||
@@ -444,6 +463,8 @@ void dhcpack (packet)
|
|||||||
{
|
{
|
||||||
struct interface_info *ip = packet -> interface;
|
struct interface_info *ip = packet -> interface;
|
||||||
struct client_lease *lease;
|
struct client_lease *lease;
|
||||||
|
struct option_cache *oc;
|
||||||
|
struct data_string ds;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* If we're not receptive to an offer right now, or if the offer
|
/* If we're not receptive to an offer right now, or if the offer
|
||||||
@@ -479,26 +500,63 @@ void dhcpack (packet)
|
|||||||
cancel_timeout (send_request, ip);
|
cancel_timeout (send_request, ip);
|
||||||
|
|
||||||
/* Figure out the lease time. */
|
/* Figure out the lease time. */
|
||||||
ip -> client -> new -> expiry =
|
oc = lookup_option (ip -> client -> new -> options.dhcp_hash,
|
||||||
getULong (ip -> client ->
|
DHO_DHCP_LEASE_TIME);
|
||||||
new -> options [DHO_DHCP_LEASE_TIME].data);
|
memset (&ds, 0, sizeof ds);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache (&ds, packet,
|
||||||
|
&ip -> client -> new -> options, oc)) {
|
||||||
|
if (ds.len > 3)
|
||||||
|
ip -> client -> new -> expiry = getULong (ds.data);
|
||||||
|
else
|
||||||
|
ip -> client -> new -> expiry = 0;
|
||||||
|
data_string_forget (&ds, "dhcpack");
|
||||||
|
} else
|
||||||
|
ip -> client -> new -> expiry = 0;
|
||||||
|
|
||||||
/* Take the server-provided renewal time if there is one;
|
if (!ip -> client -> new -> expiry) {
|
||||||
otherwise figure it out according to the spec. */
|
warn ("no expiry time on offered lease.");
|
||||||
if (ip -> client -> new -> options [DHO_DHCP_RENEWAL_TIME].len)
|
/* XXX this is going to be bad - if this _does_
|
||||||
ip -> client -> new -> renewal =
|
XXX happen, we should probably dynamically
|
||||||
getULong (ip -> client ->
|
XXX disqualify the DHCP server that gave us the
|
||||||
new -> options [DHO_DHCP_RENEWAL_TIME].data);
|
XXX bad packet from future selections and
|
||||||
else
|
XXX then go back into the init state. */
|
||||||
|
state_init (ip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take the server-provided renewal time if there is one. */
|
||||||
|
oc = lookup_option (ip -> client -> new -> options.dhcp_hash,
|
||||||
|
DHO_DHCP_RENEWAL_TIME);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache (&ds, packet,
|
||||||
|
&ip -> client -> new -> options, oc)) {
|
||||||
|
if (ds.len > 3)
|
||||||
|
ip -> client -> new -> renewal = getULong (ds.data);
|
||||||
|
else
|
||||||
|
ip -> client -> new -> renewal = 0;
|
||||||
|
} else
|
||||||
|
ip -> client -> new -> renewal = 0;
|
||||||
|
|
||||||
|
/* If it wasn't specified by the server, calculate it. */
|
||||||
|
if (!ip -> client -> new -> renewal)
|
||||||
ip -> client -> new -> renewal =
|
ip -> client -> new -> renewal =
|
||||||
ip -> client -> new -> expiry / 2;
|
ip -> client -> new -> expiry / 2;
|
||||||
|
|
||||||
/* Same deal with the rebind time. */
|
/* Same deal with the rebind time. */
|
||||||
if (ip -> client -> new -> options [DHO_DHCP_REBINDING_TIME].len)
|
oc = lookup_option (ip -> client -> new -> options.dhcp_hash,
|
||||||
ip -> client -> new -> rebind =
|
DHO_DHCP_REBINDING_TIME);
|
||||||
getULong (ip -> client -> new ->
|
if (oc &&
|
||||||
options [DHO_DHCP_REBINDING_TIME].data);
|
evaluate_option_cache (&ds, packet,
|
||||||
else
|
&ip -> client -> new -> options, oc)) {
|
||||||
|
if (ds.len > 3)
|
||||||
|
ip -> client -> new -> rebind = getULong (ds.data);
|
||||||
|
else
|
||||||
|
ip -> client -> new -> rebind = 0;
|
||||||
|
} else
|
||||||
|
ip -> client -> new -> rebind = 0;
|
||||||
|
|
||||||
|
if (!ip -> client -> new -> rebind)
|
||||||
ip -> client -> new -> rebind =
|
ip -> client -> new -> rebind =
|
||||||
ip -> client -> new -> renewal +
|
ip -> client -> new -> renewal +
|
||||||
ip -> client -> new -> renewal / 2 +
|
ip -> client -> new -> renewal / 2 +
|
||||||
@@ -537,7 +595,7 @@ void bind_lease (ip)
|
|||||||
|
|
||||||
/* Replace the old active lease with the new one. */
|
/* Replace the old active lease with the new one. */
|
||||||
if (ip -> client -> active)
|
if (ip -> client -> active)
|
||||||
free_client_lease (ip -> client -> active);
|
destroy_client_lease (ip -> client -> active);
|
||||||
ip -> client -> active = ip -> client -> new;
|
ip -> client -> active = ip -> client -> new;
|
||||||
ip -> client -> new = (struct client_lease *)0;
|
ip -> client -> new = (struct client_lease *)0;
|
||||||
|
|
||||||
@@ -562,6 +620,9 @@ void state_bound (ipp)
|
|||||||
void *ipp;
|
void *ipp;
|
||||||
{
|
{
|
||||||
struct interface_info *ip = ipp;
|
struct interface_info *ip = ipp;
|
||||||
|
int i;
|
||||||
|
struct option_cache *oc;
|
||||||
|
struct data_string ds;
|
||||||
|
|
||||||
ASSERT_STATE(state, S_BOUND);
|
ASSERT_STATE(state, S_BOUND);
|
||||||
|
|
||||||
@@ -569,12 +630,17 @@ void state_bound (ipp)
|
|||||||
make_request (ip, ip -> client -> active);
|
make_request (ip, ip -> client -> active);
|
||||||
ip -> client -> xid = ip -> client -> packet.xid;
|
ip -> client -> xid = ip -> client -> packet.xid;
|
||||||
|
|
||||||
if (ip -> client -> active ->
|
memset (&ds, 0, sizeof ds);
|
||||||
options [DHO_DHCP_SERVER_IDENTIFIER].len == 4) {
|
oc = lookup_option (ip -> client -> active -> options.dhcp_hash,
|
||||||
memcpy (ip -> client -> destination.iabuf,
|
DHO_DHCP_SERVER_IDENTIFIER);
|
||||||
ip -> client -> active ->
|
if (oc &&
|
||||||
options [DHO_DHCP_SERVER_IDENTIFIER].data, 4);
|
evaluate_option_cache (&ds, (struct packet *)0,
|
||||||
ip -> client -> destination.len = 4;
|
&ip -> client -> active -> options, oc)) {
|
||||||
|
if (ds.len > 3) {
|
||||||
|
memcpy (ip -> client -> destination.iabuf, ds.data, 4);
|
||||||
|
ip -> client -> destination.len = 4;
|
||||||
|
} else
|
||||||
|
ip -> client -> destination = iaddr_broadcast;
|
||||||
} else
|
} else
|
||||||
ip -> client -> destination = iaddr_broadcast;
|
ip -> client -> destination = iaddr_broadcast;
|
||||||
|
|
||||||
@@ -671,9 +737,9 @@ void dhcpoffer (packet)
|
|||||||
struct client_lease *lease, *lp;
|
struct client_lease *lease, *lp;
|
||||||
int i;
|
int i;
|
||||||
int arp_timeout_needed, stop_selecting;
|
int arp_timeout_needed, stop_selecting;
|
||||||
char *name = (packet -> options [DHO_DHCP_MESSAGE_TYPE].len
|
char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
|
||||||
? "DHCPOFFER" : "BOOTREPLY");
|
|
||||||
struct iaddrlist *ap;
|
struct iaddrlist *ap;
|
||||||
|
struct option_cache *oc;
|
||||||
|
|
||||||
#ifdef DEBUG_PACKET
|
#ifdef DEBUG_PACKET
|
||||||
dump_packet (packet);
|
dump_packet (packet);
|
||||||
@@ -696,11 +762,15 @@ void dhcpoffer (packet)
|
|||||||
|
|
||||||
/* If this lease doesn't supply the minimum required parameters,
|
/* If this lease doesn't supply the minimum required parameters,
|
||||||
blow it off. */
|
blow it off. */
|
||||||
for (i = 0; ip -> client -> config -> required_options [i]; i++) {
|
if (ip -> client -> config -> required_options) {
|
||||||
if (!packet -> options [ip -> client -> config ->
|
for (i = 0;
|
||||||
required_options [i]].len) {
|
ip -> client -> config -> required_options [i]; i++) {
|
||||||
note ("%s isn't satisfactory.", name);
|
if (!lookup_option
|
||||||
return;
|
(packet -> options.dhcp_hash,
|
||||||
|
ip -> client -> config -> required_options [i])) {
|
||||||
|
note ("%s isn't satisfactory.", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -723,7 +793,7 @@ void dhcpoffer (packet)
|
|||||||
|
|
||||||
/* If this lease was acquired through a BOOTREPLY, record that
|
/* If this lease was acquired through a BOOTREPLY, record that
|
||||||
fact. */
|
fact. */
|
||||||
if (!packet -> options [DHO_DHCP_MESSAGE_TYPE].len)
|
if (!packet -> options_valid || !packet -> packet_type)
|
||||||
lease -> is_bootp = 1;
|
lease -> is_bootp = 1;
|
||||||
|
|
||||||
/* Record the medium under which this lease was offered. */
|
/* Record the medium under which this lease was offered. */
|
||||||
@@ -797,8 +867,10 @@ struct client_lease *packet_to_lease (packet)
|
|||||||
{
|
{
|
||||||
struct client_lease *lease;
|
struct client_lease *lease;
|
||||||
int i;
|
int i;
|
||||||
|
struct option_cache *oc;
|
||||||
|
struct data_string data;
|
||||||
|
|
||||||
lease = (struct client_lease *)malloc (sizeof (struct client_lease));
|
lease = (struct client_lease *)new_client_lease ("packet_to_lease");
|
||||||
|
|
||||||
if (!lease) {
|
if (!lease) {
|
||||||
warn ("dhcpoffer: no memory to record lease.\n");
|
warn ("dhcpoffer: no memory to record lease.\n");
|
||||||
@@ -808,45 +880,38 @@ struct client_lease *packet_to_lease (packet)
|
|||||||
memset (lease, 0, sizeof *lease);
|
memset (lease, 0, sizeof *lease);
|
||||||
|
|
||||||
/* Copy the lease options. */
|
/* Copy the lease options. */
|
||||||
for (i = 0; i < 256; i++) {
|
lease -> options = packet -> options;
|
||||||
if (packet -> options [i].len) {
|
memset (&packet -> options, 0, sizeof packet -> options);
|
||||||
lease -> options [i].data =
|
|
||||||
(unsigned char *)
|
|
||||||
malloc (packet -> options [i].len + 1);
|
|
||||||
if (!lease -> options [i].data) {
|
|
||||||
warn ("dhcpoffer: no memory for option %d\n",
|
|
||||||
i);
|
|
||||||
free_client_lease (lease);
|
|
||||||
return (struct client_lease *)0;
|
|
||||||
} else {
|
|
||||||
memcpy (lease -> options [i].data,
|
|
||||||
packet -> options [i].data,
|
|
||||||
packet -> options [i].len);
|
|
||||||
lease -> options [i].len =
|
|
||||||
packet -> options [i].len;
|
|
||||||
lease -> options [i].data
|
|
||||||
[lease -> options [i].len] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lease -> address.len = sizeof (packet -> raw -> yiaddr);
|
lease -> address.len = sizeof (packet -> raw -> yiaddr);
|
||||||
memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
|
memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
|
||||||
lease -> address.len);
|
lease -> address.len);
|
||||||
|
|
||||||
|
/* Figure out the overload flag. */
|
||||||
|
oc = lookup_option (lease -> options.dhcp_hash,
|
||||||
|
DHO_DHCP_OPTION_OVERLOAD);
|
||||||
|
memset (&data, 0, sizeof data);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache (&data, packet, &lease -> options, oc)) {
|
||||||
|
if (data.len > 0)
|
||||||
|
i = data.data [0];
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
data_string_forget (&data, "packet_to_lease");
|
||||||
|
} else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
/* If the server name was filled out, copy it. */
|
/* If the server name was filled out, copy it. */
|
||||||
if ((!packet -> options [DHO_DHCP_OPTION_OVERLOAD].len ||
|
if (!(i & 2) && packet -> raw -> sname [0]) {
|
||||||
!(packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)) &&
|
|
||||||
packet -> raw -> sname [0]) {
|
|
||||||
int len;
|
int len;
|
||||||
/* Don't count on the NUL terminator. */
|
/* Don't count on the NUL terminator. */
|
||||||
for (len = 0; len < 64; len++)
|
for (len = 0; len < 64; len++)
|
||||||
if (!packet -> raw -> sname [len])
|
if (!packet -> raw -> sname [len])
|
||||||
break;
|
break;
|
||||||
lease -> server_name = malloc (len + 1);
|
lease -> server_name = dmalloc (len + 1, "packet_to_lease");
|
||||||
if (!lease -> server_name) {
|
if (!lease -> server_name) {
|
||||||
warn ("dhcpoffer: no memory for filename.\n");
|
warn ("dhcpoffer: no memory for filename.\n");
|
||||||
free_client_lease (lease);
|
destroy_client_lease (lease);
|
||||||
return (struct client_lease *)0;
|
return (struct client_lease *)0;
|
||||||
} else {
|
} else {
|
||||||
memcpy (lease -> server_name,
|
memcpy (lease -> server_name,
|
||||||
@@ -856,18 +921,16 @@ struct client_lease *packet_to_lease (packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Ditto for the filename. */
|
/* Ditto for the filename. */
|
||||||
if ((!packet -> options [DHO_DHCP_OPTION_OVERLOAD].len ||
|
if ((i & 1) && packet -> raw -> file [0]) {
|
||||||
!(packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 1)) &&
|
|
||||||
packet -> raw -> file [0]) {
|
|
||||||
int len;
|
int len;
|
||||||
/* Don't count on the NUL terminator. */
|
/* Don't count on the NUL terminator. */
|
||||||
for (len = 0; len < 64; len++)
|
for (len = 0; len < 64; len++)
|
||||||
if (!packet -> raw -> file [len])
|
if (!packet -> raw -> file [len])
|
||||||
break;
|
break;
|
||||||
lease -> filename = malloc (len + 1);
|
lease -> filename = dmalloc (len + 1, "packet_to_lease");
|
||||||
if (!lease -> filename) {
|
if (!lease -> filename) {
|
||||||
warn ("dhcpoffer: no memory for filename.\n");
|
warn ("dhcpoffer: no memory for filename.\n");
|
||||||
free_client_lease (lease);
|
destroy_client_lease (lease);
|
||||||
return (struct client_lease *)0;
|
return (struct client_lease *)0;
|
||||||
} else {
|
} else {
|
||||||
memcpy (lease -> filename,
|
memcpy (lease -> filename,
|
||||||
@@ -909,7 +972,7 @@ void dhcpnak (packet)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_client_lease (ip -> client -> active);
|
destroy_client_lease (ip -> client -> active);
|
||||||
ip -> client -> active = (struct client_lease *)0;
|
ip -> client -> active = (struct client_lease *)0;
|
||||||
|
|
||||||
/* Stop sending DHCPREQUEST packets... */
|
/* Stop sending DHCPREQUEST packets... */
|
||||||
@@ -1317,6 +1380,103 @@ void send_release (ipp)
|
|||||||
warn ("send_packet: %m");
|
warn ("send_packet: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void make_client_options (ip, lease, type, sid, rip, prl, statements,
|
||||||
|
options)
|
||||||
|
struct interface_info *ip;
|
||||||
|
struct client_lease *lease;
|
||||||
|
u_int8_t *type;
|
||||||
|
struct option_cache *sid;
|
||||||
|
struct iaddr *rip;
|
||||||
|
u_int32_t *prl;
|
||||||
|
struct executable_statement *statements;
|
||||||
|
struct option_state *options;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct option_cache *oc;
|
||||||
|
struct buffer *bp = (struct buffer *)0;
|
||||||
|
|
||||||
|
memset (options, 0, sizeof *options);
|
||||||
|
|
||||||
|
/* Send the server identifier if provided. */
|
||||||
|
if (sid)
|
||||||
|
save_option (options -> dhcp_hash, sid);
|
||||||
|
|
||||||
|
/* Send the requested address if provided. */
|
||||||
|
if (rip) {
|
||||||
|
ip -> client -> requested_address = *rip;
|
||||||
|
if (!(make_const_option_cache
|
||||||
|
(&oc, (struct buffer **)0,
|
||||||
|
rip -> iabuf, rip -> len,
|
||||||
|
&dhcp_options [DHO_DHCP_REQUESTED_ADDRESS],
|
||||||
|
"make_client_options")))
|
||||||
|
warn ("can't make requested address option cache.");
|
||||||
|
else {
|
||||||
|
save_option (options -> dhcp_hash, oc);
|
||||||
|
option_cache_dereference (&oc, "make_client_options");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ip -> client -> requested_address.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(make_const_option_cache
|
||||||
|
(&oc, (struct buffer **)0,
|
||||||
|
type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE],
|
||||||
|
"make_client_options")))
|
||||||
|
warn ("can't make message type.");
|
||||||
|
else {
|
||||||
|
save_option (options -> dhcp_hash, oc);
|
||||||
|
option_cache_dereference (&oc, "make_client_options");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prl) {
|
||||||
|
/* Figure out how many parameters were requested. */
|
||||||
|
for (i = 0; prl [i]; i++)
|
||||||
|
;
|
||||||
|
if (!buffer_allocate (&bp, i, "make_client_options"))
|
||||||
|
warn ("can't make buffer for parameter request list.");
|
||||||
|
else {
|
||||||
|
for (i = 0; prl [i]; i++)
|
||||||
|
bp -> data [i] = prl [i];
|
||||||
|
if (!(make_const_option_cache
|
||||||
|
(&oc, &bp, (u_int8_t *)0, i,
|
||||||
|
&dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST],
|
||||||
|
"make_client_options")))
|
||||||
|
warn ("can't make option cache");
|
||||||
|
else {
|
||||||
|
save_option (options -> dhcp_hash, oc);
|
||||||
|
option_cache_dereference
|
||||||
|
(&oc, "make_client_options");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(oc = lookup_option (options -> dhcp_hash,
|
||||||
|
DHO_DHCP_LEASE_TIME))) {
|
||||||
|
if (!buffer_allocate (&bp, sizeof (u_int32_t),
|
||||||
|
"make_client_options"))
|
||||||
|
warn ("can't make buffer for requested lease time.");
|
||||||
|
else {
|
||||||
|
putULong (bp -> data,
|
||||||
|
ip -> client -> config -> requested_lease);
|
||||||
|
if (!(make_const_option_cache
|
||||||
|
(&oc, &bp, (u_int8_t *)0, sizeof (u_int32_t),
|
||||||
|
&dhcp_options [DHO_DHCP_LEASE_TIME],
|
||||||
|
"make_client_options")))
|
||||||
|
warn ("can't make option cache");
|
||||||
|
else {
|
||||||
|
save_option (options -> dhcp_hash, oc);
|
||||||
|
option_cache_dereference
|
||||||
|
(&oc, "make_client_options");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run statements that need to be run on transmission. */
|
||||||
|
if (statements)
|
||||||
|
execute_statements ((struct packet *)0,
|
||||||
|
&lease -> options, options, statements);
|
||||||
|
}
|
||||||
|
|
||||||
void make_discover (ip, lease)
|
void make_discover (ip, lease)
|
||||||
struct interface_info *ip;
|
struct interface_info *ip;
|
||||||
struct client_lease *lease;
|
struct client_lease *lease;
|
||||||
@@ -1324,67 +1484,20 @@ void make_discover (ip, lease)
|
|||||||
struct dhcp_packet *raw;
|
struct dhcp_packet *raw;
|
||||||
unsigned char discover = DHCPDISCOVER;
|
unsigned char discover = DHCPDISCOVER;
|
||||||
int i;
|
int i;
|
||||||
|
struct option_state options;
|
||||||
|
|
||||||
struct tree_cache *options [256];
|
|
||||||
struct tree_cache option_elements [256];
|
|
||||||
|
|
||||||
memset (option_elements, 0, sizeof option_elements);
|
|
||||||
memset (options, 0, sizeof options);
|
|
||||||
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
||||||
|
|
||||||
/* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
|
make_client_options (ip, lease, &discover, (struct option_cache *)0,
|
||||||
i = DHO_DHCP_MESSAGE_TYPE;
|
lease ? &lease -> address : (struct iaddr *)0,
|
||||||
options [i] = &option_elements [i];
|
ip -> client -> config -> requested_options,
|
||||||
options [i] -> value = &discover;
|
ip -> client -> config -> on_transmission,
|
||||||
options [i] -> len = sizeof discover;
|
&options);
|
||||||
options [i] -> buf_size = sizeof discover;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* Request the options we want */
|
|
||||||
i = DHO_DHCP_PARAMETER_REQUEST_LIST;
|
|
||||||
options [i] = &option_elements [i];
|
|
||||||
options [i] -> value = ip -> client -> config -> requested_options;
|
|
||||||
options [i] -> len = ip -> client -> config -> requested_option_count;
|
|
||||||
options [i] -> buf_size =
|
|
||||||
ip -> client -> config -> requested_option_count;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* If we had an address, try to get it again. */
|
|
||||||
if (lease) {
|
|
||||||
ip -> client -> requested_address = lease -> address;
|
|
||||||
i = DHO_DHCP_REQUESTED_ADDRESS;
|
|
||||||
options [i] = &option_elements [i];
|
|
||||||
options [i] -> value = lease -> address.iabuf;
|
|
||||||
options [i] -> len = lease -> address.len;
|
|
||||||
options [i] -> buf_size = lease -> address.len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
} else {
|
|
||||||
ip -> client -> requested_address.len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send any options requested in the config file. */
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
if (!options [i] &&
|
|
||||||
ip -> client -> config -> send_options [i].data) {
|
|
||||||
options [i] = &option_elements [i];
|
|
||||||
options [i] -> value = ip -> client -> config ->
|
|
||||||
send_options [i].data;
|
|
||||||
options [i] -> len = ip -> client -> config ->
|
|
||||||
send_options [i].len;
|
|
||||||
options [i] -> buf_size = ip -> client -> config ->
|
|
||||||
send_options [i].len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up the option buffer... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
||||||
options, (struct agent_options *)0, 0, 0, 0);
|
&options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||||
|
|
||||||
@@ -1420,78 +1533,30 @@ void make_request (ip, lease)
|
|||||||
{
|
{
|
||||||
unsigned char request = DHCPREQUEST;
|
unsigned char request = DHCPREQUEST;
|
||||||
int i;
|
int i;
|
||||||
|
struct option_state options;
|
||||||
|
struct option_cache *oc;
|
||||||
|
|
||||||
struct tree_cache *options [256];
|
|
||||||
struct tree_cache option_elements [256];
|
|
||||||
|
|
||||||
memset (options, 0, sizeof options);
|
|
||||||
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
||||||
|
|
||||||
/* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
|
if (ip -> client -> state == S_REQUESTING)
|
||||||
i = DHO_DHCP_MESSAGE_TYPE;
|
oc = lookup_option (lease -> options.dhcp_hash,
|
||||||
options [i] = &option_elements [i];
|
DHO_DHCP_SERVER_IDENTIFIER);
|
||||||
options [i] -> value = &request;
|
else
|
||||||
options [i] -> len = sizeof request;
|
oc = (struct option_cache *)0;
|
||||||
options [i] -> buf_size = sizeof request;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* Request the options we want */
|
make_client_options (ip, lease, &request, oc,
|
||||||
i = DHO_DHCP_PARAMETER_REQUEST_LIST;
|
((ip -> client -> state == S_REQUESTING ||
|
||||||
options [i] = &option_elements [i];
|
ip -> client -> state == S_REBOOTING)
|
||||||
options [i] -> value = ip -> client -> config -> requested_options;
|
? &lease -> address
|
||||||
options [i] -> len = ip -> client -> config -> requested_option_count;
|
: (struct iaddr *)0),
|
||||||
options [i] -> buf_size =
|
ip -> client -> config -> requested_options,
|
||||||
ip -> client -> config -> requested_option_count;
|
ip -> client -> config -> on_transmission,
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
&options);
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* If we are requesting an address that hasn't yet been assigned
|
|
||||||
to us, use the DHCP Requested Address option. */
|
|
||||||
if (ip -> client -> state == S_REQUESTING) {
|
|
||||||
/* Send back the server identifier... */
|
|
||||||
i = DHO_DHCP_SERVER_IDENTIFIER;
|
|
||||||
options [i] = &option_elements [i];
|
|
||||||
options [i] -> value = lease -> options [i].data;
|
|
||||||
options [i] -> len = lease -> options [i].len;
|
|
||||||
options [i] -> buf_size = lease -> options [i].len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
}
|
|
||||||
if (ip -> client -> state == S_REQUESTING ||
|
|
||||||
ip -> client -> state == S_REBOOTING) {
|
|
||||||
ip -> client -> requested_address = lease -> address;
|
|
||||||
i = DHO_DHCP_REQUESTED_ADDRESS;
|
|
||||||
options [i] = &option_elements [i];
|
|
||||||
options [i] -> value = lease -> address.iabuf;
|
|
||||||
options [i] -> len = lease -> address.len;
|
|
||||||
options [i] -> buf_size = lease -> address.len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
} else {
|
|
||||||
ip -> client -> requested_address.len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send any options requested in the config file. */
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
if (!options [i] &&
|
|
||||||
ip -> client -> config -> send_options [i].data) {
|
|
||||||
options [i] = &option_elements [i];
|
|
||||||
options [i] -> value = ip -> client -> config ->
|
|
||||||
send_options [i].data;
|
|
||||||
options [i] -> len = ip -> client -> config ->
|
|
||||||
send_options [i].len;
|
|
||||||
options [i] -> buf_size = ip -> client -> config ->
|
|
||||||
send_options [i].len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up the option buffer... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
||||||
options, (struct agent_options *)0, 0, 0, 0);
|
&options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||||
|
|
||||||
@@ -1535,62 +1600,22 @@ void make_decline (ip, lease)
|
|||||||
{
|
{
|
||||||
unsigned char decline = DHCPDECLINE;
|
unsigned char decline = DHCPDECLINE;
|
||||||
int i;
|
int i;
|
||||||
|
struct option_cache *oc;
|
||||||
|
|
||||||
struct tree_cache *options [256];
|
struct option_state options;
|
||||||
struct tree_cache message_type_tree;
|
|
||||||
struct tree_cache requested_address_tree;
|
|
||||||
struct tree_cache server_id_tree;
|
|
||||||
struct tree_cache client_id_tree;
|
|
||||||
|
|
||||||
memset (options, 0, sizeof options);
|
|
||||||
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
||||||
|
|
||||||
/* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
|
oc = lookup_option (lease -> options.dhcp_hash,
|
||||||
i = DHO_DHCP_MESSAGE_TYPE;
|
DHO_DHCP_SERVER_IDENTIFIER);
|
||||||
options [i] = &message_type_tree;
|
make_client_options (ip, lease, &decline, oc,
|
||||||
options [i] -> value = &decline;
|
&lease -> address, (u_int32_t *)0,
|
||||||
options [i] -> len = sizeof decline;
|
(struct executable_statement *)0, &options);
|
||||||
options [i] -> buf_size = sizeof decline;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* Send back the server identifier... */
|
|
||||||
i = DHO_DHCP_SERVER_IDENTIFIER;
|
|
||||||
options [i] = &server_id_tree;
|
|
||||||
options [i] -> value = lease -> options [i].data;
|
|
||||||
options [i] -> len = lease -> options [i].len;
|
|
||||||
options [i] -> buf_size = lease -> options [i].len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* Send back the address we're declining. */
|
|
||||||
i = DHO_DHCP_REQUESTED_ADDRESS;
|
|
||||||
options [i] = &requested_address_tree;
|
|
||||||
options [i] -> value = lease -> address.iabuf;
|
|
||||||
options [i] -> len = lease -> address.len;
|
|
||||||
options [i] -> buf_size = lease -> address.len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* Send the uid if the user supplied one. */
|
|
||||||
i = DHO_DHCP_CLIENT_IDENTIFIER;
|
|
||||||
if (ip -> client -> config -> send_options [i].len) {
|
|
||||||
options [i] = &client_id_tree;
|
|
||||||
options [i] -> value = ip -> client -> config ->
|
|
||||||
send_options [i].data;
|
|
||||||
options [i] -> len = ip -> client -> config ->
|
|
||||||
send_options [i].len;
|
|
||||||
options [i] -> buf_size = ip -> client -> config ->
|
|
||||||
send_options [i].len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Set up the option buffer... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
||||||
options, (struct agent_options *)0, 0, 0, 0);
|
&options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||||
|
|
||||||
@@ -1626,37 +1651,22 @@ void make_release (ip, lease)
|
|||||||
{
|
{
|
||||||
unsigned char request = DHCPRELEASE;
|
unsigned char request = DHCPRELEASE;
|
||||||
int i;
|
int i;
|
||||||
|
struct option_cache *oc;
|
||||||
|
|
||||||
struct tree_cache *options [256];
|
struct option_state options;
|
||||||
struct tree_cache message_type_tree;
|
|
||||||
struct tree_cache requested_address_tree;
|
|
||||||
struct tree_cache server_id_tree;
|
|
||||||
|
|
||||||
memset (options, 0, sizeof options);
|
|
||||||
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
memset (&ip -> client -> packet, 0, sizeof (ip -> client -> packet));
|
||||||
|
|
||||||
/* Set DHCP_MESSAGE_TYPE to DHCPRELEASE */
|
oc = lookup_option (lease -> options.dhcp_hash,
|
||||||
i = DHO_DHCP_MESSAGE_TYPE;
|
DHO_DHCP_SERVER_IDENTIFIER);
|
||||||
options [i] = &message_type_tree;
|
make_client_options (ip, lease, &request, oc,
|
||||||
options [i] -> value = &request;
|
&lease -> address, (u_int32_t *)0,
|
||||||
options [i] -> len = sizeof request;
|
(struct executable_statement *)0, &options);
|
||||||
options [i] -> buf_size = sizeof request;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* Send back the server identifier... */
|
|
||||||
i = DHO_DHCP_SERVER_IDENTIFIER;
|
|
||||||
options [i] = &server_id_tree;
|
|
||||||
options [i] -> value = lease -> options [i].data;
|
|
||||||
options [i] -> len = lease -> options [i].len;
|
|
||||||
options [i] -> buf_size = lease -> options [i].len;
|
|
||||||
options [i] -> timeout = 0xFFFFFFFF;
|
|
||||||
options [i] -> tree = (struct tree *)0;
|
|
||||||
|
|
||||||
/* Set up the option buffer... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
cons_options ((struct packet *)0, &ip -> client -> packet, 0,
|
||||||
options, (struct agent_options *)0, 0, 0, 0);
|
&options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||||
|
|
||||||
@@ -1685,20 +1695,17 @@ void make_release (ip, lease)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_client_lease (lease)
|
void destroy_client_lease (lease)
|
||||||
struct client_lease *lease;
|
struct client_lease *lease;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (lease -> server_name)
|
if (lease -> server_name)
|
||||||
free (lease -> server_name);
|
dfree (lease -> server_name, "destroy_client_lease");
|
||||||
if (lease -> filename)
|
if (lease -> filename)
|
||||||
free (lease -> filename);
|
dfree (lease -> filename, "destroy_client_lease");
|
||||||
for (i = 0; i < 256; i++) {
|
option_state_dereference (&lease -> options);
|
||||||
if (lease -> options [i].len)
|
free_client_lease (lease, "destroy_client_lease");
|
||||||
free (lease -> options [i].data);
|
|
||||||
}
|
|
||||||
free (lease);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *leaseFile;
|
FILE *leaseFile;
|
||||||
@@ -1744,6 +1751,8 @@ void write_client_lease (ip, lease, rewrite)
|
|||||||
int i;
|
int i;
|
||||||
struct tm *t;
|
struct tm *t;
|
||||||
static int leases_written;
|
static int leases_written;
|
||||||
|
struct option_cache *oc;
|
||||||
|
struct data_string ds;
|
||||||
|
|
||||||
if (!rewrite) {
|
if (!rewrite) {
|
||||||
if (leases_written++ > 20) {
|
if (leases_written++ > 20) {
|
||||||
@@ -1778,14 +1787,21 @@ void write_client_lease (ip, lease, rewrite)
|
|||||||
if (lease -> medium)
|
if (lease -> medium)
|
||||||
fprintf (leaseFile, " medium \"%s\";\n",
|
fprintf (leaseFile, " medium \"%s\";\n",
|
||||||
lease -> medium -> string);
|
lease -> medium -> string);
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < OPTION_HASH_SIZE; i++) {
|
||||||
if (lease -> options [i].len) {
|
pair p;
|
||||||
fprintf (leaseFile,
|
for (p = lease -> options.dhcp_hash [i]; p; p = p -> cdr) {
|
||||||
" option %s %s;\n",
|
memset (&ds, 0, sizeof ds);
|
||||||
dhcp_options [i].name,
|
if (evaluate_option_cache (&ds, (struct packet *)0,
|
||||||
pretty_print_option
|
&lease -> options, oc)) {
|
||||||
(i, lease -> options [i].data,
|
fprintf (leaseFile,
|
||||||
lease -> options [i].len, 1, 1));
|
" option %s %s;\n",
|
||||||
|
dhcp_options [i].name,
|
||||||
|
pretty_print_option
|
||||||
|
(i, ds.data, ds.len,
|
||||||
|
1, 1));
|
||||||
|
data_string_forget (&ds,
|
||||||
|
"write_client_lease");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1863,8 +1879,8 @@ void script_write_params (ip, prefix, lease)
|
|||||||
struct client_lease *lease;
|
struct client_lease *lease;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u_int8_t dbuf [1500];
|
struct data_string data;
|
||||||
int len;
|
struct option_cache *oc;
|
||||||
|
|
||||||
fprintf (scriptFile, "%sip_address=\"%s\"\n",
|
fprintf (scriptFile, "%sip_address=\"%s\"\n",
|
||||||
prefix, piaddr (lease -> address));
|
prefix, piaddr (lease -> address));
|
||||||
@@ -1877,33 +1893,45 @@ void script_write_params (ip, prefix, lease)
|
|||||||
broadcast address, not the host address all zeroes
|
broadcast address, not the host address all zeroes
|
||||||
broadcast address). */
|
broadcast address). */
|
||||||
|
|
||||||
if (lease -> options [DHO_SUBNET_MASK].len &&
|
memset (&data, 0, sizeof data);
|
||||||
(lease -> options [DHO_SUBNET_MASK].len <
|
oc = lookup_option (lease -> options.dhcp_hash, DHO_SUBNET_MASK);
|
||||||
sizeof lease -> address.iabuf)) {
|
if (oc && evaluate_option_cache (&data, (struct packet *)0,
|
||||||
struct iaddr netmask, subnet, broadcast;
|
&lease -> options, oc)) {
|
||||||
|
if (data.len > 3) {
|
||||||
|
struct iaddr netmask, subnet, broadcast;
|
||||||
|
|
||||||
memcpy (netmask.iabuf,
|
memcpy (netmask.iabuf, data.data, data.len);
|
||||||
lease -> options [DHO_SUBNET_MASK].data,
|
netmask.len = data.len;
|
||||||
lease -> options [DHO_SUBNET_MASK].len);
|
data_string_forget (&data, "script_write_params");
|
||||||
netmask.len = lease -> options [DHO_SUBNET_MASK].len;
|
|
||||||
|
|
||||||
subnet = subnet_number (lease -> address, netmask);
|
subnet = subnet_number (lease -> address, netmask);
|
||||||
if (subnet.len) {
|
if (subnet.len) {
|
||||||
fprintf (scriptFile, "%snetwork_number=\"%s\";\n",
|
fprintf (scriptFile,
|
||||||
prefix, piaddr (subnet));
|
"%snetwork_number=\"%s\";\n",
|
||||||
fprintf (scriptFile, "export %snetwork_number\n",
|
prefix, piaddr (subnet));
|
||||||
prefix);
|
fprintf (scriptFile,
|
||||||
|
"export %snetwork_number\n", prefix);
|
||||||
|
|
||||||
if (!lease -> options [DHO_BROADCAST_ADDRESS].len) {
|
oc = lookup_option (lease -> options.dhcp_hash,
|
||||||
broadcast = broadcast_addr (subnet, netmask);
|
DHO_BROADCAST_ADDRESS);
|
||||||
if (broadcast.len) {
|
if (!oc ||
|
||||||
fprintf (scriptFile,
|
!evaluate_option_cache (&data,
|
||||||
"%s%s=\"%s\";\n", prefix,
|
(struct packet *)0,
|
||||||
"broadcast_address",
|
&lease -> options,
|
||||||
piaddr (broadcast));
|
oc)) {
|
||||||
fprintf (scriptFile,
|
broadcast = broadcast_addr (subnet,
|
||||||
"export %s%s\n", prefix,
|
netmask);
|
||||||
"broadcast_address");
|
if (broadcast.len) {
|
||||||
|
fprintf (scriptFile,
|
||||||
|
"%s%s=\"%s\";\n",
|
||||||
|
prefix,
|
||||||
|
"broadcast_address",
|
||||||
|
piaddr (broadcast));
|
||||||
|
fprintf (scriptFile,
|
||||||
|
"export %s%s\n",
|
||||||
|
prefix,
|
||||||
|
"broadcast_address");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1919,84 +1947,33 @@ void script_write_params (ip, prefix, lease)
|
|||||||
prefix, lease -> server_name);
|
prefix, lease -> server_name);
|
||||||
fprintf (scriptFile, "export %sserver_name\n", prefix);
|
fprintf (scriptFile, "export %sserver_name\n", prefix);
|
||||||
}
|
}
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
u_int8_t *dp;
|
|
||||||
|
|
||||||
if (ip -> client -> config -> defaults [i].len) {
|
execute_statements ((struct packet *)0, &lease -> options,
|
||||||
if (lease -> options [i].len) {
|
&lease -> options,
|
||||||
switch (ip -> client ->
|
ip -> client -> config -> on_transmission);
|
||||||
config -> default_actions [i]) {
|
|
||||||
case ACTION_DEFAULT:
|
for (i = 0; i < OPTION_HASH_SIZE; i++) {
|
||||||
dp = lease -> options [i].data;
|
pair hp;
|
||||||
len = lease -> options [i].len;
|
|
||||||
break;
|
for (hp = lease -> options.dhcp_hash [i]; hp; hp = hp -> cdr) {
|
||||||
case ACTION_SUPERSEDE:
|
oc = (struct option_cache *)hp -> car;
|
||||||
supersede:
|
|
||||||
dp = ip -> client ->
|
if (evaluate_option_cache (&data, (struct packet *)0,
|
||||||
config -> defaults [i].data;
|
&lease -> options, oc)) {
|
||||||
len = ip -> client ->
|
|
||||||
config -> defaults [i].len;
|
if (data.len) {
|
||||||
break;
|
char *s = (dhcp_option_ev_name
|
||||||
case ACTION_PREPEND:
|
(oc -> option));
|
||||||
len = (ip -> client ->
|
|
||||||
config -> defaults [i].len +
|
|
||||||
lease -> options [i].len);
|
|
||||||
if (len > sizeof dbuf) {
|
|
||||||
warn ("no space to %s %s",
|
|
||||||
"prepend option",
|
|
||||||
dhcp_options [i].name);
|
|
||||||
goto supersede;
|
|
||||||
}
|
|
||||||
dp = dbuf;
|
|
||||||
memcpy (dp,
|
|
||||||
ip -> client ->
|
|
||||||
config -> defaults [i].data,
|
|
||||||
ip -> client ->
|
|
||||||
config -> defaults [i].len);
|
|
||||||
memcpy (dp + ip -> client ->
|
|
||||||
config -> defaults [i].len,
|
|
||||||
lease -> options [i].data,
|
|
||||||
lease -> options [i].len);
|
|
||||||
break;
|
|
||||||
case ACTION_APPEND:
|
|
||||||
len = (ip -> client ->
|
|
||||||
config -> defaults [i].len +
|
|
||||||
lease -> options [i].len);
|
|
||||||
if (len > sizeof dbuf) {
|
|
||||||
warn ("no space to %s %s",
|
|
||||||
"prepend option",
|
|
||||||
dhcp_options [i].name);
|
|
||||||
goto supersede;
|
|
||||||
}
|
|
||||||
dp = dbuf;
|
|
||||||
memcpy (dp,
|
|
||||||
ip -> client ->
|
|
||||||
config -> defaults [i].data,
|
|
||||||
ip -> client ->
|
|
||||||
config -> defaults [i].len);
|
|
||||||
memcpy (dp + ip -> client ->
|
|
||||||
config -> defaults [i].len,
|
|
||||||
lease -> options [i].data,
|
|
||||||
lease -> options [i].len);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dp = ip -> client ->
|
|
||||||
config -> defaults [i].data;
|
|
||||||
len = ip -> client ->
|
|
||||||
config -> defaults [i].len;
|
|
||||||
}
|
|
||||||
} else if (lease -> options [i].len) {
|
|
||||||
len = lease -> options [i].len;
|
|
||||||
dp = lease -> options [i].data;
|
|
||||||
} else {
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
if (len) {
|
|
||||||
char *s = dhcp_option_ev_name (&dhcp_options [i]);
|
|
||||||
|
|
||||||
fprintf (scriptFile, "%s%s=\"%s\"\n", prefix, s,
|
fprintf (scriptFile,
|
||||||
pretty_print_option (i, dp, len, 0, 0));
|
"%s%s=\"%s\"\n", prefix, s,
|
||||||
fprintf (scriptFile, "export %s%s\n", prefix, s);
|
(pretty_print_option
|
||||||
|
(i, data.data, data.len,
|
||||||
|
0, 0)));
|
||||||
|
fprintf (scriptFile,
|
||||||
|
"export %s%s\n", prefix, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf (scriptFile, "%sexpiry=\"%d\"\n",
|
fprintf (scriptFile, "%sexpiry=\"%d\"\n",
|
||||||
|
926
common/parse.c
926
common/parse.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user