diff options
Diffstat (limited to 'common/comapi.c')
-rw-r--r-- | common/comapi.c | 922 |
1 files changed, 922 insertions, 0 deletions
diff --git a/common/comapi.c b/common/comapi.c new file mode 100644 index 0000000..c24b4a6 --- /dev/null +++ b/common/comapi.c @@ -0,0 +1,922 @@ +/* omapi.c + + OMAPI object interfaces for the DHCP server. */ + +/* + * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1999-2003 by Internet Software Consortium + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * <info@isc.org> + * https://www.isc.org/ + * + * This software has been written for Internet Systems Consortium + * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. + * To learn more about Internet Systems Consortium, see + * ``https://www.isc.org/''. To learn more about Vixie Enterprises, + * see ``http://www.vix.com''. To learn more about Nominum, Inc., see + * ``http://www.nominum.com''. + */ + +/* Many, many thanks to Brian Murrell and BCtel for this code - BCtel + provided the funding that resulted in this code and the entire + OMAPI support library being written, and Brian helped brainstorm + and refine the requirements. To the extent that this code is + useful, you have Brian and BCtel to thank. Any limitations in the + code are a result of mistakes on my part. -- Ted Lemon */ + +#include "dhcpd.h" +#include <omapip/omapip_p.h> + +OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet) +OMAPI_OBJECT_ALLOC (shared_network, struct shared_network, + dhcp_type_shared_network) +OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group) +OMAPI_OBJECT_ALLOC (dhcp_control, dhcp_control_object_t, dhcp_type_control) + +omapi_object_type_t *dhcp_type_interface; +omapi_object_type_t *dhcp_type_group; +omapi_object_type_t *dhcp_type_shared_network; +omapi_object_type_t *dhcp_type_subnet; +omapi_object_type_t *dhcp_type_control; +dhcp_control_object_t *dhcp_control_object; + +void dhcp_common_objects_setup () +{ + isc_result_t status; + + status = omapi_object_type_register (&dhcp_type_control, + "control", + dhcp_control_set_value, + dhcp_control_get_value, + dhcp_control_destroy, + dhcp_control_signal_handler, + dhcp_control_stuff_values, + dhcp_control_lookup, + dhcp_control_create, + dhcp_control_remove, 0, 0, 0, + sizeof (dhcp_control_object_t), + 0, RC_MISC); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't register control object type: %s", + isc_result_totext (status)); + status = dhcp_control_allocate (&dhcp_control_object, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't make initial control object: %s", + isc_result_totext (status)); + dhcp_control_object -> state = server_startup; + + status = omapi_object_type_register (&dhcp_type_group, + "group", + dhcp_group_set_value, + dhcp_group_get_value, + dhcp_group_destroy, + dhcp_group_signal_handler, + dhcp_group_stuff_values, + dhcp_group_lookup, + dhcp_group_create, + dhcp_group_remove, 0, 0, 0, + sizeof (struct group_object), 0, + RC_MISC); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't register group object type: %s", + isc_result_totext (status)); + + status = omapi_object_type_register (&dhcp_type_subnet, + "subnet", + dhcp_subnet_set_value, + dhcp_subnet_get_value, + dhcp_subnet_destroy, + dhcp_subnet_signal_handler, + dhcp_subnet_stuff_values, + dhcp_subnet_lookup, + dhcp_subnet_create, + dhcp_subnet_remove, 0, 0, 0, + sizeof (struct subnet), 0, + RC_MISC); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't register subnet object type: %s", + isc_result_totext (status)); + + status = omapi_object_type_register + (&dhcp_type_shared_network, + "shared-network", + dhcp_shared_network_set_value, + dhcp_shared_network_get_value, + dhcp_shared_network_destroy, + dhcp_shared_network_signal_handler, + dhcp_shared_network_stuff_values, + dhcp_shared_network_lookup, + dhcp_shared_network_create, + dhcp_shared_network_remove, 0, 0, 0, + sizeof (struct shared_network), 0, RC_MISC); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't register shared network object type: %s", + isc_result_totext (status)); + + interface_setup (); +} + +isc_result_t dhcp_group_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) +{ + struct group_object *group; + isc_result_t status; + + if (h -> type != dhcp_type_group) + return DHCP_R_INVALIDARG; + group = (struct group_object *)h; + + /* XXX For now, we can only set these values on new group objects. + XXX Soon, we need to be able to update group objects. */ + if (!omapi_ds_strcmp (name, "name")) { + if (group -> name) + return ISC_R_EXISTS; + if (value -> type == omapi_datatype_data || + value -> type == omapi_datatype_string) { + group -> name = dmalloc (value -> u.buffer.len + 1, + MDL); + if (!group -> name) + return ISC_R_NOMEMORY; + memcpy (group -> name, + value -> u.buffer.value, + value -> u.buffer.len); + group -> name [value -> u.buffer.len] = 0; + } else + return DHCP_R_INVALIDARG; + return ISC_R_SUCCESS; + } + + if (!omapi_ds_strcmp (name, "statements")) { + if (group -> group && group -> group -> statements) + return ISC_R_EXISTS; + if (!group -> group) { + if (!clone_group (&group -> group, root_group, MDL)) + return ISC_R_NOMEMORY; + } + if (value -> type == omapi_datatype_data || + value -> type == omapi_datatype_string) { + struct parse *parse; + int lose = 0; + parse = NULL; + status = new_parse(&parse, -1, + (char *) value->u.buffer.value, + value->u.buffer.len, + "network client", 0); + if (status != ISC_R_SUCCESS || parse == NULL) + return status; + if (!(parse_executable_statements + (&group -> group -> statements, parse, &lose, + context_any))) { + end_parse (&parse); + return DHCP_R_BADPARSE; + } + end_parse (&parse); + return ISC_R_SUCCESS; + } else + return DHCP_R_INVALIDARG; + } + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> set_value) { + status = ((*(h -> inner -> type -> set_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) + return status; + } + + return ISC_R_NOTFOUND; +} + + +isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id, + omapi_data_string_t *name, + omapi_value_t **value) +{ + struct group_object *group; + isc_result_t status; + + if (h -> type != dhcp_type_group) + return DHCP_R_INVALIDARG; + group = (struct group_object *)h; + + if (!omapi_ds_strcmp (name, "name")) + return omapi_make_string_value (value, + name, group -> name, MDL); + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> get_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS) + return status; + } + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line) +{ + struct group_object *group, *t; + + if (h -> type != dhcp_type_group) + return DHCP_R_INVALIDARG; + group = (struct group_object *)h; + + if (group -> name) { + if (group_name_hash) { + t = (struct group_object *)0; + if (group_hash_lookup (&t, group_name_hash, + group -> name, + strlen (group -> name), MDL)) { + group_hash_delete (group_name_hash, + group -> name, + strlen (group -> name), + MDL); + group_object_dereference (&t, MDL); + } + } + dfree (group -> name, file, line); + group -> name = (char *)0; + } + if (group -> group) + group_dereference (&group -> group, MDL); + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_group_signal_handler (omapi_object_t *h, + const char *name, va_list ap) +{ + struct group_object *group; + isc_result_t status; + int updatep = 0; + + if (h -> type != dhcp_type_group) + return DHCP_R_INVALIDARG; + group = (struct group_object *)h; + + if (!strcmp (name, "updated")) { + /* A group object isn't valid if a subgroup hasn't yet been + associated with it. */ + if (!group -> group) + return DHCP_R_INVALIDARG; + + /* Group objects always have to have names. */ + if (!group -> name) { + char hnbuf [64]; + sprintf (hnbuf, "ng%08lx%08lx", + (unsigned long)cur_time, + (unsigned long)group); + group -> name = dmalloc (strlen (hnbuf) + 1, MDL); + if (!group -> name) + return ISC_R_NOMEMORY; + strcpy (group -> name, hnbuf); + } + + supersede_group (group, 1); + updatep = 1; + } + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> signal_handler)) + (h -> inner, name, ap)); + if (status == ISC_R_SUCCESS) + return status; + } + if (updatep) + return ISC_R_SUCCESS; + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_group_stuff_values (omapi_object_t *c, + omapi_object_t *id, + omapi_object_t *h) +{ + struct group_object *group; + isc_result_t status; + + if (h -> type != dhcp_type_group) + return DHCP_R_INVALIDARG; + group = (struct group_object *)h; + + /* Write out all the values. */ + if (group -> name) { + status = omapi_connection_put_name (c, "name"); + if (status != ISC_R_SUCCESS) + return status; + status = omapi_connection_put_string (c, group -> name); + if (status != ISC_R_SUCCESS) + return status; + } + + /* Write out the inner object, if any. */ + if (h -> inner && h -> inner -> type -> stuff_values) { + status = ((*(h -> inner -> type -> stuff_values)) + (c, id, h -> inner)); + if (status == ISC_R_SUCCESS) + return status; + } + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_group_lookup (omapi_object_t **lp, + omapi_object_t *id, omapi_object_t *ref) +{ + omapi_value_t *tv = (omapi_value_t *)0; + isc_result_t status; + struct group_object *group; + + if (!ref) + return DHCP_R_NOKEYS; + + /* First see if we were sent a handle. */ + status = omapi_get_value_str (ref, id, "handle", &tv); + if (status == ISC_R_SUCCESS) { + status = omapi_handle_td_lookup (lp, tv -> value); + + omapi_value_dereference (&tv, MDL); + if (status != ISC_R_SUCCESS) + return status; + + /* Don't return the object if the type is wrong. */ + if ((*lp) -> type != dhcp_type_group) { + omapi_object_dereference (lp, MDL); + return DHCP_R_INVALIDARG; + } + } + + /* Now look for a name. */ + status = omapi_get_value_str (ref, id, "name", &tv); + if (status == ISC_R_SUCCESS) { + group = (struct group_object *)0; + if (group_name_hash && + group_hash_lookup (&group, group_name_hash, + (const char *) + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL)) { + omapi_value_dereference (&tv, MDL); + + if (*lp && *lp != (omapi_object_t *)group) { + group_object_dereference (&group, MDL); + omapi_object_dereference (lp, MDL); + return DHCP_R_KEYCONFLICT; + } else if (!*lp) { + /* XXX fix so that hash lookup itself creates + XXX the reference. */ + omapi_object_reference (lp, + (omapi_object_t *)group, + MDL); + group_object_dereference (&group, MDL); + } + } else if (!*lp) + return ISC_R_NOTFOUND; + } + + /* If we get to here without finding a group, no valid key was + specified. */ + if (!*lp) + return DHCP_R_NOKEYS; + + if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) { + omapi_object_dereference (lp, MDL); + return ISC_R_NOTFOUND; + } + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_group_create (omapi_object_t **lp, + omapi_object_t *id) +{ + struct group_object *group; + isc_result_t status; + group = (struct group_object *)0; + + status = group_object_allocate (&group, MDL); + if (status != ISC_R_SUCCESS) + return status; + group -> flags = GROUP_OBJECT_DYNAMIC; + status = omapi_object_reference (lp, (omapi_object_t *)group, MDL); + group_object_dereference (&group, MDL); + return status; +} + +isc_result_t dhcp_group_remove (omapi_object_t *lp, + omapi_object_t *id) +{ + struct group_object *group; + isc_result_t status; + if (lp -> type != dhcp_type_group) + return DHCP_R_INVALIDARG; + group = (struct group_object *)lp; + + group -> flags |= GROUP_OBJECT_DELETED; + if (group_write_hook) { + if (!(*group_write_hook) (group)) + return ISC_R_IOERROR; + } + + status = dhcp_group_destroy ((omapi_object_t *)group, MDL); + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_control_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) +{ + dhcp_control_object_t *control; + isc_result_t status; + unsigned long newstate; + + if (h -> type != dhcp_type_control) + return DHCP_R_INVALIDARG; + control = (dhcp_control_object_t *)h; + + if (!omapi_ds_strcmp (name, "state")) { + status = omapi_get_int_value (&newstate, value); + if (status != ISC_R_SUCCESS) + return status; + status = dhcp_set_control_state (control -> state, newstate); + if (status == ISC_R_SUCCESS) + control -> state = value -> u.integer; + return status; + } + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> set_value) { + status = ((*(h -> inner -> type -> set_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) + return status; + } + + return ISC_R_NOTFOUND; +} + + +isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id, + omapi_data_string_t *name, + omapi_value_t **value) +{ + dhcp_control_object_t *control; + isc_result_t status; + + if (h -> type != dhcp_type_control) + return DHCP_R_INVALIDARG; + control = (dhcp_control_object_t *)h; + + if (!omapi_ds_strcmp (name, "state")) + return omapi_make_int_value (value, + name, (int)control -> state, MDL); + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> get_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS) + return status; + } + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_control_destroy (omapi_object_t *h, + const char *file, int line) +{ + if (h -> type != dhcp_type_control) + return DHCP_R_INVALIDARG; + + /* Can't destroy the control object. */ + return ISC_R_NOPERM; +} + +isc_result_t dhcp_control_signal_handler (omapi_object_t *h, + const char *name, va_list ap) +{ + dhcp_control_object_t *control; + isc_result_t status; + + if (h -> type != dhcp_type_control) + return DHCP_R_INVALIDARG; + control = (dhcp_control_object_t *)h; + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> signal_handler)) + (h -> inner, name, ap)); + if (status == ISC_R_SUCCESS) + return status; + } + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_control_stuff_values (omapi_object_t *c, + omapi_object_t *id, + omapi_object_t *h) +{ + dhcp_control_object_t *control; + isc_result_t status; + + if (h -> type != dhcp_type_control) + return DHCP_R_INVALIDARG; + control = (dhcp_control_object_t *)h; + + /* Write out all the values. */ + status = omapi_connection_put_name (c, "state"); + if (status != ISC_R_SUCCESS) + return status; + status = omapi_connection_put_uint32 (c, sizeof (u_int32_t)); + if (status != ISC_R_SUCCESS) + return status; + status = omapi_connection_put_uint32 (c, control -> state); + if (status != ISC_R_SUCCESS) + return status; + + /* Write out the inner object, if any. */ + if (h -> inner && h -> inner -> type -> stuff_values) { + status = ((*(h -> inner -> type -> stuff_values)) + (c, id, h -> inner)); + if (status == ISC_R_SUCCESS) + return status; + } + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_control_lookup (omapi_object_t **lp, + omapi_object_t *id, omapi_object_t *ref) +{ + omapi_value_t *tv = (omapi_value_t *)0; + isc_result_t status; + + /* First see if we were sent a handle. */ + if (ref) { + status = omapi_get_value_str (ref, id, "handle", &tv); + if (status == ISC_R_SUCCESS) { + status = omapi_handle_td_lookup (lp, tv -> value); + + omapi_value_dereference (&tv, MDL); + if (status != ISC_R_SUCCESS) + return status; + + /* Don't return the object if the type is wrong. */ + if ((*lp) -> type != dhcp_type_control) { + omapi_object_dereference (lp, MDL); + return DHCP_R_INVALIDARG; + } + } + } + + /* Otherwise, stop playing coy - there's only one control object, + so we can just return it. */ + dhcp_control_reference ((dhcp_control_object_t **)lp, + dhcp_control_object, MDL); + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_control_create (omapi_object_t **lp, + omapi_object_t *id) +{ + /* Can't create a control object - there can be only one. */ + return ISC_R_NOPERM; +} + +isc_result_t dhcp_control_remove (omapi_object_t *lp, + omapi_object_t *id) +{ + /* Form is emptiness; emptiness form. The control object + cannot go out of existance. */ + return ISC_R_NOPERM; +} + +isc_result_t dhcp_subnet_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) +{ + struct subnet *subnet; + isc_result_t status; + + if (h -> type != dhcp_type_subnet) + return DHCP_R_INVALIDARG; + subnet = (struct subnet *)h; + + /* No values to set yet. */ + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> set_value) { + status = ((*(h -> inner -> type -> set_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) + return status; + } + + return ISC_R_NOTFOUND; +} + + +isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id, + omapi_data_string_t *name, + omapi_value_t **value) +{ + struct subnet *subnet; + isc_result_t status; + + if (h -> type != dhcp_type_subnet) + return DHCP_R_INVALIDARG; + subnet = (struct subnet *)h; + + /* No values to get yet. */ + + /* Try to find some inner object that can provide the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> get_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS) + return status; + } + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line) +{ + struct subnet *subnet; + + if (h -> type != dhcp_type_subnet) + return DHCP_R_INVALIDARG; + subnet = (struct subnet *)h; + +#if defined (DEBUG_MEMORY_LEAKAGE) || \ + defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) + if (subnet -> next_subnet) + subnet_dereference (&subnet -> next_subnet, file, line); + if (subnet -> next_sibling) + subnet_dereference (&subnet -> next_sibling, file, line); + if (subnet -> shared_network) + shared_network_dereference (&subnet -> shared_network, + file, line); + if (subnet -> interface) + interface_dereference (&subnet -> interface, file, line); + if (subnet -> group) + group_dereference (&subnet -> group, file, line); +#endif + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h, + const char *name, va_list ap) +{ + struct subnet *subnet; + isc_result_t status; + int updatep = 0; + + if (h -> type != dhcp_type_subnet) + return DHCP_R_INVALIDARG; + subnet = (struct subnet *)h; + + /* Can't write subnets yet. */ + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> signal_handler)) + (h -> inner, name, ap)); + if (status == ISC_R_SUCCESS) + return status; + } + if (updatep) + return ISC_R_SUCCESS; + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c, + omapi_object_t *id, + omapi_object_t *h) +{ + struct subnet *subnet; + isc_result_t status; + + if (h -> type != dhcp_type_subnet) + return DHCP_R_INVALIDARG; + subnet = (struct subnet *)h; + + /* Can't stuff subnet values yet. */ + + /* Write out the inner object, if any. */ + if (h -> inner && h -> inner -> type -> stuff_values) { + status = ((*(h -> inner -> type -> stuff_values)) + (c, id, h -> inner)); + if (status == ISC_R_SUCCESS) + return status; + } + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_subnet_lookup (omapi_object_t **lp, + omapi_object_t *id, + omapi_object_t *ref) +{ + /* Can't look up subnets yet. */ + + /* If we get to here without finding a subnet, no valid key was + specified. */ + if (!*lp) + return DHCP_R_NOKEYS; + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_subnet_create (omapi_object_t **lp, + omapi_object_t *id) +{ + return ISC_R_NOTIMPLEMENTED; +} + +isc_result_t dhcp_subnet_remove (omapi_object_t *lp, + omapi_object_t *id) +{ + return ISC_R_NOTIMPLEMENTED; +} + +isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) +{ + struct shared_network *shared_network; + isc_result_t status; + + if (h -> type != dhcp_type_shared_network) + return DHCP_R_INVALIDARG; + shared_network = (struct shared_network *)h; + + /* No values to set yet. */ + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> set_value) { + status = ((*(h -> inner -> type -> set_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) + return status; + } + + return ISC_R_NOTFOUND; +} + + +isc_result_t dhcp_shared_network_get_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_value_t **value) +{ + struct shared_network *shared_network; + isc_result_t status; + + if (h -> type != dhcp_type_shared_network) + return DHCP_R_INVALIDARG; + shared_network = (struct shared_network *)h; + + /* No values to get yet. */ + + /* Try to find some inner object that can provide the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> get_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS) + return status; + } + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_shared_network_destroy (omapi_object_t *h, + const char *file, int line) +{ + struct shared_network *shared_network; + + if (h -> type != dhcp_type_shared_network) + return DHCP_R_INVALIDARG; + shared_network = (struct shared_network *)h; + +#if defined (DEBUG_MEMORY_LEAKAGE) || \ + defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) + if (shared_network -> next) + shared_network_dereference (&shared_network -> next, + file, line); + if (shared_network -> name) { + dfree (shared_network -> name, file, line); + shared_network -> name = 0; + } + if (shared_network -> subnets) + subnet_dereference (&shared_network -> subnets, file, line); + if (shared_network -> interface) + interface_dereference (&shared_network -> interface, + file, line); + if (shared_network -> pools) + omapi_object_dereference ((omapi_object_t **) + &shared_network -> pools, file, line); + if (shared_network -> group) + group_dereference (&shared_network -> group, file, line); +#if defined (FAILOVER_PROTOCOL) + if (shared_network -> failover_peer) + omapi_object_dereference ((omapi_object_t **) + &shared_network -> failover_peer, + file, line); +#endif +#endif /* DEBUG_MEMORY_LEAKAGE */ + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h, + const char *name, + va_list ap) +{ + struct shared_network *shared_network; + isc_result_t status; + int updatep = 0; + + if (h -> type != dhcp_type_shared_network) + return DHCP_R_INVALIDARG; + shared_network = (struct shared_network *)h; + + /* Can't write shared_networks yet. */ + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> signal_handler)) + (h -> inner, name, ap)); + if (status == ISC_R_SUCCESS) + return status; + } + if (updatep) + return ISC_R_SUCCESS; + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c, + omapi_object_t *id, + omapi_object_t *h) +{ + struct shared_network *shared_network; + isc_result_t status; + + if (h -> type != dhcp_type_shared_network) + return DHCP_R_INVALIDARG; + shared_network = (struct shared_network *)h; + + /* Can't stuff shared_network values yet. */ + + /* Write out the inner object, if any. */ + if (h -> inner && h -> inner -> type -> stuff_values) { + status = ((*(h -> inner -> type -> stuff_values)) + (c, id, h -> inner)); + if (status == ISC_R_SUCCESS) + return status; + } + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp, + omapi_object_t *id, + omapi_object_t *ref) +{ + /* Can't look up shared_networks yet. */ + + /* If we get to here without finding a shared_network, no valid key was + specified. */ + if (!*lp) + return DHCP_R_NOKEYS; + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_shared_network_create (omapi_object_t **lp, + omapi_object_t *id) +{ + return ISC_R_NOTIMPLEMENTED; +} + +isc_result_t dhcp_shared_network_remove (omapi_object_t *lp, + omapi_object_t *id) +{ + return ISC_R_NOTIMPLEMENTED; +} + |