1 /* $NetBSD: comapi.c,v 1.1.1.3 2014/07/12 11:57:39 spz Exp $ */ 2 /* omapi.c 3 4 OMAPI object interfaces for the DHCP server. */ 5 6 /* 7 * Copyright (c) 2012,2014 Internet Systems Consortium, Inc. ("ISC") 8 * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC") 9 * Copyright (c) 1999-2003 by Internet Software Consortium 10 * 11 * Permission to use, copy, modify, and distribute this software for any 12 * purpose with or without fee is hereby granted, provided that the above 13 * copyright notice and this permission notice appear in all copies. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Internet Systems Consortium, Inc. 24 * 950 Charter Street 25 * Redwood City, CA 94063 26 * <info@isc.org> 27 * https://www.isc.org/ 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 __RCSID("$NetBSD: comapi.c,v 1.1.1.3 2014/07/12 11:57:39 spz Exp $"); 33 34 /* Many, many thanks to Brian Murrell and BCtel for this code - BCtel 35 provided the funding that resulted in this code and the entire 36 OMAPI support library being written, and Brian helped brainstorm 37 and refine the requirements. To the extent that this code is 38 useful, you have Brian and BCtel to thank. Any limitations in the 39 code are a result of mistakes on my part. -- Ted Lemon */ 40 41 #include "dhcpd.h" 42 #include <omapip/omapip_p.h> 43 44 OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet) 45 OMAPI_OBJECT_ALLOC (shared_network, struct shared_network, 46 dhcp_type_shared_network) 47 OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group) 48 OMAPI_OBJECT_ALLOC (dhcp_control, dhcp_control_object_t, dhcp_type_control) 49 50 omapi_object_type_t *dhcp_type_interface; 51 omapi_object_type_t *dhcp_type_group; 52 omapi_object_type_t *dhcp_type_shared_network; 53 omapi_object_type_t *dhcp_type_subnet; 54 omapi_object_type_t *dhcp_type_control; 55 dhcp_control_object_t *dhcp_control_object; 56 57 void dhcp_common_objects_setup () 58 { 59 isc_result_t status; 60 61 status = omapi_object_type_register (&dhcp_type_control, 62 "control", 63 dhcp_control_set_value, 64 dhcp_control_get_value, 65 dhcp_control_destroy, 66 dhcp_control_signal_handler, 67 dhcp_control_stuff_values, 68 dhcp_control_lookup, 69 dhcp_control_create, 70 dhcp_control_remove, 0, 0, 0, 71 sizeof (dhcp_control_object_t), 72 0, RC_MISC); 73 if (status != ISC_R_SUCCESS) 74 log_fatal ("Can't register control object type: %s", 75 isc_result_totext (status)); 76 status = dhcp_control_allocate (&dhcp_control_object, MDL); 77 if (status != ISC_R_SUCCESS) 78 log_fatal ("Can't make initial control object: %s", 79 isc_result_totext (status)); 80 dhcp_control_object -> state = server_startup; 81 82 status = omapi_object_type_register (&dhcp_type_group, 83 "group", 84 dhcp_group_set_value, 85 dhcp_group_get_value, 86 dhcp_group_destroy, 87 dhcp_group_signal_handler, 88 dhcp_group_stuff_values, 89 dhcp_group_lookup, 90 dhcp_group_create, 91 dhcp_group_remove, 0, 0, 0, 92 sizeof (struct group_object), 0, 93 RC_MISC); 94 if (status != ISC_R_SUCCESS) 95 log_fatal ("Can't register group object type: %s", 96 isc_result_totext (status)); 97 98 status = omapi_object_type_register (&dhcp_type_subnet, 99 "subnet", 100 dhcp_subnet_set_value, 101 dhcp_subnet_get_value, 102 dhcp_subnet_destroy, 103 dhcp_subnet_signal_handler, 104 dhcp_subnet_stuff_values, 105 dhcp_subnet_lookup, 106 dhcp_subnet_create, 107 dhcp_subnet_remove, 0, 0, 0, 108 sizeof (struct subnet), 0, 109 RC_MISC); 110 if (status != ISC_R_SUCCESS) 111 log_fatal ("Can't register subnet object type: %s", 112 isc_result_totext (status)); 113 114 status = omapi_object_type_register 115 (&dhcp_type_shared_network, 116 "shared-network", 117 dhcp_shared_network_set_value, 118 dhcp_shared_network_get_value, 119 dhcp_shared_network_destroy, 120 dhcp_shared_network_signal_handler, 121 dhcp_shared_network_stuff_values, 122 dhcp_shared_network_lookup, 123 dhcp_shared_network_create, 124 dhcp_shared_network_remove, 0, 0, 0, 125 sizeof (struct shared_network), 0, RC_MISC); 126 if (status != ISC_R_SUCCESS) 127 log_fatal ("Can't register shared network object type: %s", 128 isc_result_totext (status)); 129 130 interface_setup (); 131 } 132 133 isc_result_t dhcp_group_set_value (omapi_object_t *h, 134 omapi_object_t *id, 135 omapi_data_string_t *name, 136 omapi_typed_data_t *value) 137 { 138 struct group_object *group; 139 isc_result_t status; 140 141 if (h -> type != dhcp_type_group) 142 return DHCP_R_INVALIDARG; 143 group = (struct group_object *)h; 144 145 /* XXX For now, we can only set these values on new group objects. 146 XXX Soon, we need to be able to update group objects. */ 147 if (!omapi_ds_strcmp (name, "name")) { 148 if (group -> name) 149 return ISC_R_EXISTS; 150 if (value -> type == omapi_datatype_data || 151 value -> type == omapi_datatype_string) { 152 group -> name = dmalloc (value -> u.buffer.len + 1, 153 MDL); 154 if (!group -> name) 155 return ISC_R_NOMEMORY; 156 memcpy (group -> name, 157 value -> u.buffer.value, 158 value -> u.buffer.len); 159 group -> name [value -> u.buffer.len] = 0; 160 } else 161 return DHCP_R_INVALIDARG; 162 return ISC_R_SUCCESS; 163 } 164 165 if (!omapi_ds_strcmp (name, "statements")) { 166 if (group -> group && group -> group -> statements) 167 return ISC_R_EXISTS; 168 if (!group -> group) { 169 if (!clone_group (&group -> group, root_group, MDL)) 170 return ISC_R_NOMEMORY; 171 } 172 if (value -> type == omapi_datatype_data || 173 value -> type == omapi_datatype_string) { 174 struct parse *parse; 175 int lose = 0; 176 parse = NULL; 177 status = new_parse(&parse, -1, 178 (char *) value->u.buffer.value, 179 value->u.buffer.len, 180 "network client", 0); 181 if (status != ISC_R_SUCCESS || parse == NULL) 182 return status; 183 if (!(parse_executable_statements 184 (&group -> group -> statements, parse, &lose, 185 context_any))) { 186 end_parse (&parse); 187 return DHCP_R_BADPARSE; 188 } 189 end_parse (&parse); 190 return ISC_R_SUCCESS; 191 } else 192 return DHCP_R_INVALIDARG; 193 } 194 195 /* Try to find some inner object that can take the value. */ 196 if (h -> inner && h -> inner -> type -> set_value) { 197 status = ((*(h -> inner -> type -> set_value)) 198 (h -> inner, id, name, value)); 199 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 200 return status; 201 } 202 203 return ISC_R_NOTFOUND; 204 } 205 206 207 isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id, 208 omapi_data_string_t *name, 209 omapi_value_t **value) 210 { 211 struct group_object *group; 212 isc_result_t status; 213 214 if (h -> type != dhcp_type_group) 215 return DHCP_R_INVALIDARG; 216 group = (struct group_object *)h; 217 218 if (!omapi_ds_strcmp (name, "name")) 219 return omapi_make_string_value (value, 220 name, group -> name, MDL); 221 222 /* Try to find some inner object that can take the value. */ 223 if (h -> inner && h -> inner -> type -> get_value) { 224 status = ((*(h -> inner -> type -> get_value)) 225 (h -> inner, id, name, value)); 226 if (status == ISC_R_SUCCESS) 227 return status; 228 } 229 return ISC_R_NOTFOUND; 230 } 231 232 isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line) 233 { 234 struct group_object *group, *t; 235 236 if (h -> type != dhcp_type_group) 237 return DHCP_R_INVALIDARG; 238 group = (struct group_object *)h; 239 240 if (group -> name) { 241 if (group_name_hash) { 242 t = (struct group_object *)0; 243 if (group_hash_lookup (&t, group_name_hash, 244 group -> name, 245 strlen (group -> name), MDL)) { 246 group_hash_delete (group_name_hash, 247 group -> name, 248 strlen (group -> name), 249 MDL); 250 group_object_dereference (&t, MDL); 251 } 252 } 253 dfree (group -> name, file, line); 254 group -> name = (char *)0; 255 } 256 if (group -> group) 257 group_dereference (&group -> group, MDL); 258 259 return ISC_R_SUCCESS; 260 } 261 262 isc_result_t dhcp_group_signal_handler (omapi_object_t *h, 263 const char *name, va_list ap) 264 { 265 struct group_object *group; 266 isc_result_t status; 267 int updatep = 0; 268 269 if (h -> type != dhcp_type_group) 270 return DHCP_R_INVALIDARG; 271 group = (struct group_object *)h; 272 273 if (!strcmp (name, "updated")) { 274 /* A group object isn't valid if a subgroup hasn't yet been 275 associated with it. */ 276 if (!group -> group) 277 return DHCP_R_INVALIDARG; 278 279 /* Group objects always have to have names. */ 280 if (!group -> name) { 281 char hnbuf [64]; 282 sprintf (hnbuf, "ng%08lx%08lx", 283 (unsigned long)cur_time, 284 (unsigned long)group); 285 group -> name = dmalloc (strlen (hnbuf) + 1, MDL); 286 if (!group -> name) 287 return ISC_R_NOMEMORY; 288 strcpy (group -> name, hnbuf); 289 } 290 291 supersede_group (group, 1); 292 updatep = 1; 293 } 294 295 /* Try to find some inner object that can take the value. */ 296 if (h -> inner && h -> inner -> type -> get_value) { 297 status = ((*(h -> inner -> type -> signal_handler)) 298 (h -> inner, name, ap)); 299 if (status == ISC_R_SUCCESS) 300 return status; 301 } 302 if (updatep) 303 return ISC_R_SUCCESS; 304 return ISC_R_NOTFOUND; 305 } 306 307 isc_result_t dhcp_group_stuff_values (omapi_object_t *c, 308 omapi_object_t *id, 309 omapi_object_t *h) 310 { 311 struct group_object *group; 312 isc_result_t status; 313 314 if (h -> type != dhcp_type_group) 315 return DHCP_R_INVALIDARG; 316 group = (struct group_object *)h; 317 318 /* Write out all the values. */ 319 if (group -> name) { 320 status = omapi_connection_put_name (c, "name"); 321 if (status != ISC_R_SUCCESS) 322 return status; 323 status = omapi_connection_put_string (c, group -> name); 324 if (status != ISC_R_SUCCESS) 325 return status; 326 } 327 328 /* Write out the inner object, if any. */ 329 if (h -> inner && h -> inner -> type -> stuff_values) { 330 status = ((*(h -> inner -> type -> stuff_values)) 331 (c, id, h -> inner)); 332 if (status == ISC_R_SUCCESS) 333 return status; 334 } 335 336 return ISC_R_SUCCESS; 337 } 338 339 isc_result_t dhcp_group_lookup (omapi_object_t **lp, 340 omapi_object_t *id, omapi_object_t *ref) 341 { 342 omapi_value_t *tv = (omapi_value_t *)0; 343 isc_result_t status; 344 struct group_object *group; 345 346 if (!ref) 347 return DHCP_R_NOKEYS; 348 349 /* First see if we were sent a handle. */ 350 status = omapi_get_value_str (ref, id, "handle", &tv); 351 if (status == ISC_R_SUCCESS) { 352 status = omapi_handle_td_lookup (lp, tv -> value); 353 354 omapi_value_dereference (&tv, MDL); 355 if (status != ISC_R_SUCCESS) 356 return status; 357 358 /* Don't return the object if the type is wrong. */ 359 if ((*lp) -> type != dhcp_type_group) { 360 omapi_object_dereference (lp, MDL); 361 return DHCP_R_INVALIDARG; 362 } 363 } 364 365 /* Now look for a name. */ 366 status = omapi_get_value_str (ref, id, "name", &tv); 367 if (status == ISC_R_SUCCESS) { 368 group = (struct group_object *)0; 369 if (group_name_hash && 370 group_hash_lookup (&group, group_name_hash, 371 (const char *) 372 tv -> value -> u.buffer.value, 373 tv -> value -> u.buffer.len, MDL)) { 374 omapi_value_dereference (&tv, MDL); 375 376 if (*lp && *lp != (omapi_object_t *)group) { 377 group_object_dereference (&group, MDL); 378 omapi_object_dereference (lp, MDL); 379 return DHCP_R_KEYCONFLICT; 380 } else if (!*lp) { 381 /* XXX fix so that hash lookup itself creates 382 XXX the reference. */ 383 omapi_object_reference (lp, 384 (omapi_object_t *)group, 385 MDL); 386 group_object_dereference (&group, MDL); 387 } 388 } else if (!*lp) 389 return ISC_R_NOTFOUND; 390 } 391 392 /* If we get to here without finding a group, no valid key was 393 specified. */ 394 if (!*lp) 395 return DHCP_R_NOKEYS; 396 397 if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) { 398 omapi_object_dereference (lp, MDL); 399 return ISC_R_NOTFOUND; 400 } 401 return ISC_R_SUCCESS; 402 } 403 404 isc_result_t dhcp_group_create (omapi_object_t **lp, 405 omapi_object_t *id) 406 { 407 struct group_object *group; 408 isc_result_t status; 409 group = (struct group_object *)0; 410 411 status = group_object_allocate (&group, MDL); 412 if (status != ISC_R_SUCCESS) 413 return status; 414 group -> flags = GROUP_OBJECT_DYNAMIC; 415 status = omapi_object_reference (lp, (omapi_object_t *)group, MDL); 416 group_object_dereference (&group, MDL); 417 return status; 418 } 419 420 isc_result_t dhcp_group_remove (omapi_object_t *lp, 421 omapi_object_t *id) 422 { 423 struct group_object *group; 424 isc_result_t status; 425 if (lp -> type != dhcp_type_group) 426 return DHCP_R_INVALIDARG; 427 group = (struct group_object *)lp; 428 429 group -> flags |= GROUP_OBJECT_DELETED; 430 if (group_write_hook) { 431 if (!(*group_write_hook) (group)) 432 return ISC_R_IOERROR; 433 } 434 435 status = dhcp_group_destroy ((omapi_object_t *)group, MDL); 436 437 return status; 438 } 439 440 isc_result_t dhcp_control_set_value (omapi_object_t *h, 441 omapi_object_t *id, 442 omapi_data_string_t *name, 443 omapi_typed_data_t *value) 444 { 445 dhcp_control_object_t *control; 446 isc_result_t status; 447 unsigned long newstate; 448 449 if (h -> type != dhcp_type_control) 450 return DHCP_R_INVALIDARG; 451 control = (dhcp_control_object_t *)h; 452 453 if (!omapi_ds_strcmp (name, "state")) { 454 status = omapi_get_int_value (&newstate, value); 455 if (status != ISC_R_SUCCESS) 456 return status; 457 status = dhcp_set_control_state (control -> state, newstate); 458 if (status == ISC_R_SUCCESS) 459 control -> state = value -> u.integer; 460 return status; 461 } 462 463 /* Try to find some inner object that can take the value. */ 464 if (h -> inner && h -> inner -> type -> set_value) { 465 status = ((*(h -> inner -> type -> set_value)) 466 (h -> inner, id, name, value)); 467 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 468 return status; 469 } 470 471 return ISC_R_NOTFOUND; 472 } 473 474 475 isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id, 476 omapi_data_string_t *name, 477 omapi_value_t **value) 478 { 479 dhcp_control_object_t *control; 480 isc_result_t status; 481 482 if (h -> type != dhcp_type_control) 483 return DHCP_R_INVALIDARG; 484 control = (dhcp_control_object_t *)h; 485 486 if (!omapi_ds_strcmp (name, "state")) 487 return omapi_make_int_value (value, 488 name, (int)control -> state, MDL); 489 490 /* Try to find some inner object that can take the value. */ 491 if (h -> inner && h -> inner -> type -> get_value) { 492 status = ((*(h -> inner -> type -> get_value)) 493 (h -> inner, id, name, value)); 494 if (status == ISC_R_SUCCESS) 495 return status; 496 } 497 return ISC_R_NOTFOUND; 498 } 499 500 isc_result_t dhcp_control_destroy (omapi_object_t *h, 501 const char *file, int line) 502 { 503 if (h -> type != dhcp_type_control) 504 return DHCP_R_INVALIDARG; 505 506 /* Can't destroy the control object. */ 507 return ISC_R_NOPERM; 508 } 509 510 isc_result_t dhcp_control_signal_handler (omapi_object_t *h, 511 const char *name, va_list ap) 512 { 513 /* In this function h should be a (dhcp_control_object_t *) */ 514 515 isc_result_t status; 516 517 if (h -> type != dhcp_type_control) 518 return DHCP_R_INVALIDARG; 519 520 /* Try to find some inner object that can take the value. */ 521 if (h -> inner && h -> inner -> type -> get_value) { 522 status = ((*(h -> inner -> type -> signal_handler)) 523 (h -> inner, name, ap)); 524 if (status == ISC_R_SUCCESS) 525 return status; 526 } 527 return ISC_R_NOTFOUND; 528 } 529 530 isc_result_t dhcp_control_stuff_values (omapi_object_t *c, 531 omapi_object_t *id, 532 omapi_object_t *h) 533 { 534 dhcp_control_object_t *control; 535 isc_result_t status; 536 537 if (h -> type != dhcp_type_control) 538 return DHCP_R_INVALIDARG; 539 control = (dhcp_control_object_t *)h; 540 541 /* Write out all the values. */ 542 status = omapi_connection_put_name (c, "state"); 543 if (status != ISC_R_SUCCESS) 544 return status; 545 status = omapi_connection_put_uint32 (c, sizeof (u_int32_t)); 546 if (status != ISC_R_SUCCESS) 547 return status; 548 status = omapi_connection_put_uint32 (c, control -> state); 549 if (status != ISC_R_SUCCESS) 550 return status; 551 552 /* Write out the inner object, if any. */ 553 if (h -> inner && h -> inner -> type -> stuff_values) { 554 status = ((*(h -> inner -> type -> stuff_values)) 555 (c, id, h -> inner)); 556 if (status == ISC_R_SUCCESS) 557 return status; 558 } 559 560 return ISC_R_SUCCESS; 561 } 562 563 isc_result_t dhcp_control_lookup (omapi_object_t **lp, 564 omapi_object_t *id, omapi_object_t *ref) 565 { 566 omapi_value_t *tv = (omapi_value_t *)0; 567 isc_result_t status; 568 569 /* First see if we were sent a handle. */ 570 if (ref) { 571 status = omapi_get_value_str (ref, id, "handle", &tv); 572 if (status == ISC_R_SUCCESS) { 573 status = omapi_handle_td_lookup (lp, tv -> value); 574 575 omapi_value_dereference (&tv, MDL); 576 if (status != ISC_R_SUCCESS) 577 return status; 578 579 /* Don't return the object if the type is wrong. */ 580 if ((*lp) -> type != dhcp_type_control) { 581 omapi_object_dereference (lp, MDL); 582 return DHCP_R_INVALIDARG; 583 } 584 } 585 } 586 587 /* Otherwise, stop playing coy - there's only one control object, 588 so we can just return it. */ 589 dhcp_control_reference ((dhcp_control_object_t **)lp, 590 dhcp_control_object, MDL); 591 return ISC_R_SUCCESS; 592 } 593 594 isc_result_t dhcp_control_create (omapi_object_t **lp, 595 omapi_object_t *id) 596 { 597 /* Can't create a control object - there can be only one. */ 598 return ISC_R_NOPERM; 599 } 600 601 isc_result_t dhcp_control_remove (omapi_object_t *lp, 602 omapi_object_t *id) 603 { 604 /* Form is emptiness; emptiness form. The control object 605 cannot go out of existance. */ 606 return ISC_R_NOPERM; 607 } 608 609 isc_result_t dhcp_subnet_set_value (omapi_object_t *h, 610 omapi_object_t *id, 611 omapi_data_string_t *name, 612 omapi_typed_data_t *value) 613 { 614 /* In this function h should be a (struct subnet *) */ 615 616 isc_result_t status; 617 618 if (h -> type != dhcp_type_subnet) 619 return DHCP_R_INVALIDARG; 620 621 /* No values to set yet. */ 622 623 /* Try to find some inner object that can take the value. */ 624 if (h -> inner && h -> inner -> type -> set_value) { 625 status = ((*(h -> inner -> type -> set_value)) 626 (h -> inner, id, name, value)); 627 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 628 return status; 629 } 630 631 return ISC_R_NOTFOUND; 632 } 633 634 635 isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id, 636 omapi_data_string_t *name, 637 omapi_value_t **value) 638 { 639 /* In this function h should be a (struct subnet *) */ 640 641 isc_result_t status; 642 643 if (h -> type != dhcp_type_subnet) 644 return DHCP_R_INVALIDARG; 645 646 /* No values to get yet. */ 647 648 /* Try to find some inner object that can provide the value. */ 649 if (h -> inner && h -> inner -> type -> get_value) { 650 status = ((*(h -> inner -> type -> get_value)) 651 (h -> inner, id, name, value)); 652 if (status == ISC_R_SUCCESS) 653 return status; 654 } 655 return ISC_R_NOTFOUND; 656 } 657 658 isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line) 659 { 660 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 661 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 662 struct subnet *subnet; 663 #endif 664 665 if (h -> type != dhcp_type_subnet) 666 return DHCP_R_INVALIDARG; 667 668 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 669 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 670 subnet = (struct subnet *)h; 671 if (subnet -> next_subnet) 672 subnet_dereference (&subnet -> next_subnet, file, line); 673 if (subnet -> next_sibling) 674 subnet_dereference (&subnet -> next_sibling, file, line); 675 if (subnet -> shared_network) 676 shared_network_dereference (&subnet -> shared_network, 677 file, line); 678 if (subnet -> interface) 679 interface_dereference (&subnet -> interface, file, line); 680 if (subnet -> group) 681 group_dereference (&subnet -> group, file, line); 682 #endif 683 684 return ISC_R_SUCCESS; 685 } 686 687 isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h, 688 const char *name, va_list ap) 689 { 690 /* In this function h should be a (struct subnet *) */ 691 692 isc_result_t status; 693 694 if (h -> type != dhcp_type_subnet) 695 return DHCP_R_INVALIDARG; 696 697 /* Can't write subnets yet. */ 698 699 /* Try to find some inner object that can take the value. */ 700 if (h -> inner && h -> inner -> type -> get_value) { 701 status = ((*(h -> inner -> type -> signal_handler)) 702 (h -> inner, name, ap)); 703 if (status == ISC_R_SUCCESS) 704 return status; 705 } 706 707 return ISC_R_NOTFOUND; 708 } 709 710 isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c, 711 omapi_object_t *id, 712 omapi_object_t *h) 713 { 714 /* In this function h should be a (struct subnet *) */ 715 716 isc_result_t status; 717 718 if (h -> type != dhcp_type_subnet) 719 return DHCP_R_INVALIDARG; 720 721 /* Can't stuff subnet values yet. */ 722 723 /* Write out the inner object, if any. */ 724 if (h -> inner && h -> inner -> type -> stuff_values) { 725 status = ((*(h -> inner -> type -> stuff_values)) 726 (c, id, h -> inner)); 727 if (status == ISC_R_SUCCESS) 728 return status; 729 } 730 731 return ISC_R_SUCCESS; 732 } 733 734 isc_result_t dhcp_subnet_lookup (omapi_object_t **lp, 735 omapi_object_t *id, 736 omapi_object_t *ref) 737 { 738 /* Can't look up subnets yet. */ 739 740 /* If we get to here without finding a subnet, no valid key was 741 specified. */ 742 if (!*lp) 743 return DHCP_R_NOKEYS; 744 return ISC_R_SUCCESS; 745 } 746 747 isc_result_t dhcp_subnet_create (omapi_object_t **lp, 748 omapi_object_t *id) 749 { 750 return ISC_R_NOTIMPLEMENTED; 751 } 752 753 isc_result_t dhcp_subnet_remove (omapi_object_t *lp, 754 omapi_object_t *id) 755 { 756 return ISC_R_NOTIMPLEMENTED; 757 } 758 759 isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, 760 omapi_object_t *id, 761 omapi_data_string_t *name, 762 omapi_typed_data_t *value) 763 { 764 /* In this function h should be a (struct shared_network *) */ 765 766 isc_result_t status; 767 768 if (h -> type != dhcp_type_shared_network) 769 return DHCP_R_INVALIDARG; 770 771 /* No values to set yet. */ 772 773 /* Try to find some inner object that can take the value. */ 774 if (h -> inner && h -> inner -> type -> set_value) { 775 status = ((*(h -> inner -> type -> set_value)) 776 (h -> inner, id, name, value)); 777 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 778 return status; 779 } 780 781 return ISC_R_NOTFOUND; 782 } 783 784 785 isc_result_t dhcp_shared_network_get_value (omapi_object_t *h, 786 omapi_object_t *id, 787 omapi_data_string_t *name, 788 omapi_value_t **value) 789 { 790 /* In this function h should be a (struct shared_network *) */ 791 792 isc_result_t status; 793 794 if (h -> type != dhcp_type_shared_network) 795 return DHCP_R_INVALIDARG; 796 797 /* No values to get yet. */ 798 799 /* Try to find some inner object that can provide the value. */ 800 if (h -> inner && h -> inner -> type -> get_value) { 801 status = ((*(h -> inner -> type -> get_value)) 802 (h -> inner, id, name, value)); 803 if (status == ISC_R_SUCCESS) 804 return status; 805 } 806 return ISC_R_NOTFOUND; 807 } 808 809 isc_result_t dhcp_shared_network_destroy (omapi_object_t *h, 810 const char *file, int line) 811 { 812 /* In this function h should be a (struct shared_network *) */ 813 814 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 815 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 816 struct shared_network *shared_network; 817 #endif 818 819 if (h -> type != dhcp_type_shared_network) 820 return DHCP_R_INVALIDARG; 821 822 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 823 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 824 shared_network = (struct shared_network *)h; 825 if (shared_network -> next) 826 shared_network_dereference (&shared_network -> next, 827 file, line); 828 if (shared_network -> name) { 829 dfree (shared_network -> name, file, line); 830 shared_network -> name = 0; 831 } 832 if (shared_network -> subnets) 833 subnet_dereference (&shared_network -> subnets, file, line); 834 if (shared_network -> interface) 835 interface_dereference (&shared_network -> interface, 836 file, line); 837 if (shared_network -> pools) 838 omapi_object_dereference ((omapi_object_t **) 839 &shared_network -> pools, file, line); 840 if (shared_network -> group) 841 group_dereference (&shared_network -> group, file, line); 842 #if defined (FAILOVER_PROTOCOL) 843 if (shared_network -> failover_peer) 844 omapi_object_dereference ((omapi_object_t **) 845 &shared_network -> failover_peer, 846 file, line); 847 #endif 848 #endif /* DEBUG_MEMORY_LEAKAGE */ 849 850 return ISC_R_SUCCESS; 851 } 852 853 isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h, 854 const char *name, 855 va_list ap) 856 { 857 /* In this function h should be a (struct shared_network *) */ 858 859 isc_result_t status; 860 861 if (h -> type != dhcp_type_shared_network) 862 return DHCP_R_INVALIDARG; 863 864 /* Can't write shared_networks yet. */ 865 866 /* Try to find some inner object that can take the value. */ 867 if (h -> inner && h -> inner -> type -> get_value) { 868 status = ((*(h -> inner -> type -> signal_handler)) 869 (h -> inner, name, ap)); 870 if (status == ISC_R_SUCCESS) 871 return status; 872 } 873 874 return ISC_R_NOTFOUND; 875 } 876 877 isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c, 878 omapi_object_t *id, 879 omapi_object_t *h) 880 { 881 /* In this function h should be a (struct shared_network *) */ 882 883 isc_result_t status; 884 885 if (h -> type != dhcp_type_shared_network) 886 return DHCP_R_INVALIDARG; 887 888 /* Can't stuff shared_network values yet. */ 889 890 /* Write out the inner object, if any. */ 891 if (h -> inner && h -> inner -> type -> stuff_values) { 892 status = ((*(h -> inner -> type -> stuff_values)) 893 (c, id, h -> inner)); 894 if (status == ISC_R_SUCCESS) 895 return status; 896 } 897 898 return ISC_R_SUCCESS; 899 } 900 901 isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp, 902 omapi_object_t *id, 903 omapi_object_t *ref) 904 { 905 /* Can't look up shared_networks yet. */ 906 907 /* If we get to here without finding a shared_network, no valid key was 908 specified. */ 909 if (!*lp) 910 return DHCP_R_NOKEYS; 911 return ISC_R_SUCCESS; 912 } 913 914 isc_result_t dhcp_shared_network_create (omapi_object_t **lp, 915 omapi_object_t *id) 916 { 917 return ISC_R_NOTIMPLEMENTED; 918 } 919 920 isc_result_t dhcp_shared_network_remove (omapi_object_t *lp, 921 omapi_object_t *id) 922 { 923 return ISC_R_NOTIMPLEMENTED; 924 } 925 926