1 /* $NetBSD: comapi.c,v 1.2 2018/04/07 22:37:29 christos Exp $ */ 2 3 /* omapi.c 4 5 OMAPI object interfaces for the DHCP server. */ 6 7 /* 8 * Copyright (c) 2004-2017 Internet Systems Consortium, Inc. ("ISC") 9 * Copyright (c) 1999-2003 by Internet Software Consortium 10 * 11 * This Source Code Form is subject to the terms of the Mozilla Public 12 * License, v. 2.0. If a copy of the MPL was not distributed with this 13 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 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.2 2018/04/07 22:37:29 christos 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_group; 51 omapi_object_type_t *dhcp_type_shared_network; 52 omapi_object_type_t *dhcp_type_subnet; 53 omapi_object_type_t *dhcp_type_control; 54 dhcp_control_object_t *dhcp_control_object; 55 56 void dhcp_common_objects_setup () 57 { 58 isc_result_t status; 59 60 status = omapi_object_type_register (&dhcp_type_control, 61 "control", 62 dhcp_control_set_value, 63 dhcp_control_get_value, 64 dhcp_control_destroy, 65 dhcp_control_signal_handler, 66 dhcp_control_stuff_values, 67 dhcp_control_lookup, 68 dhcp_control_create, 69 dhcp_control_remove, 0, 0, 0, 70 sizeof (dhcp_control_object_t), 71 0, RC_MISC); 72 if (status != ISC_R_SUCCESS) 73 log_fatal ("Can't register control object type: %s", 74 isc_result_totext (status)); 75 status = dhcp_control_allocate (&dhcp_control_object, MDL); 76 if (status != ISC_R_SUCCESS) 77 log_fatal ("Can't make initial control object: %s", 78 isc_result_totext (status)); 79 dhcp_control_object -> state = server_startup; 80 81 status = omapi_object_type_register (&dhcp_type_group, 82 "group", 83 dhcp_group_set_value, 84 dhcp_group_get_value, 85 dhcp_group_destroy, 86 dhcp_group_signal_handler, 87 dhcp_group_stuff_values, 88 dhcp_group_lookup, 89 dhcp_group_create, 90 dhcp_group_remove, 0, 0, 0, 91 sizeof (struct group_object), 0, 92 RC_MISC); 93 if (status != ISC_R_SUCCESS) 94 log_fatal ("Can't register group object type: %s", 95 isc_result_totext (status)); 96 97 status = omapi_object_type_register (&dhcp_type_subnet, 98 "subnet", 99 dhcp_subnet_set_value, 100 dhcp_subnet_get_value, 101 dhcp_subnet_destroy, 102 dhcp_subnet_signal_handler, 103 dhcp_subnet_stuff_values, 104 dhcp_subnet_lookup, 105 dhcp_subnet_create, 106 dhcp_subnet_remove, 0, 0, 0, 107 sizeof (struct subnet), 0, 108 RC_MISC); 109 if (status != ISC_R_SUCCESS) 110 log_fatal ("Can't register subnet object type: %s", 111 isc_result_totext (status)); 112 113 status = omapi_object_type_register 114 (&dhcp_type_shared_network, 115 "shared-network", 116 dhcp_shared_network_set_value, 117 dhcp_shared_network_get_value, 118 dhcp_shared_network_destroy, 119 dhcp_shared_network_signal_handler, 120 dhcp_shared_network_stuff_values, 121 dhcp_shared_network_lookup, 122 dhcp_shared_network_create, 123 dhcp_shared_network_remove, 0, 0, 0, 124 sizeof (struct shared_network), 0, RC_MISC); 125 if (status != ISC_R_SUCCESS) 126 log_fatal ("Can't register shared network object type: %s", 127 isc_result_totext (status)); 128 129 interface_setup (); 130 } 131 132 isc_result_t dhcp_group_set_value (omapi_object_t *h, 133 omapi_object_t *id, 134 omapi_data_string_t *name, 135 omapi_typed_data_t *value) 136 { 137 struct group_object *group; 138 isc_result_t status; 139 140 if (h -> type != dhcp_type_group) 141 return DHCP_R_INVALIDARG; 142 group = (struct group_object *)h; 143 144 /* XXX For now, we can only set these values on new group objects. 145 XXX Soon, we need to be able to update group objects. */ 146 if (!omapi_ds_strcmp (name, "name")) { 147 if (group -> name) 148 return ISC_R_EXISTS; 149 if (value -> type == omapi_datatype_data || 150 value -> type == omapi_datatype_string) { 151 group -> name = dmalloc (value -> u.buffer.len + 1, 152 MDL); 153 if (!group -> name) 154 return ISC_R_NOMEMORY; 155 memcpy (group -> name, 156 value -> u.buffer.value, 157 value -> u.buffer.len); 158 group -> name [value -> u.buffer.len] = 0; 159 } else 160 return DHCP_R_INVALIDARG; 161 return ISC_R_SUCCESS; 162 } 163 164 if (!omapi_ds_strcmp (name, "statements")) { 165 if (group -> group && group -> group -> statements) 166 return ISC_R_EXISTS; 167 if (!group -> group) { 168 if (!clone_group (&group -> group, root_group, MDL)) 169 return ISC_R_NOMEMORY; 170 } 171 if (value -> type == omapi_datatype_data || 172 value -> type == omapi_datatype_string) { 173 struct parse *parse; 174 int lose = 0; 175 parse = NULL; 176 status = new_parse(&parse, -1, 177 (char *) value->u.buffer.value, 178 value->u.buffer.len, 179 "network client", 0); 180 if (status != ISC_R_SUCCESS || parse == NULL) 181 return status; 182 if (!(parse_executable_statements 183 (&group -> group -> statements, parse, &lose, 184 context_any))) { 185 end_parse (&parse); 186 return DHCP_R_BADPARSE; 187 } 188 end_parse (&parse); 189 return ISC_R_SUCCESS; 190 } else 191 return DHCP_R_INVALIDARG; 192 } 193 194 /* Try to find some inner object that can take the value. */ 195 if (h -> inner && h -> inner -> type -> set_value) { 196 status = ((*(h -> inner -> type -> set_value)) 197 (h -> inner, id, name, value)); 198 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 199 return status; 200 } 201 202 return ISC_R_NOTFOUND; 203 } 204 205 206 isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id, 207 omapi_data_string_t *name, 208 omapi_value_t **value) 209 { 210 struct group_object *group; 211 isc_result_t status; 212 213 if (h -> type != dhcp_type_group) 214 return DHCP_R_INVALIDARG; 215 group = (struct group_object *)h; 216 217 if (!omapi_ds_strcmp (name, "name")) 218 return omapi_make_string_value (value, 219 name, group -> name, MDL); 220 221 /* Try to find some inner object that can take the value. */ 222 if (h -> inner && h -> inner -> type -> get_value) { 223 status = ((*(h -> inner -> type -> get_value)) 224 (h -> inner, id, name, value)); 225 if (status == ISC_R_SUCCESS) 226 return status; 227 } 228 return ISC_R_NOTFOUND; 229 } 230 231 isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line) 232 { 233 struct group_object *group, *t; 234 235 if (h -> type != dhcp_type_group) 236 return DHCP_R_INVALIDARG; 237 group = (struct group_object *)h; 238 239 if (group -> name) { 240 if (group_name_hash) { 241 t = (struct group_object *)0; 242 if (group_hash_lookup (&t, group_name_hash, 243 group -> name, 244 strlen (group -> name), MDL)) { 245 group_hash_delete (group_name_hash, 246 group -> name, 247 strlen (group -> name), 248 MDL); 249 group_object_dereference (&t, MDL); 250 } 251 } 252 dfree (group -> name, file, line); 253 group -> name = (char *)0; 254 } 255 if (group -> group) 256 group_dereference (&group -> group, MDL); 257 258 return ISC_R_SUCCESS; 259 } 260 261 isc_result_t dhcp_group_signal_handler (omapi_object_t *h, 262 const char *name, va_list ap) 263 { 264 struct group_object *group; 265 isc_result_t status; 266 int updatep = 0; 267 268 if (h -> type != dhcp_type_group) 269 return DHCP_R_INVALIDARG; 270 group = (struct group_object *)h; 271 272 if (!strcmp (name, "updated")) { 273 /* A group object isn't valid if a subgroup hasn't yet been 274 associated with it. */ 275 if (!group -> group) 276 return DHCP_R_INVALIDARG; 277 278 /* Group objects always have to have names. */ 279 if (!group -> name) { 280 char hnbuf [64]; 281 sprintf (hnbuf, "ng%08lx%08lx", 282 (unsigned long)cur_time, 283 (unsigned long)group); 284 group -> name = dmalloc (strlen (hnbuf) + 1, MDL); 285 if (!group -> name) 286 return ISC_R_NOMEMORY; 287 strcpy (group -> name, hnbuf); 288 } 289 290 supersede_group (group, 1); 291 updatep = 1; 292 } 293 294 /* Try to find some inner object that can take the value. */ 295 if (h -> inner && h -> inner -> type -> get_value) { 296 status = ((*(h -> inner -> type -> signal_handler)) 297 (h -> inner, name, ap)); 298 if (status == ISC_R_SUCCESS) 299 return status; 300 } 301 if (updatep) 302 return ISC_R_SUCCESS; 303 return ISC_R_NOTFOUND; 304 } 305 306 isc_result_t dhcp_group_stuff_values (omapi_object_t *c, 307 omapi_object_t *id, 308 omapi_object_t *h) 309 { 310 struct group_object *group; 311 isc_result_t status; 312 313 if (h -> type != dhcp_type_group) 314 return DHCP_R_INVALIDARG; 315 group = (struct group_object *)h; 316 317 /* Write out all the values. */ 318 if (group -> name) { 319 status = omapi_connection_put_name (c, "name"); 320 if (status != ISC_R_SUCCESS) 321 return status; 322 status = omapi_connection_put_string (c, group -> name); 323 if (status != ISC_R_SUCCESS) 324 return status; 325 } 326 327 /* Write out the inner object, if any. */ 328 if (h -> inner && h -> inner -> type -> stuff_values) { 329 status = ((*(h -> inner -> type -> stuff_values)) 330 (c, id, h -> inner)); 331 if (status == ISC_R_SUCCESS) 332 return status; 333 } 334 335 return ISC_R_SUCCESS; 336 } 337 338 isc_result_t dhcp_group_lookup (omapi_object_t **lp, 339 omapi_object_t *id, omapi_object_t *ref) 340 { 341 omapi_value_t *tv = (omapi_value_t *)0; 342 isc_result_t status; 343 struct group_object *group; 344 345 if (!ref) 346 return DHCP_R_NOKEYS; 347 348 /* First see if we were sent a handle. */ 349 status = omapi_get_value_str (ref, id, "handle", &tv); 350 if (status == ISC_R_SUCCESS) { 351 status = omapi_handle_td_lookup (lp, tv -> value); 352 353 omapi_value_dereference (&tv, MDL); 354 if (status != ISC_R_SUCCESS) 355 return status; 356 357 /* Don't return the object if the type is wrong. */ 358 if ((*lp) -> type != dhcp_type_group) { 359 omapi_object_dereference (lp, MDL); 360 return DHCP_R_INVALIDARG; 361 } 362 } 363 364 /* Now look for a name. */ 365 status = omapi_get_value_str (ref, id, "name", &tv); 366 if (status == ISC_R_SUCCESS) { 367 group = (struct group_object *)0; 368 if (group_name_hash && 369 group_hash_lookup (&group, group_name_hash, 370 (const char *) 371 tv -> value -> u.buffer.value, 372 tv -> value -> u.buffer.len, MDL)) { 373 omapi_value_dereference (&tv, MDL); 374 375 if (*lp && *lp != (omapi_object_t *)group) { 376 group_object_dereference (&group, MDL); 377 omapi_object_dereference (lp, MDL); 378 return DHCP_R_KEYCONFLICT; 379 } else if (!*lp) { 380 /* XXX fix so that hash lookup itself creates 381 XXX the reference. */ 382 omapi_object_reference (lp, 383 (omapi_object_t *)group, 384 MDL); 385 group_object_dereference (&group, MDL); 386 } 387 } else if (!*lp) 388 return ISC_R_NOTFOUND; 389 } 390 391 /* If we get to here without finding a group, no valid key was 392 specified. */ 393 if (!*lp) 394 return DHCP_R_NOKEYS; 395 396 if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) { 397 omapi_object_dereference (lp, MDL); 398 return ISC_R_NOTFOUND; 399 } 400 return ISC_R_SUCCESS; 401 } 402 403 isc_result_t dhcp_group_create (omapi_object_t **lp, 404 omapi_object_t *id) 405 { 406 struct group_object *group; 407 isc_result_t status; 408 group = (struct group_object *)0; 409 410 status = group_object_allocate (&group, MDL); 411 if (status != ISC_R_SUCCESS) 412 return status; 413 group -> flags = GROUP_OBJECT_DYNAMIC; 414 status = omapi_object_reference (lp, (omapi_object_t *)group, MDL); 415 group_object_dereference (&group, MDL); 416 return status; 417 } 418 419 isc_result_t dhcp_group_remove (omapi_object_t *lp, 420 omapi_object_t *id) 421 { 422 struct group_object *group; 423 isc_result_t status; 424 if (lp -> type != dhcp_type_group) 425 return DHCP_R_INVALIDARG; 426 group = (struct group_object *)lp; 427 428 group -> flags |= GROUP_OBJECT_DELETED; 429 if (group_write_hook) { 430 if (!(*group_write_hook) (group)) 431 return ISC_R_IOERROR; 432 } 433 434 status = dhcp_group_destroy ((omapi_object_t *)group, MDL); 435 436 return status; 437 } 438 439 isc_result_t dhcp_control_set_value (omapi_object_t *h, 440 omapi_object_t *id, 441 omapi_data_string_t *name, 442 omapi_typed_data_t *value) 443 { 444 dhcp_control_object_t *control; 445 isc_result_t status; 446 unsigned long newstate; 447 448 if (h -> type != dhcp_type_control) 449 return DHCP_R_INVALIDARG; 450 control = (dhcp_control_object_t *)h; 451 452 if (!omapi_ds_strcmp (name, "state")) { 453 status = omapi_get_int_value (&newstate, value); 454 if (status != ISC_R_SUCCESS) 455 return status; 456 status = libdhcp_callbacks.dhcp_set_control_state 457 (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 struct subnet *subnet; 661 662 if (h -> type != dhcp_type_subnet) 663 return DHCP_R_INVALIDARG; 664 665 subnet = (struct subnet *)h; 666 if (subnet -> next_subnet) 667 subnet_dereference (&subnet -> next_subnet, file, line); 668 if (subnet -> next_sibling) 669 subnet_dereference (&subnet -> next_sibling, file, line); 670 if (subnet -> shared_network) 671 shared_network_dereference (&subnet -> shared_network, 672 file, line); 673 if (subnet -> interface) 674 interface_dereference (&subnet -> interface, file, line); 675 if (subnet -> group) 676 group_dereference (&subnet -> group, file, line); 677 678 return ISC_R_SUCCESS; 679 } 680 681 isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h, 682 const char *name, va_list ap) 683 { 684 /* In this function h should be a (struct subnet *) */ 685 686 isc_result_t status; 687 688 if (h -> type != dhcp_type_subnet) 689 return DHCP_R_INVALIDARG; 690 691 /* Can't write subnets yet. */ 692 693 /* Try to find some inner object that can take the value. */ 694 if (h -> inner && h -> inner -> type -> get_value) { 695 status = ((*(h -> inner -> type -> signal_handler)) 696 (h -> inner, name, ap)); 697 if (status == ISC_R_SUCCESS) 698 return status; 699 } 700 701 return ISC_R_NOTFOUND; 702 } 703 704 isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c, 705 omapi_object_t *id, 706 omapi_object_t *h) 707 { 708 /* In this function h should be a (struct subnet *) */ 709 710 isc_result_t status; 711 712 if (h -> type != dhcp_type_subnet) 713 return DHCP_R_INVALIDARG; 714 715 /* Can't stuff subnet values yet. */ 716 717 /* Write out the inner object, if any. */ 718 if (h -> inner && h -> inner -> type -> stuff_values) { 719 status = ((*(h -> inner -> type -> stuff_values)) 720 (c, id, h -> inner)); 721 if (status == ISC_R_SUCCESS) 722 return status; 723 } 724 725 return ISC_R_SUCCESS; 726 } 727 728 isc_result_t dhcp_subnet_lookup (omapi_object_t **lp, 729 omapi_object_t *id, 730 omapi_object_t *ref) 731 { 732 /* Can't look up subnets yet. */ 733 734 /* If we get to here without finding a subnet, no valid key was 735 specified. */ 736 if (!*lp) 737 return DHCP_R_NOKEYS; 738 return ISC_R_SUCCESS; 739 } 740 741 isc_result_t dhcp_subnet_create (omapi_object_t **lp, 742 omapi_object_t *id) 743 { 744 return ISC_R_NOTIMPLEMENTED; 745 } 746 747 isc_result_t dhcp_subnet_remove (omapi_object_t *lp, 748 omapi_object_t *id) 749 { 750 return ISC_R_NOTIMPLEMENTED; 751 } 752 753 isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, 754 omapi_object_t *id, 755 omapi_data_string_t *name, 756 omapi_typed_data_t *value) 757 { 758 /* In this function h should be a (struct shared_network *) */ 759 760 isc_result_t status; 761 762 if (h -> type != dhcp_type_shared_network) 763 return DHCP_R_INVALIDARG; 764 765 /* No values to set yet. */ 766 767 /* Try to find some inner object that can take the value. */ 768 if (h -> inner && h -> inner -> type -> set_value) { 769 status = ((*(h -> inner -> type -> set_value)) 770 (h -> inner, id, name, value)); 771 if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) 772 return status; 773 } 774 775 return ISC_R_NOTFOUND; 776 } 777 778 779 isc_result_t dhcp_shared_network_get_value (omapi_object_t *h, 780 omapi_object_t *id, 781 omapi_data_string_t *name, 782 omapi_value_t **value) 783 { 784 /* In this function h should be a (struct shared_network *) */ 785 786 isc_result_t status; 787 788 if (h -> type != dhcp_type_shared_network) 789 return DHCP_R_INVALIDARG; 790 791 /* No values to get yet. */ 792 793 /* Try to find some inner object that can provide the value. */ 794 if (h -> inner && h -> inner -> type -> get_value) { 795 status = ((*(h -> inner -> type -> get_value)) 796 (h -> inner, id, name, value)); 797 if (status == ISC_R_SUCCESS) 798 return status; 799 } 800 return ISC_R_NOTFOUND; 801 } 802 803 isc_result_t dhcp_shared_network_destroy (omapi_object_t *h, 804 const char *file, int line) 805 { 806 /* In this function h should be a (struct shared_network *) */ 807 808 struct shared_network *shared_network; 809 810 if (h -> type != dhcp_type_shared_network) 811 return DHCP_R_INVALIDARG; 812 813 shared_network = (struct shared_network *)h; 814 if (shared_network -> next) 815 shared_network_dereference (&shared_network -> next, 816 file, line); 817 if (shared_network -> name) { 818 dfree (shared_network -> name, file, line); 819 shared_network -> name = 0; 820 } 821 if (shared_network -> subnets) 822 subnet_dereference (&shared_network -> subnets, file, line); 823 if (shared_network -> interface) 824 interface_dereference (&shared_network -> interface, 825 file, line); 826 if (shared_network -> pools) 827 omapi_object_dereference ((omapi_object_t **) 828 &shared_network -> pools, file, line); 829 if (shared_network -> group) 830 group_dereference (&shared_network -> group, file, line); 831 #if defined (FAILOVER_PROTOCOL) 832 if (shared_network -> failover_peer) 833 omapi_object_dereference ((omapi_object_t **) 834 &shared_network -> failover_peer, 835 file, line); 836 #endif 837 838 return ISC_R_SUCCESS; 839 } 840 841 isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h, 842 const char *name, 843 va_list ap) 844 { 845 /* In this function h should be a (struct shared_network *) */ 846 847 isc_result_t status; 848 849 if (h -> type != dhcp_type_shared_network) 850 return DHCP_R_INVALIDARG; 851 852 /* Can't write shared_networks yet. */ 853 854 /* Try to find some inner object that can take the value. */ 855 if (h -> inner && h -> inner -> type -> get_value) { 856 status = ((*(h -> inner -> type -> signal_handler)) 857 (h -> inner, name, ap)); 858 if (status == ISC_R_SUCCESS) 859 return status; 860 } 861 862 return ISC_R_NOTFOUND; 863 } 864 865 isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c, 866 omapi_object_t *id, 867 omapi_object_t *h) 868 { 869 /* In this function h should be a (struct shared_network *) */ 870 871 isc_result_t status; 872 873 if (h -> type != dhcp_type_shared_network) 874 return DHCP_R_INVALIDARG; 875 876 /* Can't stuff shared_network values yet. */ 877 878 /* Write out the inner object, if any. */ 879 if (h -> inner && h -> inner -> type -> stuff_values) { 880 status = ((*(h -> inner -> type -> stuff_values)) 881 (c, id, h -> inner)); 882 if (status == ISC_R_SUCCESS) 883 return status; 884 } 885 886 return ISC_R_SUCCESS; 887 } 888 889 isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp, 890 omapi_object_t *id, 891 omapi_object_t *ref) 892 { 893 /* Can't look up shared_networks yet. */ 894 895 /* If we get to here without finding a shared_network, no valid key was 896 specified. */ 897 if (!*lp) 898 return DHCP_R_NOKEYS; 899 return ISC_R_SUCCESS; 900 } 901 902 isc_result_t dhcp_shared_network_create (omapi_object_t **lp, 903 omapi_object_t *id) 904 { 905 return ISC_R_NOTIMPLEMENTED; 906 } 907 908 isc_result_t dhcp_shared_network_remove (omapi_object_t *lp, 909 omapi_object_t *id) 910 { 911 return ISC_R_NOTIMPLEMENTED; 912 } 913 914