1 /* $NetBSD: omapi.c,v 1.2 2014/07/12 12:09:38 spz Exp $ */
4 OMAPI object interfaces for the DHCP server. */
7 * Copyright (c) 2012-2014 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1999-2003 by Internet Software Consortium
11 * Permission to use, copy, modify, and distribute this software for any
12 * purpose with or without fee is hereby granted, provided that the above
13 * copyright notice and this permission notice appear in all copies.
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.
23 * Internet Systems Consortium, Inc.
25 * Redwood City, CA 94063
27 * https://www.isc.org/
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: omapi.c,v 1.2 2014/07/12 12:09:38 spz Exp $");
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 */
42 #include <omapip/omapip_p.h>
44 static isc_result_t
class_lookup (omapi_object_t
**,
45 omapi_object_t
*, omapi_object_t
*,
46 omapi_object_type_t
*);
48 omapi_object_type_t
*dhcp_type_lease
;
49 omapi_object_type_t
*dhcp_type_pool
;
50 omapi_object_type_t
*dhcp_type_class
;
51 omapi_object_type_t
*dhcp_type_subclass
;
52 omapi_object_type_t
*dhcp_type_host
;
53 #if defined (FAILOVER_PROTOCOL)
54 omapi_object_type_t
*dhcp_type_failover_state
;
55 omapi_object_type_t
*dhcp_type_failover_link
;
56 omapi_object_type_t
*dhcp_type_failover_listener
;
59 void dhcp_db_objects_setup ()
63 status
= omapi_object_type_register (&dhcp_type_lease
,
68 dhcp_lease_signal_handler
,
69 dhcp_lease_stuff_values
,
73 #if defined (COMPACT_LEASES)
80 sizeof (struct lease
),
82 if (status
!= ISC_R_SUCCESS
)
83 log_fatal ("Can't register lease object type: %s",
84 isc_result_totext (status
));
86 status
= omapi_object_type_register (&dhcp_type_class
,
91 dhcp_class_signal_handler
,
92 dhcp_class_stuff_values
,
95 dhcp_class_remove
, 0, 0, 0,
96 sizeof (struct class), 0,
98 if (status
!= ISC_R_SUCCESS
)
99 log_fatal ("Can't register class object type: %s",
100 isc_result_totext (status
));
102 status
= omapi_object_type_register (&dhcp_type_subclass
,
104 dhcp_subclass_set_value
,
105 dhcp_subclass_get_value
,
107 dhcp_subclass_signal_handler
,
108 dhcp_subclass_stuff_values
,
109 dhcp_subclass_lookup
,
110 dhcp_subclass_create
,
111 dhcp_subclass_remove
, 0, 0, 0,
112 sizeof (struct class), 0, RC_MISC
);
113 if (status
!= ISC_R_SUCCESS
)
114 log_fatal ("Can't register subclass object type: %s",
115 isc_result_totext (status
));
117 status
= omapi_object_type_register (&dhcp_type_pool
,
122 dhcp_pool_signal_handler
,
123 dhcp_pool_stuff_values
,
126 dhcp_pool_remove
, 0, 0, 0,
127 sizeof (struct pool
), 0, RC_MISC
);
129 if (status
!= ISC_R_SUCCESS
)
130 log_fatal ("Can't register pool object type: %s",
131 isc_result_totext (status
));
133 status
= omapi_object_type_register (&dhcp_type_host
,
138 dhcp_host_signal_handler
,
139 dhcp_host_stuff_values
,
142 dhcp_host_remove
, 0, 0, 0,
143 sizeof (struct host_decl
),
146 if (status
!= ISC_R_SUCCESS
)
147 log_fatal ("Can't register host object type: %s",
148 isc_result_totext (status
));
150 #if defined (FAILOVER_PROTOCOL)
151 status
= omapi_object_type_register (&dhcp_type_failover_state
,
153 dhcp_failover_state_set_value
,
154 dhcp_failover_state_get_value
,
155 dhcp_failover_state_destroy
,
156 dhcp_failover_state_signal
,
157 dhcp_failover_state_stuff
,
158 dhcp_failover_state_lookup
,
159 dhcp_failover_state_create
,
160 dhcp_failover_state_remove
,
162 sizeof (dhcp_failover_state_t
),
165 if (status
!= ISC_R_SUCCESS
)
166 log_fatal ("Can't register failover state object type: %s",
167 isc_result_totext (status
));
169 status
= omapi_object_type_register (&dhcp_type_failover_link
,
171 dhcp_failover_link_set_value
,
172 dhcp_failover_link_get_value
,
173 dhcp_failover_link_destroy
,
174 dhcp_failover_link_signal
,
175 dhcp_failover_link_stuff_values
,
177 sizeof (dhcp_failover_link_t
), 0,
180 if (status
!= ISC_R_SUCCESS
)
181 log_fatal ("Can't register failover link object type: %s",
182 isc_result_totext (status
));
184 status
= omapi_object_type_register (&dhcp_type_failover_listener
,
186 dhcp_failover_listener_set_value
,
187 dhcp_failover_listener_get_value
,
188 dhcp_failover_listener_destroy
,
189 dhcp_failover_listener_signal
,
190 dhcp_failover_listener_stuff
,
193 (dhcp_failover_listener_t
), 0,
196 if (status
!= ISC_R_SUCCESS
)
197 log_fatal ("Can't register failover listener object type: %s",
198 isc_result_totext (status
));
199 #endif /* FAILOVER_PROTOCOL */
202 isc_result_t
dhcp_lease_set_value (omapi_object_t
*h
,
204 omapi_data_string_t
*name
,
205 omapi_typed_data_t
*value
)
210 if (h
-> type
!= dhcp_type_lease
)
211 return DHCP_R_INVALIDARG
;
212 lease
= (struct lease
*)h
;
214 /* We're skipping a lot of things it might be interesting to
215 set - for now, we just make it possible to whack the state. */
216 if (!omapi_ds_strcmp (name
, "state")) {
218 const char *ols
, *nls
;
219 status
= omapi_get_int_value (&bar
, value
);
220 if (status
!= ISC_R_SUCCESS
)
223 if (bar
< 1 || bar
> FTS_LAST
)
224 return DHCP_R_INVALIDARG
;
225 nls
= binding_state_names
[bar
- 1];
226 if (lease
-> binding_state
>= 1 &&
227 lease
-> binding_state
<= FTS_LAST
)
228 ols
= binding_state_names
[lease
-> binding_state
- 1];
230 ols
= "unknown state";
232 if (lease
-> binding_state
!= bar
) {
233 lease
-> next_binding_state
= bar
;
234 if (supersede_lease (lease
, 0, 1, 1, 1)) {
235 log_info ("lease %s state changed from %s to %s",
236 piaddr(lease
->ip_addr
), ols
, nls
);
237 return ISC_R_SUCCESS
;
239 log_info ("lease %s state change from %s to %s failed.",
240 piaddr (lease
-> ip_addr
), ols
, nls
);
241 return ISC_R_IOERROR
;
243 return DHCP_R_UNCHANGED
;
244 } else if (!omapi_ds_strcmp (name
, "ip-address")) {
246 } else if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
247 return DHCP_R_UNCHANGED
; /* XXX take change. */
248 } else if (!omapi_ds_strcmp (name
, "hostname")) {
249 return DHCP_R_UNCHANGED
; /* XXX take change. */
250 } else if (!omapi_ds_strcmp (name
, "client-hostname")) {
251 return DHCP_R_UNCHANGED
; /* XXX take change. */
252 } else if (!omapi_ds_strcmp (name
, "host")) {
253 return DHCP_R_UNCHANGED
; /* XXX take change. */
254 } else if (!omapi_ds_strcmp (name
, "subnet")) {
255 return DHCP_R_INVALIDARG
;
256 } else if (!omapi_ds_strcmp (name
, "pool")) {
258 } else if (!omapi_ds_strcmp (name
, "starts")) {
260 } else if (!omapi_ds_strcmp (name
, "ends")) {
261 unsigned long lease_end
, old_lease_end
;
262 status
= omapi_get_int_value (&lease_end
, value
);
263 if (status
!= ISC_R_SUCCESS
)
265 old_lease_end
= lease
->ends
;
266 lease
->ends
= lease_end
;
267 if (supersede_lease (lease
, 0, 1, 1, 1)) {
268 log_info ("lease %s end changed from %lu to %lu",
269 piaddr(lease
->ip_addr
), old_lease_end
, lease_end
);
270 return ISC_R_SUCCESS
;
272 log_info ("lease %s end change from %lu to %lu failed",
273 piaddr(lease
->ip_addr
), old_lease_end
, lease_end
);
274 return ISC_R_IOERROR
;
275 } else if (!omapi_ds_strcmp(name
, "flags")) {
278 if (value
->type
!= omapi_datatype_data
)
279 return DHCP_R_INVALIDARG
;
281 oldflags
= lease
->flags
;
282 lease
->flags
= (value
->u
.buffer
.value
[0] & EPHEMERAL_FLAGS
) |
283 (lease
->flags
& ~EPHEMERAL_FLAGS
);
284 if(oldflags
== lease
->flags
)
285 return ISC_R_SUCCESS
;
286 if (!supersede_lease(lease
, NULL
, 1, 1, 1)) {
287 log_error("Failed to update flags for lease %s.",
288 piaddr(lease
->ip_addr
));
289 return ISC_R_IOERROR
;
291 return ISC_R_SUCCESS
;
292 } else if (!omapi_ds_strcmp (name
, "billing-class")) {
293 return DHCP_R_UNCHANGED
; /* XXX carefully allow change. */
294 } else if (!omapi_ds_strcmp (name
, "hardware-address")) {
295 return DHCP_R_UNCHANGED
; /* XXX take change. */
296 } else if (!omapi_ds_strcmp (name
, "hardware-type")) {
297 return DHCP_R_UNCHANGED
; /* XXX take change. */
298 } else if (lease
-> scope
) {
299 status
= binding_scope_set_value (lease
-> scope
, 0, name
, value
);
300 if (status
== ISC_R_SUCCESS
) {
301 if (write_lease (lease
) && commit_leases ())
302 return ISC_R_SUCCESS
;
303 return ISC_R_IOERROR
;
307 /* Try to find some inner object that can take the value. */
308 if (h
-> inner
&& h
-> inner
-> type
-> set_value
) {
309 status
= ((*(h
-> inner
-> type
-> set_value
))
310 (h
-> inner
, id
, name
, value
));
311 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
315 if (!lease
-> scope
) {
316 if (!binding_scope_allocate (&lease
-> scope
, MDL
))
317 return ISC_R_NOMEMORY
;
319 status
= binding_scope_set_value (lease
-> scope
, 1, name
, value
);
320 if (status
!= ISC_R_SUCCESS
)
323 if (write_lease (lease
) && commit_leases ())
324 return ISC_R_SUCCESS
;
325 return ISC_R_IOERROR
;
329 isc_result_t
dhcp_lease_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
330 omapi_data_string_t
*name
,
331 omapi_value_t
**value
)
336 if (h
-> type
!= dhcp_type_lease
)
337 return DHCP_R_INVALIDARG
;
338 lease
= (struct lease
*)h
;
340 if (!omapi_ds_strcmp (name
, "state"))
341 return omapi_make_int_value (value
, name
,
342 (int)lease
-> binding_state
, MDL
);
343 else if (!omapi_ds_strcmp (name
, "ip-address"))
344 return omapi_make_const_value (value
, name
,
345 lease
-> ip_addr
.iabuf
,
346 lease
-> ip_addr
.len
, MDL
);
347 else if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
348 return omapi_make_const_value (value
, name
,
350 lease
-> uid_len
, MDL
);
351 } else if (!omapi_ds_strcmp (name
, "client-hostname")) {
352 if (lease
-> client_hostname
)
353 return omapi_make_string_value
354 (value
, name
, lease
-> client_hostname
, MDL
);
355 return ISC_R_NOTFOUND
;
356 } else if (!omapi_ds_strcmp (name
, "host")) {
358 return omapi_make_handle_value
360 ((omapi_object_t
*)lease
-> host
), MDL
);
361 } else if (!omapi_ds_strcmp (name
, "subnet"))
362 return omapi_make_handle_value (value
, name
,
364 lease
-> subnet
), MDL
);
365 else if (!omapi_ds_strcmp (name
, "pool"))
366 return omapi_make_handle_value (value
, name
,
368 lease
-> pool
), MDL
);
369 else if (!omapi_ds_strcmp (name
, "billing-class")) {
370 if (lease
-> billing_class
)
371 return omapi_make_handle_value
373 ((omapi_object_t
*)lease
-> billing_class
),
375 return ISC_R_NOTFOUND
;
376 } else if (!omapi_ds_strcmp (name
, "hardware-address")) {
377 if (lease
-> hardware_addr
.hlen
)
378 return omapi_make_const_value
379 (value
, name
, &lease
-> hardware_addr
.hbuf
[1],
380 (unsigned)(lease
-> hardware_addr
.hlen
- 1),
382 return ISC_R_NOTFOUND
;
383 } else if (!omapi_ds_strcmp (name
, "hardware-type")) {
384 if (lease
-> hardware_addr
.hlen
)
385 return omapi_make_int_value
386 (value
, name
, lease
-> hardware_addr
.hbuf
[0],
388 return ISC_R_NOTFOUND
;
389 } else if (lease
-> scope
) {
390 status
= binding_scope_get_value (value
, lease
-> scope
, name
);
391 if (status
!= ISC_R_NOTFOUND
)
395 /* Try to find some inner object that can take the value. */
396 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
397 status
= ((*(h
-> inner
-> type
-> get_value
))
398 (h
-> inner
, id
, name
, value
));
399 if (status
== ISC_R_SUCCESS
)
402 return DHCP_R_UNKNOWNATTRIBUTE
;
405 isc_result_t
dhcp_lease_destroy (omapi_object_t
*h
, const char *file
, int line
)
409 if (h
->type
!= dhcp_type_lease
)
410 return DHCP_R_INVALIDARG
;
411 lease
= (struct lease
*)h
;
414 uid_hash_delete (lease
);
415 hw_hash_delete (lease
);
417 if (lease
->on_star
.on_release
)
418 executable_statement_dereference (&lease
->on_star
.on_release
,
420 if (lease
->on_star
.on_expiry
)
421 executable_statement_dereference (&lease
->on_star
.on_expiry
,
423 if (lease
->on_star
.on_commit
)
424 executable_statement_dereference (&lease
->on_star
.on_commit
,
427 binding_scope_dereference (&lease
->scope
, file
, line
);
429 if (lease
->agent_options
)
430 option_chain_head_dereference (&lease
->agent_options
,
432 if (lease
->uid
&& lease
->uid
!= lease
->uid_buf
) {
433 dfree (lease
->uid
, MDL
);
434 lease
->uid
= &lease
->uid_buf
[0];
438 if (lease
->client_hostname
) {
439 dfree (lease
->client_hostname
, MDL
);
440 lease
->client_hostname
= (char *)0;
444 host_dereference (&lease
->host
, file
, line
);
446 subnet_dereference (&lease
->subnet
, file
, line
);
448 pool_dereference (&lease
->pool
, file
, line
);
451 free_lease_state (lease
->state
, file
, line
);
452 lease
->state
= (struct lease_state
*)0;
454 cancel_timeout (lease_ping_timeout
, lease
);
455 --outstanding_pings
; /* XXX */
458 if (lease
->billing_class
)
460 (&lease
->billing_class
, file
, line
);
462 #if defined (DEBUG_MEMORY_LEAKAGE) || \
463 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
464 /* XXX we should never be destroying a lease with a next
465 XXX pointer except on exit... */
467 lease_dereference (&lease
->next
, file
, line
);
469 lease_dereference (&lease
->n_hw
, file
, line
);
471 lease_dereference (&lease
->n_uid
, file
, line
);
472 if (lease
->next_pending
)
473 lease_dereference (&lease
->next_pending
, file
, line
);
476 return ISC_R_SUCCESS
;
479 isc_result_t
dhcp_lease_signal_handler (omapi_object_t
*h
,
480 const char *name
, va_list ap
)
482 /* h should point to (struct lease *) */
485 if (h
-> type
!= dhcp_type_lease
)
486 return DHCP_R_INVALIDARG
;
488 if (!strcmp (name
, "updated"))
489 return ISC_R_SUCCESS
;
491 /* Try to find some inner object that can take the value. */
492 if (h
-> inner
&& h
-> inner
-> type
-> signal_handler
) {
493 status
= ((*(h
-> inner
-> type
-> signal_handler
))
494 (h
-> inner
, name
, ap
));
495 if (status
== ISC_R_SUCCESS
)
498 return ISC_R_NOTFOUND
;
501 isc_result_t
dhcp_lease_stuff_values (omapi_object_t
*c
,
510 if (h
-> type
!= dhcp_type_lease
)
511 return DHCP_R_INVALIDARG
;
512 lease
= (struct lease
*)h
;
514 /* Write out all the values. */
516 status
= omapi_connection_put_named_uint32(c
, "state",
517 lease
->binding_state
);
518 if (status
!= ISC_R_SUCCESS
)
521 status
= omapi_connection_put_name (c
, "ip-address");
522 if (status
!= ISC_R_SUCCESS
)
524 status
= omapi_connection_put_uint32 (c
, lease
-> ip_addr
.len
);
525 if (status
!= ISC_R_SUCCESS
)
527 status
= omapi_connection_copyin (c
, lease
-> ip_addr
.iabuf
,
528 lease
-> ip_addr
.len
);
529 if (status
!= ISC_R_SUCCESS
)
532 if (lease
-> uid_len
) {
533 status
= omapi_connection_put_name (c
,
534 "dhcp-client-identifier");
535 if (status
!= ISC_R_SUCCESS
)
537 status
= omapi_connection_put_uint32 (c
, lease
-> uid_len
);
538 if (status
!= ISC_R_SUCCESS
)
540 if (lease
-> uid_len
) {
541 status
= omapi_connection_copyin (c
, lease
-> uid
,
543 if (status
!= ISC_R_SUCCESS
)
548 if (lease
-> client_hostname
) {
549 status
= omapi_connection_put_name (c
, "client-hostname");
550 if (status
!= ISC_R_SUCCESS
)
553 omapi_connection_put_string (c
,
554 lease
-> client_hostname
);
555 if (status
!= ISC_R_SUCCESS
)
560 status
= omapi_connection_put_name (c
, "host");
561 if (status
!= ISC_R_SUCCESS
)
563 status
= omapi_connection_put_handle (c
,
566 if (status
!= ISC_R_SUCCESS
)
570 status
= omapi_connection_put_name (c
, "subnet");
571 if (status
!= ISC_R_SUCCESS
)
573 status
= omapi_connection_put_handle
574 (c
, (omapi_object_t
*)lease
-> subnet
);
575 if (status
!= ISC_R_SUCCESS
)
578 status
= omapi_connection_put_name (c
, "pool");
579 if (status
!= ISC_R_SUCCESS
)
581 status
= omapi_connection_put_handle (c
,
582 (omapi_object_t
*)lease
-> pool
);
583 if (status
!= ISC_R_SUCCESS
)
586 if (lease
-> billing_class
) {
587 status
= omapi_connection_put_name (c
, "billing-class");
588 if (status
!= ISC_R_SUCCESS
)
590 status
= omapi_connection_put_handle
591 (c
, (omapi_object_t
*)lease
-> billing_class
);
592 if (status
!= ISC_R_SUCCESS
)
596 if (lease
-> hardware_addr
.hlen
) {
597 status
= omapi_connection_put_name (c
, "hardware-address");
598 if (status
!= ISC_R_SUCCESS
)
600 status
= (omapi_connection_put_uint32
602 (unsigned long)(lease
-> hardware_addr
.hlen
- 1)));
603 if (status
!= ISC_R_SUCCESS
)
605 status
= (omapi_connection_copyin
606 (c
, &lease
-> hardware_addr
.hbuf
[1],
607 (unsigned long)(lease
-> hardware_addr
.hlen
- 1)));
609 if (status
!= ISC_R_SUCCESS
)
612 status
= omapi_connection_put_named_uint32(c
, "hardware-type",
613 lease
->hardware_addr
.hbuf
[0]);
614 if (status
!= ISC_R_SUCCESS
)
618 /* TIME values may be 64-bit, depending on system architecture.
619 * OMAPI must be system independent, both in terms of transmitting
620 * bytes on the wire in network byte order, and in terms of being
621 * readable and usable by both systems.
623 * XXX: In a future feature release, a put_int64() should be made
624 * to exist, and perhaps a put_time() wrapper that selects which
625 * to use based upon sizeof(TIME). In the meantime, use existing,
628 bouncer
= (u_int32_t
)lease
->ends
;
629 status
= omapi_connection_put_named_uint32(c
, "ends", bouncer
);
630 if (status
!= ISC_R_SUCCESS
)
633 bouncer
= (u_int32_t
)lease
->starts
;
634 status
= omapi_connection_put_named_uint32(c
, "starts", bouncer
);
635 if (status
!= ISC_R_SUCCESS
)
638 bouncer
= (u_int32_t
)lease
->tstp
;
639 status
= omapi_connection_put_named_uint32(c
, "tstp", bouncer
);
640 if (status
!= ISC_R_SUCCESS
)
643 bouncer
= (u_int32_t
)lease
->tsfp
;
644 status
= omapi_connection_put_named_uint32(c
, "tsfp", bouncer
);
645 if (status
!= ISC_R_SUCCESS
)
648 bouncer
= (u_int32_t
)lease
->atsfp
;
649 status
= omapi_connection_put_named_uint32(c
, "atsfp", bouncer
);
650 if (status
!= ISC_R_SUCCESS
)
653 bouncer
= (u_int32_t
)lease
->cltt
;
654 status
= omapi_connection_put_named_uint32(c
, "cltt", bouncer
);
655 if (status
!= ISC_R_SUCCESS
)
658 status
= omapi_connection_put_name (c
, "flags");
659 if (status
!= ISC_R_SUCCESS
)
661 status
= omapi_connection_put_uint32(c
, sizeof(flagbuf
));
662 if (status
!= ISC_R_SUCCESS
)
664 flagbuf
= lease
->flags
& EPHEMERAL_FLAGS
;
665 status
= omapi_connection_copyin(c
, &flagbuf
, sizeof(flagbuf
));
666 if (status
!= ISC_R_SUCCESS
)
669 if (lease
-> scope
) {
670 status
= binding_scope_stuff_values (c
, lease
-> scope
);
671 if (status
!= ISC_R_SUCCESS
)
675 /* Write out the inner object, if any. */
676 if (h
-> inner
&& h
-> inner
-> type
-> stuff_values
) {
677 status
= ((*(h
-> inner
-> type
-> stuff_values
))
678 (c
, id
, h
-> inner
));
679 if (status
== ISC_R_SUCCESS
)
683 return ISC_R_SUCCESS
;
686 isc_result_t
dhcp_lease_lookup (omapi_object_t
**lp
,
687 omapi_object_t
*id
, omapi_object_t
*ref
)
689 omapi_value_t
*tv
= (omapi_value_t
*)0;
694 return DHCP_R_NOKEYS
;
696 /* First see if we were sent a handle. */
697 status
= omapi_get_value_str (ref
, id
, "handle", &tv
);
698 if (status
== ISC_R_SUCCESS
) {
699 status
= omapi_handle_td_lookup (lp
, tv
-> value
);
701 omapi_value_dereference (&tv
, MDL
);
702 if (status
!= ISC_R_SUCCESS
)
705 /* Don't return the object if the type is wrong. */
706 if ((*lp
) -> type
!= dhcp_type_lease
) {
707 omapi_object_dereference (lp
, MDL
);
708 return DHCP_R_INVALIDARG
;
712 /* Now look for an IP address. */
713 status
= omapi_get_value_str (ref
, id
, "ip-address", &tv
);
714 if (status
== ISC_R_SUCCESS
) {
715 lease
= (struct lease
*)0;
716 lease_ip_hash_lookup(&lease
, lease_ip_addr_hash
,
717 tv
->value
->u
.buffer
.value
,
718 tv
->value
->u
.buffer
.len
, MDL
);
720 omapi_value_dereference (&tv
, MDL
);
722 /* If we already have a lease, and it's not the same one,
723 then the query was invalid. */
724 if (*lp
&& *lp
!= (omapi_object_t
*)lease
) {
725 omapi_object_dereference (lp
, MDL
);
726 lease_dereference (&lease
, MDL
);
727 return DHCP_R_KEYCONFLICT
;
730 omapi_object_dereference (lp
, MDL
);
731 return ISC_R_NOTFOUND
;
733 /* XXX fix so that hash lookup itself creates
734 XXX the reference. */
735 omapi_object_reference (lp
,
736 (omapi_object_t
*)lease
, MDL
);
737 lease_dereference (&lease
, MDL
);
741 /* Now look for a client identifier. */
742 status
= omapi_get_value_str (ref
, id
, "dhcp-client-identifier", &tv
);
743 if (status
== ISC_R_SUCCESS
) {
744 lease
= (struct lease
*)0;
745 lease_id_hash_lookup(&lease
, lease_uid_hash
,
746 tv
->value
->u
.buffer
.value
,
747 tv
->value
->u
.buffer
.len
, MDL
);
748 omapi_value_dereference (&tv
, MDL
);
750 if (*lp
&& *lp
!= (omapi_object_t
*)lease
) {
751 omapi_object_dereference (lp
, MDL
);
752 lease_dereference (&lease
, MDL
);
753 return DHCP_R_KEYCONFLICT
;
756 omapi_object_dereference (lp
, MDL
);
757 return ISC_R_NOTFOUND
;
758 } else if (lease
-> n_uid
) {
760 omapi_object_dereference (lp
, MDL
);
761 return DHCP_R_MULTIPLE
;
763 /* XXX fix so that hash lookup itself creates
764 XXX the reference. */
765 omapi_object_reference (lp
,
766 (omapi_object_t
*)lease
, MDL
);
767 lease_dereference (&lease
, MDL
);
771 /* Now look for a hardware address. */
772 status
= omapi_get_value_str (ref
, id
, "hardware-address", &tv
);
773 if (status
== ISC_R_SUCCESS
) {
774 unsigned char *haddr
;
777 len
= tv
-> value
-> u
.buffer
.len
+ 1;
778 haddr
= dmalloc (len
, MDL
);
780 omapi_value_dereference (&tv
, MDL
);
781 return ISC_R_NOMEMORY
;
784 memcpy (haddr
+ 1, tv
-> value
-> u
.buffer
.value
, len
- 1);
785 omapi_value_dereference (&tv
, MDL
);
787 status
= omapi_get_value_str (ref
, id
, "hardware-type", &tv
);
788 if (status
== ISC_R_SUCCESS
) {
789 if (tv
-> value
-> type
== omapi_datatype_data
) {
790 if ((tv
-> value
-> u
.buffer
.len
!= 4) ||
791 (tv
-> value
-> u
.buffer
.value
[0] != 0) ||
792 (tv
-> value
-> u
.buffer
.value
[1] != 0) ||
793 (tv
-> value
-> u
.buffer
.value
[2] != 0)) {
794 omapi_value_dereference (&tv
, MDL
);
796 return DHCP_R_INVALIDARG
;
799 haddr
[0] = tv
-> value
-> u
.buffer
.value
[3];
800 } else if (tv
-> value
-> type
== omapi_datatype_int
) {
801 haddr
[0] = (unsigned char)
802 tv
-> value
-> u
.integer
;
804 omapi_value_dereference (&tv
, MDL
);
806 return DHCP_R_INVALIDARG
;
809 omapi_value_dereference (&tv
, MDL
);
811 /* If no hardware-type is specified, default to
812 ethernet. This may or may not be a good idea,
813 but Telus is currently relying on this behavior.
815 haddr
[0] = HTYPE_ETHER
;
818 lease
= (struct lease
*)0;
819 lease_id_hash_lookup(&lease
, lease_hw_addr_hash
, haddr
, len
,
823 if (*lp
&& *lp
!= (omapi_object_t
*)lease
) {
824 omapi_object_dereference (lp
, MDL
);
825 lease_dereference (&lease
, MDL
);
826 return DHCP_R_KEYCONFLICT
;
829 omapi_object_dereference (lp
, MDL
);
830 return ISC_R_NOTFOUND
;
831 } else if (lease
-> n_hw
) {
833 omapi_object_dereference (lp
, MDL
);
834 lease_dereference (&lease
, MDL
);
835 return DHCP_R_MULTIPLE
;
837 /* XXX fix so that hash lookup itself creates
838 XXX the reference. */
839 omapi_object_reference (lp
,
840 (omapi_object_t
*)lease
, MDL
);
841 lease_dereference (&lease
, MDL
);
845 /* If we get to here without finding a lease, no valid key was
848 return DHCP_R_NOKEYS
;
849 return ISC_R_SUCCESS
;
852 isc_result_t
dhcp_lease_create (omapi_object_t
**lp
,
855 return ISC_R_NOTIMPLEMENTED
;
858 isc_result_t
dhcp_lease_remove (omapi_object_t
*lp
,
861 return ISC_R_NOTIMPLEMENTED
;
864 isc_result_t
dhcp_host_set_value (omapi_object_t
*h
,
866 omapi_data_string_t
*name
,
867 omapi_typed_data_t
*value
)
869 struct host_decl
*host
;
872 if (h
-> type
!= dhcp_type_host
)
873 return DHCP_R_INVALIDARG
;
874 host
= (struct host_decl
*)h
;
876 /* XXX For now, we can only set these values on new host objects.
877 XXX Soon, we need to be able to update host objects. */
878 if (!omapi_ds_strcmp (name
, "name")) {
881 if (value
&& (value
-> type
== omapi_datatype_data
||
882 value
-> type
== omapi_datatype_string
)) {
883 host
-> name
= dmalloc (value
-> u
.buffer
.len
+ 1,
886 return ISC_R_NOMEMORY
;
887 memcpy (host
-> name
,
888 value
-> u
.buffer
.value
,
889 value
-> u
.buffer
.len
);
890 host
-> name
[value
-> u
.buffer
.len
] = 0;
892 return DHCP_R_INVALIDARG
;
893 return ISC_R_SUCCESS
;
896 if (!omapi_ds_strcmp (name
, "group")) {
897 if (value
&& (value
-> type
== omapi_datatype_data
||
898 value
-> type
== omapi_datatype_string
)) {
899 struct group_object
*group
;
900 group
= (struct group_object
*)0;
901 group_hash_lookup (&group
, group_name_hash
,
902 (char *)value
-> u
.buffer
.value
,
903 value
-> u
.buffer
.len
, MDL
);
904 if (!group
|| (group
-> flags
& GROUP_OBJECT_DELETED
))
905 return ISC_R_NOTFOUND
;
907 group_dereference (&host
-> group
, MDL
);
908 group_reference (&host
-> group
, group
-> group
, MDL
);
909 if (host
-> named_group
)
910 group_object_dereference (&host
-> named_group
,
912 group_object_reference (&host
-> named_group
,
914 group_object_dereference (&group
, MDL
);
916 return DHCP_R_INVALIDARG
;
917 return ISC_R_SUCCESS
;
920 if (!omapi_ds_strcmp (name
, "hardware-address")) {
921 if (host
-> interface
.hlen
)
923 if (value
&& (value
-> type
== omapi_datatype_data
||
924 value
-> type
== omapi_datatype_string
)) {
925 if (value
-> u
.buffer
.len
>
926 (sizeof host
-> interface
.hbuf
) - 1)
927 return DHCP_R_INVALIDARG
;
928 memcpy (&host
-> interface
.hbuf
[1],
929 value
-> u
.buffer
.value
,
930 value
-> u
.buffer
.len
);
931 host
-> interface
.hlen
= value
-> u
.buffer
.len
+ 1;
933 return DHCP_R_INVALIDARG
;
934 return ISC_R_SUCCESS
;
937 if (!omapi_ds_strcmp (name
, "hardware-type")) {
939 if ((value
!= NULL
) &&
940 ((value
->type
== omapi_datatype_data
) &&
941 (value
->u
.buffer
.len
== sizeof(type
)))) {
942 if (value
->u
.buffer
.len
> sizeof(type
))
943 return (DHCP_R_INVALIDARG
);
944 memcpy(&type
, value
->u
.buffer
.value
,
945 value
->u
.buffer
.len
);
947 } else if ((value
!= NULL
) &&
948 (value
->type
== omapi_datatype_int
))
949 type
= value
->u
.integer
;
951 return (DHCP_R_INVALIDARG
);
952 host
->interface
.hbuf
[0] = type
;
953 return (ISC_R_SUCCESS
);
956 if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
957 if (host
-> client_identifier
.data
)
959 if (value
&& (value
-> type
== omapi_datatype_data
||
960 value
-> type
== omapi_datatype_string
)) {
961 if (!buffer_allocate (&host
-> client_identifier
.buffer
,
962 value
-> u
.buffer
.len
, MDL
))
963 return ISC_R_NOMEMORY
;
964 host
-> client_identifier
.data
=
965 &host
-> client_identifier
.buffer
-> data
[0];
966 memcpy (host
-> client_identifier
.buffer
-> data
,
967 value
-> u
.buffer
.value
,
968 value
-> u
.buffer
.len
);
969 host
-> client_identifier
.len
= value
-> u
.buffer
.len
;
971 return DHCP_R_INVALIDARG
;
972 return ISC_R_SUCCESS
;
975 if (!omapi_ds_strcmp (name
, "ip-address")) {
976 if (host
-> fixed_addr
)
977 option_cache_dereference (&host
-> fixed_addr
, MDL
);
979 return ISC_R_SUCCESS
;
980 if (value
&& (value
-> type
== omapi_datatype_data
||
981 value
-> type
== omapi_datatype_string
)) {
982 struct data_string ds
;
983 memset (&ds
, 0, sizeof ds
);
984 ds
.len
= value
-> u
.buffer
.len
;
985 if (!buffer_allocate (&ds
.buffer
, ds
.len
, MDL
))
986 return ISC_R_NOMEMORY
;
987 ds
.data
= (&ds
.buffer
-> data
[0]);
988 memcpy (ds
.buffer
-> data
,
989 value
-> u
.buffer
.value
, ds
.len
);
990 if (!option_cache (&host
-> fixed_addr
,
991 &ds
, (struct expression
*)0,
992 (struct option
*)0, MDL
)) {
993 data_string_forget (&ds
, MDL
);
994 return ISC_R_NOMEMORY
;
996 data_string_forget (&ds
, MDL
);
998 return DHCP_R_INVALIDARG
;
999 return ISC_R_SUCCESS
;
1002 if (!omapi_ds_strcmp (name
, "statements")) {
1003 if (!host
-> group
) {
1004 if (!clone_group (&host
-> group
, root_group
, MDL
))
1005 return ISC_R_NOMEMORY
;
1007 if (host
-> group
-> statements
&&
1008 (!host
-> named_group
||
1009 host
-> group
!= host
-> named_group
-> group
) &&
1010 host
-> group
!= root_group
)
1011 return ISC_R_EXISTS
;
1012 if (!clone_group (&host
-> group
, host
-> group
, MDL
))
1013 return ISC_R_NOMEMORY
;
1016 return ISC_R_NOMEMORY
;
1017 if (value
&& (value
-> type
== omapi_datatype_data
||
1018 value
-> type
== omapi_datatype_string
)) {
1019 struct parse
*parse
;
1021 parse
= (struct parse
*)0;
1022 status
= new_parse(&parse
, -1,
1023 (char *) value
->u
.buffer
.value
,
1024 value
->u
.buffer
.len
,
1025 "network client", 0);
1026 if (status
!= ISC_R_SUCCESS
|| parse
== NULL
)
1029 if (!(parse_executable_statements
1030 (&host
-> group
-> statements
, parse
, &lose
,
1033 return DHCP_R_BADPARSE
;
1037 return DHCP_R_INVALIDARG
;
1038 return ISC_R_SUCCESS
;
1041 /* The "known" flag isn't supported in the database yet, but it's
1043 if (!omapi_ds_strcmp (name
, "known")) {
1044 return ISC_R_SUCCESS
;
1047 /* Try to find some inner object that can take the value. */
1048 if (h
-> inner
&& h
-> inner
-> type
-> set_value
) {
1049 status
= ((*(h
-> inner
-> type
-> set_value
))
1050 (h
-> inner
, id
, name
, value
));
1051 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
1055 return DHCP_R_UNKNOWNATTRIBUTE
;
1059 isc_result_t
dhcp_host_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
1060 omapi_data_string_t
*name
,
1061 omapi_value_t
**value
)
1063 struct host_decl
*host
;
1064 isc_result_t status
;
1065 struct data_string ip_addrs
;
1067 if (h
-> type
!= dhcp_type_host
)
1068 return DHCP_R_INVALIDARG
;
1069 host
= (struct host_decl
*)h
;
1071 if (!omapi_ds_strcmp (name
, "ip-addresses")) {
1072 memset (&ip_addrs
, 0, sizeof ip_addrs
);
1073 if (host
-> fixed_addr
&&
1074 evaluate_option_cache (&ip_addrs
, (struct packet
*)0,
1076 (struct client_state
*)0,
1077 (struct option_state
*)0,
1078 (struct option_state
*)0,
1080 host
-> fixed_addr
, MDL
)) {
1081 status
= omapi_make_const_value (value
, name
,
1084 data_string_forget (&ip_addrs
, MDL
);
1087 return ISC_R_NOTFOUND
;
1090 if (!omapi_ds_strcmp (name
, "dhcp-client-identifier")) {
1091 if (!host
-> client_identifier
.len
)
1092 return ISC_R_NOTFOUND
;
1093 return omapi_make_const_value (value
, name
,
1094 host
-> client_identifier
.data
,
1095 host
-> client_identifier
.len
,
1099 if (!omapi_ds_strcmp (name
, "name"))
1100 return omapi_make_string_value (value
, name
, host
-> name
,
1103 if (!omapi_ds_strcmp (name
, "hardware-address")) {
1104 if (!host
-> interface
.hlen
)
1105 return ISC_R_NOTFOUND
;
1106 return (omapi_make_const_value
1107 (value
, name
, &host
-> interface
.hbuf
[1],
1108 (unsigned long)(host
-> interface
.hlen
- 1), MDL
));
1111 if (!omapi_ds_strcmp (name
, "hardware-type")) {
1112 if (!host
-> interface
.hlen
)
1113 return ISC_R_NOTFOUND
;
1114 return omapi_make_int_value (value
, name
,
1115 host
-> interface
.hbuf
[0], MDL
);
1118 /* Try to find some inner object that can take the value. */
1119 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
1120 status
= ((*(h
-> inner
-> type
-> get_value
))
1121 (h
-> inner
, id
, name
, value
));
1122 if (status
== ISC_R_SUCCESS
)
1125 return DHCP_R_UNKNOWNATTRIBUTE
;
1128 isc_result_t
dhcp_host_destroy (omapi_object_t
*h
, const char *file
, int line
)
1131 if (h
-> type
!= dhcp_type_host
)
1132 return DHCP_R_INVALIDARG
;
1134 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1135 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1136 struct host_decl
*host
= (struct host_decl
*)h
;
1137 if (host
-> n_ipaddr
)
1138 host_dereference (&host
-> n_ipaddr
, file
, line
);
1139 if (host
-> n_dynamic
)
1140 host_dereference (&host
-> n_dynamic
, file
, line
);
1142 dfree (host
-> name
, file
, line
);
1143 host
-> name
= (char *)0;
1145 data_string_forget (&host
-> client_identifier
, file
, line
);
1146 if (host
-> fixed_addr
)
1147 option_cache_dereference (&host
-> fixed_addr
, file
, line
);
1149 group_dereference (&host
-> group
, file
, line
);
1150 if (host
-> named_group
)
1151 omapi_object_dereference ((omapi_object_t
**)
1152 &host
-> named_group
, file
, line
);
1153 data_string_forget (&host
-> auth_key_id
, file
, line
);
1156 return ISC_R_SUCCESS
;
1159 isc_result_t
dhcp_host_signal_handler (omapi_object_t
*h
,
1160 const char *name
, va_list ap
)
1162 struct host_decl
*host
;
1163 isc_result_t status
;
1166 if (h
-> type
!= dhcp_type_host
)
1167 return DHCP_R_INVALIDARG
;
1168 host
= (struct host_decl
*)h
;
1170 if (!strcmp (name
, "updated")) {
1171 /* There must be a client identifier of some sort. */
1172 if (host
-> interface
.hlen
== 0 &&
1173 !host
-> client_identifier
.len
)
1174 return DHCP_R_INVALIDARG
;
1176 if (!host
-> name
) {
1178 sprintf (hnbuf
, "nh%08lx%08lx",
1179 (unsigned long)cur_time
, (unsigned long)host
);
1180 host
-> name
= dmalloc (strlen (hnbuf
) + 1, MDL
);
1182 return ISC_R_NOMEMORY
;
1183 strcpy (host
-> name
, hnbuf
);
1187 log_debug ("OMAPI added host %s", host
-> name
);
1189 status
= enter_host (host
, 1, 1);
1190 if (status
!= ISC_R_SUCCESS
)
1195 /* Try to find some inner object that can take the value. */
1196 if (h
-> inner
&& h
-> inner
-> type
-> signal_handler
) {
1197 status
= ((*(h
-> inner
-> type
-> signal_handler
))
1198 (h
-> inner
, name
, ap
));
1199 if (status
== ISC_R_SUCCESS
)
1203 return ISC_R_SUCCESS
;
1204 return ISC_R_NOTFOUND
;
1207 isc_result_t
dhcp_host_stuff_values (omapi_object_t
*c
,
1211 struct host_decl
*host
;
1212 isc_result_t status
;
1213 struct data_string ip_addrs
;
1215 if (h
-> type
!= dhcp_type_host
)
1216 return DHCP_R_INVALIDARG
;
1217 host
= (struct host_decl
*)h
;
1219 /* Write out all the values. */
1221 memset (&ip_addrs
, 0, sizeof ip_addrs
);
1222 if (host
-> fixed_addr
&&
1223 evaluate_option_cache (&ip_addrs
, (struct packet
*)0,
1225 (struct client_state
*)0,
1226 (struct option_state
*)0,
1227 (struct option_state
*)0,
1229 host
-> fixed_addr
, MDL
)) {
1230 status
= omapi_connection_put_name (c
, "ip-address");
1231 if (status
!= ISC_R_SUCCESS
)
1233 status
= omapi_connection_put_uint32 (c
, ip_addrs
.len
);
1234 if (status
!= ISC_R_SUCCESS
)
1236 status
= omapi_connection_copyin (c
,
1237 ip_addrs
.data
, ip_addrs
.len
);
1238 if (status
!= ISC_R_SUCCESS
)
1242 if (host
-> client_identifier
.len
) {
1243 status
= omapi_connection_put_name (c
,
1244 "dhcp-client-identifier");
1245 if (status
!= ISC_R_SUCCESS
)
1247 status
= (omapi_connection_put_uint32
1248 (c
, host
-> client_identifier
.len
));
1249 if (status
!= ISC_R_SUCCESS
)
1251 status
= (omapi_connection_copyin
1253 host
-> client_identifier
.data
,
1254 host
-> client_identifier
.len
));
1255 if (status
!= ISC_R_SUCCESS
)
1260 status
= omapi_connection_put_name (c
, "name");
1261 if (status
!= ISC_R_SUCCESS
)
1263 status
= omapi_connection_put_string (c
, host
-> name
);
1264 if (status
!= ISC_R_SUCCESS
)
1268 if (host
-> interface
.hlen
) {
1269 status
= omapi_connection_put_name (c
, "hardware-address");
1270 if (status
!= ISC_R_SUCCESS
)
1272 status
= (omapi_connection_put_uint32
1273 (c
, (unsigned long)(host
-> interface
.hlen
- 1)));
1274 if (status
!= ISC_R_SUCCESS
)
1276 status
= (omapi_connection_copyin
1277 (c
, &host
-> interface
.hbuf
[1],
1278 (unsigned long)(host
-> interface
.hlen
- 1)));
1279 if (status
!= ISC_R_SUCCESS
)
1282 status
= omapi_connection_put_named_uint32(c
, "hardware-type",
1283 host
->interface
.hbuf
[0]);
1284 if (status
!= ISC_R_SUCCESS
)
1288 /* Write out the inner object, if any. */
1289 if (h
-> inner
&& h
-> inner
-> type
-> stuff_values
) {
1290 status
= ((*(h
-> inner
-> type
-> stuff_values
))
1291 (c
, id
, h
-> inner
));
1292 if (status
== ISC_R_SUCCESS
)
1296 return ISC_R_SUCCESS
;
1299 isc_result_t
dhcp_host_lookup (omapi_object_t
**lp
,
1300 omapi_object_t
*id
, omapi_object_t
*ref
)
1302 omapi_value_t
*tv
= (omapi_value_t
*)0;
1303 isc_result_t status
;
1304 struct host_decl
*host
;
1307 return DHCP_R_NOKEYS
;
1309 /* First see if we were sent a handle. */
1310 status
= omapi_get_value_str (ref
, id
, "handle", &tv
);
1311 if (status
== ISC_R_SUCCESS
) {
1312 status
= omapi_handle_td_lookup (lp
, tv
-> value
);
1314 omapi_value_dereference (&tv
, MDL
);
1315 if (status
!= ISC_R_SUCCESS
)
1318 /* Don't return the object if the type is wrong. */
1319 if ((*lp
) -> type
!= dhcp_type_host
) {
1320 omapi_object_dereference (lp
, MDL
);
1321 return DHCP_R_INVALIDARG
;
1323 if (((struct host_decl
*)(*lp
)) -> flags
& HOST_DECL_DELETED
) {
1324 omapi_object_dereference (lp
, MDL
);
1328 /* Now look for a client identifier. */
1329 status
= omapi_get_value_str (ref
, id
, "dhcp-client-identifier", &tv
);
1330 if (status
== ISC_R_SUCCESS
) {
1331 host
= (struct host_decl
*)0;
1332 host_hash_lookup (&host
, host_uid_hash
,
1333 tv
-> value
-> u
.buffer
.value
,
1334 tv
-> value
-> u
.buffer
.len
, MDL
);
1335 omapi_value_dereference (&tv
, MDL
);
1337 if (*lp
&& *lp
!= (omapi_object_t
*)host
) {
1338 omapi_object_dereference (lp
, MDL
);
1340 host_dereference (&host
, MDL
);
1341 return DHCP_R_KEYCONFLICT
;
1342 } else if (!host
|| (host
-> flags
& HOST_DECL_DELETED
)) {
1344 omapi_object_dereference (lp
, MDL
);
1346 host_dereference (&host
, MDL
);
1347 return ISC_R_NOTFOUND
;
1349 /* XXX fix so that hash lookup itself creates
1350 XXX the reference. */
1351 omapi_object_reference (lp
,
1352 (omapi_object_t
*)host
, MDL
);
1353 host_dereference (&host
, MDL
);
1357 /* Now look for a hardware address. */
1358 status
= omapi_get_value_str (ref
, id
, "hardware-address", &tv
);
1359 if (status
== ISC_R_SUCCESS
) {
1360 unsigned char *haddr
;
1363 len
= tv
-> value
-> u
.buffer
.len
+ 1;
1364 haddr
= dmalloc (len
, MDL
);
1366 omapi_value_dereference (&tv
, MDL
);
1367 return ISC_R_NOMEMORY
;
1370 memcpy (haddr
+ 1, tv
-> value
-> u
.buffer
.value
, len
- 1);
1371 omapi_value_dereference (&tv
, MDL
);
1373 status
= omapi_get_value_str (ref
, id
, "hardware-type", &tv
);
1374 if (status
== ISC_R_SUCCESS
) {
1375 if (tv
-> value
-> type
== omapi_datatype_data
) {
1376 if ((tv
-> value
-> u
.buffer
.len
!= 4) ||
1377 (tv
-> value
-> u
.buffer
.value
[0] != 0) ||
1378 (tv
-> value
-> u
.buffer
.value
[1] != 0) ||
1379 (tv
-> value
-> u
.buffer
.value
[2] != 0)) {
1380 omapi_value_dereference (&tv
, MDL
);
1382 return DHCP_R_INVALIDARG
;
1385 haddr
[0] = tv
-> value
-> u
.buffer
.value
[3];
1386 } else if (tv
-> value
-> type
== omapi_datatype_int
) {
1387 haddr
[0] = (unsigned char)
1388 tv
-> value
-> u
.integer
;
1390 omapi_value_dereference (&tv
, MDL
);
1392 return DHCP_R_INVALIDARG
;
1395 omapi_value_dereference (&tv
, MDL
);
1397 /* If no hardware-type is specified, default to
1398 ethernet. This may or may not be a good idea,
1399 but Telus is currently relying on this behavior.
1401 haddr
[0] = HTYPE_ETHER
;
1404 host
= (struct host_decl
*)0;
1405 host_hash_lookup (&host
, host_hw_addr_hash
, haddr
, len
, MDL
);
1408 if (*lp
&& *lp
!= (omapi_object_t
*)host
) {
1409 omapi_object_dereference (lp
, MDL
);
1411 host_dereference (&host
, MDL
);
1412 return DHCP_R_KEYCONFLICT
;
1413 } else if (!host
|| (host
-> flags
& HOST_DECL_DELETED
)) {
1415 omapi_object_dereference (lp
, MDL
);
1417 host_dereference (&host
, MDL
);
1418 return ISC_R_NOTFOUND
;
1420 /* XXX fix so that hash lookup itself creates
1421 XXX the reference. */
1422 omapi_object_reference (lp
,
1423 (omapi_object_t
*)host
, MDL
);
1424 host_dereference (&host
, MDL
);
1428 /* Now look for an ip address. */
1429 status
= omapi_get_value_str (ref
, id
, "ip-address", &tv
);
1430 if (status
== ISC_R_SUCCESS
) {
1433 /* first find the lease for this ip address */
1434 l
= (struct lease
*)0;
1435 lease_ip_hash_lookup(&l
, lease_ip_addr_hash
,
1436 tv
->value
->u
.buffer
.value
,
1437 tv
->value
->u
.buffer
.len
, MDL
);
1438 omapi_value_dereference (&tv
, MDL
);
1441 return ISC_R_NOTFOUND
;
1444 /* now use that to get a host */
1445 host
= (struct host_decl
*)0;
1446 host_hash_lookup (&host
, host_hw_addr_hash
,
1447 l
-> hardware_addr
.hbuf
,
1448 l
-> hardware_addr
.hlen
, MDL
);
1450 if (host
&& *lp
&& *lp
!= (omapi_object_t
*)host
) {
1451 omapi_object_dereference (lp
, MDL
);
1453 host_dereference (&host
, MDL
);
1454 return DHCP_R_KEYCONFLICT
;
1455 } else if (!host
|| (host
-> flags
&
1456 HOST_DECL_DELETED
)) {
1458 host_dereference (&host
, MDL
);
1460 return ISC_R_NOTFOUND
;
1462 /* XXX fix so that hash lookup itself creates
1463 XXX the reference. */
1464 omapi_object_reference (lp
, (omapi_object_t
*)host
,
1466 host_dereference (&host
, MDL
);
1468 lease_dereference (&l
, MDL
);
1472 /* Now look for a name. */
1473 status
= omapi_get_value_str (ref
, id
, "name", &tv
);
1474 if (status
== ISC_R_SUCCESS
) {
1475 host
= (struct host_decl
*)0;
1476 host_hash_lookup (&host
, host_name_hash
,
1477 tv
-> value
-> u
.buffer
.value
,
1478 tv
-> value
-> u
.buffer
.len
, MDL
);
1479 omapi_value_dereference (&tv
, MDL
);
1481 if (*lp
&& *lp
!= (omapi_object_t
*)host
) {
1482 omapi_object_dereference (lp
, MDL
);
1484 host_dereference (&host
, MDL
);
1485 return DHCP_R_KEYCONFLICT
;
1486 } else if (!host
|| (host
-> flags
& HOST_DECL_DELETED
)) {
1488 host_dereference (&host
, MDL
);
1489 return ISC_R_NOTFOUND
;
1491 /* XXX fix so that hash lookup itself creates
1492 XXX the reference. */
1493 omapi_object_reference (lp
,
1494 (omapi_object_t
*)host
, MDL
);
1495 host_dereference (&host
, MDL
);
1499 /* If we get to here without finding a host, no valid key was
1502 return DHCP_R_NOKEYS
;
1503 return ISC_R_SUCCESS
;
1506 isc_result_t
dhcp_host_create (omapi_object_t
**lp
,
1509 struct host_decl
*hp
;
1510 isc_result_t status
;
1511 hp
= (struct host_decl
*)0;
1512 status
= host_allocate (&hp
, MDL
);
1513 if (status
!= ISC_R_SUCCESS
)
1515 group_reference (&hp
-> group
, root_group
, MDL
);
1516 hp
-> flags
= HOST_DECL_DYNAMIC
;
1517 status
= omapi_object_reference (lp
, (omapi_object_t
*)hp
, MDL
);
1518 host_dereference (&hp
, MDL
);
1522 isc_result_t
dhcp_host_remove (omapi_object_t
*lp
,
1525 struct host_decl
*hp
;
1526 if (lp
-> type
!= dhcp_type_host
)
1527 return DHCP_R_INVALIDARG
;
1528 hp
= (struct host_decl
*)lp
;
1531 log_debug ("OMAPI delete host %s", hp
-> name
);
1533 delete_host (hp
, 1);
1534 return ISC_R_SUCCESS
;
1537 isc_result_t
dhcp_pool_set_value (omapi_object_t
*h
,
1539 omapi_data_string_t
*name
,
1540 omapi_typed_data_t
*value
)
1542 /* h should point to (struct pool *) */
1543 isc_result_t status
;
1545 if (h
-> type
!= dhcp_type_pool
)
1546 return DHCP_R_INVALIDARG
;
1548 /* No values to set yet. */
1550 /* Try to find some inner object that can take the value. */
1551 if (h
-> inner
&& h
-> inner
-> type
-> set_value
) {
1552 status
= ((*(h
-> inner
-> type
-> set_value
))
1553 (h
-> inner
, id
, name
, value
));
1554 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
1558 return DHCP_R_UNKNOWNATTRIBUTE
;
1562 isc_result_t
dhcp_pool_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
1563 omapi_data_string_t
*name
,
1564 omapi_value_t
**value
)
1566 /* h should point to (struct pool *) */
1567 isc_result_t status
;
1569 if (h
-> type
!= dhcp_type_pool
)
1570 return DHCP_R_INVALIDARG
;
1572 /* No values to get yet. */
1574 /* Try to find some inner object that can provide the value. */
1575 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
1576 status
= ((*(h
-> inner
-> type
-> get_value
))
1577 (h
-> inner
, id
, name
, value
));
1578 if (status
== ISC_R_SUCCESS
)
1581 return DHCP_R_UNKNOWNATTRIBUTE
;
1584 isc_result_t
dhcp_pool_destroy (omapi_object_t
*h
, const char *file
, int line
)
1586 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1587 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1588 struct permit
*pc
, *pn
;
1591 if (h
-> type
!= dhcp_type_pool
)
1592 return DHCP_R_INVALIDARG
;
1594 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1595 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1596 struct pool
*pool
= (struct pool
*)h
;
1598 pool_dereference (&pool
-> next
, file
, line
);
1600 group_dereference (&pool
-> group
, file
, line
);
1601 if (pool
-> shared_network
)
1602 shared_network_dereference (&pool
-> shared_network
, file
, line
);
1604 lease_dereference (&pool
-> active
, file
, line
);
1605 if (pool
-> expired
)
1606 lease_dereference (&pool
-> expired
, file
, line
);
1608 lease_dereference (&pool
-> free
, file
, line
);
1610 lease_dereference (&pool
-> backup
, file
, line
);
1611 if (pool
-> abandoned
)
1612 lease_dereference (&pool
-> abandoned
, file
, line
);
1613 #if defined (FAILOVER_PROTOCOL)
1614 if (pool
-> failover_peer
)
1615 dhcp_failover_state_dereference (&pool
-> failover_peer
,
1618 for (pc
= pool
-> permit_list
; pc
; pc
= pn
) {
1620 free_permit (pc
, file
, line
);
1622 pool
-> permit_list
= (struct permit
*)0;
1624 for (pc
= pool
-> prohibit_list
; pc
; pc
= pn
) {
1626 free_permit (pc
, file
, line
);
1628 pool
-> prohibit_list
= (struct permit
*)0;
1631 return ISC_R_SUCCESS
;
1634 isc_result_t
dhcp_pool_signal_handler (omapi_object_t
*h
,
1635 const char *name
, va_list ap
)
1637 /* h should point to (struct pool *) */
1638 isc_result_t status
;
1640 if (h
-> type
!= dhcp_type_pool
)
1641 return DHCP_R_INVALIDARG
;
1643 /* Can't write pools yet. */
1645 /* Try to find some inner object that can take the value. */
1646 if (h
-> inner
&& h
-> inner
-> type
-> signal_handler
) {
1647 status
= ((*(h
-> inner
-> type
-> signal_handler
))
1648 (h
-> inner
, name
, ap
));
1649 if (status
== ISC_R_SUCCESS
)
1653 return ISC_R_NOTFOUND
;
1656 isc_result_t
dhcp_pool_stuff_values (omapi_object_t
*c
,
1661 isc_result_t status
;
1663 if (h
->type
!= dhcp_type_pool
)
1664 return (DHCP_R_INVALIDARG
);
1665 pool
= (struct pool
*)h
;
1668 * I don't think we can actually find a pool yet
1669 * but include the output of interesting values
1672 status
= omapi_connection_put_named_uint32(c
, "lease-count",
1674 pool
->lease_count
));
1675 if (status
!= ISC_R_SUCCESS
)
1678 status
= omapi_connection_put_named_uint32(c
, "free-leases",
1680 pool
->free_leases
));
1681 if (status
!= ISC_R_SUCCESS
)
1684 status
= omapi_connection_put_named_uint32(c
, "backup-leases",
1686 pool
->backup_leases
));
1687 if (status
!= ISC_R_SUCCESS
)
1689 /* we could add time stamps but lets wait on those */
1691 /* Write out the inner object, if any. */
1692 if (h
->inner
&& h
->inner
->type
->stuff_values
) {
1693 status
= ((*(h
->inner
->type
->stuff_values
))
1695 if (status
== ISC_R_SUCCESS
)
1699 return (ISC_R_SUCCESS
);
1702 isc_result_t
dhcp_pool_lookup (omapi_object_t
**lp
,
1703 omapi_object_t
*id
, omapi_object_t
*ref
)
1705 /* Can't look up pools yet. */
1707 /* If we get to here without finding a pool, no valid key was
1710 return DHCP_R_NOKEYS
;
1711 return ISC_R_SUCCESS
;
1714 isc_result_t
dhcp_pool_create (omapi_object_t
**lp
,
1717 return ISC_R_NOTIMPLEMENTED
;
1720 isc_result_t
dhcp_pool_remove (omapi_object_t
*lp
,
1723 return ISC_R_NOTIMPLEMENTED
;
1727 class_set_value (omapi_object_t
*h
,
1729 omapi_data_string_t
*name
,
1730 omapi_typed_data_t
*value
)
1732 struct class *class;
1733 struct class *superclass
= 0;
1734 isc_result_t status
;
1735 int issubclass
= (h
-> type
== dhcp_type_subclass
);
1737 class = (struct class *)h
;
1739 if (!omapi_ds_strcmp(name
, "name")) {
1743 return ISC_R_EXISTS
;
1745 if ((tname
= dmalloc(value
->u
.buffer
.len
+ 1, MDL
)) == NULL
) {
1746 return ISC_R_NOMEMORY
;
1749 /* tname is null terminated from dmalloc() */
1750 memcpy(tname
, value
->u
.buffer
.value
, value
->u
.buffer
.len
);
1753 status
= find_class(&superclass
, tname
, MDL
);
1756 if (status
== ISC_R_NOTFOUND
)
1759 if (class->superclass
!= NULL
)
1760 class_dereference(&class->superclass
, MDL
);
1761 class_reference(&class->superclass
, superclass
, MDL
);
1763 if (class->group
!= NULL
)
1764 group_dereference(&class->group
, MDL
);
1765 group_reference(&class->group
, superclass
->group
, MDL
);
1767 class->lease_limit
= superclass
->lease_limit
;
1768 if (class->lease_limit
!= 0) {
1769 class->billed_leases
=
1770 dmalloc(class->lease_limit
*
1771 sizeof(struct lease
*),
1773 if (class->billed_leases
== NULL
) {
1774 return ISC_R_NOMEMORY
;
1778 } else if (value
->type
== omapi_datatype_data
||
1779 value
->type
== omapi_datatype_string
) {
1780 class->name
= dmalloc(value
->u
.buffer
.len
+ 1, MDL
);
1782 return ISC_R_NOMEMORY
;
1784 /* class->name is null-terminated from dmalloc() */
1785 memcpy(class->name
, value
->u
.buffer
.value
,
1786 value
->u
.buffer
.len
);
1788 return DHCP_R_INVALIDARG
;
1790 return ISC_R_SUCCESS
;
1794 if (issubclass
&& !omapi_ds_strcmp(name
, "hashstring")) {
1795 if (class->hash_string
.data
)
1796 return ISC_R_EXISTS
;
1798 if (value
->type
== omapi_datatype_data
||
1799 value
->type
== omapi_datatype_string
) {
1800 if (!buffer_allocate(&class->hash_string
.buffer
,
1801 value
->u
.buffer
.len
, MDL
))
1802 return ISC_R_NOMEMORY
;
1803 class->hash_string
.data
=
1804 class->hash_string
.buffer
->data
;
1805 memcpy(class->hash_string
.buffer
->data
,
1806 value
->u
.buffer
.value
, value
->u
.buffer
.len
);
1807 class->hash_string
.len
= value
->u
.buffer
.len
;
1809 return DHCP_R_INVALIDARG
;
1811 return ISC_R_SUCCESS
;
1814 if (!omapi_ds_strcmp(name
, "group")) {
1815 if (value
->type
== omapi_datatype_data
||
1816 value
->type
== omapi_datatype_string
) {
1817 struct group_object
*group
= NULL
;
1819 group_hash_lookup(&group
, group_name_hash
,
1820 (char *)value
->u
.buffer
.value
,
1821 value
->u
.buffer
.len
, MDL
);
1822 if (!group
|| (group
->flags
& GROUP_OBJECT_DELETED
))
1823 return ISC_R_NOTFOUND
;
1825 group_dereference(&class->group
, MDL
);
1826 group_reference(&class->group
, group
->group
, MDL
);
1827 group_object_dereference(&group
, MDL
);
1829 return DHCP_R_INVALIDARG
;
1831 return ISC_R_SUCCESS
;
1835 /* note we do not support full expressions via omapi because the
1836 expressions parser needs to be re-done to support parsing from
1837 strings and not just files. */
1839 if (!omapi_ds_strcmp(name
, "match")) {
1840 if (value
->type
== omapi_datatype_data
||
1841 value
->type
== omapi_datatype_string
) {
1842 unsigned minlen
= (value
->u
.buffer
.len
> 8 ?
1843 8 : value
->u
.buffer
.len
);
1845 if (!strncmp("hardware",
1846 (char *)value
->u
.buffer
.value
, minlen
))
1848 if (!expression_allocate(&class->submatch
, MDL
))
1849 return ISC_R_NOMEMORY
;
1851 class->submatch
->op
= expr_hardware
;
1853 return DHCP_R_INVALIDARG
;
1855 return DHCP_R_INVALIDARG
;
1857 return ISC_R_SUCCESS
;
1861 if (!omapi_ds_strcmp(name
, "option")) {
1862 if (value
->type
== omapi_datatype_data
||
1863 value
->type
== omapi_datatype_string
) {
1864 /* XXXJAB support 'options' here. */
1865 /* XXXJAB specifically 'bootfile-name' */
1866 return DHCP_R_INVALIDARG
; /* XXX tmp */
1868 return DHCP_R_INVALIDARG
;
1871 * Currently no way to get here, if we update the above
1872 * code so that we do get here this return needs to be
1874 * return ISC_R_SUCCESS;
1879 /* Try to find some inner object that can take the value. */
1880 if (h
->inner
&& h
->inner
->type
->set_value
) {
1881 status
= ((*(h
->inner
->type
->set_value
))
1882 (h
->inner
, id
, name
, value
));
1883 if (status
== ISC_R_SUCCESS
|| status
== DHCP_R_UNCHANGED
)
1887 return DHCP_R_UNKNOWNATTRIBUTE
;
1892 isc_result_t
dhcp_class_set_value (omapi_object_t
*h
,
1894 omapi_data_string_t
*name
,
1895 omapi_typed_data_t
*value
)
1897 if (h
-> type
!= dhcp_type_class
)
1898 return DHCP_R_INVALIDARG
;
1900 return class_set_value(h
, id
, name
, value
);
1903 isc_result_t
dhcp_class_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
1904 omapi_data_string_t
*name
,
1905 omapi_value_t
**value
)
1907 struct class *class;
1908 isc_result_t status
;
1910 if (h
-> type
!= dhcp_type_class
)
1911 return DHCP_R_INVALIDARG
;
1912 class = (struct class *)h
;
1914 if (!omapi_ds_strcmp (name
, "name"))
1915 return omapi_make_string_value (value
, name
, class -> name
,
1918 /* Try to find some inner object that can provide the value. */
1919 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
1920 status
= ((*(h
-> inner
-> type
-> get_value
))
1921 (h
-> inner
, id
, name
, value
));
1922 if (status
== ISC_R_SUCCESS
)
1925 return DHCP_R_UNKNOWNATTRIBUTE
;
1928 isc_result_t
dhcp_class_destroy (omapi_object_t
*h
, const char *file
, int line
)
1931 if (h
-> type
!= dhcp_type_class
&& h
-> type
!= dhcp_type_subclass
)
1932 return DHCP_R_INVALIDARG
;
1933 struct class *class = (struct class *)h
;
1936 class_dereference (&class -> nic
, file
, line
);
1937 if (class -> superclass
)
1938 class_dereference (&class -> superclass
, file
, line
);
1939 if (class -> name
) {
1940 dfree (class -> name
, file
, line
);
1941 class -> name
= (char *)0;
1943 if (class -> billed_leases
) {
1945 for (i
= 0; i
< class -> lease_limit
; i
++) {
1946 if (class -> billed_leases
[i
]) {
1947 lease_dereference (&class -> billed_leases
[i
],
1951 dfree (class -> billed_leases
, file
, line
);
1952 class -> billed_leases
= (struct lease
**)0;
1954 if (class -> hash
) {
1955 class_free_hash_table (&class -> hash
, file
, line
);
1956 class -> hash
= (class_hash_t
*)0;
1958 data_string_forget (&class -> hash_string
, file
, line
);
1961 expression_dereference (&class -> expr
, file
, line
);
1962 if (class -> submatch
)
1963 expression_dereference (&class -> submatch
, file
, line
);
1965 group_dereference (&class -> group
, file
, line
);
1966 if (class -> statements
)
1967 executable_statement_dereference (&class -> statements
,
1969 if (class -> superclass
)
1970 class_dereference (&class -> superclass
, file
, line
);
1972 return ISC_R_SUCCESS
;
1976 class_signal_handler(omapi_object_t
*h
,
1977 const char *name
, va_list ap
)
1979 struct class *class = (struct class *)h
;
1980 isc_result_t status
;
1984 issubclass
= (h
->type
== dhcp_type_subclass
);
1986 if (!strcmp (name
, "updated")) {
1989 if (class->name
== 0 || strlen(class->name
) == 0) {
1990 return DHCP_R_INVALIDARG
;
1993 if (class->superclass
== 0) {
1994 return DHCP_R_INVALIDARG
; /* didn't give name */
1997 if (class->hash_string
.data
== NULL
) {
1998 return DHCP_R_INVALIDARG
;
2004 if (!class->superclass
->hash
)
2005 class_new_hash(&class->superclass
->hash
,
2006 SCLASS_HASH_SIZE
, MDL
);
2008 class_hash_add(class->superclass
->hash
,
2009 (const char *)class->hash_string
.data
,
2010 class->hash_string
.len
,
2011 (void *)class, MDL
);
2016 log_debug ("OMAPI added subclass %s",
2017 class->superclass
->name
);
2019 log_debug ("OMAPI added class %s", class->name
);
2023 status
= enter_class (class, 1, 1);
2024 if (status
!= ISC_R_SUCCESS
)
2029 /* Try to find some inner object that can take the value. */
2030 if (h
->inner
&& h
->inner
->type
->signal_handler
) {
2031 status
= ((*(h
->inner
->type
->signal_handler
))
2032 (h
->inner
, name
, ap
));
2033 if (status
== ISC_R_SUCCESS
)
2038 return ISC_R_SUCCESS
;
2040 return ISC_R_NOTFOUND
;
2044 isc_result_t
dhcp_class_signal_handler (omapi_object_t
*h
,
2045 const char *name
, va_list ap
)
2047 if (h
-> type
!= dhcp_type_class
)
2048 return DHCP_R_INVALIDARG
;
2050 return class_signal_handler(h
, name
, ap
);
2055 * Routine to put out generic class & subclass information
2057 static isc_result_t
class_stuff_values (omapi_object_t
*c
,
2061 struct class *class;
2062 isc_result_t status
;
2064 class = (struct class *)h
;
2066 status
= omapi_connection_put_named_uint32(c
, "lease-limit",
2068 class->lease_limit
));
2069 if (status
!= ISC_R_SUCCESS
)
2072 status
= omapi_connection_put_named_uint32(c
, "leases-used",
2074 class->leases_consumed
));
2075 if (status
!= ISC_R_SUCCESS
)
2078 /* Write out the inner object, if any. */
2079 if (h
->inner
&& h
->inner
->type
->stuff_values
) {
2080 status
= ((*(h
->inner
->type
->stuff_values
))
2082 if (status
== ISC_R_SUCCESS
)
2086 return (ISC_R_SUCCESS
);
2090 isc_result_t
dhcp_class_stuff_values (omapi_object_t
*c
,
2094 if (h
->type
!= dhcp_type_class
)
2095 return (DHCP_R_INVALIDARG
);
2097 /* add any class specific items here */
2099 return (class_stuff_values(c
, id
, h
));
2102 static isc_result_t
class_lookup (omapi_object_t
**lp
,
2103 omapi_object_t
*id
, omapi_object_t
*ref
,
2104 omapi_object_type_t
*typewanted
)
2106 omapi_value_t
*nv
= NULL
;
2107 omapi_value_t
*hv
= NULL
;
2108 isc_result_t status
;
2109 struct class *class = 0;
2110 struct class *subclass
= 0;
2115 return (DHCP_R_NOKEYS
);
2117 /* see if we have a name */
2118 status
= omapi_get_value_str(ref
, id
, "name", &nv
);
2119 if (status
== ISC_R_SUCCESS
) {
2120 char *name
= dmalloc(nv
->value
->u
.buffer
.len
+ 1, MDL
);
2122 nv
->value
->u
.buffer
.value
,
2123 nv
->value
->u
.buffer
.len
);
2125 omapi_value_dereference(&nv
, MDL
);
2127 find_class(&class, name
, MDL
);
2131 if (class == NULL
) {
2132 return (ISC_R_NOTFOUND
);
2135 if (typewanted
== dhcp_type_subclass
) {
2136 status
= omapi_get_value_str(ref
, id
,
2138 if (status
!= ISC_R_SUCCESS
) {
2139 class_dereference(&class, MDL
);
2140 return (DHCP_R_NOKEYS
);
2143 if (hv
->value
->type
!= omapi_datatype_data
&&
2144 hv
->value
->type
!= omapi_datatype_string
) {
2145 class_dereference(&class, MDL
);
2146 omapi_value_dereference(&hv
, MDL
);
2147 return (DHCP_R_NOKEYS
);
2150 class_hash_lookup(&subclass
, class->hash
,
2152 hv
->value
->u
.buffer
.value
,
2153 hv
->value
->u
.buffer
.len
, MDL
);
2155 omapi_value_dereference(&hv
, MDL
);
2157 class_dereference(&class, MDL
);
2159 if (subclass
== NULL
) {
2160 return (ISC_R_NOTFOUND
);
2163 class_reference(&class, subclass
, MDL
);
2164 class_dereference(&subclass
, MDL
);
2167 /* Don't return the object if the type is wrong. */
2168 if (class->type
!= typewanted
) {
2169 class_dereference(&class, MDL
);
2170 return (DHCP_R_INVALIDARG
);
2173 if (class->flags
& CLASS_DECL_DELETED
) {
2174 class_dereference(&class, MDL
);
2175 return (ISC_R_NOTFOUND
);
2178 omapi_object_reference(lp
, (omapi_object_t
*)class, MDL
);
2179 class_dereference(&class, MDL
);
2181 return (ISC_R_SUCCESS
);
2184 return (DHCP_R_NOKEYS
);
2188 isc_result_t
dhcp_class_lookup (omapi_object_t
**lp
,
2189 omapi_object_t
*id
, omapi_object_t
*ref
)
2191 return class_lookup(lp
, id
, ref
, dhcp_type_class
);
2194 isc_result_t
dhcp_class_create (omapi_object_t
**lp
,
2197 struct class *cp
= 0;
2198 isc_result_t status
;
2200 status
= class_allocate(&cp
, MDL
);
2201 if (status
!= ISC_R_SUCCESS
)
2204 clone_group(&cp
->group
, root_group
, MDL
);
2205 cp
->flags
= CLASS_DECL_DYNAMIC
;
2206 status
= omapi_object_reference(lp
, (omapi_object_t
*)cp
, MDL
);
2207 class_dereference(&cp
, MDL
);
2211 isc_result_t
dhcp_class_remove (omapi_object_t
*lp
,
2215 if (lp
-> type
!= dhcp_type_class
)
2216 return DHCP_R_INVALIDARG
;
2217 cp
= (struct class *)lp
;
2220 log_debug ("OMAPI delete class %s", cp
-> name
);
2223 delete_class (cp
, 1);
2224 return ISC_R_SUCCESS
;
2227 isc_result_t
dhcp_subclass_set_value (omapi_object_t
*h
,
2229 omapi_data_string_t
*name
,
2230 omapi_typed_data_t
*value
)
2232 if (h
-> type
!= dhcp_type_subclass
)
2233 return DHCP_R_INVALIDARG
;
2235 return class_set_value(h
, id
, name
, value
);
2239 isc_result_t
dhcp_subclass_get_value (omapi_object_t
*h
, omapi_object_t
*id
,
2240 omapi_data_string_t
*name
,
2241 omapi_value_t
**value
)
2243 struct class *subclass
;
2244 isc_result_t status
;
2246 if (h
-> type
!= dhcp_type_class
)
2247 return DHCP_R_INVALIDARG
;
2248 subclass
= (struct class *)h
;
2249 if (subclass
-> name
!= 0)
2250 return DHCP_R_INVALIDARG
;
2252 /* XXXJAB No values to get yet. */
2254 /* Try to find some inner object that can provide the value. */
2255 if (h
-> inner
&& h
-> inner
-> type
-> get_value
) {
2256 status
= ((*(h
-> inner
-> type
-> get_value
))
2257 (h
-> inner
, id
, name
, value
));
2258 if (status
== ISC_R_SUCCESS
)
2261 return DHCP_R_UNKNOWNATTRIBUTE
;
2264 isc_result_t
dhcp_subclass_signal_handler (omapi_object_t
*h
,
2265 const char *name
, va_list ap
)
2267 if (h
-> type
!= dhcp_type_subclass
)
2268 return DHCP_R_INVALIDARG
;
2270 return class_signal_handler(h
, name
, ap
);
2274 isc_result_t
dhcp_subclass_stuff_values (omapi_object_t
*c
,
2278 struct class *subclass
;
2280 if (h
->type
!= dhcp_type_subclass
)
2281 return (DHCP_R_INVALIDARG
);
2282 subclass
= (struct class *)h
;
2283 if (subclass
->name
!= 0)
2284 return (DHCP_R_INVALIDARG
);
2286 /* add any subclass specific items here */
2288 return (class_stuff_values(c
, id
, h
));
2291 isc_result_t
dhcp_subclass_lookup (omapi_object_t
**lp
,
2292 omapi_object_t
*id
, omapi_object_t
*ref
)
2294 return class_lookup(lp
, id
, ref
, dhcp_type_subclass
);
2300 isc_result_t
dhcp_subclass_create (omapi_object_t
**lp
,
2303 struct class *cp
= 0;
2304 isc_result_t status
;
2306 status
= subclass_allocate(&cp
, MDL
);
2307 if (status
!= ISC_R_SUCCESS
)
2309 group_reference (&cp
->group
, root_group
, MDL
);
2311 cp
->flags
= CLASS_DECL_DYNAMIC
;
2313 status
= omapi_object_reference (lp
, (omapi_object_t
*)cp
, MDL
);
2314 subclass_dereference (&cp
, MDL
);
2318 isc_result_t
dhcp_subclass_remove (omapi_object_t
*lp
,
2322 if (lp
-> type
!= dhcp_type_subclass
)
2323 return DHCP_R_INVALIDARG
;
2324 cp
= (struct class *)lp
;
2327 log_debug ("OMAPI delete subclass %s", cp
-> name
);
2330 delete_class (cp
, 1);
2332 return ISC_R_SUCCESS
;
2335 isc_result_t
binding_scope_set_value (struct binding_scope
*scope
, int createp
,
2336 omapi_data_string_t
*name
,
2337 omapi_typed_data_t
*value
)
2341 struct binding_value
*nv
;
2342 nname
= dmalloc (name
-> len
+ 1, MDL
);
2344 return ISC_R_NOMEMORY
;
2345 memcpy (nname
, name
-> value
, name
-> len
);
2346 nname
[name
-> len
] = 0;
2347 bp
= find_binding (scope
, nname
);
2348 if (!bp
&& !createp
) {
2350 return DHCP_R_UNKNOWNATTRIBUTE
;
2355 return DHCP_R_UNKNOWNATTRIBUTE
;
2356 binding_value_dereference (&bp
-> value
, MDL
);
2357 return ISC_R_SUCCESS
;
2360 nv
= (struct binding_value
*)0;
2361 if (!binding_value_allocate (&nv
, MDL
)) {
2363 return ISC_R_NOMEMORY
;
2365 switch (value
-> type
) {
2366 case omapi_datatype_int
:
2367 nv
-> type
= binding_numeric
;
2368 nv
-> value
.intval
= value
-> u
.integer
;
2371 case omapi_datatype_string
:
2372 case omapi_datatype_data
:
2373 if (!buffer_allocate (&nv
-> value
.data
.buffer
,
2374 value
-> u
.buffer
.len
, MDL
)) {
2375 binding_value_dereference (&nv
, MDL
);
2377 return ISC_R_NOMEMORY
;
2379 memcpy (&nv
-> value
.data
.buffer
-> data
[1],
2380 value
-> u
.buffer
.value
, value
-> u
.buffer
.len
);
2381 nv
-> value
.data
.len
= value
-> u
.buffer
.len
;
2384 case omapi_datatype_object
:
2385 binding_value_dereference (&nv
, MDL
);
2387 return DHCP_R_INVALIDARG
;
2391 bp
= dmalloc (sizeof *bp
, MDL
);
2393 binding_value_dereference (&nv
, MDL
);
2395 return ISC_R_NOMEMORY
;
2397 memset (bp
, 0, sizeof *bp
);
2399 bp
-> next
= scope
-> bindings
;
2400 scope
-> bindings
= bp
;
2403 binding_value_dereference (&bp
-> value
, MDL
);
2406 binding_value_reference (&bp
-> value
, nv
, MDL
);
2407 binding_value_dereference (&nv
, MDL
);
2408 return ISC_R_SUCCESS
;
2411 isc_result_t
binding_scope_get_value (omapi_value_t
**value
,
2412 struct binding_scope
*scope
,
2413 omapi_data_string_t
*name
)
2416 omapi_typed_data_t
*td
;
2417 isc_result_t status
;
2419 nname
= dmalloc (name
-> len
+ 1, MDL
);
2421 return ISC_R_NOMEMORY
;
2422 memcpy (nname
, name
-> value
, name
-> len
);
2423 nname
[name
-> len
] = 0;
2424 bp
= find_binding (scope
, nname
);
2427 return DHCP_R_UNKNOWNATTRIBUTE
;
2429 return DHCP_R_UNKNOWNATTRIBUTE
;
2431 switch (bp
-> value
-> type
) {
2432 case binding_boolean
:
2433 td
= (omapi_typed_data_t
*)0;
2434 status
= omapi_typed_data_new (MDL
, &td
, omapi_datatype_int
,
2435 bp
-> value
-> value
.boolean
);
2438 case binding_numeric
:
2439 td
= (omapi_typed_data_t
*)0;
2440 status
= omapi_typed_data_new (MDL
, &td
, omapi_datatype_int
,
2442 bp
-> value
-> value
.intval
);
2446 td
= (omapi_typed_data_t
*)0;
2447 status
= omapi_typed_data_new (MDL
, &td
, omapi_datatype_data
,
2448 bp
-> value
-> value
.data
.len
);
2449 if (status
!= ISC_R_SUCCESS
)
2451 memcpy (&td
-> u
.buffer
.value
[0],
2452 bp
-> value
-> value
.data
.data
,
2453 bp
-> value
-> value
.data
.len
);
2456 /* Can't return values for these two (yet?). */
2458 case binding_function
:
2459 return DHCP_R_INVALIDARG
;
2462 log_fatal ("Impossible case at %s:%d.", MDL
);
2463 return ISC_R_FAILURE
;
2466 if (status
!= ISC_R_SUCCESS
)
2468 status
= omapi_value_new (value
, MDL
);
2469 if (status
!= ISC_R_SUCCESS
) {
2470 omapi_typed_data_dereference (&td
, MDL
);
2474 omapi_data_string_reference (&(*value
) -> name
, name
, MDL
);
2475 omapi_typed_data_reference (&(*value
) -> value
, td
, MDL
);
2476 omapi_typed_data_dereference (&td
, MDL
);
2478 return ISC_R_SUCCESS
;
2481 isc_result_t
binding_scope_stuff_values (omapi_object_t
*c
,
2482 struct binding_scope
*scope
)
2486 isc_result_t status
;
2488 for (bp
= scope
-> bindings
; bp
; bp
= bp
-> next
) {
2490 if (bp
-> value
-> type
== binding_dns
||
2491 bp
-> value
-> type
== binding_function
)
2494 /* Stuff the name. */
2495 len
= strlen (bp
-> name
);
2496 status
= omapi_connection_put_uint16 (c
, len
);
2497 if (status
!= ISC_R_SUCCESS
)
2499 status
= omapi_connection_copyin (c
,
2500 (unsigned char *)bp
-> name
,
2502 if (status
!= ISC_R_SUCCESS
)
2505 switch (bp
-> value
-> type
) {
2506 case binding_boolean
:
2507 status
= omapi_connection_put_uint32 (c
,
2508 sizeof (u_int32_t
));
2509 if (status
!= ISC_R_SUCCESS
)
2511 status
= (omapi_connection_put_uint32
2513 ((u_int32_t
)(bp
-> value
-> value
.boolean
))));
2514 if (status
!= ISC_R_SUCCESS
)
2519 status
= (omapi_connection_put_uint32
2520 (c
, bp
-> value
-> value
.data
.len
));
2521 if (status
!= ISC_R_SUCCESS
)
2523 if (bp
-> value
-> value
.data
.len
) {
2524 status
= (omapi_connection_copyin
2525 (c
, bp
-> value
-> value
.data
.data
,
2526 bp
-> value
-> value
.data
.len
));
2527 if (status
!= ISC_R_SUCCESS
)
2532 case binding_numeric
:
2533 status
= (omapi_connection_put_uint32
2534 (c
, sizeof (u_int32_t
)));
2535 if (status
!= ISC_R_SUCCESS
)
2537 status
= (omapi_connection_put_uint32
2539 (bp
-> value
-> value
.intval
))));
2540 if (status
!= ISC_R_SUCCESS
)
2547 case binding_function
:
2552 return ISC_R_SUCCESS
;
2555 /* vim: set tabstop=8: */