#ifndef lint
static char copyright[] =
-"$Id: options.c,v 1.69 2000/11/24 04:00:04 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: options.c,v 1.70 2000/11/28 23:10:28 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
continue;
}
+ /* Don't look for length if the buffer isn't that big. */
+ if (offset + 2 > length) {
+ len = 65536;
+ goto bogus;
+ }
+
/* All other fields (except end, see above) have a
one-byte length. */
len = buffer [offset + 1];
/* If the length is outrageous, the options are bad. */
if (offset + len + 2 > length) {
- log_error ("Client option %s (%d) larger than buffer.",
- dhcp_options [code].name, len);
+ bogus:
+ log_error ("parse_option_buffer: option %s (%d) %s.",
+ dhcp_options [code].name, len,
+ "larger than buffer");
buffer_dereference (&bp, MDL);
return 0;
}
three seperate buffers if needed. This allows us to cons up a set
of vendor options using the same routine. */
-int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
+int cons_options (inpacket, outpacket, lease, client_state,
+ mms, in_options, cfg_options,
scope, overload, terminate, bootpp, prl, vuname)
struct packet *inpacket;
struct dhcp_packet *outpacket;
struct lease *lease;
+ struct client_state *client_state;
int mms;
struct option_state *in_options;
struct option_state *cfg_options;
if (!mms && inpacket &&
(op = lookup_option (&dhcp_universe, inpacket -> options,
DHO_DHCP_MAX_MESSAGE_SIZE))) {
- evaluate_option_cache (&ds, inpacket, lease, in_options,
+ evaluate_option_cache (&ds, inpacket,
+ lease, client_state, in_options,
cfg_options, scope, op, MDL);
if (ds.len >= sizeof (u_int16_t))
mms = getUShort (ds.data);
(main_buffer_size - 7 +
((overload & 1) ? DHCP_FILE_LEN : 0) +
((overload & 2) ? DHCP_SNAME_LEN : 0)),
- inpacket,
- lease,
+ inpacket, lease, client_state,
in_options, cfg_options, scope,
priority_list, priority_len,
main_buffer_size,
/* Now hack in the agent options if there are any. */
priority_list [0] = DHO_DHCP_AGENT_OPTIONS;
priority_len = 1;
- agentix +=
+ length +=
store_options (&outpacket -> options [agentix],
1500 - DHCP_FIXED_LEN - agentix,
- inpacket, lease,
+ inpacket, lease, client_state,
in_options, cfg_options, scope,
priority_list, priority_len,
1500 - DHCP_FIXED_LEN - agentix,
/* Store all the requested options into the requested buffer. */
-int store_options (buffer, buflen, packet, lease,
+int store_options (buffer, buflen, packet, lease, client_state,
in_options, cfg_options, scope, priority_list, priority_len,
first_cutoff, second_cutoff, terminate, vuname)
unsigned char *buffer;
unsigned buflen;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope **scope;
vendor_cfg_option -> code);
if (tmp)
evaluate_option_cache (&name, packet, lease,
+ client_state,
in_options,
cfg_options,
scope, tmp, MDL);
memset (&encapsulation, 0, sizeof encapsulation);
have_encapsulation =
(option_space_encapsulate
- (&encapsulation, packet, lease,
+ (&encapsulation, packet, lease, client_state,
in_options, cfg_options, scope, &name));
data_string_forget (&name, MDL);
}
/* Find the value of the option... */
if (oc) {
- evaluate_option_cache (&od, packet, lease, in_options,
+ evaluate_option_cache (&od, packet,
+ lease, client_state, in_options,
cfg_options, scope, oc, MDL);
if (!od.len) {
data_string_forget (&encapsulation, MDL);
return optbuf;
}
-int get_option (result, universe, packet, lease,
+int get_option (result, universe, packet, lease, client_state,
in_options, cfg_options, options, scope, code)
struct data_string *result;
struct universe *universe;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct option_state *options;
oc = ((*universe -> lookup_func) (universe, options, code));
if (!oc)
return 0;
- if (!evaluate_option_cache (result, packet, lease, in_options,
- cfg_options, scope, oc, MDL))
+ if (!evaluate_option_cache (result, packet, lease, client_state,
+ in_options, cfg_options, scope, oc, MDL))
return 0;
return 1;
}
return 1;
}
-int store_option (result, universe, packet, lease,
+int store_option (result, universe, packet, lease, client_state,
in_options, cfg_options, scope, oc)
struct data_string *result;
struct universe *universe;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope **scope;
memset (&d1, 0, sizeof d1);
memset (&d2, 0, sizeof d2);
- if (evaluate_option_cache (&d2, packet, lease, in_options,
- cfg_options, scope, oc, MDL)) {
+ if (evaluate_option_cache (&d2, packet, lease, client_state,
+ in_options, cfg_options, scope, oc, MDL)) {
if (!buffer_allocate (&d1.buffer,
(result -> len +
universe -> length_size +
return 0;
}
-int option_space_encapsulate (result, packet, lease,
+int option_space_encapsulate (result, packet, lease, client_state,
in_options, cfg_options, scope, name)
struct data_string *result;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope **scope;
if (u -> encapsulate)
return (*u -> encapsulate) (result, packet, lease,
+ client_state,
in_options, cfg_options, scope, u);
log_error ("encapsulation requested for %s with no support.",
name -> data);
return 0;
}
-int hashed_option_space_encapsulate (result, packet, lease,
+int hashed_option_space_encapsulate (result, packet, lease, client_state,
in_options, cfg_options, scope, universe)
struct data_string *result;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope **scope;
status = 0;
for (i = 0; i < OPTION_HASH_SIZE; i++) {
for (p = hash [i]; p; p = p -> cdr) {
- if (store_option (result, universe, packet, lease,
- in_options, cfg_options, scope,
+ if (store_option (result, universe, packet,
+ lease, client_state, in_options,
+ cfg_options, scope,
(struct option_cache *)p -> car))
status = 1;
}
return status;
}
-int nwip_option_space_encapsulate (result, packet, lease,
+int nwip_option_space_encapsulate (result, packet, lease, client_state,
in_options, cfg_options, scope, universe)
struct data_string *result;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope **scope;
status = 0;
for (i = 0; hash && i < OPTION_HASH_SIZE; i++) {
for (p = hash [i]; p; p = p -> cdr) {
- if (store_option (result, universe, packet, lease,
- in_options, cfg_options, scope,
+ if (store_option (result, universe, packet,
+ lease, client_state, in_options,
+ cfg_options, scope,
(struct option_cache *)p -> car))
status = 1;
}
}
if (no_nwip) {
if (store_option (result, universe, packet, lease,
- in_options, cfg_options,
- scope, no_nwip))
+ client_state, in_options,
+ cfg_options, scope, no_nwip))
status = 1;
}
} else {
return status;
}
-int fqdn_option_space_encapsulate (result, packet, lease,
+int fqdn_option_space_encapsulate (result, packet, lease, client_state,
in_options, cfg_options, scope, universe)
struct data_string *result;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope **scope;
if (oc -> option -> code > FQDN_SUBOPTION_COUNT)
continue;
evaluate_option_cache (&results [oc -> option -> code],
- packet, lease, in_options,
+ packet, lease, client_state, in_options,
cfg_options, scope, oc, MDL);
}
len = 4 + results [FQDN_NAME].len;
}
void option_space_foreach (struct packet *packet, struct lease *lease,
+ struct client_state *client_state,
struct option_state *in_options,
struct option_state *cfg_options,
struct binding_scope **scope,
struct universe *u, void *stuff,
void (*func) (struct option_cache *,
struct packet *,
- struct lease *, struct option_state *,
+ struct lease *, struct client_state *,
+ struct option_state *,
struct option_state *,
struct binding_scope **,
struct universe *, void *))
{
if (u -> foreach)
- (*u -> foreach) (packet, lease, in_options, cfg_options,
- scope, u, stuff, func);
+ (*u -> foreach) (packet, lease, client_state, in_options,
+ cfg_options, scope, u, stuff, func);
}
void suboption_foreach (struct packet *packet, struct lease *lease,
+ struct client_state *client_state,
struct option_state *in_options,
struct option_state *cfg_options,
struct binding_scope **scope,
struct universe *u, void *stuff,
void (*func) (struct option_cache *,
struct packet *,
- struct lease *, struct option_state *,
+ struct lease *, struct client_state *,
+ struct option_state *,
struct option_state *,
struct binding_scope **,
struct universe *, void *),
int i;
if (universe -> foreach)
- (*universe -> foreach) (packet, lease, in_options, cfg_options,
+ (*universe -> foreach) (packet, lease, client_state,
+ in_options, cfg_options,
scope, universe, stuff, func);
}
void hashed_option_space_foreach (struct packet *packet, struct lease *lease,
+ struct client_state *client_state,
struct option_state *in_options,
struct option_state *cfg_options,
struct binding_scope **scope,
void (*func) (struct option_cache *,
struct packet *,
struct lease *,
+ struct client_state *,
struct option_state *,
struct option_state *,
struct binding_scope **,
/* XXX save _all_ options! XXX */
for (p = hash [i]; p; p = p -> cdr) {
oc = (struct option_cache *)p -> car;
- (*func) (oc, packet, lease,
+ (*func) (oc, packet, lease, client_state,
in_options, cfg_options, scope, u, stuff);
}
}
option_cache_reference (tail, oc, MDL);
}
-int linked_option_space_encapsulate (result, packet, lease,
+int linked_option_space_encapsulate (result, packet, lease, client_state,
in_options, cfg_options, scope, universe)
struct data_string *result;
struct packet *packet;
struct lease *lease;
+ struct client_state *client_state;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope **scope;
for (oc = ((struct option_cache *)
cfg_options -> universes [universe -> index]);
oc; oc = oc -> next) {
- if (store_option (result, universe, packet, lease,
- in_options, cfg_options, scope, oc))
+ if (store_option (result, universe, packet,
+ lease, client_state, in_options, cfg_options,
+ scope, oc))
status = 1;
}
}
void linked_option_space_foreach (struct packet *packet, struct lease *lease,
- struct option_state *in_options,
- struct option_state *cfg_options,
- struct binding_scope **scope,
- struct universe *u, void *stuff,
- void (*func) (struct option_cache *,
- struct packet *,
- struct lease *,
- struct option_state *,
- struct option_state *,
- struct binding_scope **,
- struct universe *, void *))
+ struct client_state *client_state,
+ struct option_state *in_options,
+ struct option_state *cfg_options,
+ struct binding_scope **scope,
+ struct universe *u, void *stuff,
+ void (*func) (struct option_cache *,
+ struct packet *,
+ struct lease *,
+ struct client_state *,
+ struct option_state *,
+ struct option_state *,
+ struct binding_scope **,
+ struct universe *, void *))
{
struct option_cache *oc;
for (oc = ((struct option_cache *)
cfg_options -> universes [u -> index]);
oc; oc = oc -> next) {
- (*func) (oc, packet, lease,
+ (*func) (oc, packet, lease, client_state,
in_options, cfg_options, scope, u, stuff);
}
}
memset (&dp, 0, sizeof dp);
evaluate_option_cache (&dp, decoded_packet,
(struct lease *)0,
+ (struct client_state *)0,
decoded_packet -> options,
(struct option_state *)0,
(struct binding_scope **)0,