3 OMAPI object interfaces for the DHCP server. */
6 * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1999-2003 by Internet Software Consortium
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.
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.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
25 * https://www.isc.org/
29 /* Many, many thanks to Brian Murrell and BCtel for this code - BCtel
30 provided the funding that resulted in this code and the entire
31 OMAPI support library being written, and Brian helped brainstorm
32 and refine the requirements. To the extent that this code is
33 useful, you have Brian and BCtel to thank. Any limitations in the
34 code are a result of mistakes on my part. -- Ted Lemon */
37 #include <omapip/omapip_p.h>
39 static isc_result_t
class_lookup (omapi_object_t
**,
40 omapi_object_t
*, omapi_object_t
*,
41 omapi_object_type_t
*);
43 static isc_result_t
update_lease_flags(struct lease
* lease
,
44 omapi_typed_data_t
*value
);
46 omapi_object_type_t
*dhcp_type_lease
;
47 omapi_object_type_t
*dhcp_type_pool
;
48 omapi_object_type_t
*dhcp_type_class
;
49 omapi_object_type_t
*dhcp_type_subclass
;
50 omapi_object_type_t
*dhcp_type_host
;
51 #if defined (FAILOVER_PROTOCOL)
52 omapi_object_type_t
*dhcp_type_failover_state
;
53 omapi_object_type_t
*dhcp_type_failover_link
;
54 omapi_object_type_t
*dhcp_type_failover_listener
;
57 void dhcp_db_objects_setup ()
61 status
= omapi_object_type_register (&dhcp_type_lease
,
66 dhcp_lease_signal_handler
,
67 dhcp_lease_stuff_values
,
71 #if defined (COMPACT_LEASES)
78 sizeof (struct lease
),
80 if (status
!= ISC_R_SUCCESS
)
81 log_fatal ("Can't register lease object type: %s",
82 isc_result_totext (status
));
84 status
= omapi_object_type_register (&dhcp_type_class
,
89 dhcp_class_signal_handler
,
90 dhcp_class_stuff_values
,
93 dhcp_class_remove
, 0, 0, 0,
94 sizeof (struct class), 0,
96 if (status
!= ISC_R_SUCCESS
)
97 log_fatal ("Can't register class object type: %s",
98 isc_result_totext (status
));
100 status
= omapi_object_type_register (&dhcp_type_subclass
,
102 dhcp_subclass_set_value
,
103 dhcp_subclass_get_value
,
105 dhcp_subclass_signal_handler
,
106 dhcp_subclass_stuff_values
,
107 dhcp_subclass_lookup
,
108 dhcp_subclass_create
,
109 dhcp_subclass_remove
, 0, 0, 0,
110 sizeof (struct class), 0, RC_MISC
);
111 if (status
!= ISC_R_SUCCESS
)
112 log_fatal ("Can't register subclass object type: %s",
113 isc_result_totext (status
));
115 status
= omapi_object_type_register (&dhcp_type_pool
,
120 dhcp_pool_signal_handler
,
121 dhcp_pool_stuff_values
,
124 dhcp_pool_remove
, 0, 0, 0,
125 sizeof (struct pool
), 0, RC_MISC
);
127 if (status
!= ISC_R_SUCCESS
)
128 log_fatal ("Can't register pool object type: %s",
129 isc_result_totext (status
));
131 status
= omapi_object_type_register (&dhcp_type_host
,
136 dhcp_host_signal_handler
,
137 dhcp_host_stuff_values
,
140 dhcp_host_remove
, 0, 0, 0,
141 sizeof (struct host_decl
),
144 if (status
!= ISC_R_SUCCESS
)
145 log_fatal ("Can't register host object type: %s",
146 isc_result_totext (status
));
148 #if defined (FAILOVER_PROTOCOL)
149 status
= omapi_object_type_register (&dhcp_type_failover_state
,
151 dhcp_failover_state_set_value
,
152 dhcp_failover_state_get_value
,
153 dhcp_failover_state_destroy
,
154 dhcp_failover_state_signal
,
155 dhcp_failover_state_stuff
,
156 dhcp_failover_state_lookup
,
157 dhcp_failover_state_create
,
158 dhcp_failover_state_remove
,
160 sizeof (dhcp_failover_state_t
),
163 if (status
!= ISC_R_SUCCESS
)
164 log_fatal ("Can't register failover state object type: %s",
165 isc_result_totext (status
));
167 status
= omapi_object_type_register (&dhcp_type_failover_link
,
169 dhcp_failover_link_set_value
,
170 dhcp_failover_link_get_value
,
171 dhcp_failover_link_destroy
,
172 dhcp_failover_link_signal
,
173 dhcp_failover_link_stuff_values
,
175 sizeof (dhcp_failover_link_t
), 0,
178 if (status
!= ISC_R_SUCCESS
)
179 log_fatal ("Can't register failover link object type: %s",
180 isc_result_totext (status
));
182 status
= omapi_object_type_register (&dhcp_type_failover_listener
,
184 dhcp_failover_listener_set_value
,
185 dhcp_failover_listener_get_value
,
186 dhcp_failover_listener_destroy
,
187 dhcp_failover_listener_signal
,
188 dhcp_failover_listener_stuff
,
191 (dhcp_failover_listener_t
), 0,
194 if (status
!= ISC_R_SUCCESS
)
195 log_fatal ("Can't register failover listener object type: %s",
196 isc_result_totext (status
));
197 #endif /* FAILOVER_PROTOCOL */
200 isc_result_t
dhcp_lease_set_value (omapi_object_t
*h
,
202 omapi_data_string_t
*name
,
203 omapi_typed_data_t
*value
)
208 if (h
-> type
!= dhcp_type_lease
)
209 return DHCP_R_INVALIDARG
;
210 lease
= (struct lease
*)h
;
212 /* We're skipping a lot of things it might be interesting to
213 set - for now, we just make it possible to whack the state. */
214 if (!omapi_ds_strcmp (name
, "state")) {
216 const char *ols
, *nls
;
217 status
= omapi_get_int_value (&bar
, value
);
218 if (status
!= ISC_R_SUCCESS
)
221 if (bar
< 1 || bar
> FTS_LAST
)
222 return DHCP_R_INVALIDARG
;
223 nls
= binding_state_names
[bar
- 1];
224 if (lease
-> binding_state
>= 1 &&
225 lease
-> binding_state
<= FTS_LAST
)
226 ols
= binding_state_names
[lease
-> binding_state
- 1];
228 ols
= "unknown state";
230 if (lease
-> binding_state
!= bar
) {
231 lease
-> next_binding_state
= bar
;
232 if (supersede_lease (lease
, NULL
, 1, 1, 1, 0)) {
233 log_info ("lease %s state changed from %s to %s",
234 piaddr(lease
->ip_addr
), ols
, nls
);
235 return ISC_R_SUCCESS
;
237 log_info ("lease %s state change from %s to %s failed.",
238 piaddr (lease
-> ip_addr
), ols
, nls
);
239 return ISC_R_IOERROR
;
241 return DHCP_R_UNCHANGED
;
242 } else if (!omapi_ds_strcmp (name
, "ip-address")) {
244 } else if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
245 return DHCP_R_UNCHANGED
; /* XXX take change. */
246 } else if (!omapi_ds_strcmp (name
, "hostname")) {
247 return DHCP_R_UNCHANGED
; /* XXX take change. */
248 } else if (!omapi_ds_strcmp (name
, "client-hostname")) {
249 return DHCP_R_UNCHANGED
; /* XXX take change. */
250 } else if (!omapi_ds_strcmp (name
, "host")) {
251 return DHCP_R_UNCHANGED
; /* XXX take change. */
252 } else if (!omapi_ds_strcmp (name
, "subnet")) {
253 return DHCP_R_INVALIDARG
;
254 } else if (!omapi_ds_strcmp (name
, "pool")) {
256 } else if (!omapi_ds_strcmp (name
, "starts")) {
258 } else if (!omapi_ds_strcmp (name
, "ends")) {
259 unsigned long lease_end
, old_lease_end
;
260 status
= omapi_get_int_value (&lease_end
, value
);
261 if (status
!= ISC_R_SUCCESS
)
263 old_lease_end
= lease
->ends
;
264 lease
->ends
= lease_end
;
265 if (supersede_lease (lease
, NULL
, 1, 1, 1, 0)) {
266 log_info ("lease %s end changed from %lu to %lu",
267 piaddr(lease
->ip_addr
), old_lease_end
, lease_end
);
268 return ISC_R_SUCCESS
;
270 log_info ("lease %s end change from %lu to %lu failed",
271 piaddr(lease
->ip_addr
), old_lease_end
, lease_end
);
272 return ISC_R_IOERROR
;
273 } else if (!omapi_ds_strcmp(name
, "flags")) {
274 return (update_lease_flags(lease
, value
));
275 } else if (!omapi_ds_strcmp (name
, "billing-class")) {
276 return DHCP_R_UNCHANGED
; /* XXX carefully allow change. */
277 } else if (!omapi_ds_strcmp (name
, "hardware-address")) {
278 return DHCP_R_UNCHANGED
; /* XXX take change. */
279 } else if (!omapi_ds_strcmp (name
, "hardware-type")) {
280 return DHCP_R_UNCHANGED
; /* XXX take change. */
281 } else if (lease
-> scope
) {
282 status
= binding_scope_set_value (lease
-> scope
, 0, name
, value
);
283 if (status
== ISC_R_SUCCESS
) {
284 if (write_lease (lease
) && commit_leases ())
285 return ISC_R_SUCCESS
;
286 return ISC_R_IOERROR
;
290 /* Try to find some inner object that can take the value. */
291 if (h
-> inner
&& h
-> inner
-> type
-> set_value
) {
292 status
= ((*(h
-> inner
-> type
-> set_value
))
293 (h
-> inner
, id
, name
, value
));
294 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
298 if (!lease
-> scope
) {
299 if (!binding_scope_allocate (&lease
-> scope
, MDL
))
300 return ISC_R_NOMEMORY
;
302 status
= binding_scope_set_value (lease
-> scope
, 1, name
, value
);
303 if (status
!= ISC_R_SUCCESS
)
306 if (write_lease (lease
) && commit_leases ())
307 return ISC_R_SUCCESS
;
308 return ISC_R_IOERROR
;
312 * \brief Updates the lease's flags to a given value
314 * In order to update the lease's flags, we make a copy of the
315 * lease, and update the copy's flags with the new value.
316 * We then use the updated copy as the second parameter to a
317 * call to supersede_lease(). This ensures that the lease
318 * moves between queues correctly. This is critical when
319 * the RESERVED_LEASE flag is being changed.
321 * Note that only the EPHEMERAL flags are permitted to be changed.
323 * \param lease - pointer to the lease to update
324 * \param value - omapi data value containing the new flags value
326 * \return ISC_R_SUCCESS if the lease was successfully updated,
327 * DHCP_R_UNCHANGED if new value would result in no change to the
328 * lease's flags, or an appropriate status on other errors
330 static isc_result_t
update_lease_flags(struct lease
* lease
,
331 omapi_typed_data_t
*value
)
335 struct lease
* lupdate
= NULL
;
338 /* Grab the requested flags value. We (the server) send flags
339 * out as 1-byte, so we expect clients to do the same. However
340 * omshell, will send a network-ordered 4 byte integer if the
341 * input is "set flags = <n>", so we'll accomdate that too. */
342 if (value
->u
.buffer
.len
== 1) {
343 newflags
= value
->u
.buffer
.value
[0];
347 status
= omapi_get_int_value (&tmp
, value
);
348 if (status
!= ISC_R_SUCCESS
) {
352 newflags
= (u_int8_t
)tmp
;
355 /* Save off the current flags value. */
356 oldflags
= lease
->flags
;
358 /* The new value must preserve all PERSISTANT_FLAGS */
359 newflags
= ((lease
->flags
& ~EPHEMERAL_FLAGS
) |
360 (newflags
& EPHEMERAL_FLAGS
));
362 /* If there's no net change, we're done */
363 if (oldflags
== newflags
) {
364 return (DHCP_R_UNCHANGED
);
367 /* Make a copy of the lease. */
368 if (!lease_copy(&lupdate
, lease
, MDL
)) {
369 return (ISC_R_FAILURE
);
372 /* Set the copy's flags to the new value */
373 lupdate
->flags
= newflags
;
375 /* Attempt to update the lease */
376 if (!supersede_lease(lease
, lupdate
, 1, 1, 1, 0)) {
377 log_error("Failed to update flags for lease %s.",
378 piaddr(lease
->ip_addr
));
379 status
= ISC_R_FAILURE
;
381 log_debug ("lease flags changed from %x to %x for lease %s.",
382 oldflags
, newflags
, piaddr(lease
->ip_addr
));
383 status
= ISC_R_SUCCESS
;
386 lease_dereference(&lupdate
, MDL
);
391 isc_result_t
dhcp_lease_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
392 omapi_data_string_t
*name
,
393 omapi_value_t
**value
)
398 if (h
-> type
!= dhcp_type_lease
)
399 return DHCP_R_INVALIDARG
;
400 lease
= (struct lease
*)h
;
402 if (!omapi_ds_strcmp (name
, "state"))
403 return omapi_make_int_value (value
, name
,
404 (int)lease
-> binding_state
, MDL
);
405 else if (!omapi_ds_strcmp (name
, "ip-address"))
406 return omapi_make_const_value (value
, name
,
407 lease
-> ip_addr
.iabuf
,
408 lease
-> ip_addr
.len
, MDL
);
409 else if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
410 return omapi_make_const_value (value
, name
,
412 lease
-> uid_len
, MDL
);
413 } else if (!omapi_ds_strcmp (name
, "client-hostname")) {
414 if (lease
-> client_hostname
)
415 return omapi_make_string_value
416 (value
, name
, lease
-> client_hostname
, MDL
);
417 return ISC_R_NOTFOUND
;
418 } else if (!omapi_ds_strcmp (name
, "host")) {
420 return omapi_make_handle_value
422 ((omapi_object_t
*)lease
-> host
), MDL
);
423 } else if (!omapi_ds_strcmp (name
, "subnet"))
424 return omapi_make_handle_value (value
, name
,
426 lease
-> subnet
), MDL
);
427 else if (!omapi_ds_strcmp (name
, "pool"))
428 return omapi_make_handle_value (value
, name
,
430 lease
-> pool
), MDL
);
431 else if (!omapi_ds_strcmp (name
, "billing-class")) {
432 if (lease
-> billing_class
)
433 return omapi_make_handle_value
435 ((omapi_object_t
*)lease
-> billing_class
),
437 return ISC_R_NOTFOUND
;
438 } else if (!omapi_ds_strcmp (name
, "hardware-address")) {
439 if (lease
-> hardware_addr
.hlen
)
440 return omapi_make_const_value
441 (value
, name
, &lease
-> hardware_addr
.hbuf
[1],
442 (unsigned)(lease
-> hardware_addr
.hlen
- 1),
444 return ISC_R_NOTFOUND
;
445 } else if (!omapi_ds_strcmp (name
, "hardware-type")) {
446 if (lease
-> hardware_addr
.hlen
)
447 return omapi_make_int_value
448 (value
, name
, lease
-> hardware_addr
.hbuf
[0],
450 return ISC_R_NOTFOUND
;
451 } else if (lease
-> scope
) {
452 status
= binding_scope_get_value (value
, lease
-> scope
, name
);
453 if (status
!= ISC_R_NOTFOUND
)
457 /* Try to find some inner object that can take the value. */
458 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
459 status
= ((*(h
-> inner
-> type
-> get_value
))
460 (h
-> inner
, id
, name
, value
));
461 if (status
== ISC_R_SUCCESS
)
464 return DHCP_R_UNKNOWNATTRIBUTE
;
467 isc_result_t
dhcp_lease_destroy (omapi_object_t
*h
, const char *file
, int line
)
471 if (h
->type
!= dhcp_type_lease
)
472 return DHCP_R_INVALIDARG
;
473 lease
= (struct lease
*)h
;
476 uid_hash_delete (lease
);
477 hw_hash_delete (lease
);
479 if (lease
->on_star
.on_release
)
480 executable_statement_dereference (&lease
->on_star
.on_release
,
482 if (lease
->on_star
.on_expiry
)
483 executable_statement_dereference (&lease
->on_star
.on_expiry
,
485 if (lease
->on_star
.on_commit
)
486 executable_statement_dereference (&lease
->on_star
.on_commit
,
489 binding_scope_dereference (&lease
->scope
, file
, line
);
491 if (lease
->agent_options
)
492 option_chain_head_dereference (&lease
->agent_options
,
494 if (lease
->uid
&& lease
->uid
!= lease
->uid_buf
) {
495 dfree (lease
->uid
, MDL
);
496 lease
->uid
= &lease
->uid_buf
[0];
500 if (lease
->client_hostname
) {
501 dfree (lease
->client_hostname
, MDL
);
502 lease
->client_hostname
= (char *)0;
506 host_dereference (&lease
->host
, file
, line
);
508 subnet_dereference (&lease
->subnet
, file
, line
);
510 pool_dereference (&lease
->pool
, file
, line
);
513 free_lease_state (lease
->state
, file
, line
);
514 lease
->state
= (struct lease_state
*)0;
516 cancel_timeout (lease_ping_timeout
, lease
);
517 --outstanding_pings
; /* XXX */
520 if (lease
->billing_class
)
522 (&lease
->billing_class
, file
, line
);
524 /* We no longer check for a next pointer as that should
525 * be cleared when we destroy the pool and as before we
526 * should only ever be doing that on exit.
528 lease_dereference (&lease->next, file, line);
532 lease_dereference (&lease
->n_hw
, file
, line
);
534 lease_dereference (&lease
->n_uid
, file
, line
);
535 if (lease
->next_pending
)
536 lease_dereference (&lease
->next_pending
, file
, line
);
538 return ISC_R_SUCCESS
;
541 isc_result_t
dhcp_lease_signal_handler (omapi_object_t
*h
,
542 const char *name
, va_list ap
)
544 /* h should point to (struct lease *) */
547 if (h
-> type
!= dhcp_type_lease
)
548 return DHCP_R_INVALIDARG
;
550 if (!strcmp (name
, "updated"))
551 return ISC_R_SUCCESS
;
553 /* Try to find some inner object that can take the value. */
554 if (h
-> inner
&& h
-> inner
-> type
-> signal_handler
) {
555 status
= ((*(h
-> inner
-> type
-> signal_handler
))
556 (h
-> inner
, name
, ap
));
557 if (status
== ISC_R_SUCCESS
)
560 return ISC_R_NOTFOUND
;
563 isc_result_t
dhcp_lease_stuff_values (omapi_object_t
*c
,
572 if (h
-> type
!= dhcp_type_lease
)
573 return DHCP_R_INVALIDARG
;
574 lease
= (struct lease
*)h
;
576 /* Write out all the values. */
578 status
= omapi_connection_put_named_uint32(c
, "state",
579 lease
->binding_state
);
580 if (status
!= ISC_R_SUCCESS
)
583 status
= omapi_connection_put_name (c
, "ip-address");
584 if (status
!= ISC_R_SUCCESS
)
586 status
= omapi_connection_put_uint32 (c
, lease
-> ip_addr
.len
);
587 if (status
!= ISC_R_SUCCESS
)
589 status
= omapi_connection_copyin (c
, lease
-> ip_addr
.iabuf
,
590 lease
-> ip_addr
.len
);
591 if (status
!= ISC_R_SUCCESS
)
594 if (lease
-> uid_len
) {
595 status
= omapi_connection_put_name (c
,
596 "dhcp-client-identifier");
597 if (status
!= ISC_R_SUCCESS
)
599 status
= omapi_connection_put_uint32 (c
, lease
-> uid_len
);
600 if (status
!= ISC_R_SUCCESS
)
602 if (lease
-> uid_len
) {
603 status
= omapi_connection_copyin (c
, lease
-> uid
,
605 if (status
!= ISC_R_SUCCESS
)
610 if (lease
-> client_hostname
) {
611 status
= omapi_connection_put_name (c
, "client-hostname");
612 if (status
!= ISC_R_SUCCESS
)
615 omapi_connection_put_string (c
,
616 lease
-> client_hostname
);
617 if (status
!= ISC_R_SUCCESS
)
622 status
= omapi_connection_put_name (c
, "host");
623 if (status
!= ISC_R_SUCCESS
)
625 status
= omapi_connection_put_handle (c
,
628 if (status
!= ISC_R_SUCCESS
)
632 status
= omapi_connection_put_name (c
, "subnet");
633 if (status
!= ISC_R_SUCCESS
)
635 status
= omapi_connection_put_handle
636 (c
, (omapi_object_t
*)lease
-> subnet
);
637 if (status
!= ISC_R_SUCCESS
)
640 status
= omapi_connection_put_name (c
, "pool");
641 if (status
!= ISC_R_SUCCESS
)
643 status
= omapi_connection_put_handle (c
,
644 (omapi_object_t
*)lease
-> pool
);
645 if (status
!= ISC_R_SUCCESS
)
648 if (lease
-> billing_class
) {
649 status
= omapi_connection_put_name (c
, "billing-class");
650 if (status
!= ISC_R_SUCCESS
)
652 status
= omapi_connection_put_handle
653 (c
, (omapi_object_t
*)lease
-> billing_class
);
654 if (status
!= ISC_R_SUCCESS
)
658 if (lease
-> hardware_addr
.hlen
) {
659 status
= omapi_connection_put_name (c
, "hardware-address");
660 if (status
!= ISC_R_SUCCESS
)
662 status
= (omapi_connection_put_uint32
664 (unsigned long)(lease
-> hardware_addr
.hlen
- 1)));
665 if (status
!= ISC_R_SUCCESS
)
667 status
= (omapi_connection_copyin
668 (c
, &lease
-> hardware_addr
.hbuf
[1],
669 (unsigned long)(lease
-> hardware_addr
.hlen
- 1)));
671 if (status
!= ISC_R_SUCCESS
)
674 status
= omapi_connection_put_named_uint32(c
, "hardware-type",
675 lease
->hardware_addr
.hbuf
[0]);
676 if (status
!= ISC_R_SUCCESS
)
680 /* TIME values may be 64-bit, depending on system architecture.
681 * OMAPI must be system independent, both in terms of transmitting
682 * bytes on the wire in network byte order, and in terms of being
683 * readable and usable by both systems.
685 * XXX: In a future feature release, a put_int64() should be made
686 * to exist, and perhaps a put_time() wrapper that selects which
687 * to use based upon sizeof(TIME). In the meantime, use existing,
690 bouncer
= (u_int32_t
)lease
->ends
;
691 status
= omapi_connection_put_named_uint32(c
, "ends", bouncer
);
692 if (status
!= ISC_R_SUCCESS
)
695 bouncer
= (u_int32_t
)lease
->starts
;
696 status
= omapi_connection_put_named_uint32(c
, "starts", bouncer
);
697 if (status
!= ISC_R_SUCCESS
)
700 bouncer
= (u_int32_t
)lease
->tstp
;
701 status
= omapi_connection_put_named_uint32(c
, "tstp", bouncer
);
702 if (status
!= ISC_R_SUCCESS
)
705 bouncer
= (u_int32_t
)lease
->tsfp
;
706 status
= omapi_connection_put_named_uint32(c
, "tsfp", bouncer
);
707 if (status
!= ISC_R_SUCCESS
)
710 bouncer
= (u_int32_t
)lease
->atsfp
;
711 status
= omapi_connection_put_named_uint32(c
, "atsfp", bouncer
);
712 if (status
!= ISC_R_SUCCESS
)
715 bouncer
= (u_int32_t
)lease
->cltt
;
716 status
= omapi_connection_put_named_uint32(c
, "cltt", bouncer
);
717 if (status
!= ISC_R_SUCCESS
)
720 status
= omapi_connection_put_name (c
, "flags");
721 if (status
!= ISC_R_SUCCESS
)
723 status
= omapi_connection_put_uint32(c
, sizeof(flagbuf
));
724 if (status
!= ISC_R_SUCCESS
)
726 flagbuf
= lease
->flags
& EPHEMERAL_FLAGS
;
727 status
= omapi_connection_copyin(c
, &flagbuf
, sizeof(flagbuf
));
728 if (status
!= ISC_R_SUCCESS
)
731 if (lease
-> scope
) {
732 status
= binding_scope_stuff_values (c
, lease
-> scope
);
733 if (status
!= ISC_R_SUCCESS
)
737 /* Write out the inner object, if any. */
738 if (h
-> inner
&& h
-> inner
-> type
-> stuff_values
) {
739 status
= ((*(h
-> inner
-> type
-> stuff_values
))
740 (c
, id
, h
-> inner
));
741 if (status
== ISC_R_SUCCESS
)
745 return ISC_R_SUCCESS
;
748 isc_result_t
dhcp_lease_lookup (omapi_object_t
**lp
,
749 omapi_object_t
*id
, omapi_object_t
*ref
)
751 omapi_value_t
*tv
= (omapi_value_t
*)0;
756 return DHCP_R_NOKEYS
;
758 /* First see if we were sent a handle. */
759 status
= omapi_get_value_str (ref
, id
, "handle", &tv
);
760 if (status
== ISC_R_SUCCESS
) {
761 status
= omapi_handle_td_lookup (lp
, tv
-> value
);
763 omapi_value_dereference (&tv
, MDL
);
764 if (status
!= ISC_R_SUCCESS
)
767 /* Don't return the object if the type is wrong. */
768 if ((*lp
) -> type
!= dhcp_type_lease
) {
769 omapi_object_dereference (lp
, MDL
);
770 return DHCP_R_INVALIDARG
;
774 /* Now look for an IP address. */
775 status
= omapi_get_value_str (ref
, id
, "ip-address", &tv
);
776 if (status
== ISC_R_SUCCESS
) {
777 lease
= (struct lease
*)0;
778 lease_ip_hash_lookup(&lease
, lease_ip_addr_hash
,
779 tv
->value
->u
.buffer
.value
,
780 tv
->value
->u
.buffer
.len
, MDL
);
782 omapi_value_dereference (&tv
, MDL
);
784 /* If we already have a lease, and it's not the same one,
785 then the query was invalid. */
786 if (*lp
&& *lp
!= (omapi_object_t
*)lease
) {
787 omapi_object_dereference (lp
, MDL
);
788 lease_dereference (&lease
, MDL
);
789 return DHCP_R_KEYCONFLICT
;
792 omapi_object_dereference (lp
, MDL
);
793 return ISC_R_NOTFOUND
;
795 /* XXX fix so that hash lookup itself creates
796 XXX the reference. */
797 omapi_object_reference (lp
,
798 (omapi_object_t
*)lease
, MDL
);
799 lease_dereference (&lease
, MDL
);
803 /* Now look for a client identifier. */
804 status
= omapi_get_value_str (ref
, id
, "dhcp-client-identifier", &tv
);
805 if (status
== ISC_R_SUCCESS
) {
806 lease
= (struct lease
*)0;
807 lease_id_hash_lookup(&lease
, lease_uid_hash
,
808 tv
->value
->u
.buffer
.value
,
809 tv
->value
->u
.buffer
.len
, MDL
);
810 omapi_value_dereference (&tv
, MDL
);
812 if (*lp
&& *lp
!= (omapi_object_t
*)lease
) {
813 omapi_object_dereference (lp
, MDL
);
814 lease_dereference (&lease
, MDL
);
815 return DHCP_R_KEYCONFLICT
;
818 omapi_object_dereference (lp
, MDL
);
819 return ISC_R_NOTFOUND
;
820 } else if (lease
-> n_uid
) {
822 omapi_object_dereference (lp
, MDL
);
823 return DHCP_R_MULTIPLE
;
825 /* XXX fix so that hash lookup itself creates
826 XXX the reference. */
827 omapi_object_reference (lp
,
828 (omapi_object_t
*)lease
, MDL
);
829 lease_dereference (&lease
, MDL
);
833 /* Now look for a hardware address. */
834 status
= omapi_get_value_str (ref
, id
, "hardware-address", &tv
);
835 if (status
== ISC_R_SUCCESS
) {
836 unsigned char *haddr
;
839 len
= tv
-> value
-> u
.buffer
.len
+ 1;
840 haddr
= dmalloc (len
, MDL
);
842 omapi_value_dereference (&tv
, MDL
);
843 return ISC_R_NOMEMORY
;
846 memcpy (haddr
+ 1, tv
-> value
-> u
.buffer
.value
, len
- 1);
847 omapi_value_dereference (&tv
, MDL
);
849 status
= omapi_get_value_str (ref
, id
, "hardware-type", &tv
);
850 if (status
== ISC_R_SUCCESS
) {
851 if (tv
-> value
-> type
== omapi_datatype_data
) {
852 if ((tv
-> value
-> u
.buffer
.len
!= 4) ||
853 (tv
-> value
-> u
.buffer
.value
[0] != 0) ||
854 (tv
-> value
-> u
.buffer
.value
[1] != 0) ||
855 (tv
-> value
-> u
.buffer
.value
[2] != 0)) {
856 omapi_value_dereference (&tv
, MDL
);
858 return DHCP_R_INVALIDARG
;
861 haddr
[0] = tv
-> value
-> u
.buffer
.value
[3];
862 } else if (tv
-> value
-> type
== omapi_datatype_int
) {
863 haddr
[0] = (unsigned char)
864 tv
-> value
-> u
.integer
;
866 omapi_value_dereference (&tv
, MDL
);
868 return DHCP_R_INVALIDARG
;
871 omapi_value_dereference (&tv
, MDL
);
873 /* If no hardware-type is specified, default to
874 ethernet. This may or may not be a good idea,
875 but Telus is currently relying on this behavior.
877 haddr
[0] = HTYPE_ETHER
;
880 lease
= (struct lease
*)0;
881 lease_id_hash_lookup(&lease
, lease_hw_addr_hash
, haddr
, len
,
885 if (*lp
&& *lp
!= (omapi_object_t
*)lease
) {
886 omapi_object_dereference (lp
, MDL
);
887 lease_dereference (&lease
, MDL
);
888 return DHCP_R_KEYCONFLICT
;
891 omapi_object_dereference (lp
, MDL
);
892 return ISC_R_NOTFOUND
;
893 } else if (lease
-> n_hw
) {
895 omapi_object_dereference (lp
, MDL
);
896 lease_dereference (&lease
, MDL
);
897 return DHCP_R_MULTIPLE
;
899 /* XXX fix so that hash lookup itself creates
900 XXX the reference. */
901 omapi_object_reference (lp
,
902 (omapi_object_t
*)lease
, MDL
);
903 lease_dereference (&lease
, MDL
);
907 /* If we get to here without finding a lease, no valid key was
910 return DHCP_R_NOKEYS
;
911 return ISC_R_SUCCESS
;
914 isc_result_t
dhcp_lease_create (omapi_object_t
**lp
,
917 return ISC_R_NOTIMPLEMENTED
;
920 isc_result_t
dhcp_lease_remove (omapi_object_t
*lp
,
923 return ISC_R_NOTIMPLEMENTED
;
926 isc_result_t
dhcp_host_set_value (omapi_object_t
*h
,
928 omapi_data_string_t
*name
,
929 omapi_typed_data_t
*value
)
931 struct host_decl
*host
;
934 if (h
-> type
!= dhcp_type_host
)
935 return DHCP_R_INVALIDARG
;
936 host
= (struct host_decl
*)h
;
938 /* XXX For now, we can only set these values on new host objects.
939 XXX Soon, we need to be able to update host objects. */
940 if (!omapi_ds_strcmp (name
, "name")) {
943 if (value
&& (value
-> type
== omapi_datatype_data
||
944 value
-> type
== omapi_datatype_string
)) {
945 host
-> name
= dmalloc (value
-> u
.buffer
.len
+ 1,
948 return ISC_R_NOMEMORY
;
949 memcpy (host
-> name
,
950 value
-> u
.buffer
.value
,
951 value
-> u
.buffer
.len
);
952 host
-> name
[value
-> u
.buffer
.len
] = 0;
954 return DHCP_R_INVALIDARG
;
955 return ISC_R_SUCCESS
;
958 if (!omapi_ds_strcmp (name
, "group")) {
959 if (value
&& (value
-> type
== omapi_datatype_data
||
960 value
-> type
== omapi_datatype_string
)) {
961 struct group_object
*group
;
962 group
= (struct group_object
*)0;
963 group_hash_lookup (&group
, group_name_hash
,
964 (char *)value
-> u
.buffer
.value
,
965 value
-> u
.buffer
.len
, MDL
);
966 if (!group
|| (group
-> flags
& GROUP_OBJECT_DELETED
))
967 return ISC_R_NOTFOUND
;
969 group_dereference (&host
-> group
, MDL
);
970 group_reference (&host
-> group
, group
-> group
, MDL
);
971 if (host
-> named_group
)
972 group_object_dereference (&host
-> named_group
,
974 group_object_reference (&host
-> named_group
,
976 group_object_dereference (&group
, MDL
);
978 return DHCP_R_INVALIDARG
;
979 return ISC_R_SUCCESS
;
982 if (!omapi_ds_strcmp (name
, "hardware-address")) {
983 if (host
-> interface
.hlen
)
985 if (value
&& (value
-> type
== omapi_datatype_data
||
986 value
-> type
== omapi_datatype_string
)) {
987 if (value
-> u
.buffer
.len
>
988 (sizeof host
-> interface
.hbuf
) - 1)
989 return DHCP_R_INVALIDARG
;
990 memcpy (&host
-> interface
.hbuf
[1],
991 value
-> u
.buffer
.value
,
992 value
-> u
.buffer
.len
);
993 host
-> interface
.hlen
= value
-> u
.buffer
.len
+ 1;
995 return DHCP_R_INVALIDARG
;
996 return ISC_R_SUCCESS
;
999 if (!omapi_ds_strcmp (name
, "hardware-type")) {
1001 if ((value
!= NULL
) &&
1002 ((value
->type
== omapi_datatype_data
) &&
1003 (value
->u
.buffer
.len
== sizeof(type
)))) {
1004 if (value
->u
.buffer
.len
> sizeof(type
))
1005 return (DHCP_R_INVALIDARG
);
1006 memcpy(&type
, value
->u
.buffer
.value
,
1007 value
->u
.buffer
.len
);
1009 } else if ((value
!= NULL
) &&
1010 (value
->type
== omapi_datatype_int
))
1011 type
= value
->u
.integer
;
1013 return (DHCP_R_INVALIDARG
);
1014 host
->interface
.hbuf
[0] = type
;
1015 return (ISC_R_SUCCESS
);
1018 if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
1019 if (host
-> client_identifier
.data
)
1020 return ISC_R_EXISTS
;
1021 if (value
&& (value
-> type
== omapi_datatype_data
||
1022 value
-> type
== omapi_datatype_string
)) {
1023 if (!buffer_allocate (&host
-> client_identifier
.buffer
,
1024 value
-> u
.buffer
.len
, MDL
))
1025 return ISC_R_NOMEMORY
;
1026 host
-> client_identifier
.data
=
1027 &host
-> client_identifier
.buffer
-> data
[0];
1028 memcpy (host
-> client_identifier
.buffer
-> data
,
1029 value
-> u
.buffer
.value
,
1030 value
-> u
.buffer
.len
);
1031 host
-> client_identifier
.len
= value
-> u
.buffer
.len
;
1033 return DHCP_R_INVALIDARG
;
1034 return ISC_R_SUCCESS
;
1037 if (!omapi_ds_strcmp (name
, "ip-address")) {
1038 if (host
-> fixed_addr
)
1039 option_cache_dereference (&host
-> fixed_addr
, MDL
);
1041 return ISC_R_SUCCESS
;
1042 if (value
&& (value
-> type
== omapi_datatype_data
||
1043 value
-> type
== omapi_datatype_string
)) {
1044 struct data_string ds
;
1045 memset (&ds
, 0, sizeof ds
);
1046 ds
.len
= value
-> u
.buffer
.len
;
1047 if (!buffer_allocate (&ds
.buffer
, ds
.len
, MDL
))
1048 return ISC_R_NOMEMORY
;
1049 ds
.data
= (&ds
.buffer
-> data
[0]);
1050 memcpy (ds
.buffer
-> data
,
1051 value
-> u
.buffer
.value
, ds
.len
);
1052 if (!option_cache (&host
-> fixed_addr
,
1053 &ds
, (struct expression
*)0,
1054 (struct option
*)0, MDL
)) {
1055 data_string_forget (&ds
, MDL
);
1056 return ISC_R_NOMEMORY
;
1058 data_string_forget (&ds
, MDL
);
1060 return DHCP_R_INVALIDARG
;
1061 return ISC_R_SUCCESS
;
1064 if (!omapi_ds_strcmp (name
, "statements")) {
1065 if (!host
-> group
) {
1066 if (!clone_group (&host
-> group
, root_group
, MDL
))
1067 return ISC_R_NOMEMORY
;
1069 if (host
-> group
-> statements
&&
1070 (!host
-> named_group
||
1071 host
-> group
!= host
-> named_group
-> group
) &&
1072 host
-> group
!= root_group
)
1073 return ISC_R_EXISTS
;
1074 if (!clone_group (&host
-> group
, host
-> group
, MDL
))
1075 return ISC_R_NOMEMORY
;
1078 return ISC_R_NOMEMORY
;
1079 if (value
&& (value
-> type
== omapi_datatype_data
||
1080 value
-> type
== omapi_datatype_string
)) {
1081 struct parse
*parse
;
1083 parse
= (struct parse
*)0;
1084 status
= new_parse(&parse
, -1,
1085 (char *) value
->u
.buffer
.value
,
1086 value
->u
.buffer
.len
,
1087 "network client", 0);
1088 if (status
!= ISC_R_SUCCESS
|| parse
== NULL
)
1091 if (!(parse_executable_statements
1092 (&host
-> group
-> statements
, parse
, &lose
,
1095 return DHCP_R_BADPARSE
;
1099 return DHCP_R_INVALIDARG
;
1100 return ISC_R_SUCCESS
;
1103 /* The "known" flag isn't supported in the database yet, but it's
1105 if (!omapi_ds_strcmp (name
, "known")) {
1106 return ISC_R_SUCCESS
;
1109 /* Try to find some inner object that can take the value. */
1110 if (h
-> inner
&& h
-> inner
-> type
-> set_value
) {
1111 status
= ((*(h
-> inner
-> type
-> set_value
))
1112 (h
-> inner
, id
, name
, value
));
1113 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
1117 return DHCP_R_UNKNOWNATTRIBUTE
;
1121 isc_result_t
dhcp_host_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
1122 omapi_data_string_t
*name
,
1123 omapi_value_t
**value
)
1125 struct host_decl
*host
;
1126 isc_result_t status
;
1127 struct data_string ip_addrs
;
1129 if (h
-> type
!= dhcp_type_host
)
1130 return DHCP_R_INVALIDARG
;
1131 host
= (struct host_decl
*)h
;
1133 if (!omapi_ds_strcmp (name
, "ip-addresses")) {
1134 memset (&ip_addrs
, 0, sizeof ip_addrs
);
1135 if (host
-> fixed_addr
&&
1136 evaluate_option_cache (&ip_addrs
, (struct packet
*)0,
1138 (struct client_state
*)0,
1139 (struct option_state
*)0,
1140 (struct option_state
*)0,
1142 host
-> fixed_addr
, MDL
)) {
1143 status
= omapi_make_const_value (value
, name
,
1146 data_string_forget (&ip_addrs
, MDL
);
1149 return ISC_R_NOTFOUND
;
1152 if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
1153 if (!host
-> client_identifier
.len
)
1154 return ISC_R_NOTFOUND
;
1155 return omapi_make_const_value (value
, name
,
1156 host
-> client_identifier
.data
,
1157 host
-> client_identifier
.len
,
1161 if (!omapi_ds_strcmp (name
, "name"))
1162 return omapi_make_string_value (value
, name
, host
-> name
,
1165 if (!omapi_ds_strcmp (name
, "hardware-address")) {
1166 if (!host
-> interface
.hlen
)
1167 return ISC_R_NOTFOUND
;
1168 return (omapi_make_const_value
1169 (value
, name
, &host
-> interface
.hbuf
[1],
1170 (unsigned long)(host
-> interface
.hlen
- 1), MDL
));
1173 if (!omapi_ds_strcmp (name
, "hardware-type")) {
1174 if (!host
-> interface
.hlen
)
1175 return ISC_R_NOTFOUND
;
1176 return omapi_make_int_value (value
, name
,
1177 host
-> interface
.hbuf
[0], MDL
);
1180 /* Try to find some inner object that can take the value. */
1181 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
1182 status
= ((*(h
-> inner
-> type
-> get_value
))
1183 (h
-> inner
, id
, name
, value
));
1184 if (status
== ISC_R_SUCCESS
)
1187 return DHCP_R_UNKNOWNATTRIBUTE
;
1190 isc_result_t
dhcp_host_destroy (omapi_object_t
*h
, const char *file
, int line
)
1193 if (h
-> type
!= dhcp_type_host
)
1194 return DHCP_R_INVALIDARG
;
1196 struct host_decl
*host
= (struct host_decl
*)h
;
1197 if (host
-> n_ipaddr
)
1198 host_dereference (&host
-> n_ipaddr
, file
, line
);
1199 if (host
-> n_dynamic
)
1200 host_dereference (&host
-> n_dynamic
, file
, line
);
1202 dfree (host
-> name
, file
, line
);
1203 host
-> name
= (char *)0;
1205 data_string_forget (&host
-> client_identifier
, file
, line
);
1206 if (host
-> fixed_addr
)
1207 option_cache_dereference (&host
-> fixed_addr
, file
, line
);
1209 group_dereference (&host
-> group
, file
, line
);
1210 if (host
-> named_group
)
1211 omapi_object_dereference ((omapi_object_t
**)
1212 &host
-> named_group
, file
, line
);
1213 data_string_forget (&host
-> auth_key_id
, file
, line
);
1215 return ISC_R_SUCCESS
;
1218 isc_result_t
dhcp_host_signal_handler (omapi_object_t
*h
,
1219 const char *name
, va_list ap
)
1221 struct host_decl
*host
;
1222 isc_result_t status
;
1225 if (h
-> type
!= dhcp_type_host
)
1226 return DHCP_R_INVALIDARG
;
1227 host
= (struct host_decl
*)h
;
1229 if (!strcmp (name
, "updated")) {
1230 /* There must be a client identifier of some sort. */
1231 if (host
-> interface
.hlen
== 0 &&
1232 !host
-> client_identifier
.len
)
1233 return DHCP_R_INVALIDARG
;
1235 if (!host
-> name
) {
1237 sprintf (hnbuf
, "nh%08lx%08lx",
1238 (unsigned long)cur_time
, (unsigned long)host
);
1239 host
-> name
= dmalloc (strlen (hnbuf
) + 1, MDL
);
1241 return ISC_R_NOMEMORY
;
1242 strcpy (host
-> name
, hnbuf
);
1246 log_debug ("OMAPI added host %s", host
-> name
);
1248 status
= enter_host (host
, 1, 1);
1249 if (status
!= ISC_R_SUCCESS
)
1254 /* Try to find some inner object that can take the value. */
1255 if (h
-> inner
&& h
-> inner
-> type
-> signal_handler
) {
1256 status
= ((*(h
-> inner
-> type
-> signal_handler
))
1257 (h
-> inner
, name
, ap
));
1258 if (status
== ISC_R_SUCCESS
)
1262 return ISC_R_SUCCESS
;
1263 return ISC_R_NOTFOUND
;
1266 isc_result_t
dhcp_host_stuff_values (omapi_object_t
*c
,
1270 struct host_decl
*host
;
1271 isc_result_t status
;
1272 struct data_string ip_addrs
;
1274 if (h
-> type
!= dhcp_type_host
)
1275 return DHCP_R_INVALIDARG
;
1276 host
= (struct host_decl
*)h
;
1278 /* Write out all the values. */
1280 memset (&ip_addrs
, 0, sizeof ip_addrs
);
1281 if (host
-> fixed_addr
&&
1282 evaluate_option_cache (&ip_addrs
, (struct packet
*)0,
1284 (struct client_state
*)0,
1285 (struct option_state
*)0,
1286 (struct option_state
*)0,
1288 host
-> fixed_addr
, MDL
)) {
1290 status
= omapi_connection_put_name (c
, "ip-address");
1291 if (status
!= ISC_R_SUCCESS
) {
1292 data_string_forget (&ip_addrs
, MDL
);
1296 status
= omapi_connection_put_uint32 (c
, ip_addrs
.len
);
1297 if (status
!= ISC_R_SUCCESS
) {
1298 data_string_forget (&ip_addrs
, MDL
);
1302 status
= omapi_connection_copyin (c
,
1303 ip_addrs
.data
, ip_addrs
.len
);
1304 if (status
!= ISC_R_SUCCESS
) {
1305 data_string_forget (&ip_addrs
, MDL
);
1309 data_string_forget (&ip_addrs
, MDL
);
1312 if (host
-> client_identifier
.len
) {
1313 status
= omapi_connection_put_name (c
,
1314 "dhcp-client-identifier");
1315 if (status
!= ISC_R_SUCCESS
)
1317 status
= (omapi_connection_put_uint32
1318 (c
, host
-> client_identifier
.len
));
1319 if (status
!= ISC_R_SUCCESS
)
1321 status
= (omapi_connection_copyin
1323 host
-> client_identifier
.data
,
1324 host
-> client_identifier
.len
));
1325 if (status
!= ISC_R_SUCCESS
)
1330 status
= omapi_connection_put_name (c
, "name");
1331 if (status
!= ISC_R_SUCCESS
)
1333 status
= omapi_connection_put_string (c
, host
-> name
);
1334 if (status
!= ISC_R_SUCCESS
)
1338 if (host
-> interface
.hlen
) {
1339 status
= omapi_connection_put_name (c
, "hardware-address");
1340 if (status
!= ISC_R_SUCCESS
)
1342 status
= (omapi_connection_put_uint32
1343 (c
, (unsigned long)(host
-> interface
.hlen
- 1)));
1344 if (status
!= ISC_R_SUCCESS
)
1346 status
= (omapi_connection_copyin
1347 (c
, &host
-> interface
.hbuf
[1],
1348 (unsigned long)(host
-> interface
.hlen
- 1)));
1349 if (status
!= ISC_R_SUCCESS
)
1352 status
= omapi_connection_put_named_uint32(c
, "hardware-type",
1353 host
->interface
.hbuf
[0]);
1354 if (status
!= ISC_R_SUCCESS
)
1358 /* Write out the inner object, if any. */
1359 if (h
-> inner
&& h
-> inner
-> type
-> stuff_values
) {
1360 status
= ((*(h
-> inner
-> type
-> stuff_values
))
1361 (c
, id
, h
-> inner
));
1362 if (status
== ISC_R_SUCCESS
)
1366 return ISC_R_SUCCESS
;
1369 isc_result_t
dhcp_host_lookup (omapi_object_t
**lp
,
1370 omapi_object_t
*id
, omapi_object_t
*ref
)
1372 omapi_value_t
*tv
= (omapi_value_t
*)0;
1373 isc_result_t status
;
1374 struct host_decl
*host
;
1377 return DHCP_R_NOKEYS
;
1379 /* First see if we were sent a handle. */
1380 status
= omapi_get_value_str (ref
, id
, "handle", &tv
);
1381 if (status
== ISC_R_SUCCESS
) {
1382 status
= omapi_handle_td_lookup (lp
, tv
-> value
);
1384 omapi_value_dereference (&tv
, MDL
);
1385 if (status
!= ISC_R_SUCCESS
)
1388 /* Don't return the object if the type is wrong. */
1389 if ((*lp
) -> type
!= dhcp_type_host
) {
1390 omapi_object_dereference (lp
, MDL
);
1391 return DHCP_R_INVALIDARG
;
1393 if (((struct host_decl
*)(*lp
)) -> flags
& HOST_DECL_DELETED
) {
1394 omapi_object_dereference (lp
, MDL
);
1398 /* Now look for a client identifier. */
1399 status
= omapi_get_value_str (ref
, id
, "dhcp-client-identifier", &tv
);
1400 if (status
== ISC_R_SUCCESS
) {
1401 host
= (struct host_decl
*)0;
1402 host_hash_lookup (&host
, host_uid_hash
,
1403 tv
-> value
-> u
.buffer
.value
,
1404 tv
-> value
-> u
.buffer
.len
, MDL
);
1405 omapi_value_dereference (&tv
, MDL
);
1407 if (*lp
&& *lp
!= (omapi_object_t
*)host
) {
1408 omapi_object_dereference (lp
, MDL
);
1410 host_dereference (&host
, MDL
);
1411 return DHCP_R_KEYCONFLICT
;
1412 } else if (!host
|| (host
-> flags
& HOST_DECL_DELETED
)) {
1414 omapi_object_dereference (lp
, MDL
);
1416 host_dereference (&host
, MDL
);
1417 return ISC_R_NOTFOUND
;
1419 /* XXX fix so that hash lookup itself creates
1420 XXX the reference. */
1421 omapi_object_reference (lp
,
1422 (omapi_object_t
*)host
, MDL
);
1423 host_dereference (&host
, MDL
);
1427 /* Now look for a hardware address. */
1428 status
= omapi_get_value_str (ref
, id
, "hardware-address", &tv
);
1429 if (status
== ISC_R_SUCCESS
) {
1430 unsigned char *haddr
;
1433 len
= tv
-> value
-> u
.buffer
.len
+ 1;
1434 haddr
= dmalloc (len
, MDL
);
1436 omapi_value_dereference (&tv
, MDL
);
1437 return ISC_R_NOMEMORY
;
1440 memcpy (haddr
+ 1, tv
-> value
-> u
.buffer
.value
, len
- 1);
1441 omapi_value_dereference (&tv
, MDL
);
1443 status
= omapi_get_value_str (ref
, id
, "hardware-type", &tv
);
1444 if (status
== ISC_R_SUCCESS
) {
1445 if (tv
-> value
-> type
== omapi_datatype_data
) {
1446 if ((tv
-> value
-> u
.buffer
.len
!= 4) ||
1447 (tv
-> value
-> u
.buffer
.value
[0] != 0) ||
1448 (tv
-> value
-> u
.buffer
.value
[1] != 0) ||
1449 (tv
-> value
-> u
.buffer
.value
[2] != 0)) {
1450 omapi_value_dereference (&tv
, MDL
);
1452 return DHCP_R_INVALIDARG
;
1455 haddr
[0] = tv
-> value
-> u
.buffer
.value
[3];
1456 } else if (tv
-> value
-> type
== omapi_datatype_int
) {
1457 haddr
[0] = (unsigned char)
1458 tv
-> value
-> u
.integer
;
1460 omapi_value_dereference (&tv
, MDL
);
1462 return DHCP_R_INVALIDARG
;
1465 omapi_value_dereference (&tv
, MDL
);
1467 /* If no hardware-type is specified, default to
1468 ethernet. This may or may not be a good idea,
1469 but Telus is currently relying on this behavior.
1471 haddr
[0] = HTYPE_ETHER
;
1474 host
= (struct host_decl
*)0;
1475 host_hash_lookup (&host
, host_hw_addr_hash
, haddr
, len
, MDL
);
1478 if (*lp
&& *lp
!= (omapi_object_t
*)host
) {
1479 omapi_object_dereference (lp
, MDL
);
1481 host_dereference (&host
, MDL
);
1482 return DHCP_R_KEYCONFLICT
;
1483 } else if (!host
|| (host
-> flags
& HOST_DECL_DELETED
)) {
1485 omapi_object_dereference (lp
, MDL
);
1487 host_dereference (&host
, MDL
);
1488 return ISC_R_NOTFOUND
;
1490 /* XXX fix so that hash lookup itself creates
1491 XXX the reference. */
1492 omapi_object_reference (lp
,
1493 (omapi_object_t
*)host
, MDL
);
1494 host_dereference (&host
, MDL
);
1498 /* Now look for an ip address. */
1499 status
= omapi_get_value_str (ref
, id
, "ip-address", &tv
);
1500 if (status
== ISC_R_SUCCESS
) {
1503 /* first find the lease for this ip address */
1504 l
= (struct lease
*)0;
1505 lease_ip_hash_lookup(&l
, lease_ip_addr_hash
,
1506 tv
->value
->u
.buffer
.value
,
1507 tv
->value
->u
.buffer
.len
, MDL
);
1508 omapi_value_dereference (&tv
, MDL
);
1511 return ISC_R_NOTFOUND
;
1514 /* now use that to get a host */
1515 host
= (struct host_decl
*)0;
1516 host_hash_lookup (&host
, host_hw_addr_hash
,
1517 l
-> hardware_addr
.hbuf
,
1518 l
-> hardware_addr
.hlen
, MDL
);
1520 if (host
&& *lp
&& *lp
!= (omapi_object_t
*)host
) {
1521 omapi_object_dereference (lp
, MDL
);
1523 host_dereference (&host
, MDL
);
1524 return DHCP_R_KEYCONFLICT
;
1525 } else if (!host
|| (host
-> flags
&
1526 HOST_DECL_DELETED
)) {
1528 host_dereference (&host
, MDL
);
1530 return ISC_R_NOTFOUND
;
1532 /* XXX fix so that hash lookup itself creates
1533 XXX the reference. */
1534 omapi_object_reference (lp
, (omapi_object_t
*)host
,
1536 host_dereference (&host
, MDL
);
1538 lease_dereference (&l
, MDL
);
1542 /* Now look for a name. */
1543 status
= omapi_get_value_str (ref
, id
, "name", &tv
);
1544 if (status
== ISC_R_SUCCESS
) {
1545 host
= (struct host_decl
*)0;
1546 host_hash_lookup (&host
, host_name_hash
,
1547 tv
-> value
-> u
.buffer
.value
,
1548 tv
-> value
-> u
.buffer
.len
, MDL
);
1549 omapi_value_dereference (&tv
, MDL
);
1551 if (*lp
&& *lp
!= (omapi_object_t
*)host
) {
1552 omapi_object_dereference (lp
, MDL
);
1554 host_dereference (&host
, MDL
);
1555 return DHCP_R_KEYCONFLICT
;
1556 } else if (!host
|| (host
-> flags
& HOST_DECL_DELETED
)) {
1558 host_dereference (&host
, MDL
);
1559 return ISC_R_NOTFOUND
;
1561 /* XXX fix so that hash lookup itself creates
1562 XXX the reference. */
1563 omapi_object_reference (lp
,
1564 (omapi_object_t
*)host
, MDL
);
1565 host_dereference (&host
, MDL
);
1569 /* If we get to here without finding a host, no valid key was
1572 return DHCP_R_NOKEYS
;
1573 return ISC_R_SUCCESS
;
1576 isc_result_t
dhcp_host_create (omapi_object_t
**lp
,
1579 struct host_decl
*hp
;
1580 isc_result_t status
;
1581 hp
= (struct host_decl
*)0;
1582 status
= host_allocate (&hp
, MDL
);
1583 if (status
!= ISC_R_SUCCESS
)
1585 group_reference (&hp
-> group
, root_group
, MDL
);
1586 hp
-> flags
= HOST_DECL_DYNAMIC
;
1587 status
= omapi_object_reference (lp
, (omapi_object_t
*)hp
, MDL
);
1588 host_dereference (&hp
, MDL
);
1592 isc_result_t
dhcp_host_remove (omapi_object_t
*lp
,
1595 struct host_decl
*hp
;
1596 if (lp
-> type
!= dhcp_type_host
)
1597 return DHCP_R_INVALIDARG
;
1598 hp
= (struct host_decl
*)lp
;
1601 log_debug ("OMAPI delete host %s", hp
-> name
);
1603 delete_host (hp
, 1);
1604 return ISC_R_SUCCESS
;
1607 isc_result_t
dhcp_pool_set_value (omapi_object_t
*h
,
1609 omapi_data_string_t
*name
,
1610 omapi_typed_data_t
*value
)
1612 /* h should point to (struct pool *) */
1613 isc_result_t status
;
1615 if (h
-> type
!= dhcp_type_pool
)
1616 return DHCP_R_INVALIDARG
;
1618 /* No values to set yet. */
1620 /* Try to find some inner object that can take the value. */
1621 if (h
-> inner
&& h
-> inner
-> type
-> set_value
) {
1622 status
= ((*(h
-> inner
-> type
-> set_value
))
1623 (h
-> inner
, id
, name
, value
));
1624 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
1628 return DHCP_R_UNKNOWNATTRIBUTE
;
1632 isc_result_t
dhcp_pool_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
1633 omapi_data_string_t
*name
,
1634 omapi_value_t
**value
)
1636 /* h should point to (struct pool *) */
1637 isc_result_t status
;
1639 if (h
-> type
!= dhcp_type_pool
)
1640 return DHCP_R_INVALIDARG
;
1642 /* No values to get yet. */
1644 /* Try to find some inner object that can provide the value. */
1645 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
1646 status
= ((*(h
-> inner
-> type
-> get_value
))
1647 (h
-> inner
, id
, name
, value
));
1648 if (status
== ISC_R_SUCCESS
)
1651 return DHCP_R_UNKNOWNATTRIBUTE
;
1654 isc_result_t
dhcp_pool_destroy (omapi_object_t
*h
, const char *file
, int line
)
1656 struct permit
*pc
, *pn
;
1658 if (h
-> type
!= dhcp_type_pool
)
1659 return DHCP_R_INVALIDARG
;
1661 struct pool
*pool
= (struct pool
*)h
;
1663 pool_dereference (&pool
-> next
, file
, line
);
1665 group_dereference (&pool
-> group
, file
, line
);
1666 if (pool
-> shared_network
)
1667 shared_network_dereference (&pool
-> shared_network
, file
, line
);
1669 POOL_DESTROYP(&pool
->active
);
1670 POOL_DESTROYP(&pool
->expired
);
1671 POOL_DESTROYP(&pool
->free
);
1672 POOL_DESTROYP(&pool
->backup
);
1673 POOL_DESTROYP(&pool
->abandoned
);
1674 POOL_DESTROYP(&pool
->reserved
);
1676 #if defined (FAILOVER_PROTOCOL)
1677 if (pool
-> failover_peer
)
1678 dhcp_failover_state_dereference (&pool
-> failover_peer
,
1682 for (pc
= pool
-> permit_list
; pc
; pc
= pn
) {
1684 free_permit (pc
, file
, line
);
1686 pool
-> permit_list
= (struct permit
*)0;
1688 for (pc
= pool
-> prohibit_list
; pc
; pc
= pn
) {
1690 free_permit (pc
, file
, line
);
1692 pool
-> prohibit_list
= (struct permit
*)0;
1694 return ISC_R_SUCCESS
;
1697 isc_result_t
dhcp_pool_signal_handler (omapi_object_t
*h
,
1698 const char *name
, va_list ap
)
1700 /* h should point to (struct pool *) */
1701 isc_result_t status
;
1703 if (h
-> type
!= dhcp_type_pool
)
1704 return DHCP_R_INVALIDARG
;
1706 /* Can't write pools yet. */
1708 /* Try to find some inner object that can take the value. */
1709 if (h
-> inner
&& h
-> inner
-> type
-> signal_handler
) {
1710 status
= ((*(h
-> inner
-> type
-> signal_handler
))
1711 (h
-> inner
, name
, ap
));
1712 if (status
== ISC_R_SUCCESS
)
1716 return ISC_R_NOTFOUND
;
1719 isc_result_t
dhcp_pool_stuff_values (omapi_object_t
*c
,
1724 isc_result_t status
;
1726 if (h
->type
!= dhcp_type_pool
)
1727 return (DHCP_R_INVALIDARG
);
1728 pool
= (struct pool
*)h
;
1731 * I don't think we can actually find a pool yet
1732 * but include the output of interesting values
1735 status
= omapi_connection_put_named_uint32(c
, "lease-count",
1737 pool
->lease_count
));
1738 if (status
!= ISC_R_SUCCESS
)
1741 status
= omapi_connection_put_named_uint32(c
, "free-leases",
1743 pool
->free_leases
));
1744 if (status
!= ISC_R_SUCCESS
)
1747 status
= omapi_connection_put_named_uint32(c
, "backup-leases",
1749 pool
->backup_leases
));
1750 if (status
!= ISC_R_SUCCESS
)
1752 /* we could add time stamps but lets wait on those */
1754 /* Write out the inner object, if any. */
1755 if (h
->inner
&& h
->inner
->type
->stuff_values
) {
1756 status
= ((*(h
->inner
->type
->stuff_values
))
1758 if (status
== ISC_R_SUCCESS
)
1762 return (ISC_R_SUCCESS
);
1765 isc_result_t
dhcp_pool_lookup (omapi_object_t
**lp
,
1766 omapi_object_t
*id
, omapi_object_t
*ref
)
1768 /* Can't look up pools yet. */
1770 /* If we get to here without finding a pool, no valid key was
1773 return DHCP_R_NOKEYS
;
1774 return ISC_R_SUCCESS
;
1777 isc_result_t
dhcp_pool_create (omapi_object_t
**lp
,
1780 return ISC_R_NOTIMPLEMENTED
;
1783 isc_result_t
dhcp_pool_remove (omapi_object_t
*lp
,
1786 return ISC_R_NOTIMPLEMENTED
;
1790 class_set_value (omapi_object_t
*h
,
1792 omapi_data_string_t
*name
,
1793 omapi_typed_data_t
*value
)
1795 struct class *class;
1796 struct class *superclass
= 0;
1797 isc_result_t status
;
1798 int issubclass
= (h
-> type
== dhcp_type_subclass
);
1800 class = (struct class *)h
;
1802 if (!omapi_ds_strcmp(name
, "name")) {
1804 return ISC_R_EXISTS
;
1807 char tname
[value
->u
.buffer
.len
+ 1];
1808 memcpy(tname
, value
->u
.buffer
.value
, value
->u
.buffer
.len
);
1809 tname
[sizeof(tname
)-1] = '\0';
1810 status
= find_class(&superclass
, tname
, MDL
);
1812 if (status
== ISC_R_NOTFOUND
)
1815 if (class->superclass
!= NULL
)
1816 class_dereference(&class->superclass
, MDL
);
1817 class_reference(&class->superclass
, superclass
, MDL
);
1819 if (class->group
!= NULL
)
1820 group_dereference(&class->group
, MDL
);
1821 group_reference(&class->group
, superclass
->group
, MDL
);
1823 class->lease_limit
= superclass
->lease_limit
;
1824 if (class->lease_limit
!= 0) {
1825 class->billed_leases
=
1826 dmalloc(class->lease_limit
*
1827 sizeof(struct lease
*),
1829 if (class->billed_leases
== NULL
) {
1830 return ISC_R_NOMEMORY
;
1834 } else if (value
->type
== omapi_datatype_data
||
1835 value
->type
== omapi_datatype_string
) {
1836 class->name
= dmalloc(value
->u
.buffer
.len
+ 1, MDL
);
1838 return ISC_R_NOMEMORY
;
1840 /* class->name is null-terminated from dmalloc() */
1841 memcpy(class->name
, value
->u
.buffer
.value
,
1842 value
->u
.buffer
.len
);
1844 return DHCP_R_INVALIDARG
;
1846 return ISC_R_SUCCESS
;
1850 if (issubclass
&& !omapi_ds_strcmp(name
, "hashstring")) {
1851 if (class->hash_string
.data
)
1852 return ISC_R_EXISTS
;
1854 if (value
->type
== omapi_datatype_data
||
1855 value
->type
== omapi_datatype_string
) {
1856 if (!buffer_allocate(&class->hash_string
.buffer
,
1857 value
->u
.buffer
.len
, MDL
))
1858 return ISC_R_NOMEMORY
;
1859 class->hash_string
.data
=
1860 class->hash_string
.buffer
->data
;
1861 memcpy(class->hash_string
.buffer
->data
,
1862 value
->u
.buffer
.value
, value
->u
.buffer
.len
);
1863 class->hash_string
.len
= value
->u
.buffer
.len
;
1865 return DHCP_R_INVALIDARG
;
1867 return ISC_R_SUCCESS
;
1870 if (!omapi_ds_strcmp(name
, "group")) {
1871 if (value
->type
== omapi_datatype_data
||
1872 value
->type
== omapi_datatype_string
) {
1873 struct group_object
*group
= NULL
;
1875 group_hash_lookup(&group
, group_name_hash
,
1876 (char *)value
->u
.buffer
.value
,
1877 value
->u
.buffer
.len
, MDL
);
1878 if (!group
|| (group
->flags
& GROUP_OBJECT_DELETED
))
1879 return ISC_R_NOTFOUND
;
1881 group_dereference(&class->group
, MDL
);
1882 group_reference(&class->group
, group
->group
, MDL
);
1883 group_object_dereference(&group
, MDL
);
1885 return DHCP_R_INVALIDARG
;
1887 return ISC_R_SUCCESS
;
1891 /* note we do not support full expressions via omapi because the
1892 expressions parser needs to be re-done to support parsing from
1893 strings and not just files. */
1895 if (!omapi_ds_strcmp(name
, "match")) {
1896 if (value
->type
== omapi_datatype_data
||
1897 value
->type
== omapi_datatype_string
) {
1898 unsigned minlen
= (value
->u
.buffer
.len
> 8 ?
1899 8 : value
->u
.buffer
.len
);
1901 if (!strncmp("hardware",
1902 (char *)value
->u
.buffer
.value
, minlen
))
1904 if (!expression_allocate(&class->submatch
, MDL
))
1905 return ISC_R_NOMEMORY
;
1907 class->submatch
->op
= expr_hardware
;
1909 return DHCP_R_INVALIDARG
;
1911 return DHCP_R_INVALIDARG
;
1913 return ISC_R_SUCCESS
;
1917 if (!omapi_ds_strcmp(name
, "option")) {
1918 if (value
->type
== omapi_datatype_data
||
1919 value
->type
== omapi_datatype_string
) {
1920 /* XXXJAB support 'options' here. */
1921 /* XXXJAB specifically 'bootfile-name' */
1922 return DHCP_R_INVALIDARG
; /* XXX tmp */
1924 return DHCP_R_INVALIDARG
;
1927 * Currently no way to get here, if we update the above
1928 * code so that we do get here this return needs to be
1930 * return ISC_R_SUCCESS;
1935 /* Try to find some inner object that can take the value. */
1936 if (h
->inner
&& h
->inner
->type
->set_value
) {
1937 status
= ((*(h
->inner
->type
->set_value
))
1938 (h
->inner
, id
, name
, value
));
1939 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
1943 return DHCP_R_UNKNOWNATTRIBUTE
;
1948 isc_result_t
dhcp_class_set_value (omapi_object_t
*h
,
1950 omapi_data_string_t
*name
,
1951 omapi_typed_data_t
*value
)
1953 if (h
-> type
!= dhcp_type_class
)
1954 return DHCP_R_INVALIDARG
;
1956 return class_set_value(h
, id
, name
, value
);
1959 isc_result_t
dhcp_class_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
1960 omapi_data_string_t
*name
,
1961 omapi_value_t
**value
)
1963 struct class *class;
1964 isc_result_t status
;
1966 if (h
-> type
!= dhcp_type_class
)
1967 return DHCP_R_INVALIDARG
;
1968 class = (struct class *)h
;
1970 if (!omapi_ds_strcmp (name
, "name"))
1971 return omapi_make_string_value (value
, name
, class -> name
,
1974 /* Try to find some inner object that can provide the value. */
1975 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
1976 status
= ((*(h
-> inner
-> type
-> get_value
))
1977 (h
-> inner
, id
, name
, value
));
1978 if (status
== ISC_R_SUCCESS
)
1981 return DHCP_R_UNKNOWNATTRIBUTE
;
1984 isc_result_t
dhcp_class_destroy (omapi_object_t
*h
, const char *file
, int line
)
1987 if (h
-> type
!= dhcp_type_class
&& h
-> type
!= dhcp_type_subclass
)
1988 return DHCP_R_INVALIDARG
;
1989 struct class *class = (struct class *)h
;
1992 class_dereference (&class -> nic
, file
, line
);
1993 if (class -> superclass
)
1994 class_dereference (&class -> superclass
, file
, line
);
1995 if (class -> name
) {
1996 dfree (class -> name
, file
, line
);
1997 class -> name
= (char *)0;
1999 if (class -> billed_leases
) {
2001 for (i
= 0; i
< class -> lease_limit
; i
++) {
2002 if (class -> billed_leases
[i
]) {
2003 lease_dereference (&class -> billed_leases
[i
],
2007 dfree (class -> billed_leases
, file
, line
);
2008 class -> billed_leases
= (struct lease
**)0;
2010 if (class -> hash
) {
2011 class_free_hash_table (&class -> hash
, file
, line
);
2012 class -> hash
= (class_hash_t
*)0;
2014 data_string_forget (&class -> hash_string
, file
, line
);
2017 expression_dereference (&class -> expr
, file
, line
);
2018 if (class -> submatch
)
2019 expression_dereference (&class -> submatch
, file
, line
);
2021 group_dereference (&class -> group
, file
, line
);
2022 if (class -> statements
)
2023 executable_statement_dereference (&class -> statements
,
2025 if (class -> superclass
)
2026 class_dereference (&class -> superclass
, file
, line
);
2028 return ISC_R_SUCCESS
;
2032 class_signal_handler(omapi_object_t
*h
,
2033 const char *name
, va_list ap
)
2035 struct class *class = (struct class *)h
;
2036 isc_result_t status
;
2040 issubclass
= (h
->type
== dhcp_type_subclass
);
2042 if (!strcmp (name
, "updated")) {
2045 if (class->name
== 0 || strlen(class->name
) == 0) {
2046 return DHCP_R_INVALIDARG
;
2049 if (class->superclass
== 0) {
2050 return DHCP_R_INVALIDARG
; /* didn't give name */
2053 if (class->hash_string
.data
== NULL
) {
2054 return DHCP_R_INVALIDARG
;
2060 if (!class->superclass
->hash
)
2061 class_new_hash(&class->superclass
->hash
,
2062 SCLASS_HASH_SIZE
, MDL
);
2064 class_hash_add(class->superclass
->hash
,
2065 (const char *)class->hash_string
.data
,
2066 class->hash_string
.len
,
2067 (void *)class, MDL
);
2072 log_debug ("OMAPI added subclass %s",
2073 class->superclass
->name
);
2075 log_debug ("OMAPI added class %s", class->name
);
2079 status
= enter_class (class, 1, 1);
2080 if (status
!= ISC_R_SUCCESS
)
2085 /* Try to find some inner object that can take the value. */
2086 if (h
->inner
&& h
->inner
->type
->signal_handler
) {
2087 status
= ((*(h
->inner
->type
->signal_handler
))
2088 (h
->inner
, name
, ap
));
2089 if (status
== ISC_R_SUCCESS
)
2094 return ISC_R_SUCCESS
;
2096 return ISC_R_NOTFOUND
;
2100 isc_result_t
dhcp_class_signal_handler (omapi_object_t
*h
,
2101 const char *name
, va_list ap
)
2103 if (h
-> type
!= dhcp_type_class
)
2104 return DHCP_R_INVALIDARG
;
2106 return class_signal_handler(h
, name
, ap
);
2111 * Routine to put out generic class & subclass information
2113 isc_result_t
class_stuff_values (omapi_object_t
*c
,
2117 struct class *class;
2118 isc_result_t status
;
2120 class = (struct class *)h
;
2122 status
= omapi_connection_put_named_uint32(c
, "lease-limit",
2124 class->lease_limit
));
2125 if (status
!= ISC_R_SUCCESS
)
2128 status
= omapi_connection_put_named_uint32(c
, "leases-used",
2130 class->leases_consumed
));
2131 if (status
!= ISC_R_SUCCESS
)
2134 /* Write out the inner object, if any. */
2135 if (h
->inner
&& h
->inner
->type
->stuff_values
) {
2136 status
= ((*(h
->inner
->type
->stuff_values
))
2138 if (status
== ISC_R_SUCCESS
)
2142 return (ISC_R_SUCCESS
);
2146 isc_result_t
dhcp_class_stuff_values (omapi_object_t
*c
,
2150 if (h
->type
!= dhcp_type_class
)
2151 return (DHCP_R_INVALIDARG
);
2153 /* add any class specific items here */
2155 return (class_stuff_values(c
, id
, h
));
2158 static isc_result_t
class_lookup (omapi_object_t
**lp
,
2159 omapi_object_t
*id
, omapi_object_t
*ref
,
2160 omapi_object_type_t
*typewanted
)
2162 omapi_value_t
*nv
= NULL
;
2163 omapi_value_t
*hv
= NULL
;
2164 isc_result_t status
;
2165 struct class *class = 0;
2166 struct class *subclass
= 0;
2171 return (DHCP_R_NOKEYS
);
2173 /* see if we have a name */
2174 status
= omapi_get_value_str(ref
, id
, "name", &nv
);
2175 if (status
== ISC_R_SUCCESS
) {
2176 char *name
= dmalloc(nv
->value
->u
.buffer
.len
+ 1, MDL
);
2178 return (ISC_R_NOMEMORY
);
2180 nv
->value
->u
.buffer
.value
,
2181 nv
->value
->u
.buffer
.len
);
2183 omapi_value_dereference(&nv
, MDL
);
2185 find_class(&class, name
, MDL
);
2189 if (class == NULL
) {
2190 return (ISC_R_NOTFOUND
);
2193 if (typewanted
== dhcp_type_subclass
) {
2194 status
= omapi_get_value_str(ref
, id
,
2196 if (status
!= ISC_R_SUCCESS
) {
2197 class_dereference(&class, MDL
);
2198 return (DHCP_R_NOKEYS
);
2201 if (hv
->value
->type
!= omapi_datatype_data
&&
2202 hv
->value
->type
!= omapi_datatype_string
) {
2203 class_dereference(&class, MDL
);
2204 omapi_value_dereference(&hv
, MDL
);
2205 return (DHCP_R_NOKEYS
);
2208 class_hash_lookup(&subclass
, class->hash
,
2210 hv
->value
->u
.buffer
.value
,
2211 hv
->value
->u
.buffer
.len
, MDL
);
2213 omapi_value_dereference(&hv
, MDL
);
2215 class_dereference(&class, MDL
);
2217 if (subclass
== NULL
) {
2218 return (ISC_R_NOTFOUND
);
2221 class_reference(&class, subclass
, MDL
);
2222 class_dereference(&subclass
, MDL
);
2225 /* Don't return the object if the type is wrong. */
2226 if (class->type
!= typewanted
) {
2227 class_dereference(&class, MDL
);
2228 return (DHCP_R_INVALIDARG
);
2231 if (class->flags
& CLASS_DECL_DELETED
) {
2232 class_dereference(&class, MDL
);
2233 return (ISC_R_NOTFOUND
);
2236 omapi_object_reference(lp
, (omapi_object_t
*)class, MDL
);
2237 class_dereference(&class, MDL
);
2239 return (ISC_R_SUCCESS
);
2242 return (DHCP_R_NOKEYS
);
2246 isc_result_t
dhcp_class_lookup (omapi_object_t
**lp
,
2247 omapi_object_t
*id
, omapi_object_t
*ref
)
2249 return class_lookup(lp
, id
, ref
, dhcp_type_class
);
2252 isc_result_t
dhcp_class_create (omapi_object_t
**lp
,
2255 struct class *cp
= 0;
2256 isc_result_t status
;
2258 status
= class_allocate(&cp
, MDL
);
2259 if (status
!= ISC_R_SUCCESS
)
2262 if (clone_group(&cp
->group
, root_group
, MDL
) == 0)
2263 return (ISC_R_NOMEMORY
);
2265 cp
->flags
= CLASS_DECL_DYNAMIC
;
2266 status
= omapi_object_reference(lp
, (omapi_object_t
*)cp
, MDL
);
2267 class_dereference(&cp
, MDL
);
2271 isc_result_t
dhcp_class_remove (omapi_object_t
*lp
,
2275 if (lp
-> type
!= dhcp_type_class
)
2276 return DHCP_R_INVALIDARG
;
2277 cp
= (struct class *)lp
;
2280 log_debug ("OMAPI delete class %s", cp
-> name
);
2283 delete_class (cp
, 1);
2284 return ISC_R_SUCCESS
;
2287 isc_result_t
dhcp_subclass_set_value (omapi_object_t
*h
,
2289 omapi_data_string_t
*name
,
2290 omapi_typed_data_t
*value
)
2292 if (h
-> type
!= dhcp_type_subclass
)
2293 return DHCP_R_INVALIDARG
;
2295 return class_set_value(h
, id
, name
, value
);
2299 isc_result_t
dhcp_subclass_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
2300 omapi_data_string_t
*name
,
2301 omapi_value_t
**value
)
2303 struct class *subclass
;
2304 isc_result_t status
;
2306 if (h
-> type
!= dhcp_type_class
)
2307 return DHCP_R_INVALIDARG
;
2308 subclass
= (struct class *)h
;
2309 if (subclass
-> name
!= 0)
2310 return DHCP_R_INVALIDARG
;
2312 /* XXXJAB No values to get yet. */
2314 /* Try to find some inner object that can provide the value. */
2315 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
2316 status
= ((*(h
-> inner
-> type
-> get_value
))
2317 (h
-> inner
, id
, name
, value
));
2318 if (status
== ISC_R_SUCCESS
)
2321 return DHCP_R_UNKNOWNATTRIBUTE
;
2324 isc_result_t
dhcp_subclass_signal_handler (omapi_object_t
*h
,
2325 const char *name
, va_list ap
)
2327 if (h
-> type
!= dhcp_type_subclass
)
2328 return DHCP_R_INVALIDARG
;
2330 return class_signal_handler(h
, name
, ap
);
2334 isc_result_t
dhcp_subclass_stuff_values (omapi_object_t
*c
,
2338 struct class *subclass
;
2340 if (h
->type
!= dhcp_type_subclass
)
2341 return (DHCP_R_INVALIDARG
);
2342 subclass
= (struct class *)h
;
2343 if (subclass
->name
!= 0)
2344 return (DHCP_R_INVALIDARG
);
2346 /* add any subclass specific items here */
2348 return (class_stuff_values(c
, id
, h
));
2351 isc_result_t
dhcp_subclass_lookup (omapi_object_t
**lp
,
2352 omapi_object_t
*id
, omapi_object_t
*ref
)
2354 return class_lookup(lp
, id
, ref
, dhcp_type_subclass
);
2360 isc_result_t
dhcp_subclass_create (omapi_object_t
**lp
,
2363 struct class *cp
= 0;
2364 isc_result_t status
;
2366 status
= subclass_allocate(&cp
, MDL
);
2367 if (status
!= ISC_R_SUCCESS
)
2369 group_reference (&cp
->group
, root_group
, MDL
);
2371 cp
->flags
= CLASS_DECL_DYNAMIC
;
2373 status
= omapi_object_reference (lp
, (omapi_object_t
*)cp
, MDL
);
2374 subclass_dereference (&cp
, MDL
);
2378 isc_result_t
dhcp_subclass_remove (omapi_object_t
*lp
,
2382 if (lp
-> type
!= dhcp_type_subclass
)
2383 return DHCP_R_INVALIDARG
;
2384 cp
= (struct class *)lp
;
2387 log_debug ("OMAPI delete subclass %s", cp
-> name
);
2390 delete_class (cp
, 1);
2392 return ISC_R_SUCCESS
;
2395 isc_result_t
binding_scope_set_value (struct binding_scope
*scope
, int createp
,
2396 omapi_data_string_t
*name
,
2397 omapi_typed_data_t
*value
)
2401 struct binding_value
*nv
;
2402 nname
= dmalloc (name
-> len
+ 1, MDL
);
2404 return ISC_R_NOMEMORY
;
2405 memcpy (nname
, name
-> value
, name
-> len
);
2406 nname
[name
-> len
] = 0;
2407 bp
= find_binding (scope
, nname
);
2408 if (!bp
&& !createp
) {
2410 return DHCP_R_UNKNOWNATTRIBUTE
;
2415 return DHCP_R_UNKNOWNATTRIBUTE
;
2416 binding_value_dereference (&bp
-> value
, MDL
);
2417 return ISC_R_SUCCESS
;
2420 nv
= (struct binding_value
*)0;
2421 if (!binding_value_allocate (&nv
, MDL
)) {
2423 return ISC_R_NOMEMORY
;
2425 switch (value
-> type
) {
2426 case omapi_datatype_int
:
2427 nv
-> type
= binding_numeric
;
2428 nv
-> value
.intval
= value
-> u
.integer
;
2431 case omapi_datatype_string
:
2432 case omapi_datatype_data
:
2433 if (!buffer_allocate (&nv
-> value
.data
.buffer
,
2434 value
-> u
.buffer
.len
, MDL
)) {
2435 binding_value_dereference (&nv
, MDL
);
2437 return ISC_R_NOMEMORY
;
2439 memcpy (&nv
-> value
.data
.buffer
-> data
[1],
2440 value
-> u
.buffer
.value
, value
-> u
.buffer
.len
);
2441 nv
-> value
.data
.len
= value
-> u
.buffer
.len
;
2444 case omapi_datatype_object
:
2445 binding_value_dereference (&nv
, MDL
);
2447 return DHCP_R_INVALIDARG
;
2451 bp
= dmalloc (sizeof *bp
, MDL
);
2453 binding_value_dereference (&nv
, MDL
);
2455 return ISC_R_NOMEMORY
;
2457 memset (bp
, 0, sizeof *bp
);
2459 bp
-> next
= scope
-> bindings
;
2460 scope
-> bindings
= bp
;
2463 binding_value_dereference (&bp
-> value
, MDL
);
2466 binding_value_reference (&bp
-> value
, nv
, MDL
);
2467 binding_value_dereference (&nv
, MDL
);
2468 return ISC_R_SUCCESS
;
2471 isc_result_t
binding_scope_get_value (omapi_value_t
**value
,
2472 struct binding_scope
*scope
,
2473 omapi_data_string_t
*name
)
2476 omapi_typed_data_t
*td
;
2477 isc_result_t status
;
2479 nname
= dmalloc (name
-> len
+ 1, MDL
);
2481 return ISC_R_NOMEMORY
;
2482 memcpy (nname
, name
-> value
, name
-> len
);
2483 nname
[name
-> len
] = 0;
2484 bp
= find_binding (scope
, nname
);
2487 return DHCP_R_UNKNOWNATTRIBUTE
;
2489 return DHCP_R_UNKNOWNATTRIBUTE
;
2491 switch (bp
-> value
-> type
) {
2492 case binding_boolean
:
2493 td
= (omapi_typed_data_t
*)0;
2494 status
= omapi_typed_data_new (MDL
, &td
, omapi_datatype_int
,
2495 bp
-> value
-> value
.boolean
);
2498 case binding_numeric
:
2499 td
= (omapi_typed_data_t
*)0;
2500 status
= omapi_typed_data_new (MDL
, &td
, omapi_datatype_int
,
2502 bp
-> value
-> value
.intval
);
2506 td
= (omapi_typed_data_t
*)0;
2507 status
= omapi_typed_data_new (MDL
, &td
, omapi_datatype_data
,
2508 bp
-> value
-> value
.data
.len
);
2509 if (status
!= ISC_R_SUCCESS
)
2511 memcpy (&td
-> u
.buffer
.value
[0],
2512 bp
-> value
-> value
.data
.data
,
2513 bp
-> value
-> value
.data
.len
);
2516 /* Can't return values for these two (yet?). */
2518 case binding_function
:
2519 return DHCP_R_INVALIDARG
;
2522 log_fatal ("Impossible case at %s:%d.", MDL
);
2523 return ISC_R_FAILURE
;
2526 if (status
!= ISC_R_SUCCESS
)
2528 status
= omapi_value_new (value
, MDL
);
2529 if (status
!= ISC_R_SUCCESS
) {
2530 omapi_typed_data_dereference (&td
, MDL
);
2534 omapi_data_string_reference (&(*value
) -> name
, name
, MDL
);
2535 omapi_typed_data_reference (&(*value
) -> value
, td
, MDL
);
2536 omapi_typed_data_dereference (&td
, MDL
);
2538 return ISC_R_SUCCESS
;
2541 isc_result_t
binding_scope_stuff_values (omapi_object_t
*c
,
2542 struct binding_scope
*scope
)
2546 isc_result_t status
;
2548 for (bp
= scope
-> bindings
; bp
; bp
= bp
-> next
) {
2550 if (bp
-> value
-> type
== binding_dns
||
2551 bp
-> value
-> type
== binding_function
)
2554 /* Stuff the name. */
2555 len
= strlen (bp
-> name
);
2556 status
= omapi_connection_put_uint16 (c
, len
);
2557 if (status
!= ISC_R_SUCCESS
)
2559 status
= omapi_connection_copyin (c
,
2560 (unsigned char *)bp
-> name
,
2562 if (status
!= ISC_R_SUCCESS
)
2565 switch (bp
-> value
-> type
) {
2566 case binding_boolean
:
2567 status
= omapi_connection_put_uint32 (c
,
2568 sizeof (u_int32_t
));
2569 if (status
!= ISC_R_SUCCESS
)
2571 status
= (omapi_connection_put_uint32
2573 ((u_int32_t
)(bp
-> value
-> value
.boolean
))));
2574 if (status
!= ISC_R_SUCCESS
)
2579 status
= (omapi_connection_put_uint32
2580 (c
, bp
-> value
-> value
.data
.len
));
2581 if (status
!= ISC_R_SUCCESS
)
2583 if (bp
-> value
-> value
.data
.len
) {
2584 status
= (omapi_connection_copyin
2585 (c
, bp
-> value
-> value
.data
.data
,
2586 bp
-> value
-> value
.data
.len
));
2587 if (status
!= ISC_R_SUCCESS
)
2592 case binding_numeric
:
2593 status
= (omapi_connection_put_uint32
2594 (c
, sizeof (u_int32_t
)));
2595 if (status
!= ISC_R_SUCCESS
)
2597 status
= (omapi_connection_put_uint32
2599 (bp
-> value
-> value
.intval
))));
2600 if (status
!= ISC_R_SUCCESS
)
2607 case binding_function
:
2612 return ISC_R_SUCCESS
;
2615 /* vim: set tabstop=8: */