Annotation of embedaddon/dhcp/server/omapi.c, revision 1.1
1.1 ! misho 1: /* omapi.c
! 2:
! 3: OMAPI object interfaces for the DHCP server. */
! 4:
! 5: /*
! 6: * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
! 7: * Copyright (c) 1999-2003 by Internet Software Consortium
! 8: *
! 9: * Permission to use, copy, modify, and distribute this software for any
! 10: * purpose with or without fee is hereby granted, provided that the above
! 11: * copyright notice and this permission notice appear in all copies.
! 12: *
! 13: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
! 14: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 15: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
! 16: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 17: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 18: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 19: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 20: *
! 21: * Internet Systems Consortium, Inc.
! 22: * 950 Charter Street
! 23: * Redwood City, CA 94063
! 24: * <info@isc.org>
! 25: * https://www.isc.org/
! 26: *
! 27: * This software has been written for Internet Systems Consortium
! 28: * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
! 29: * To learn more about Internet Systems Consortium, see
! 30: * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
! 31: * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
! 32: * ``http://www.nominum.com''.
! 33: */
! 34:
! 35: /* Many, many thanks to Brian Murrell and BCtel for this code - BCtel
! 36: provided the funding that resulted in this code and the entire
! 37: OMAPI support library being written, and Brian helped brainstorm
! 38: and refine the requirements. To the extent that this code is
! 39: useful, you have Brian and BCtel to thank. Any limitations in the
! 40: code are a result of mistakes on my part. -- Ted Lemon */
! 41:
! 42: #include "dhcpd.h"
! 43: #include <omapip/omapip_p.h>
! 44:
! 45: static isc_result_t class_lookup (omapi_object_t **,
! 46: omapi_object_t *, omapi_object_t *,
! 47: omapi_object_type_t *);
! 48:
! 49: omapi_object_type_t *dhcp_type_lease;
! 50: omapi_object_type_t *dhcp_type_pool;
! 51: omapi_object_type_t *dhcp_type_class;
! 52: omapi_object_type_t *dhcp_type_subclass;
! 53: omapi_object_type_t *dhcp_type_host;
! 54: #if defined (FAILOVER_PROTOCOL)
! 55: omapi_object_type_t *dhcp_type_failover_state;
! 56: omapi_object_type_t *dhcp_type_failover_link;
! 57: omapi_object_type_t *dhcp_type_failover_listener;
! 58: #endif
! 59:
! 60: void dhcp_db_objects_setup ()
! 61: {
! 62: isc_result_t status;
! 63:
! 64: status = omapi_object_type_register (&dhcp_type_lease,
! 65: "lease",
! 66: dhcp_lease_set_value,
! 67: dhcp_lease_get_value,
! 68: dhcp_lease_destroy,
! 69: dhcp_lease_signal_handler,
! 70: dhcp_lease_stuff_values,
! 71: dhcp_lease_lookup,
! 72: dhcp_lease_create,
! 73: dhcp_lease_remove,
! 74: #if defined (COMPACT_LEASES)
! 75: dhcp_lease_free,
! 76: dhcp_lease_get,
! 77: #else
! 78: 0, 0,
! 79: #endif
! 80: 0,
! 81: sizeof (struct lease),
! 82: 0, RC_LEASE);
! 83: if (status != ISC_R_SUCCESS)
! 84: log_fatal ("Can't register lease object type: %s",
! 85: isc_result_totext (status));
! 86:
! 87: status = omapi_object_type_register (&dhcp_type_class,
! 88: "class",
! 89: dhcp_class_set_value,
! 90: dhcp_class_get_value,
! 91: dhcp_class_destroy,
! 92: dhcp_class_signal_handler,
! 93: dhcp_class_stuff_values,
! 94: dhcp_class_lookup,
! 95: dhcp_class_create,
! 96: dhcp_class_remove, 0, 0, 0,
! 97: sizeof (struct class), 0,
! 98: RC_MISC);
! 99: if (status != ISC_R_SUCCESS)
! 100: log_fatal ("Can't register class object type: %s",
! 101: isc_result_totext (status));
! 102:
! 103: status = omapi_object_type_register (&dhcp_type_subclass,
! 104: "subclass",
! 105: dhcp_subclass_set_value,
! 106: dhcp_subclass_get_value,
! 107: dhcp_class_destroy,
! 108: dhcp_subclass_signal_handler,
! 109: dhcp_subclass_stuff_values,
! 110: dhcp_subclass_lookup,
! 111: dhcp_subclass_create,
! 112: dhcp_subclass_remove, 0, 0, 0,
! 113: sizeof (struct class), 0, RC_MISC);
! 114: if (status != ISC_R_SUCCESS)
! 115: log_fatal ("Can't register subclass object type: %s",
! 116: isc_result_totext (status));
! 117:
! 118: status = omapi_object_type_register (&dhcp_type_pool,
! 119: "pool",
! 120: dhcp_pool_set_value,
! 121: dhcp_pool_get_value,
! 122: dhcp_pool_destroy,
! 123: dhcp_pool_signal_handler,
! 124: dhcp_pool_stuff_values,
! 125: dhcp_pool_lookup,
! 126: dhcp_pool_create,
! 127: dhcp_pool_remove, 0, 0, 0,
! 128: sizeof (struct pool), 0, RC_MISC);
! 129:
! 130: if (status != ISC_R_SUCCESS)
! 131: log_fatal ("Can't register pool object type: %s",
! 132: isc_result_totext (status));
! 133:
! 134: status = omapi_object_type_register (&dhcp_type_host,
! 135: "host",
! 136: dhcp_host_set_value,
! 137: dhcp_host_get_value,
! 138: dhcp_host_destroy,
! 139: dhcp_host_signal_handler,
! 140: dhcp_host_stuff_values,
! 141: dhcp_host_lookup,
! 142: dhcp_host_create,
! 143: dhcp_host_remove, 0, 0, 0,
! 144: sizeof (struct host_decl),
! 145: 0, RC_MISC);
! 146:
! 147: if (status != ISC_R_SUCCESS)
! 148: log_fatal ("Can't register host object type: %s",
! 149: isc_result_totext (status));
! 150:
! 151: #if defined (FAILOVER_PROTOCOL)
! 152: status = omapi_object_type_register (&dhcp_type_failover_state,
! 153: "failover-state",
! 154: dhcp_failover_state_set_value,
! 155: dhcp_failover_state_get_value,
! 156: dhcp_failover_state_destroy,
! 157: dhcp_failover_state_signal,
! 158: dhcp_failover_state_stuff,
! 159: dhcp_failover_state_lookup,
! 160: dhcp_failover_state_create,
! 161: dhcp_failover_state_remove,
! 162: 0, 0, 0,
! 163: sizeof (dhcp_failover_state_t),
! 164: 0, RC_MISC);
! 165:
! 166: if (status != ISC_R_SUCCESS)
! 167: log_fatal ("Can't register failover state object type: %s",
! 168: isc_result_totext (status));
! 169:
! 170: status = omapi_object_type_register (&dhcp_type_failover_link,
! 171: "failover-link",
! 172: dhcp_failover_link_set_value,
! 173: dhcp_failover_link_get_value,
! 174: dhcp_failover_link_destroy,
! 175: dhcp_failover_link_signal,
! 176: dhcp_failover_link_stuff_values,
! 177: 0, 0, 0, 0, 0, 0,
! 178: sizeof (dhcp_failover_link_t), 0,
! 179: RC_MISC);
! 180:
! 181: if (status != ISC_R_SUCCESS)
! 182: log_fatal ("Can't register failover link object type: %s",
! 183: isc_result_totext (status));
! 184:
! 185: status = omapi_object_type_register (&dhcp_type_failover_listener,
! 186: "failover-listener",
! 187: dhcp_failover_listener_set_value,
! 188: dhcp_failover_listener_get_value,
! 189: dhcp_failover_listener_destroy,
! 190: dhcp_failover_listener_signal,
! 191: dhcp_failover_listener_stuff,
! 192: 0, 0, 0, 0, 0, 0,
! 193: sizeof
! 194: (dhcp_failover_listener_t), 0,
! 195: RC_MISC);
! 196:
! 197: if (status != ISC_R_SUCCESS)
! 198: log_fatal ("Can't register failover listener object type: %s",
! 199: isc_result_totext (status));
! 200: #endif /* FAILOVER_PROTOCOL */
! 201: }
! 202:
! 203: isc_result_t dhcp_lease_set_value (omapi_object_t *h,
! 204: omapi_object_t *id,
! 205: omapi_data_string_t *name,
! 206: omapi_typed_data_t *value)
! 207: {
! 208: struct lease *lease;
! 209: isc_result_t status;
! 210:
! 211: if (h -> type != dhcp_type_lease)
! 212: return ISC_R_INVALIDARG;
! 213: lease = (struct lease *)h;
! 214:
! 215: /* We're skipping a lot of things it might be interesting to
! 216: set - for now, we just make it possible to whack the state. */
! 217: if (!omapi_ds_strcmp (name, "state")) {
! 218: unsigned long bar;
! 219: const char *ols, *nls;
! 220: status = omapi_get_int_value (&bar, value);
! 221: if (status != ISC_R_SUCCESS)
! 222: return status;
! 223:
! 224: if (bar < 1 || bar > FTS_LAST)
! 225: return ISC_R_INVALIDARG;
! 226: nls = binding_state_names [bar - 1];
! 227: if (lease -> binding_state >= 1 &&
! 228: lease -> binding_state <= FTS_LAST)
! 229: ols = binding_state_names [lease -> binding_state - 1];
! 230: else
! 231: ols = "unknown state";
! 232:
! 233: if (lease -> binding_state != bar) {
! 234: lease -> next_binding_state = bar;
! 235: if (supersede_lease (lease, 0, 1, 1, 1)) {
! 236: log_info ("lease %s state changed from %s to %s",
! 237: piaddr(lease->ip_addr), ols, nls);
! 238: return ISC_R_SUCCESS;
! 239: }
! 240: log_info ("lease %s state change from %s to %s failed.",
! 241: piaddr (lease -> ip_addr), ols, nls);
! 242: return ISC_R_IOERROR;
! 243: }
! 244: return ISC_R_UNCHANGED;
! 245: } else if (!omapi_ds_strcmp (name, "ip-address")) {
! 246: return ISC_R_NOPERM;
! 247: } else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
! 248: return ISC_R_UNCHANGED; /* XXX take change. */
! 249: } else if (!omapi_ds_strcmp (name, "hostname")) {
! 250: return ISC_R_UNCHANGED; /* XXX take change. */
! 251: } else if (!omapi_ds_strcmp (name, "client-hostname")) {
! 252: return ISC_R_UNCHANGED; /* XXX take change. */
! 253: } else if (!omapi_ds_strcmp (name, "host")) {
! 254: return ISC_R_UNCHANGED; /* XXX take change. */
! 255: } else if (!omapi_ds_strcmp (name, "subnet")) {
! 256: return ISC_R_INVALIDARG;
! 257: } else if (!omapi_ds_strcmp (name, "pool")) {
! 258: return ISC_R_NOPERM;
! 259: } else if (!omapi_ds_strcmp (name, "starts")) {
! 260: return ISC_R_NOPERM;
! 261: } else if (!omapi_ds_strcmp (name, "ends")) {
! 262: unsigned long lease_end, old_lease_end;
! 263: status = omapi_get_int_value (&lease_end, value);
! 264: if (status != ISC_R_SUCCESS)
! 265: return status;
! 266: old_lease_end = lease->ends;
! 267: lease->ends = lease_end;
! 268: if (supersede_lease (lease, 0, 1, 1, 1)) {
! 269: log_info ("lease %s end changed from %lu to %lu",
! 270: piaddr(lease->ip_addr), old_lease_end, lease_end);
! 271: return ISC_R_SUCCESS;
! 272: }
! 273: log_info ("lease %s end change from %lu to %lu failed",
! 274: piaddr(lease->ip_addr), old_lease_end, lease_end);
! 275: return ISC_R_IOERROR;
! 276: } else if (!omapi_ds_strcmp(name, "flags")) {
! 277: u_int8_t oldflags;
! 278:
! 279: if (value->type != omapi_datatype_data)
! 280: return ISC_R_INVALIDARG;
! 281:
! 282: oldflags = lease->flags;
! 283: lease->flags = (value->u.buffer.value[0] & EPHEMERAL_FLAGS) |
! 284: (lease->flags & ~EPHEMERAL_FLAGS);
! 285: if(oldflags == lease->flags)
! 286: return ISC_R_SUCCESS;
! 287: if (!supersede_lease(lease, NULL, 1, 1, 1)) {
! 288: log_error("Failed to update flags for lease %s.",
! 289: piaddr(lease->ip_addr));
! 290: return ISC_R_IOERROR;
! 291: }
! 292: return ISC_R_SUCCESS;
! 293: } else if (!omapi_ds_strcmp (name, "billing-class")) {
! 294: return ISC_R_UNCHANGED; /* XXX carefully allow change. */
! 295: } else if (!omapi_ds_strcmp (name, "hardware-address")) {
! 296: return ISC_R_UNCHANGED; /* XXX take change. */
! 297: } else if (!omapi_ds_strcmp (name, "hardware-type")) {
! 298: return ISC_R_UNCHANGED; /* XXX take change. */
! 299: } else if (lease -> scope) {
! 300: status = binding_scope_set_value (lease -> scope, 0, name, value);
! 301: if (status == ISC_R_SUCCESS) {
! 302: if (write_lease (lease) && commit_leases ())
! 303: return ISC_R_SUCCESS;
! 304: return ISC_R_IOERROR;
! 305: }
! 306: }
! 307:
! 308: /* Try to find some inner object that can take the value. */
! 309: if (h -> inner && h -> inner -> type -> set_value) {
! 310: status = ((*(h -> inner -> type -> set_value))
! 311: (h -> inner, id, name, value));
! 312: if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
! 313: return status;
! 314: }
! 315:
! 316: if (!lease -> scope) {
! 317: if (!binding_scope_allocate (&lease -> scope, MDL))
! 318: return ISC_R_NOMEMORY;
! 319: }
! 320: status = binding_scope_set_value (lease -> scope, 1, name, value);
! 321: if (status != ISC_R_SUCCESS)
! 322: return status;
! 323:
! 324: if (write_lease (lease) && commit_leases ())
! 325: return ISC_R_SUCCESS;
! 326: return ISC_R_IOERROR;
! 327: }
! 328:
! 329:
! 330: isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
! 331: omapi_data_string_t *name,
! 332: omapi_value_t **value)
! 333: {
! 334: struct lease *lease;
! 335: isc_result_t status;
! 336:
! 337: if (h -> type != dhcp_type_lease)
! 338: return ISC_R_INVALIDARG;
! 339: lease = (struct lease *)h;
! 340:
! 341: if (!omapi_ds_strcmp (name, "state"))
! 342: return omapi_make_int_value (value, name,
! 343: (int)lease -> binding_state, MDL);
! 344: else if (!omapi_ds_strcmp (name, "ip-address"))
! 345: return omapi_make_const_value (value, name,
! 346: lease -> ip_addr.iabuf,
! 347: lease -> ip_addr.len, MDL);
! 348: else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
! 349: return omapi_make_const_value (value, name,
! 350: lease -> uid,
! 351: lease -> uid_len, MDL);
! 352: } else if (!omapi_ds_strcmp (name, "client-hostname")) {
! 353: if (lease -> client_hostname)
! 354: return omapi_make_string_value
! 355: (value, name, lease -> client_hostname, MDL);
! 356: return ISC_R_NOTFOUND;
! 357: } else if (!omapi_ds_strcmp (name, "host")) {
! 358: if (lease -> host)
! 359: return omapi_make_handle_value
! 360: (value, name,
! 361: ((omapi_object_t *)lease -> host), MDL);
! 362: } else if (!omapi_ds_strcmp (name, "subnet"))
! 363: return omapi_make_handle_value (value, name,
! 364: ((omapi_object_t *)
! 365: lease -> subnet), MDL);
! 366: else if (!omapi_ds_strcmp (name, "pool"))
! 367: return omapi_make_handle_value (value, name,
! 368: ((omapi_object_t *)
! 369: lease -> pool), MDL);
! 370: else if (!omapi_ds_strcmp (name, "billing-class")) {
! 371: if (lease -> billing_class)
! 372: return omapi_make_handle_value
! 373: (value, name,
! 374: ((omapi_object_t *)lease -> billing_class),
! 375: MDL);
! 376: return ISC_R_NOTFOUND;
! 377: } else if (!omapi_ds_strcmp (name, "hardware-address")) {
! 378: if (lease -> hardware_addr.hlen)
! 379: return omapi_make_const_value
! 380: (value, name, &lease -> hardware_addr.hbuf [1],
! 381: (unsigned)(lease -> hardware_addr.hlen - 1),
! 382: MDL);
! 383: return ISC_R_NOTFOUND;
! 384: } else if (!omapi_ds_strcmp (name, "hardware-type")) {
! 385: if (lease -> hardware_addr.hlen)
! 386: return omapi_make_int_value
! 387: (value, name, lease -> hardware_addr.hbuf [0],
! 388: MDL);
! 389: return ISC_R_NOTFOUND;
! 390: } else if (lease -> scope) {
! 391: status = binding_scope_get_value (value, lease -> scope, name);
! 392: if (status != ISC_R_NOTFOUND)
! 393: return status;
! 394: }
! 395:
! 396: /* Try to find some inner object that can take the value. */
! 397: if (h -> inner && h -> inner -> type -> get_value) {
! 398: status = ((*(h -> inner -> type -> get_value))
! 399: (h -> inner, id, name, value));
! 400: if (status == ISC_R_SUCCESS)
! 401: return status;
! 402: }
! 403: return ISC_R_UNKNOWNATTRIBUTE;
! 404: }
! 405:
! 406: isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
! 407: {
! 408: struct lease *lease;
! 409:
! 410: if (h -> type != dhcp_type_lease)
! 411: return ISC_R_INVALIDARG;
! 412: lease = (struct lease *)h;
! 413:
! 414: if (lease -> uid)
! 415: uid_hash_delete (lease);
! 416: hw_hash_delete (lease);
! 417:
! 418: if (lease -> on_release)
! 419: executable_statement_dereference (&lease -> on_release,
! 420: file, line);
! 421: if (lease -> on_expiry)
! 422: executable_statement_dereference (&lease -> on_expiry,
! 423: file, line);
! 424: if (lease -> on_commit)
! 425: executable_statement_dereference (&lease -> on_commit,
! 426: file, line);
! 427: if (lease -> scope)
! 428: binding_scope_dereference (&lease -> scope, file, line);
! 429:
! 430: if (lease -> agent_options)
! 431: option_chain_head_dereference (&lease -> agent_options,
! 432: file, line);
! 433: if (lease -> uid && lease -> uid != lease -> uid_buf) {
! 434: dfree (lease -> uid, MDL);
! 435: lease -> uid = &lease -> uid_buf [0];
! 436: lease -> uid_len = 0;
! 437: }
! 438:
! 439: if (lease -> client_hostname) {
! 440: dfree (lease -> client_hostname, MDL);
! 441: lease -> client_hostname = (char *)0;
! 442: }
! 443:
! 444: if (lease -> host)
! 445: host_dereference (&lease -> host, file, line);
! 446: if (lease -> subnet)
! 447: subnet_dereference (&lease -> subnet, file, line);
! 448: if (lease -> pool)
! 449: pool_dereference (&lease -> pool, file, line);
! 450:
! 451: if (lease -> state) {
! 452: free_lease_state (lease -> state, file, line);
! 453: lease -> state = (struct lease_state *)0;
! 454:
! 455: cancel_timeout (lease_ping_timeout, lease);
! 456: --outstanding_pings; /* XXX */
! 457: }
! 458:
! 459: if (lease -> billing_class)
! 460: class_dereference
! 461: (&lease -> billing_class, file, line);
! 462:
! 463: #if defined (DEBUG_MEMORY_LEAKAGE) || \
! 464: defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
! 465: /* XXX we should never be destroying a lease with a next
! 466: XXX pointer except on exit... */
! 467: if (lease -> next)
! 468: lease_dereference (&lease -> next, file, line);
! 469: if (lease -> n_hw)
! 470: lease_dereference (&lease -> n_hw, file, line);
! 471: if (lease -> n_uid)
! 472: lease_dereference (&lease -> n_uid, file, line);
! 473: if (lease -> next_pending)
! 474: lease_dereference (&lease -> next_pending, file, line);
! 475: #endif
! 476:
! 477: return ISC_R_SUCCESS;
! 478: }
! 479:
! 480: isc_result_t dhcp_lease_signal_handler (omapi_object_t *h,
! 481: const char *name, va_list ap)
! 482: {
! 483: struct lease *lease;
! 484: isc_result_t status;
! 485:
! 486: if (h -> type != dhcp_type_lease)
! 487: return ISC_R_INVALIDARG;
! 488: lease = (struct lease *)h;
! 489:
! 490: if (!strcmp (name, "updated"))
! 491: return ISC_R_SUCCESS;
! 492:
! 493: /* Try to find some inner object that can take the value. */
! 494: if (h -> inner && h -> inner -> type -> signal_handler) {
! 495: status = ((*(h -> inner -> type -> signal_handler))
! 496: (h -> inner, name, ap));
! 497: if (status == ISC_R_SUCCESS)
! 498: return status;
! 499: }
! 500: return ISC_R_NOTFOUND;
! 501: }
! 502:
! 503: isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
! 504: omapi_object_t *id,
! 505: omapi_object_t *h)
! 506: {
! 507: u_int32_t bouncer;
! 508: struct lease *lease;
! 509: isc_result_t status;
! 510: u_int8_t flagbuf;
! 511:
! 512: if (h -> type != dhcp_type_lease)
! 513: return ISC_R_INVALIDARG;
! 514: lease = (struct lease *)h;
! 515:
! 516: /* Write out all the values. */
! 517:
! 518: status = omapi_connection_put_name (c, "state");
! 519: if (status != ISC_R_SUCCESS)
! 520: return status;
! 521: status = omapi_connection_put_uint32 (c, sizeof (int));
! 522: if (status != ISC_R_SUCCESS)
! 523: return status;
! 524: status = omapi_connection_put_uint32 (c, lease -> binding_state);
! 525: if (status != ISC_R_SUCCESS)
! 526: return status;
! 527:
! 528: status = omapi_connection_put_name (c, "ip-address");
! 529: if (status != ISC_R_SUCCESS)
! 530: return status;
! 531: status = omapi_connection_put_uint32 (c, lease -> ip_addr.len);
! 532: if (status != ISC_R_SUCCESS)
! 533: return status;
! 534: status = omapi_connection_copyin (c, lease -> ip_addr.iabuf,
! 535: lease -> ip_addr.len);
! 536: if (status != ISC_R_SUCCESS)
! 537: return status;
! 538:
! 539: if (lease -> uid_len) {
! 540: status = omapi_connection_put_name (c,
! 541: "dhcp-client-identifier");
! 542: if (status != ISC_R_SUCCESS)
! 543: return status;
! 544: status = omapi_connection_put_uint32 (c, lease -> uid_len);
! 545: if (status != ISC_R_SUCCESS)
! 546: return status;
! 547: if (lease -> uid_len) {
! 548: status = omapi_connection_copyin (c, lease -> uid,
! 549: lease -> uid_len);
! 550: if (status != ISC_R_SUCCESS)
! 551: return status;
! 552: }
! 553: }
! 554:
! 555: if (lease -> client_hostname) {
! 556: status = omapi_connection_put_name (c, "client-hostname");
! 557: if (status != ISC_R_SUCCESS)
! 558: return status;
! 559: status =
! 560: omapi_connection_put_string (c,
! 561: lease -> client_hostname);
! 562: if (status != ISC_R_SUCCESS)
! 563: return status;
! 564: }
! 565:
! 566: if (lease -> host) {
! 567: status = omapi_connection_put_name (c, "host");
! 568: if (status != ISC_R_SUCCESS)
! 569: return status;
! 570: status = omapi_connection_put_handle (c,
! 571: (omapi_object_t *)
! 572: lease -> host);
! 573: if (status != ISC_R_SUCCESS)
! 574: return status;
! 575: }
! 576:
! 577: status = omapi_connection_put_name (c, "subnet");
! 578: if (status != ISC_R_SUCCESS)
! 579: return status;
! 580: status = omapi_connection_put_handle
! 581: (c, (omapi_object_t *)lease -> subnet);
! 582: if (status != ISC_R_SUCCESS)
! 583: return status;
! 584:
! 585: status = omapi_connection_put_name (c, "pool");
! 586: if (status != ISC_R_SUCCESS)
! 587: return status;
! 588: status = omapi_connection_put_handle (c,
! 589: (omapi_object_t *)lease -> pool);
! 590: if (status != ISC_R_SUCCESS)
! 591: return status;
! 592:
! 593: if (lease -> billing_class) {
! 594: status = omapi_connection_put_name (c, "billing-class");
! 595: if (status != ISC_R_SUCCESS)
! 596: return status;
! 597: status = omapi_connection_put_handle
! 598: (c, (omapi_object_t *)lease -> billing_class);
! 599: if (status != ISC_R_SUCCESS)
! 600: return status;
! 601: }
! 602:
! 603: if (lease -> hardware_addr.hlen) {
! 604: status = omapi_connection_put_name (c, "hardware-address");
! 605: if (status != ISC_R_SUCCESS)
! 606: return status;
! 607: status = (omapi_connection_put_uint32
! 608: (c,
! 609: (unsigned long)(lease -> hardware_addr.hlen - 1)));
! 610: if (status != ISC_R_SUCCESS)
! 611: return status;
! 612: status = (omapi_connection_copyin
! 613: (c, &lease -> hardware_addr.hbuf [1],
! 614: (unsigned long)(lease -> hardware_addr.hlen - 1)));
! 615:
! 616: if (status != ISC_R_SUCCESS)
! 617: return status;
! 618:
! 619: status = omapi_connection_put_name (c, "hardware-type");
! 620: if (status != ISC_R_SUCCESS)
! 621: return status;
! 622: status = omapi_connection_put_uint32 (c, sizeof (int));
! 623: if (status != ISC_R_SUCCESS)
! 624: return status;
! 625: status = omapi_connection_put_uint32
! 626: (c, lease -> hardware_addr.hbuf [0]);
! 627: if (status != ISC_R_SUCCESS)
! 628: return status;
! 629: }
! 630:
! 631: /* TIME values may be 64-bit, depending on system architecture.
! 632: * OMAPI must be system independent, both in terms of transmitting
! 633: * bytes on the wire in network byte order, and in terms of being
! 634: * readable and usable by both systems.
! 635: *
! 636: * XXX: In a future feature release, a put_int64() should be made
! 637: * to exist, and perhaps a put_time() wrapper that selects which
! 638: * to use based upon sizeof(TIME). In the meantime, use existing,
! 639: * 32-bit, code.
! 640: */
! 641: bouncer = (u_int32_t)lease->ends;
! 642: status = omapi_connection_put_name(c, "ends");
! 643: if (status != ISC_R_SUCCESS)
! 644: return status;
! 645: status = omapi_connection_put_uint32(c, sizeof(bouncer));
! 646: if (status != ISC_R_SUCCESS)
! 647: return status;
! 648: status = omapi_connection_put_uint32(c, bouncer);
! 649: if (status != ISC_R_SUCCESS)
! 650: return status;
! 651:
! 652: bouncer = (u_int32_t)lease->starts;
! 653: status = omapi_connection_put_name(c, "starts");
! 654: if (status != ISC_R_SUCCESS)
! 655: return status;
! 656: status = omapi_connection_put_uint32(c, sizeof(bouncer));
! 657: if (status != ISC_R_SUCCESS)
! 658: return status;
! 659: status = omapi_connection_put_uint32(c, bouncer);
! 660: if (status != ISC_R_SUCCESS)
! 661: return status;
! 662:
! 663: bouncer = (u_int32_t)lease->tstp;
! 664: status = omapi_connection_put_name(c, "tstp");
! 665: if (status != ISC_R_SUCCESS)
! 666: return status;
! 667: status = omapi_connection_put_uint32(c, sizeof(bouncer));
! 668: if (status != ISC_R_SUCCESS)
! 669: return status;
! 670: status = omapi_connection_put_uint32(c, bouncer);
! 671: if (status != ISC_R_SUCCESS)
! 672: return status;
! 673:
! 674: bouncer = (u_int32_t)lease->tsfp;
! 675: status = omapi_connection_put_name(c, "tsfp");
! 676: if (status != ISC_R_SUCCESS)
! 677: return status;
! 678: status = omapi_connection_put_uint32(c, sizeof(bouncer));
! 679: if (status != ISC_R_SUCCESS)
! 680: return status;
! 681: status = omapi_connection_put_uint32(c, bouncer);
! 682: if (status != ISC_R_SUCCESS)
! 683: return status;
! 684:
! 685: bouncer = (u_int32_t)lease->atsfp;
! 686: status = omapi_connection_put_name(c, "atsfp");
! 687: if (status != ISC_R_SUCCESS)
! 688: return status;
! 689: status = omapi_connection_put_uint32(c, sizeof(bouncer));
! 690: if (status != ISC_R_SUCCESS)
! 691: return status;
! 692: status = omapi_connection_put_uint32(c, bouncer);
! 693: if (status != ISC_R_SUCCESS)
! 694: return status;
! 695:
! 696: bouncer = (u_int32_t)lease->cltt;
! 697: status = omapi_connection_put_name(c, "cltt");
! 698: if (status != ISC_R_SUCCESS)
! 699: return status;
! 700: status = omapi_connection_put_uint32(c, sizeof(bouncer));
! 701: if (status != ISC_R_SUCCESS)
! 702: return status;
! 703: status = omapi_connection_put_uint32(c, bouncer);
! 704: if (status != ISC_R_SUCCESS)
! 705: return status;
! 706:
! 707: status = omapi_connection_put_name (c, "flags");
! 708: if (status != ISC_R_SUCCESS)
! 709: return status;
! 710: status = omapi_connection_put_uint32(c, sizeof(flagbuf));
! 711: if (status != ISC_R_SUCCESS)
! 712: return status;
! 713: flagbuf = lease->flags & EPHEMERAL_FLAGS;
! 714: status = omapi_connection_copyin(c, &flagbuf, sizeof(flagbuf));
! 715: if (status != ISC_R_SUCCESS)
! 716: return status;
! 717:
! 718: if (lease -> scope) {
! 719: status = binding_scope_stuff_values (c, lease -> scope);
! 720: if (status != ISC_R_SUCCESS)
! 721: return status;
! 722: }
! 723:
! 724: /* Write out the inner object, if any. */
! 725: if (h -> inner && h -> inner -> type -> stuff_values) {
! 726: status = ((*(h -> inner -> type -> stuff_values))
! 727: (c, id, h -> inner));
! 728: if (status == ISC_R_SUCCESS)
! 729: return status;
! 730: }
! 731:
! 732: return ISC_R_SUCCESS;
! 733: }
! 734:
! 735: isc_result_t dhcp_lease_lookup (omapi_object_t **lp,
! 736: omapi_object_t *id, omapi_object_t *ref)
! 737: {
! 738: omapi_value_t *tv = (omapi_value_t *)0;
! 739: isc_result_t status;
! 740: struct lease *lease;
! 741:
! 742: if (!ref)
! 743: return ISC_R_NOKEYS;
! 744:
! 745: /* First see if we were sent a handle. */
! 746: status = omapi_get_value_str (ref, id, "handle", &tv);
! 747: if (status == ISC_R_SUCCESS) {
! 748: status = omapi_handle_td_lookup (lp, tv -> value);
! 749:
! 750: omapi_value_dereference (&tv, MDL);
! 751: if (status != ISC_R_SUCCESS)
! 752: return status;
! 753:
! 754: /* Don't return the object if the type is wrong. */
! 755: if ((*lp) -> type != dhcp_type_lease) {
! 756: omapi_object_dereference (lp, MDL);
! 757: return ISC_R_INVALIDARG;
! 758: }
! 759: }
! 760:
! 761: /* Now look for an IP address. */
! 762: status = omapi_get_value_str (ref, id, "ip-address", &tv);
! 763: if (status == ISC_R_SUCCESS) {
! 764: lease = (struct lease *)0;
! 765: lease_ip_hash_lookup(&lease, lease_ip_addr_hash,
! 766: tv->value->u.buffer.value,
! 767: tv->value->u.buffer.len, MDL);
! 768:
! 769: omapi_value_dereference (&tv, MDL);
! 770:
! 771: /* If we already have a lease, and it's not the same one,
! 772: then the query was invalid. */
! 773: if (*lp && *lp != (omapi_object_t *)lease) {
! 774: omapi_object_dereference (lp, MDL);
! 775: lease_dereference (&lease, MDL);
! 776: return ISC_R_KEYCONFLICT;
! 777: } else if (!lease) {
! 778: if (*lp)
! 779: omapi_object_dereference (lp, MDL);
! 780: return ISC_R_NOTFOUND;
! 781: } else if (!*lp) {
! 782: /* XXX fix so that hash lookup itself creates
! 783: XXX the reference. */
! 784: omapi_object_reference (lp,
! 785: (omapi_object_t *)lease, MDL);
! 786: lease_dereference (&lease, MDL);
! 787: }
! 788: }
! 789:
! 790: /* Now look for a client identifier. */
! 791: status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
! 792: if (status == ISC_R_SUCCESS) {
! 793: lease = (struct lease *)0;
! 794: lease_id_hash_lookup(&lease, lease_uid_hash,
! 795: tv->value->u.buffer.value,
! 796: tv->value->u.buffer.len, MDL);
! 797: omapi_value_dereference (&tv, MDL);
! 798:
! 799: if (*lp && *lp != (omapi_object_t *)lease) {
! 800: omapi_object_dereference (lp, MDL);
! 801: lease_dereference (&lease, MDL);
! 802: return ISC_R_KEYCONFLICT;
! 803: } else if (!lease) {
! 804: if (*lp)
! 805: omapi_object_dereference (lp, MDL);
! 806: return ISC_R_NOTFOUND;
! 807: } else if (lease -> n_uid) {
! 808: if (*lp)
! 809: omapi_object_dereference (lp, MDL);
! 810: return ISC_R_MULTIPLE;
! 811: } else if (!*lp) {
! 812: /* XXX fix so that hash lookup itself creates
! 813: XXX the reference. */
! 814: omapi_object_reference (lp,
! 815: (omapi_object_t *)lease, MDL);
! 816: lease_dereference (&lease, MDL);
! 817: }
! 818: }
! 819:
! 820: /* Now look for a hardware address. */
! 821: status = omapi_get_value_str (ref, id, "hardware-address", &tv);
! 822: if (status == ISC_R_SUCCESS) {
! 823: unsigned char *haddr;
! 824: unsigned int len;
! 825:
! 826: len = tv -> value -> u.buffer.len + 1;
! 827: haddr = dmalloc (len, MDL);
! 828: if (!haddr) {
! 829: omapi_value_dereference (&tv, MDL);
! 830: return ISC_R_NOMEMORY;
! 831: }
! 832:
! 833: memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
! 834: omapi_value_dereference (&tv, MDL);
! 835:
! 836: status = omapi_get_value_str (ref, id, "hardware-type", &tv);
! 837: if (status == ISC_R_SUCCESS) {
! 838: if (tv -> value -> type == omapi_datatype_data) {
! 839: if ((tv -> value -> u.buffer.len != 4) ||
! 840: (tv -> value -> u.buffer.value[0] != 0) ||
! 841: (tv -> value -> u.buffer.value[1] != 0) ||
! 842: (tv -> value -> u.buffer.value[2] != 0)) {
! 843: omapi_value_dereference (&tv, MDL);
! 844: dfree (haddr, MDL);
! 845: return ISC_R_INVALIDARG;
! 846: }
! 847:
! 848: haddr[0] = tv -> value -> u.buffer.value[3];
! 849: } else if (tv -> value -> type == omapi_datatype_int) {
! 850: haddr[0] = (unsigned char)
! 851: tv -> value -> u.integer;
! 852: } else {
! 853: omapi_value_dereference (&tv, MDL);
! 854: dfree (haddr, MDL);
! 855: return ISC_R_INVALIDARG;
! 856: }
! 857:
! 858: omapi_value_dereference (&tv, MDL);
! 859: } else {
! 860: /* If no hardware-type is specified, default to
! 861: ethernet. This may or may not be a good idea,
! 862: but Telus is currently relying on this behavior.
! 863: - DPN */
! 864: haddr[0] = HTYPE_ETHER;
! 865: }
! 866:
! 867: lease = (struct lease *)0;
! 868: lease_id_hash_lookup(&lease, lease_hw_addr_hash, haddr, len,
! 869: MDL);
! 870: dfree (haddr, MDL);
! 871:
! 872: if (*lp && *lp != (omapi_object_t *)lease) {
! 873: omapi_object_dereference (lp, MDL);
! 874: lease_dereference (&lease, MDL);
! 875: return ISC_R_KEYCONFLICT;
! 876: } else if (!lease) {
! 877: if (*lp)
! 878: omapi_object_dereference (lp, MDL);
! 879: return ISC_R_NOTFOUND;
! 880: } else if (lease -> n_hw) {
! 881: if (*lp)
! 882: omapi_object_dereference (lp, MDL);
! 883: lease_dereference (&lease, MDL);
! 884: return ISC_R_MULTIPLE;
! 885: } else if (!*lp) {
! 886: /* XXX fix so that hash lookup itself creates
! 887: XXX the reference. */
! 888: omapi_object_reference (lp,
! 889: (omapi_object_t *)lease, MDL);
! 890: lease_dereference (&lease, MDL);
! 891: }
! 892: }
! 893:
! 894: /* If we get to here without finding a lease, no valid key was
! 895: specified. */
! 896: if (!*lp)
! 897: return ISC_R_NOKEYS;
! 898: return ISC_R_SUCCESS;
! 899: }
! 900:
! 901: isc_result_t dhcp_lease_create (omapi_object_t **lp,
! 902: omapi_object_t *id)
! 903: {
! 904: return ISC_R_NOTIMPLEMENTED;
! 905: }
! 906:
! 907: isc_result_t dhcp_lease_remove (omapi_object_t *lp,
! 908: omapi_object_t *id)
! 909: {
! 910: return ISC_R_NOTIMPLEMENTED;
! 911: }
! 912:
! 913: isc_result_t dhcp_host_set_value (omapi_object_t *h,
! 914: omapi_object_t *id,
! 915: omapi_data_string_t *name,
! 916: omapi_typed_data_t *value)
! 917: {
! 918: struct host_decl *host;
! 919: isc_result_t status;
! 920:
! 921: if (h -> type != dhcp_type_host)
! 922: return ISC_R_INVALIDARG;
! 923: host = (struct host_decl *)h;
! 924:
! 925: /* XXX For now, we can only set these values on new host objects.
! 926: XXX Soon, we need to be able to update host objects. */
! 927: if (!omapi_ds_strcmp (name, "name")) {
! 928: if (host -> name)
! 929: return ISC_R_EXISTS;
! 930: if (value && (value -> type == omapi_datatype_data ||
! 931: value -> type == omapi_datatype_string)) {
! 932: host -> name = dmalloc (value -> u.buffer.len + 1,
! 933: MDL);
! 934: if (!host -> name)
! 935: return ISC_R_NOMEMORY;
! 936: memcpy (host -> name,
! 937: value -> u.buffer.value,
! 938: value -> u.buffer.len);
! 939: host -> name [value -> u.buffer.len] = 0;
! 940: } else
! 941: return ISC_R_INVALIDARG;
! 942: return ISC_R_SUCCESS;
! 943: }
! 944:
! 945: if (!omapi_ds_strcmp (name, "group")) {
! 946: if (value && (value -> type == omapi_datatype_data ||
! 947: value -> type == omapi_datatype_string)) {
! 948: struct group_object *group;
! 949: group = (struct group_object *)0;
! 950: group_hash_lookup (&group, group_name_hash,
! 951: (char *)value -> u.buffer.value,
! 952: value -> u.buffer.len, MDL);
! 953: if (!group || (group -> flags & GROUP_OBJECT_DELETED))
! 954: return ISC_R_NOTFOUND;
! 955: if (host -> group)
! 956: group_dereference (&host -> group, MDL);
! 957: group_reference (&host -> group, group -> group, MDL);
! 958: if (host -> named_group)
! 959: group_object_dereference (&host -> named_group,
! 960: MDL);
! 961: group_object_reference (&host -> named_group,
! 962: group, MDL);
! 963: group_object_dereference (&group, MDL);
! 964: } else
! 965: return ISC_R_INVALIDARG;
! 966: return ISC_R_SUCCESS;
! 967: }
! 968:
! 969: if (!omapi_ds_strcmp (name, "hardware-address")) {
! 970: if (host -> interface.hlen)
! 971: return ISC_R_EXISTS;
! 972: if (value && (value -> type == omapi_datatype_data ||
! 973: value -> type == omapi_datatype_string)) {
! 974: if (value -> u.buffer.len >
! 975: (sizeof host -> interface.hbuf) - 1)
! 976: return ISC_R_INVALIDARG;
! 977: memcpy (&host -> interface.hbuf [1],
! 978: value -> u.buffer.value,
! 979: value -> u.buffer.len);
! 980: host -> interface.hlen = value -> u.buffer.len + 1;
! 981: } else
! 982: return ISC_R_INVALIDARG;
! 983: return ISC_R_SUCCESS;
! 984: }
! 985:
! 986: if (!omapi_ds_strcmp (name, "hardware-type")) {
! 987: int type;
! 988: if (value && (value -> type == omapi_datatype_data &&
! 989: value -> u.buffer.len == sizeof type)) {
! 990: if (value -> u.buffer.len > sizeof type)
! 991: return ISC_R_INVALIDARG;
! 992: memcpy (&type,
! 993: value -> u.buffer.value,
! 994: value -> u.buffer.len);
! 995: type = ntohl (type);
! 996: } else if (value -> type == omapi_datatype_int)
! 997: type = value -> u.integer;
! 998: else
! 999: return ISC_R_INVALIDARG;
! 1000: host -> interface.hbuf [0] = type;
! 1001: return ISC_R_SUCCESS;
! 1002: }
! 1003:
! 1004: if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
! 1005: if (host -> client_identifier.data)
! 1006: return ISC_R_EXISTS;
! 1007: if (value && (value -> type == omapi_datatype_data ||
! 1008: value -> type == omapi_datatype_string)) {
! 1009: if (!buffer_allocate (&host -> client_identifier.buffer,
! 1010: value -> u.buffer.len, MDL))
! 1011: return ISC_R_NOMEMORY;
! 1012: host -> client_identifier.data =
! 1013: &host -> client_identifier.buffer -> data [0];
! 1014: memcpy (host -> client_identifier.buffer -> data,
! 1015: value -> u.buffer.value,
! 1016: value -> u.buffer.len);
! 1017: host -> client_identifier.len = value -> u.buffer.len;
! 1018: } else
! 1019: return ISC_R_INVALIDARG;
! 1020: return ISC_R_SUCCESS;
! 1021: }
! 1022:
! 1023: if (!omapi_ds_strcmp (name, "ip-address")) {
! 1024: if (host -> fixed_addr)
! 1025: option_cache_dereference (&host -> fixed_addr, MDL);
! 1026: if (!value)
! 1027: return ISC_R_SUCCESS;
! 1028: if (value && (value -> type == omapi_datatype_data ||
! 1029: value -> type == omapi_datatype_string)) {
! 1030: struct data_string ds;
! 1031: memset (&ds, 0, sizeof ds);
! 1032: ds.len = value -> u.buffer.len;
! 1033: if (!buffer_allocate (&ds.buffer, ds.len, MDL))
! 1034: return ISC_R_NOMEMORY;
! 1035: ds.data = (&ds.buffer -> data [0]);
! 1036: memcpy (ds.buffer -> data,
! 1037: value -> u.buffer.value, ds.len);
! 1038: if (!option_cache (&host -> fixed_addr,
! 1039: &ds, (struct expression *)0,
! 1040: (struct option *)0, MDL)) {
! 1041: data_string_forget (&ds, MDL);
! 1042: return ISC_R_NOMEMORY;
! 1043: }
! 1044: data_string_forget (&ds, MDL);
! 1045: } else
! 1046: return ISC_R_INVALIDARG;
! 1047: return ISC_R_SUCCESS;
! 1048: }
! 1049:
! 1050: if (!omapi_ds_strcmp (name, "statements")) {
! 1051: if (!host -> group) {
! 1052: if (!clone_group (&host -> group, root_group, MDL))
! 1053: return ISC_R_NOMEMORY;
! 1054: } else {
! 1055: if (host -> group -> statements &&
! 1056: (!host -> named_group ||
! 1057: host -> group != host -> named_group -> group) &&
! 1058: host -> group != root_group)
! 1059: return ISC_R_EXISTS;
! 1060: if (!clone_group (&host -> group, host -> group, MDL))
! 1061: return ISC_R_NOMEMORY;
! 1062: }
! 1063: if (!host -> group)
! 1064: return ISC_R_NOMEMORY;
! 1065: if (value && (value -> type == omapi_datatype_data ||
! 1066: value -> type == omapi_datatype_string)) {
! 1067: struct parse *parse;
! 1068: int lose = 0;
! 1069: parse = (struct parse *)0;
! 1070: status = new_parse(&parse, -1,
! 1071: (char *) value->u.buffer.value,
! 1072: value->u.buffer.len,
! 1073: "network client", 0);
! 1074: if (status != ISC_R_SUCCESS || parse == NULL)
! 1075: return status;
! 1076:
! 1077: if (!(parse_executable_statements
! 1078: (&host -> group -> statements, parse, &lose,
! 1079: context_any))) {
! 1080: end_parse (&parse);
! 1081: return ISC_R_BADPARSE;
! 1082: }
! 1083: end_parse (&parse);
! 1084: } else
! 1085: return ISC_R_INVALIDARG;
! 1086: return ISC_R_SUCCESS;
! 1087: }
! 1088:
! 1089: /* The "known" flag isn't supported in the database yet, but it's
! 1090: legitimate. */
! 1091: if (!omapi_ds_strcmp (name, "known")) {
! 1092: return ISC_R_SUCCESS;
! 1093: }
! 1094:
! 1095: /* Try to find some inner object that can take the value. */
! 1096: if (h -> inner && h -> inner -> type -> set_value) {
! 1097: status = ((*(h -> inner -> type -> set_value))
! 1098: (h -> inner, id, name, value));
! 1099: if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
! 1100: return status;
! 1101: }
! 1102:
! 1103: return ISC_R_UNKNOWNATTRIBUTE;
! 1104: }
! 1105:
! 1106:
! 1107: isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id,
! 1108: omapi_data_string_t *name,
! 1109: omapi_value_t **value)
! 1110: {
! 1111: struct host_decl *host;
! 1112: isc_result_t status;
! 1113: struct data_string ip_addrs;
! 1114:
! 1115: if (h -> type != dhcp_type_host)
! 1116: return ISC_R_INVALIDARG;
! 1117: host = (struct host_decl *)h;
! 1118:
! 1119: if (!omapi_ds_strcmp (name, "ip-addresses")) {
! 1120: memset (&ip_addrs, 0, sizeof ip_addrs);
! 1121: if (host -> fixed_addr &&
! 1122: evaluate_option_cache (&ip_addrs, (struct packet *)0,
! 1123: (struct lease *)0,
! 1124: (struct client_state *)0,
! 1125: (struct option_state *)0,
! 1126: (struct option_state *)0,
! 1127: &global_scope,
! 1128: host -> fixed_addr, MDL)) {
! 1129: status = omapi_make_const_value (value, name,
! 1130: ip_addrs.data,
! 1131: ip_addrs.len, MDL);
! 1132: data_string_forget (&ip_addrs, MDL);
! 1133: return status;
! 1134: }
! 1135: return ISC_R_NOTFOUND;
! 1136: }
! 1137:
! 1138: if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
! 1139: if (!host -> client_identifier.len)
! 1140: return ISC_R_NOTFOUND;
! 1141: return omapi_make_const_value (value, name,
! 1142: host -> client_identifier.data,
! 1143: host -> client_identifier.len,
! 1144: MDL);
! 1145: }
! 1146:
! 1147: if (!omapi_ds_strcmp (name, "name"))
! 1148: return omapi_make_string_value (value, name, host -> name,
! 1149: MDL);
! 1150:
! 1151: if (!omapi_ds_strcmp (name, "hardware-address")) {
! 1152: if (!host -> interface.hlen)
! 1153: return ISC_R_NOTFOUND;
! 1154: return (omapi_make_const_value
! 1155: (value, name, &host -> interface.hbuf [1],
! 1156: (unsigned long)(host -> interface.hlen - 1), MDL));
! 1157: }
! 1158:
! 1159: if (!omapi_ds_strcmp (name, "hardware-type")) {
! 1160: if (!host -> interface.hlen)
! 1161: return ISC_R_NOTFOUND;
! 1162: return omapi_make_int_value (value, name,
! 1163: host -> interface.hbuf [0], MDL);
! 1164: }
! 1165:
! 1166: /* Try to find some inner object that can take the value. */
! 1167: if (h -> inner && h -> inner -> type -> get_value) {
! 1168: status = ((*(h -> inner -> type -> get_value))
! 1169: (h -> inner, id, name, value));
! 1170: if (status == ISC_R_SUCCESS)
! 1171: return status;
! 1172: }
! 1173: return ISC_R_UNKNOWNATTRIBUTE;
! 1174: }
! 1175:
! 1176: isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
! 1177: {
! 1178: struct host_decl *host;
! 1179:
! 1180: if (h -> type != dhcp_type_host)
! 1181: return ISC_R_INVALIDARG;
! 1182: host = (struct host_decl *)h;
! 1183:
! 1184: #if defined (DEBUG_MEMORY_LEAKAGE) || \
! 1185: defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
! 1186: if (host -> n_ipaddr)
! 1187: host_dereference (&host -> n_ipaddr, file, line);
! 1188: if (host -> n_dynamic)
! 1189: host_dereference (&host -> n_dynamic, file, line);
! 1190: if (host -> name) {
! 1191: dfree (host -> name, file, line);
! 1192: host -> name = (char *)0;
! 1193: }
! 1194: data_string_forget (&host -> client_identifier, file, line);
! 1195: if (host -> fixed_addr)
! 1196: option_cache_dereference (&host -> fixed_addr, file, line);
! 1197: if (host -> group)
! 1198: group_dereference (&host -> group, file, line);
! 1199: if (host -> named_group)
! 1200: omapi_object_dereference ((omapi_object_t **)
! 1201: &host -> named_group, file, line);
! 1202: data_string_forget (&host -> auth_key_id, file, line);
! 1203: #endif
! 1204:
! 1205: return ISC_R_SUCCESS;
! 1206: }
! 1207:
! 1208: isc_result_t dhcp_host_signal_handler (omapi_object_t *h,
! 1209: const char *name, va_list ap)
! 1210: {
! 1211: struct host_decl *host;
! 1212: isc_result_t status;
! 1213: int updatep = 0;
! 1214:
! 1215: if (h -> type != dhcp_type_host)
! 1216: return ISC_R_INVALIDARG;
! 1217: host = (struct host_decl *)h;
! 1218:
! 1219: if (!strcmp (name, "updated")) {
! 1220: /* There must be a client identifier of some sort. */
! 1221: if (host -> interface.hlen == 0 &&
! 1222: !host -> client_identifier.len)
! 1223: return ISC_R_INVALIDARG;
! 1224:
! 1225: if (!host -> name) {
! 1226: char hnbuf [64];
! 1227: sprintf (hnbuf, "nh%08lx%08lx",
! 1228: (unsigned long)cur_time, (unsigned long)host);
! 1229: host -> name = dmalloc (strlen (hnbuf) + 1, MDL);
! 1230: if (!host -> name)
! 1231: return ISC_R_NOMEMORY;
! 1232: strcpy (host -> name, hnbuf);
! 1233: }
! 1234:
! 1235: #ifdef DEBUG_OMAPI
! 1236: log_debug ("OMAPI added host %s", host -> name);
! 1237: #endif
! 1238: status = enter_host (host, 1, 1);
! 1239: if (status != ISC_R_SUCCESS)
! 1240: return status;
! 1241: updatep = 1;
! 1242: }
! 1243:
! 1244: /* Try to find some inner object that can take the value. */
! 1245: if (h -> inner && h -> inner -> type -> signal_handler) {
! 1246: status = ((*(h -> inner -> type -> signal_handler))
! 1247: (h -> inner, name, ap));
! 1248: if (status == ISC_R_SUCCESS)
! 1249: return status;
! 1250: }
! 1251: if (updatep)
! 1252: return ISC_R_SUCCESS;
! 1253: return ISC_R_NOTFOUND;
! 1254: }
! 1255:
! 1256: isc_result_t dhcp_host_stuff_values (omapi_object_t *c,
! 1257: omapi_object_t *id,
! 1258: omapi_object_t *h)
! 1259: {
! 1260: struct host_decl *host;
! 1261: isc_result_t status;
! 1262: struct data_string ip_addrs;
! 1263:
! 1264: if (h -> type != dhcp_type_host)
! 1265: return ISC_R_INVALIDARG;
! 1266: host = (struct host_decl *)h;
! 1267:
! 1268: /* Write out all the values. */
! 1269:
! 1270: memset (&ip_addrs, 0, sizeof ip_addrs);
! 1271: if (host -> fixed_addr &&
! 1272: evaluate_option_cache (&ip_addrs, (struct packet *)0,
! 1273: (struct lease *)0,
! 1274: (struct client_state *)0,
! 1275: (struct option_state *)0,
! 1276: (struct option_state *)0,
! 1277: &global_scope,
! 1278: host -> fixed_addr, MDL)) {
! 1279: status = omapi_connection_put_name (c, "ip-address");
! 1280: if (status != ISC_R_SUCCESS)
! 1281: return status;
! 1282: status = omapi_connection_put_uint32 (c, ip_addrs.len);
! 1283: if (status != ISC_R_SUCCESS)
! 1284: return status;
! 1285: status = omapi_connection_copyin (c,
! 1286: ip_addrs.data, ip_addrs.len);
! 1287: if (status != ISC_R_SUCCESS)
! 1288: return status;
! 1289: }
! 1290:
! 1291: if (host -> client_identifier.len) {
! 1292: status = omapi_connection_put_name (c,
! 1293: "dhcp-client-identifier");
! 1294: if (status != ISC_R_SUCCESS)
! 1295: return status;
! 1296: status = (omapi_connection_put_uint32
! 1297: (c, host -> client_identifier.len));
! 1298: if (status != ISC_R_SUCCESS)
! 1299: return status;
! 1300: status = (omapi_connection_copyin
! 1301: (c,
! 1302: host -> client_identifier.data,
! 1303: host -> client_identifier.len));
! 1304: if (status != ISC_R_SUCCESS)
! 1305: return status;
! 1306: }
! 1307:
! 1308: if (host -> name) {
! 1309: status = omapi_connection_put_name (c, "name");
! 1310: if (status != ISC_R_SUCCESS)
! 1311: return status;
! 1312: status = omapi_connection_put_string (c, host -> name);
! 1313: if (status != ISC_R_SUCCESS)
! 1314: return status;
! 1315: }
! 1316:
! 1317: if (host -> interface.hlen) {
! 1318: status = omapi_connection_put_name (c, "hardware-address");
! 1319: if (status != ISC_R_SUCCESS)
! 1320: return status;
! 1321: status = (omapi_connection_put_uint32
! 1322: (c, (unsigned long)(host -> interface.hlen - 1)));
! 1323: if (status != ISC_R_SUCCESS)
! 1324: return status;
! 1325: status = (omapi_connection_copyin
! 1326: (c, &host -> interface.hbuf [1],
! 1327: (unsigned long)(host -> interface.hlen - 1)));
! 1328: if (status != ISC_R_SUCCESS)
! 1329: return status;
! 1330:
! 1331: status = omapi_connection_put_name (c, "hardware-type");
! 1332: if (status != ISC_R_SUCCESS)
! 1333: return status;
! 1334: status = omapi_connection_put_uint32 (c, sizeof (int));
! 1335: if (status != ISC_R_SUCCESS)
! 1336: return status;
! 1337: status = (omapi_connection_put_uint32
! 1338: (c, host -> interface.hbuf [0]));
! 1339: if (status != ISC_R_SUCCESS)
! 1340: return status;
! 1341: }
! 1342:
! 1343: /* Write out the inner object, if any. */
! 1344: if (h -> inner && h -> inner -> type -> stuff_values) {
! 1345: status = ((*(h -> inner -> type -> stuff_values))
! 1346: (c, id, h -> inner));
! 1347: if (status == ISC_R_SUCCESS)
! 1348: return status;
! 1349: }
! 1350:
! 1351: return ISC_R_SUCCESS;
! 1352: }
! 1353:
! 1354: isc_result_t dhcp_host_lookup (omapi_object_t **lp,
! 1355: omapi_object_t *id, omapi_object_t *ref)
! 1356: {
! 1357: omapi_value_t *tv = (omapi_value_t *)0;
! 1358: isc_result_t status;
! 1359: struct host_decl *host;
! 1360:
! 1361: if (!ref)
! 1362: return ISC_R_NOKEYS;
! 1363:
! 1364: /* First see if we were sent a handle. */
! 1365: status = omapi_get_value_str (ref, id, "handle", &tv);
! 1366: if (status == ISC_R_SUCCESS) {
! 1367: status = omapi_handle_td_lookup (lp, tv -> value);
! 1368:
! 1369: omapi_value_dereference (&tv, MDL);
! 1370: if (status != ISC_R_SUCCESS)
! 1371: return status;
! 1372:
! 1373: /* Don't return the object if the type is wrong. */
! 1374: if ((*lp) -> type != dhcp_type_host) {
! 1375: omapi_object_dereference (lp, MDL);
! 1376: return ISC_R_INVALIDARG;
! 1377: }
! 1378: if (((struct host_decl *)(*lp)) -> flags & HOST_DECL_DELETED) {
! 1379: omapi_object_dereference (lp, MDL);
! 1380: }
! 1381: }
! 1382:
! 1383: /* Now look for a client identifier. */
! 1384: status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
! 1385: if (status == ISC_R_SUCCESS) {
! 1386: host = (struct host_decl *)0;
! 1387: host_hash_lookup (&host, host_uid_hash,
! 1388: tv -> value -> u.buffer.value,
! 1389: tv -> value -> u.buffer.len, MDL);
! 1390: omapi_value_dereference (&tv, MDL);
! 1391:
! 1392: if (*lp && *lp != (omapi_object_t *)host) {
! 1393: omapi_object_dereference (lp, MDL);
! 1394: if (host)
! 1395: host_dereference (&host, MDL);
! 1396: return ISC_R_KEYCONFLICT;
! 1397: } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
! 1398: if (*lp)
! 1399: omapi_object_dereference (lp, MDL);
! 1400: if (host)
! 1401: host_dereference (&host, MDL);
! 1402: return ISC_R_NOTFOUND;
! 1403: } else if (!*lp) {
! 1404: /* XXX fix so that hash lookup itself creates
! 1405: XXX the reference. */
! 1406: omapi_object_reference (lp,
! 1407: (omapi_object_t *)host, MDL);
! 1408: host_dereference (&host, MDL);
! 1409: }
! 1410: }
! 1411:
! 1412: /* Now look for a hardware address. */
! 1413: status = omapi_get_value_str (ref, id, "hardware-address", &tv);
! 1414: if (status == ISC_R_SUCCESS) {
! 1415: unsigned char *haddr;
! 1416: unsigned int len;
! 1417:
! 1418: len = tv -> value -> u.buffer.len + 1;
! 1419: haddr = dmalloc (len, MDL);
! 1420: if (!haddr) {
! 1421: omapi_value_dereference (&tv, MDL);
! 1422: return ISC_R_NOMEMORY;
! 1423: }
! 1424:
! 1425: memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
! 1426: omapi_value_dereference (&tv, MDL);
! 1427:
! 1428: status = omapi_get_value_str (ref, id, "hardware-type", &tv);
! 1429: if (status == ISC_R_SUCCESS) {
! 1430: if (tv -> value -> type == omapi_datatype_data) {
! 1431: if ((tv -> value -> u.buffer.len != 4) ||
! 1432: (tv -> value -> u.buffer.value[0] != 0) ||
! 1433: (tv -> value -> u.buffer.value[1] != 0) ||
! 1434: (tv -> value -> u.buffer.value[2] != 0)) {
! 1435: omapi_value_dereference (&tv, MDL);
! 1436: dfree (haddr, MDL);
! 1437: return ISC_R_INVALIDARG;
! 1438: }
! 1439:
! 1440: haddr[0] = tv -> value -> u.buffer.value[3];
! 1441: } else if (tv -> value -> type == omapi_datatype_int) {
! 1442: haddr[0] = (unsigned char)
! 1443: tv -> value -> u.integer;
! 1444: } else {
! 1445: omapi_value_dereference (&tv, MDL);
! 1446: dfree (haddr, MDL);
! 1447: return ISC_R_INVALIDARG;
! 1448: }
! 1449:
! 1450: omapi_value_dereference (&tv, MDL);
! 1451: } else {
! 1452: /* If no hardware-type is specified, default to
! 1453: ethernet. This may or may not be a good idea,
! 1454: but Telus is currently relying on this behavior.
! 1455: - DPN */
! 1456: haddr[0] = HTYPE_ETHER;
! 1457: }
! 1458:
! 1459: host = (struct host_decl *)0;
! 1460: host_hash_lookup (&host, host_hw_addr_hash, haddr, len, MDL);
! 1461: dfree (haddr, MDL);
! 1462:
! 1463: if (*lp && *lp != (omapi_object_t *)host) {
! 1464: omapi_object_dereference (lp, MDL);
! 1465: if (host)
! 1466: host_dereference (&host, MDL);
! 1467: return ISC_R_KEYCONFLICT;
! 1468: } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
! 1469: if (*lp)
! 1470: omapi_object_dereference (lp, MDL);
! 1471: if (host)
! 1472: host_dereference (&host, MDL);
! 1473: return ISC_R_NOTFOUND;
! 1474: } else if (!*lp) {
! 1475: /* XXX fix so that hash lookup itself creates
! 1476: XXX the reference. */
! 1477: omapi_object_reference (lp,
! 1478: (omapi_object_t *)host, MDL);
! 1479: host_dereference (&host, MDL);
! 1480: }
! 1481: }
! 1482:
! 1483: /* Now look for an ip address. */
! 1484: status = omapi_get_value_str (ref, id, "ip-address", &tv);
! 1485: if (status == ISC_R_SUCCESS) {
! 1486: struct lease *l;
! 1487:
! 1488: /* first find the lease for this ip address */
! 1489: l = (struct lease *)0;
! 1490: lease_ip_hash_lookup(&l, lease_ip_addr_hash,
! 1491: tv->value->u.buffer.value,
! 1492: tv->value->u.buffer.len, MDL);
! 1493: omapi_value_dereference (&tv, MDL);
! 1494:
! 1495: if (!l && !*lp)
! 1496: return ISC_R_NOTFOUND;
! 1497:
! 1498: if (l) {
! 1499: /* now use that to get a host */
! 1500: host = (struct host_decl *)0;
! 1501: host_hash_lookup (&host, host_hw_addr_hash,
! 1502: l -> hardware_addr.hbuf,
! 1503: l -> hardware_addr.hlen, MDL);
! 1504:
! 1505: if (host && *lp && *lp != (omapi_object_t *)host) {
! 1506: omapi_object_dereference (lp, MDL);
! 1507: if (host)
! 1508: host_dereference (&host, MDL);
! 1509: return ISC_R_KEYCONFLICT;
! 1510: } else if (!host || (host -> flags &
! 1511: HOST_DECL_DELETED)) {
! 1512: if (host)
! 1513: host_dereference (&host, MDL);
! 1514: if (!*lp)
! 1515: return ISC_R_NOTFOUND;
! 1516: } else if (!*lp) {
! 1517: /* XXX fix so that hash lookup itself creates
! 1518: XXX the reference. */
! 1519: omapi_object_reference (lp, (omapi_object_t *)host,
! 1520: MDL);
! 1521: host_dereference (&host, MDL);
! 1522: }
! 1523: lease_dereference (&l, MDL);
! 1524: }
! 1525: }
! 1526:
! 1527: /* Now look for a name. */
! 1528: status = omapi_get_value_str (ref, id, "name", &tv);
! 1529: if (status == ISC_R_SUCCESS) {
! 1530: host = (struct host_decl *)0;
! 1531: host_hash_lookup (&host, host_name_hash,
! 1532: tv -> value -> u.buffer.value,
! 1533: tv -> value -> u.buffer.len, MDL);
! 1534: omapi_value_dereference (&tv, MDL);
! 1535:
! 1536: if (*lp && *lp != (omapi_object_t *)host) {
! 1537: omapi_object_dereference (lp, MDL);
! 1538: if (host)
! 1539: host_dereference (&host, MDL);
! 1540: return ISC_R_KEYCONFLICT;
! 1541: } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
! 1542: if (host)
! 1543: host_dereference (&host, MDL);
! 1544: return ISC_R_NOTFOUND;
! 1545: } else if (!*lp) {
! 1546: /* XXX fix so that hash lookup itself creates
! 1547: XXX the reference. */
! 1548: omapi_object_reference (lp,
! 1549: (omapi_object_t *)host, MDL);
! 1550: host_dereference (&host, MDL);
! 1551: }
! 1552: }
! 1553:
! 1554: /* If we get to here without finding a host, no valid key was
! 1555: specified. */
! 1556: if (!*lp)
! 1557: return ISC_R_NOKEYS;
! 1558: return ISC_R_SUCCESS;
! 1559: }
! 1560:
! 1561: isc_result_t dhcp_host_create (omapi_object_t **lp,
! 1562: omapi_object_t *id)
! 1563: {
! 1564: struct host_decl *hp;
! 1565: isc_result_t status;
! 1566: hp = (struct host_decl *)0;
! 1567: status = host_allocate (&hp, MDL);
! 1568: if (status != ISC_R_SUCCESS)
! 1569: return status;
! 1570: group_reference (&hp -> group, root_group, MDL);
! 1571: hp -> flags = HOST_DECL_DYNAMIC;
! 1572: status = omapi_object_reference (lp, (omapi_object_t *)hp, MDL);
! 1573: host_dereference (&hp, MDL);
! 1574: return status;
! 1575: }
! 1576:
! 1577: isc_result_t dhcp_host_remove (omapi_object_t *lp,
! 1578: omapi_object_t *id)
! 1579: {
! 1580: struct host_decl *hp;
! 1581: if (lp -> type != dhcp_type_host)
! 1582: return ISC_R_INVALIDARG;
! 1583: hp = (struct host_decl *)lp;
! 1584:
! 1585: #ifdef DEBUG_OMAPI
! 1586: log_debug ("OMAPI delete host %s", hp -> name);
! 1587: #endif
! 1588: delete_host (hp, 1);
! 1589: return ISC_R_SUCCESS;
! 1590: }
! 1591:
! 1592: isc_result_t dhcp_pool_set_value (omapi_object_t *h,
! 1593: omapi_object_t *id,
! 1594: omapi_data_string_t *name,
! 1595: omapi_typed_data_t *value)
! 1596: {
! 1597: struct pool *pool;
! 1598: isc_result_t status;
! 1599:
! 1600: if (h -> type != dhcp_type_pool)
! 1601: return ISC_R_INVALIDARG;
! 1602: pool = (struct pool *)h;
! 1603:
! 1604: /* No values to set yet. */
! 1605:
! 1606: /* Try to find some inner object that can take the value. */
! 1607: if (h -> inner && h -> inner -> type -> set_value) {
! 1608: status = ((*(h -> inner -> type -> set_value))
! 1609: (h -> inner, id, name, value));
! 1610: if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
! 1611: return status;
! 1612: }
! 1613:
! 1614: return ISC_R_UNKNOWNATTRIBUTE;
! 1615: }
! 1616:
! 1617:
! 1618: isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id,
! 1619: omapi_data_string_t *name,
! 1620: omapi_value_t **value)
! 1621: {
! 1622: struct pool *pool;
! 1623: isc_result_t status;
! 1624:
! 1625: if (h -> type != dhcp_type_pool)
! 1626: return ISC_R_INVALIDARG;
! 1627: pool = (struct pool *)h;
! 1628:
! 1629: /* No values to get yet. */
! 1630:
! 1631: /* Try to find some inner object that can provide the value. */
! 1632: if (h -> inner && h -> inner -> type -> get_value) {
! 1633: status = ((*(h -> inner -> type -> get_value))
! 1634: (h -> inner, id, name, value));
! 1635: if (status == ISC_R_SUCCESS)
! 1636: return status;
! 1637: }
! 1638: return ISC_R_UNKNOWNATTRIBUTE;
! 1639: }
! 1640:
! 1641: isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line)
! 1642: {
! 1643: struct pool *pool;
! 1644: #if defined (DEBUG_MEMORY_LEAKAGE) || \
! 1645: defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
! 1646: struct permit *pc, *pn;
! 1647: #endif
! 1648:
! 1649: if (h -> type != dhcp_type_pool)
! 1650: return ISC_R_INVALIDARG;
! 1651: pool = (struct pool *)h;
! 1652:
! 1653: #if defined (DEBUG_MEMORY_LEAKAGE) || \
! 1654: defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
! 1655: if (pool -> next)
! 1656: pool_dereference (&pool -> next, file, line);
! 1657: if (pool -> group)
! 1658: group_dereference (&pool -> group, file, line);
! 1659: if (pool -> shared_network)
! 1660: shared_network_dereference (&pool -> shared_network, file, line);
! 1661: if (pool -> active)
! 1662: lease_dereference (&pool -> active, file, line);
! 1663: if (pool -> expired)
! 1664: lease_dereference (&pool -> expired, file, line);
! 1665: if (pool -> free)
! 1666: lease_dereference (&pool -> free, file, line);
! 1667: if (pool -> backup)
! 1668: lease_dereference (&pool -> backup, file, line);
! 1669: if (pool -> abandoned)
! 1670: lease_dereference (&pool -> abandoned, file, line);
! 1671: #if defined (FAILOVER_PROTOCOL)
! 1672: if (pool -> failover_peer)
! 1673: dhcp_failover_state_dereference (&pool -> failover_peer,
! 1674: file, line);
! 1675: #endif
! 1676: for (pc = pool -> permit_list; pc; pc = pn) {
! 1677: pn = pc -> next;
! 1678: free_permit (pc, file, line);
! 1679: }
! 1680: pool -> permit_list = (struct permit *)0;
! 1681:
! 1682: for (pc = pool -> prohibit_list; pc; pc = pn) {
! 1683: pn = pc -> next;
! 1684: free_permit (pc, file, line);
! 1685: }
! 1686: pool -> prohibit_list = (struct permit *)0;
! 1687: #endif
! 1688:
! 1689: return ISC_R_SUCCESS;
! 1690: }
! 1691:
! 1692: isc_result_t dhcp_pool_signal_handler (omapi_object_t *h,
! 1693: const char *name, va_list ap)
! 1694: {
! 1695: struct pool *pool;
! 1696: isc_result_t status;
! 1697: int updatep = 0;
! 1698:
! 1699: if (h -> type != dhcp_type_pool)
! 1700: return ISC_R_INVALIDARG;
! 1701: pool = (struct pool *)h;
! 1702:
! 1703: /* Can't write pools yet. */
! 1704:
! 1705: /* Try to find some inner object that can take the value. */
! 1706: if (h -> inner && h -> inner -> type -> signal_handler) {
! 1707: status = ((*(h -> inner -> type -> signal_handler))
! 1708: (h -> inner, name, ap));
! 1709: if (status == ISC_R_SUCCESS)
! 1710: return status;
! 1711: }
! 1712: if (updatep)
! 1713: return ISC_R_SUCCESS;
! 1714: return ISC_R_NOTFOUND;
! 1715: }
! 1716:
! 1717: isc_result_t dhcp_pool_stuff_values (omapi_object_t *c,
! 1718: omapi_object_t *id,
! 1719: omapi_object_t *h)
! 1720: {
! 1721: struct pool *pool;
! 1722: isc_result_t status;
! 1723:
! 1724: if (h -> type != dhcp_type_pool)
! 1725: return ISC_R_INVALIDARG;
! 1726: pool = (struct pool *)h;
! 1727:
! 1728: /* Can't stuff pool values yet. */
! 1729:
! 1730: /* Write out the inner object, if any. */
! 1731: if (h -> inner && h -> inner -> type -> stuff_values) {
! 1732: status = ((*(h -> inner -> type -> stuff_values))
! 1733: (c, id, h -> inner));
! 1734: if (status == ISC_R_SUCCESS)
! 1735: return status;
! 1736: }
! 1737:
! 1738: return ISC_R_SUCCESS;
! 1739: }
! 1740:
! 1741: isc_result_t dhcp_pool_lookup (omapi_object_t **lp,
! 1742: omapi_object_t *id, omapi_object_t *ref)
! 1743: {
! 1744: /* Can't look up pools yet. */
! 1745:
! 1746: /* If we get to here without finding a pool, no valid key was
! 1747: specified. */
! 1748: if (!*lp)
! 1749: return ISC_R_NOKEYS;
! 1750: return ISC_R_SUCCESS;
! 1751: }
! 1752:
! 1753: isc_result_t dhcp_pool_create (omapi_object_t **lp,
! 1754: omapi_object_t *id)
! 1755: {
! 1756: return ISC_R_NOTIMPLEMENTED;
! 1757: }
! 1758:
! 1759: isc_result_t dhcp_pool_remove (omapi_object_t *lp,
! 1760: omapi_object_t *id)
! 1761: {
! 1762: return ISC_R_NOTIMPLEMENTED;
! 1763: }
! 1764:
! 1765: static isc_result_t
! 1766: class_set_value (omapi_object_t *h,
! 1767: omapi_object_t *id,
! 1768: omapi_data_string_t *name,
! 1769: omapi_typed_data_t *value)
! 1770: {
! 1771: struct class *class;
! 1772: struct class *superclass = 0;
! 1773: isc_result_t status;
! 1774: int issubclass = (h -> type == dhcp_type_subclass);
! 1775:
! 1776: class = (struct class *)h;
! 1777:
! 1778: if (!omapi_ds_strcmp(name, "name")) {
! 1779: char *tname;
! 1780:
! 1781: if (class->name)
! 1782: return ISC_R_EXISTS;
! 1783:
! 1784: if ((tname = dmalloc(value->u.buffer.len + 1, MDL)) == NULL) {
! 1785: return ISC_R_NOMEMORY;
! 1786: }
! 1787:
! 1788: /* tname is null terminated from dmalloc() */
! 1789: memcpy(tname, value->u.buffer.value, value->u.buffer.len);
! 1790:
! 1791: if (issubclass) {
! 1792: status = find_class(&superclass, tname, MDL);
! 1793: dfree(tname, MDL);
! 1794:
! 1795: if (status == ISC_R_NOTFOUND)
! 1796: return status;
! 1797:
! 1798: if (class->superclass != NULL)
! 1799: class_dereference(&class->superclass, MDL);
! 1800:
! 1801: class_reference(&class->superclass, superclass, MDL);
! 1802: } else if (value -> type == omapi_datatype_data ||
! 1803: value -> type == omapi_datatype_string) {
! 1804: class->name = dmalloc(value->u.buffer.len + 1, MDL);
! 1805: if (!class->name)
! 1806: return ISC_R_NOMEMORY;
! 1807:
! 1808: /* class->name is null-terminated from dmalloc() */
! 1809: memcpy(class->name, value->u.buffer.value,
! 1810: value->u.buffer.len);
! 1811: } else
! 1812: return ISC_R_INVALIDARG;
! 1813:
! 1814: return ISC_R_SUCCESS;
! 1815: }
! 1816:
! 1817:
! 1818: if (issubclass && !omapi_ds_strcmp(name, "hashstring")) {
! 1819: if (class->hash_string.data)
! 1820: return ISC_R_EXISTS;
! 1821:
! 1822: if (value->type == omapi_datatype_data ||
! 1823: value->type == omapi_datatype_string) {
! 1824: if (!buffer_allocate(&class->hash_string.buffer,
! 1825: value->u.buffer.len, MDL))
! 1826: return ISC_R_NOMEMORY;
! 1827: class->hash_string.data =
! 1828: class->hash_string.buffer->data;
! 1829: memcpy(class->hash_string.buffer->data,
! 1830: value->u.buffer.value, value->u.buffer.len);
! 1831: class->hash_string.len = value->u.buffer.len;
! 1832: } else
! 1833: return ISC_R_INVALIDARG;
! 1834:
! 1835: return ISC_R_SUCCESS;
! 1836: }
! 1837:
! 1838: if (!omapi_ds_strcmp(name, "group")) {
! 1839: if (value->type == omapi_datatype_data ||
! 1840: value->type == omapi_datatype_string) {
! 1841: struct group_object *group = NULL;
! 1842:
! 1843: group_hash_lookup(&group, group_name_hash,
! 1844: (char *)value->u.buffer.value,
! 1845: value->u.buffer.len, MDL);
! 1846: if (!group || (group->flags & GROUP_OBJECT_DELETED))
! 1847: return ISC_R_NOTFOUND;
! 1848: if (class->group)
! 1849: group_dereference(&class->group, MDL);
! 1850: group_reference(&class->group, group->group, MDL);
! 1851: group_object_dereference(&group, MDL);
! 1852: } else
! 1853: return ISC_R_INVALIDARG;
! 1854:
! 1855: return ISC_R_SUCCESS;
! 1856: }
! 1857:
! 1858:
! 1859: /* note we do not support full expressions via omapi because the
! 1860: expressions parser needs to be re-done to support parsing from
! 1861: strings and not just files. */
! 1862:
! 1863: if (!omapi_ds_strcmp(name, "match")) {
! 1864: if (value->type == omapi_datatype_data ||
! 1865: value->type == omapi_datatype_string) {
! 1866: unsigned minlen = (value->u.buffer.len > 8 ?
! 1867: 8 : value->u.buffer.len);
! 1868:
! 1869: if (!strncmp("hardware",
! 1870: (char *)value->u.buffer.value, minlen))
! 1871: {
! 1872: if (!expression_allocate(&class->submatch, MDL))
! 1873: return ISC_R_NOMEMORY;
! 1874:
! 1875: class->submatch->op = expr_hardware;
! 1876: } else
! 1877: return ISC_R_INVALIDARG;
! 1878: } else
! 1879: return ISC_R_INVALIDARG;
! 1880:
! 1881: return ISC_R_SUCCESS;
! 1882: }
! 1883:
! 1884:
! 1885: if (!omapi_ds_strcmp(name, "option")) {
! 1886: if (value->type == omapi_datatype_data ||
! 1887: value->type == omapi_datatype_string) {
! 1888: /* XXXJAB support 'options' here. */
! 1889: /* XXXJAB specifically 'bootfile-name' */
! 1890: return ISC_R_INVALIDARG; /* XXX tmp */
! 1891: } else
! 1892: return ISC_R_INVALIDARG;
! 1893:
! 1894: /*
! 1895: * Currently no way to get here, if we update the above
! 1896: * code so that we do get here this return needs to be
! 1897: * uncommented.
! 1898: * return ISC_R_SUCCESS;
! 1899: */
! 1900: }
! 1901:
! 1902:
! 1903: /* Try to find some inner object that can take the value. */
! 1904: if (h->inner && h->inner->type->set_value) {
! 1905: status = ((*(h->inner->type->set_value))
! 1906: (h->inner, id, name, value));
! 1907: if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
! 1908: return status;
! 1909: }
! 1910:
! 1911: return ISC_R_UNKNOWNATTRIBUTE;
! 1912: }
! 1913:
! 1914:
! 1915:
! 1916: isc_result_t dhcp_class_set_value (omapi_object_t *h,
! 1917: omapi_object_t *id,
! 1918: omapi_data_string_t *name,
! 1919: omapi_typed_data_t *value)
! 1920: {
! 1921: if (h -> type != dhcp_type_class)
! 1922: return ISC_R_INVALIDARG;
! 1923:
! 1924: return class_set_value(h, id, name, value);
! 1925: }
! 1926:
! 1927: isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id,
! 1928: omapi_data_string_t *name,
! 1929: omapi_value_t **value)
! 1930: {
! 1931: struct class *class;
! 1932: isc_result_t status;
! 1933:
! 1934: if (h -> type != dhcp_type_class)
! 1935: return ISC_R_INVALIDARG;
! 1936: class = (struct class *)h;
! 1937:
! 1938: if (!omapi_ds_strcmp (name, "name"))
! 1939: return omapi_make_string_value (value, name, class -> name,
! 1940: MDL);
! 1941:
! 1942: /* Try to find some inner object that can provide the value. */
! 1943: if (h -> inner && h -> inner -> type -> get_value) {
! 1944: status = ((*(h -> inner -> type -> get_value))
! 1945: (h -> inner, id, name, value));
! 1946: if (status == ISC_R_SUCCESS)
! 1947: return status;
! 1948: }
! 1949: return ISC_R_UNKNOWNATTRIBUTE;
! 1950: }
! 1951:
! 1952: isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
! 1953: {
! 1954: struct class *class;
! 1955:
! 1956: if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass)
! 1957: return ISC_R_INVALIDARG;
! 1958: class = (struct class *)h;
! 1959:
! 1960: #if defined (DEBUG_MEMORY_LEAKAGE) || \
! 1961: defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
! 1962: if (class -> nic)
! 1963: class_dereference (&class -> nic, file, line);
! 1964: if (class -> superclass)
! 1965: class_dereference (&class -> superclass, file, line);
! 1966: if (class -> name) {
! 1967: dfree (class -> name, file, line);
! 1968: class -> name = (char *)0;
! 1969: }
! 1970: if (class -> billed_leases) {
! 1971: int i;
! 1972: for (i = 0; i < class -> lease_limit; i++) {
! 1973: if (class -> billed_leases [i]) {
! 1974: lease_dereference (&class -> billed_leases [i],
! 1975: file, line);
! 1976: }
! 1977: }
! 1978: dfree (class -> billed_leases, file, line);
! 1979: class -> billed_leases = (struct lease **)0;
! 1980: }
! 1981: if (class -> hash) {
! 1982: class_free_hash_table (&class -> hash, file, line);
! 1983: class -> hash = (class_hash_t *)0;
! 1984: }
! 1985: data_string_forget (&class -> hash_string, file, line);
! 1986:
! 1987: if (class -> expr)
! 1988: expression_dereference (&class -> expr, file, line);
! 1989: if (class -> submatch)
! 1990: expression_dereference (&class -> submatch, file, line);
! 1991: if (class -> group)
! 1992: group_dereference (&class -> group, file, line);
! 1993: if (class -> statements)
! 1994: executable_statement_dereference (&class -> statements,
! 1995: file, line);
! 1996: if (class -> superclass)
! 1997: class_dereference (&class -> superclass, file, line);
! 1998: #endif
! 1999:
! 2000: return ISC_R_SUCCESS;
! 2001: }
! 2002:
! 2003: static isc_result_t
! 2004: class_signal_handler(omapi_object_t *h,
! 2005: const char *name, va_list ap)
! 2006: {
! 2007: struct class *class = (struct class *)h;
! 2008: isc_result_t status;
! 2009: int updatep = 0;
! 2010: int issubclass;
! 2011:
! 2012: issubclass = (h -> type == dhcp_type_subclass);
! 2013:
! 2014: if (!strcmp (name, "updated")) {
! 2015:
! 2016: if (!issubclass) {
! 2017: if (class -> name == 0 || strlen(class -> name) == 0) {
! 2018: return ISC_R_INVALIDARG;
! 2019: }
! 2020: } else {
! 2021: if (class -> superclass == 0) {
! 2022: return ISC_R_INVALIDARG; /* didn't give name */
! 2023: }
! 2024:
! 2025: if (class -> hash_string.data == NULL) {
! 2026: return ISC_R_INVALIDARG;
! 2027: }
! 2028: }
! 2029:
! 2030:
! 2031: if (issubclass) {
! 2032: if (!class -> superclass -> hash)
! 2033: class_new_hash(&class->superclass->hash,
! 2034: SCLASS_HASH_SIZE, MDL);
! 2035:
! 2036: add_hash (class -> superclass -> hash,
! 2037: class -> hash_string.data,
! 2038: class -> hash_string.len,
! 2039: (void *)class, MDL);
! 2040: }
! 2041:
! 2042:
! 2043: #ifdef DEBUG_OMAPI
! 2044: if (issubclass) {
! 2045: log_debug ("OMAPI added subclass %s",
! 2046: class -> superclass -> name);
! 2047: } else {
! 2048: log_debug ("OMAPI added class %s", class -> name);
! 2049: }
! 2050: #endif
! 2051:
! 2052: status = enter_class (class, 1, 1);
! 2053: if (status != ISC_R_SUCCESS)
! 2054: return status;
! 2055: updatep = 1;
! 2056: }
! 2057:
! 2058: /* Try to find some inner object that can take the value. */
! 2059: if (h -> inner && h -> inner -> type -> signal_handler) {
! 2060: status = ((*(h -> inner -> type -> signal_handler))
! 2061: (h -> inner, name, ap));
! 2062: if (status == ISC_R_SUCCESS)
! 2063: return status;
! 2064: }
! 2065:
! 2066: if (updatep)
! 2067: return ISC_R_SUCCESS;
! 2068:
! 2069: return ISC_R_NOTFOUND;
! 2070: }
! 2071:
! 2072:
! 2073: isc_result_t dhcp_class_signal_handler (omapi_object_t *h,
! 2074: const char *name, va_list ap)
! 2075: {
! 2076: if (h -> type != dhcp_type_class)
! 2077: return ISC_R_INVALIDARG;
! 2078:
! 2079: return class_signal_handler(h, name, ap);
! 2080: }
! 2081:
! 2082: isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
! 2083: omapi_object_t *id,
! 2084: omapi_object_t *h)
! 2085: {
! 2086: struct class *class;
! 2087: isc_result_t status;
! 2088:
! 2089: if (h -> type != dhcp_type_class)
! 2090: return ISC_R_INVALIDARG;
! 2091: class = (struct class *)h;
! 2092:
! 2093: /* Can't stuff class values yet. */
! 2094:
! 2095: /* Write out the inner object, if any. */
! 2096: if (h -> inner && h -> inner -> type -> stuff_values) {
! 2097: status = ((*(h -> inner -> type -> stuff_values))
! 2098: (c, id, h -> inner));
! 2099: if (status == ISC_R_SUCCESS)
! 2100: return status;
! 2101: }
! 2102:
! 2103: return ISC_R_SUCCESS;
! 2104: }
! 2105:
! 2106: static isc_result_t class_lookup (omapi_object_t **lp,
! 2107: omapi_object_t *id, omapi_object_t *ref,
! 2108: omapi_object_type_t *typewanted)
! 2109: {
! 2110: omapi_value_t *nv = (omapi_value_t *)0;
! 2111: omapi_value_t *hv = (omapi_value_t *)0;
! 2112: isc_result_t status;
! 2113: struct class *class = 0;
! 2114: struct class *subclass = 0;
! 2115:
! 2116: *lp = NULL;
! 2117:
! 2118: /* see if we have a name */
! 2119: status = omapi_get_value_str (ref, id, "name", &nv);
! 2120: if (status == ISC_R_SUCCESS) {
! 2121: char *name = dmalloc(nv -> value -> u.buffer.len + 1, MDL);
! 2122: memcpy (name,
! 2123: nv -> value -> u.buffer.value,
! 2124: nv -> value -> u.buffer.len);
! 2125:
! 2126: omapi_value_dereference (&nv, MDL);
! 2127:
! 2128: find_class(&class, name, MDL);
! 2129:
! 2130: dfree(name, MDL);
! 2131:
! 2132: if (class == NULL) {
! 2133: return ISC_R_NOTFOUND;
! 2134: }
! 2135:
! 2136: if (typewanted == dhcp_type_subclass) {
! 2137: status = omapi_get_value_str (ref, id,
! 2138: "hashstring", &hv);
! 2139: if (status != ISC_R_SUCCESS) {
! 2140: class_dereference(&class, MDL);
! 2141: return ISC_R_NOKEYS;
! 2142: }
! 2143:
! 2144: if (hv -> value -> type != omapi_datatype_data &&
! 2145: hv -> value -> type != omapi_datatype_string) {
! 2146: class_dereference(&class, MDL);
! 2147: omapi_value_dereference (&hv, MDL);
! 2148: return ISC_R_NOKEYS;
! 2149: }
! 2150:
! 2151: class_hash_lookup (&subclass, class -> hash,
! 2152: (const char *)
! 2153: hv -> value -> u.buffer.value,
! 2154: hv -> value -> u.buffer.len, MDL);
! 2155:
! 2156: omapi_value_dereference (&hv, MDL);
! 2157:
! 2158: class_dereference(&class, MDL);
! 2159:
! 2160: if (subclass == NULL) {
! 2161: return ISC_R_NOTFOUND;
! 2162: }
! 2163:
! 2164: class_reference(&class, subclass, MDL);
! 2165: class_dereference(&subclass, MDL);
! 2166: }
! 2167:
! 2168:
! 2169: /* Don't return the object if the type is wrong. */
! 2170: if (class -> type != typewanted) {
! 2171: class_dereference (&class, MDL);
! 2172: return ISC_R_INVALIDARG;
! 2173: }
! 2174:
! 2175: if (class -> flags & CLASS_DECL_DELETED) {
! 2176: class_dereference (&class, MDL);
! 2177: }
! 2178:
! 2179: omapi_object_reference(lp, (omapi_object_t *)class, MDL);
! 2180:
! 2181: return ISC_R_SUCCESS;
! 2182: }
! 2183:
! 2184: return ISC_R_NOKEYS;
! 2185: }
! 2186:
! 2187:
! 2188: isc_result_t dhcp_class_lookup (omapi_object_t **lp,
! 2189: omapi_object_t *id, omapi_object_t *ref)
! 2190: {
! 2191: return class_lookup(lp, id, ref, dhcp_type_class);
! 2192: }
! 2193:
! 2194: isc_result_t dhcp_class_create (omapi_object_t **lp,
! 2195: omapi_object_t *id)
! 2196: {
! 2197: struct class *cp = 0;
! 2198: isc_result_t status;
! 2199:
! 2200: status = class_allocate(&cp, MDL);
! 2201: if (status != ISC_R_SUCCESS)
! 2202: return status;
! 2203:
! 2204: group_reference (&cp -> group, root_group, MDL);
! 2205: cp -> flags = CLASS_DECL_DYNAMIC;
! 2206: status = omapi_object_reference (lp, (omapi_object_t *)cp, MDL);
! 2207: class_dereference (&cp, MDL);
! 2208: return status;
! 2209: }
! 2210:
! 2211: isc_result_t dhcp_class_remove (omapi_object_t *lp,
! 2212: omapi_object_t *id)
! 2213: {
! 2214: struct class *cp;
! 2215: if (lp -> type != dhcp_type_class)
! 2216: return ISC_R_INVALIDARG;
! 2217: cp = (struct class *)lp;
! 2218:
! 2219: #ifdef DEBUG_OMAPI
! 2220: log_debug ("OMAPI delete class %s", cp -> name);
! 2221: #endif
! 2222:
! 2223: delete_class (cp, 1);
! 2224: return ISC_R_SUCCESS;
! 2225: }
! 2226:
! 2227: isc_result_t dhcp_subclass_set_value (omapi_object_t *h,
! 2228: omapi_object_t *id,
! 2229: omapi_data_string_t *name,
! 2230: omapi_typed_data_t *value)
! 2231: {
! 2232: if (h -> type != dhcp_type_subclass)
! 2233: return ISC_R_INVALIDARG;
! 2234:
! 2235: return class_set_value(h, id, name, value);
! 2236: }
! 2237:
! 2238:
! 2239: isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id,
! 2240: omapi_data_string_t *name,
! 2241: omapi_value_t **value)
! 2242: {
! 2243: struct class *subclass;
! 2244: isc_result_t status;
! 2245:
! 2246: if (h -> type != dhcp_type_class)
! 2247: return ISC_R_INVALIDARG;
! 2248: subclass = (struct class *)h;
! 2249: if (subclass -> name != 0)
! 2250: return ISC_R_INVALIDARG;
! 2251:
! 2252: /* XXXJAB No values to get yet. */
! 2253:
! 2254: /* Try to find some inner object that can provide the value. */
! 2255: if (h -> inner && h -> inner -> type -> get_value) {
! 2256: status = ((*(h -> inner -> type -> get_value))
! 2257: (h -> inner, id, name, value));
! 2258: if (status == ISC_R_SUCCESS)
! 2259: return status;
! 2260: }
! 2261: return ISC_R_UNKNOWNATTRIBUTE;
! 2262: }
! 2263:
! 2264: isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h,
! 2265: const char *name, va_list ap)
! 2266: {
! 2267: if (h -> type != dhcp_type_subclass)
! 2268: return ISC_R_INVALIDARG;
! 2269:
! 2270: return class_signal_handler(h, name, ap);
! 2271: }
! 2272:
! 2273:
! 2274: isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c,
! 2275: omapi_object_t *id,
! 2276: omapi_object_t *h)
! 2277: {
! 2278: struct class *subclass;
! 2279: isc_result_t status;
! 2280:
! 2281: if (h -> type != dhcp_type_class)
! 2282: return ISC_R_INVALIDARG;
! 2283: subclass = (struct class *)h;
! 2284: if (subclass -> name != 0)
! 2285: return ISC_R_INVALIDARG;
! 2286:
! 2287:
! 2288: /* Can't stuff subclass values yet. */
! 2289:
! 2290: /* Write out the inner object, if any. */
! 2291: if (h -> inner && h -> inner -> type -> stuff_values) {
! 2292: status = ((*(h -> inner -> type -> stuff_values))
! 2293: (c, id, h -> inner));
! 2294: if (status == ISC_R_SUCCESS)
! 2295: return status;
! 2296: }
! 2297:
! 2298: return ISC_R_SUCCESS;
! 2299: }
! 2300:
! 2301: isc_result_t dhcp_subclass_lookup (omapi_object_t **lp,
! 2302: omapi_object_t *id, omapi_object_t *ref)
! 2303: {
! 2304: return class_lookup(lp, id, ref, dhcp_type_subclass);
! 2305: }
! 2306:
! 2307:
! 2308:
! 2309:
! 2310: isc_result_t dhcp_subclass_create (omapi_object_t **lp,
! 2311: omapi_object_t *id)
! 2312: {
! 2313: struct class *cp = 0;
! 2314: isc_result_t status;
! 2315:
! 2316: /*
! 2317: * XXX
! 2318: * NOTE: subclasses and classes have the same internal type, which makes it
! 2319: * difficult to tell them apart. Specifically, in this function we need to
! 2320: * create a class object (because there is no such thing as a subclass
! 2321: * object), but one field of the class object is the type (which has the
! 2322: * value dhcp_type_class), and it is from here that all the other omapi
! 2323: * functions are accessed. So, even though there's a whole suite of
! 2324: * subclass functions registered, they won't get used. Now we could change
! 2325: * the type pointer after creating the class object, but I'm not certain
! 2326: * that won't break something else.
! 2327: */
! 2328:
! 2329: status = subclass_allocate(&cp, MDL);
! 2330: if (status != ISC_R_SUCCESS)
! 2331: return status;
! 2332: group_reference (&cp -> group, root_group, MDL);
! 2333:
! 2334: cp -> flags = CLASS_DECL_DYNAMIC;
! 2335:
! 2336: status = omapi_object_reference (lp, (omapi_object_t *)cp, MDL);
! 2337: subclass_dereference (&cp, MDL);
! 2338: return status;
! 2339: }
! 2340:
! 2341: isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
! 2342: omapi_object_t *id)
! 2343: {
! 2344: #if 1
! 2345:
! 2346: log_fatal("calling dhcp_subclass_set_value");
! 2347: /* this should never be called see dhcp_subclass_create for why */
! 2348:
! 2349: #else
! 2350:
! 2351: struct class *cp;
! 2352: if (lp -> type != dhcp_type_subclass)
! 2353: return ISC_R_INVALIDARG;
! 2354: cp = (struct class *)lp;
! 2355:
! 2356: #ifdef DEBUG_OMAPI
! 2357: log_debug ("OMAPI delete subclass %s", cp -> name);
! 2358: #endif
! 2359:
! 2360: delete_class (cp, 1);
! 2361:
! 2362: #endif
! 2363:
! 2364: return ISC_R_SUCCESS;
! 2365: }
! 2366:
! 2367: isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp,
! 2368: omapi_data_string_t *name,
! 2369: omapi_typed_data_t *value)
! 2370: {
! 2371: struct binding *bp;
! 2372: char *nname;
! 2373: struct binding_value *nv;
! 2374: nname = dmalloc (name -> len + 1, MDL);
! 2375: if (!nname)
! 2376: return ISC_R_NOMEMORY;
! 2377: memcpy (nname, name -> value, name -> len);
! 2378: nname [name -> len] = 0;
! 2379: bp = find_binding (scope, nname);
! 2380: if (!bp && !createp) {
! 2381: dfree (nname, MDL);
! 2382: return ISC_R_UNKNOWNATTRIBUTE;
! 2383: }
! 2384: if (!value) {
! 2385: dfree (nname, MDL);
! 2386: if (!bp)
! 2387: return ISC_R_UNKNOWNATTRIBUTE;
! 2388: binding_value_dereference (&bp -> value, MDL);
! 2389: return ISC_R_SUCCESS;
! 2390: }
! 2391:
! 2392: nv = (struct binding_value *)0;
! 2393: if (!binding_value_allocate (&nv, MDL)) {
! 2394: dfree (nname, MDL);
! 2395: return ISC_R_NOMEMORY;
! 2396: }
! 2397: switch (value -> type) {
! 2398: case omapi_datatype_int:
! 2399: nv -> type = binding_numeric;
! 2400: nv -> value.intval = value -> u.integer;
! 2401: break;
! 2402:
! 2403: case omapi_datatype_string:
! 2404: case omapi_datatype_data:
! 2405: if (!buffer_allocate (&nv -> value.data.buffer,
! 2406: value -> u.buffer.len, MDL)) {
! 2407: binding_value_dereference (&nv, MDL);
! 2408: dfree (nname, MDL);
! 2409: return ISC_R_NOMEMORY;
! 2410: }
! 2411: memcpy (&nv -> value.data.buffer -> data [1],
! 2412: value -> u.buffer.value, value -> u.buffer.len);
! 2413: nv -> value.data.len = value -> u.buffer.len;
! 2414: break;
! 2415:
! 2416: case omapi_datatype_object:
! 2417: binding_value_dereference (&nv, MDL);
! 2418: dfree (nname, MDL);
! 2419: return ISC_R_INVALIDARG;
! 2420: }
! 2421:
! 2422: if (!bp) {
! 2423: bp = dmalloc (sizeof *bp, MDL);
! 2424: if (!bp) {
! 2425: binding_value_dereference (&nv, MDL);
! 2426: dfree (nname, MDL);
! 2427: return ISC_R_NOMEMORY;
! 2428: }
! 2429: memset (bp, 0, sizeof *bp);
! 2430: bp -> name = nname;
! 2431: nname = (char *)0;
! 2432: bp -> next = scope -> bindings;
! 2433: scope -> bindings = bp;
! 2434: } else {
! 2435: if (bp -> value)
! 2436: binding_value_dereference (&bp -> value, MDL);
! 2437: dfree (nname, MDL);
! 2438: }
! 2439: binding_value_reference (&bp -> value, nv, MDL);
! 2440: binding_value_dereference (&nv, MDL);
! 2441: return ISC_R_SUCCESS;
! 2442: }
! 2443:
! 2444: isc_result_t binding_scope_get_value (omapi_value_t **value,
! 2445: struct binding_scope *scope,
! 2446: omapi_data_string_t *name)
! 2447: {
! 2448: struct binding *bp;
! 2449: omapi_typed_data_t *td;
! 2450: isc_result_t status;
! 2451: char *nname;
! 2452: nname = dmalloc (name -> len + 1, MDL);
! 2453: if (!nname)
! 2454: return ISC_R_NOMEMORY;
! 2455: memcpy (nname, name -> value, name -> len);
! 2456: nname [name -> len] = 0;
! 2457: bp = find_binding (scope, nname);
! 2458: dfree (nname, MDL);
! 2459: if (!bp)
! 2460: return ISC_R_UNKNOWNATTRIBUTE;
! 2461: if (!bp -> value)
! 2462: return ISC_R_UNKNOWNATTRIBUTE;
! 2463:
! 2464: switch (bp -> value -> type) {
! 2465: case binding_boolean:
! 2466: td = (omapi_typed_data_t *)0;
! 2467: status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
! 2468: bp -> value -> value.boolean);
! 2469: break;
! 2470:
! 2471: case binding_numeric:
! 2472: td = (omapi_typed_data_t *)0;
! 2473: status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
! 2474: (int)
! 2475: bp -> value -> value.intval);
! 2476: break;
! 2477:
! 2478: case binding_data:
! 2479: td = (omapi_typed_data_t *)0;
! 2480: status = omapi_typed_data_new (MDL, &td, omapi_datatype_data,
! 2481: bp -> value -> value.data.len);
! 2482: if (status != ISC_R_SUCCESS)
! 2483: return status;
! 2484: memcpy (&td -> u.buffer.value [0],
! 2485: bp -> value -> value.data.data,
! 2486: bp -> value -> value.data.len);
! 2487: break;
! 2488:
! 2489: /* Can't return values for these two (yet?). */
! 2490: case binding_dns:
! 2491: case binding_function:
! 2492: return ISC_R_INVALIDARG;
! 2493:
! 2494: default:
! 2495: log_fatal ("Impossible case at %s:%d.", MDL);
! 2496: return ISC_R_FAILURE;
! 2497: }
! 2498:
! 2499: if (status != ISC_R_SUCCESS)
! 2500: return status;
! 2501: status = omapi_value_new (value, MDL);
! 2502: if (status != ISC_R_SUCCESS) {
! 2503: omapi_typed_data_dereference (&td, MDL);
! 2504: return status;
! 2505: }
! 2506:
! 2507: omapi_data_string_reference (&(*value) -> name, name, MDL);
! 2508: omapi_typed_data_reference (&(*value) -> value, td, MDL);
! 2509: omapi_typed_data_dereference (&td, MDL);
! 2510:
! 2511: return ISC_R_SUCCESS;
! 2512: }
! 2513:
! 2514: isc_result_t binding_scope_stuff_values (omapi_object_t *c,
! 2515: struct binding_scope *scope)
! 2516: {
! 2517: struct binding *bp;
! 2518: unsigned len;
! 2519: isc_result_t status;
! 2520:
! 2521: for (bp = scope -> bindings; bp; bp = bp -> next) {
! 2522: if (bp -> value) {
! 2523: if (bp -> value -> type == binding_dns ||
! 2524: bp -> value -> type == binding_function)
! 2525: continue;
! 2526:
! 2527: /* Stuff the name. */
! 2528: len = strlen (bp -> name);
! 2529: status = omapi_connection_put_uint16 (c, len);
! 2530: if (status != ISC_R_SUCCESS)
! 2531: return status;
! 2532: status = omapi_connection_copyin (c,
! 2533: (unsigned char *)bp -> name,
! 2534: len);
! 2535: if (status != ISC_R_SUCCESS)
! 2536: return status;
! 2537:
! 2538: switch (bp -> value -> type) {
! 2539: case binding_boolean:
! 2540: status = omapi_connection_put_uint32 (c,
! 2541: sizeof (u_int32_t));
! 2542: if (status != ISC_R_SUCCESS)
! 2543: return status;
! 2544: status = (omapi_connection_put_uint32
! 2545: (c,
! 2546: ((u_int32_t)(bp -> value -> value.boolean))));
! 2547: break;
! 2548:
! 2549: case binding_data:
! 2550: status = (omapi_connection_put_uint32
! 2551: (c, bp -> value -> value.data.len));
! 2552: if (status != ISC_R_SUCCESS)
! 2553: return status;
! 2554: if (bp -> value -> value.data.len) {
! 2555: status = (omapi_connection_copyin
! 2556: (c, bp -> value -> value.data.data,
! 2557: bp -> value -> value.data.len));
! 2558: if (status != ISC_R_SUCCESS)
! 2559: return status;
! 2560: }
! 2561: break;
! 2562:
! 2563: case binding_numeric:
! 2564: status = (omapi_connection_put_uint32
! 2565: (c, sizeof (u_int32_t)));
! 2566: if (status != ISC_R_SUCCESS)
! 2567: return status;
! 2568: status = (omapi_connection_put_uint32
! 2569: (c, ((u_int32_t)
! 2570: (bp -> value -> value.intval))));
! 2571: break;
! 2572:
! 2573:
! 2574: /* NOTREACHED */
! 2575: case binding_dns:
! 2576: case binding_function:
! 2577: break;
! 2578: }
! 2579: }
! 2580: }
! 2581: return ISC_R_SUCCESS;
! 2582: }
! 2583:
! 2584: /* vim: set tabstop=8: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>