Sync with HEAD.
[dragonfly.git] / contrib / dhcp-3.0 / server / omapi.c
blob06d0519e1ab5911a580ab3db7f6486b9d774a0e7
1 /* omapi.c
3 OMAPI object interfaces for the DHCP server. */
5 /*
6 * Copyright (c) 2004 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.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
35 /* Many, many thanks to Brian Murrell and BCtel for this code - BCtel
36 provided the funding that resulted in this code and the entire
37 OMAPI support library being written, and Brian helped brainstorm
38 and refine the requirements. To the extent that this code is
39 useful, you have Brian and BCtel to thank. Any limitations in the
40 code are a result of mistakes on my part. -- Ted Lemon */
42 #ifndef lint
43 static char copyright[] =
44 "$Id: omapi.c,v 1.46.2.19 2004/11/24 17:39:19 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
45 #endif /* not lint */
47 #include "dhcpd.h"
48 #include <omapip/omapip_p.h>
50 omapi_object_type_t *dhcp_type_lease;
51 omapi_object_type_t *dhcp_type_pool;
52 omapi_object_type_t *dhcp_type_class;
53 omapi_object_type_t *dhcp_type_subclass;
54 omapi_object_type_t *dhcp_type_host;
55 #if defined (FAILOVER_PROTOCOL)
56 omapi_object_type_t *dhcp_type_failover_state;
57 omapi_object_type_t *dhcp_type_failover_link;
58 omapi_object_type_t *dhcp_type_failover_listener;
59 #endif
61 void dhcp_db_objects_setup ()
63 isc_result_t status;
65 status = omapi_object_type_register (&dhcp_type_lease,
66 "lease",
67 dhcp_lease_set_value,
68 dhcp_lease_get_value,
69 dhcp_lease_destroy,
70 dhcp_lease_signal_handler,
71 dhcp_lease_stuff_values,
72 dhcp_lease_lookup,
73 dhcp_lease_create,
74 dhcp_lease_remove,
75 #if defined (COMPACT_LEASES)
76 dhcp_lease_free,
77 dhcp_lease_get,
78 #else
79 0, 0,
80 #endif
82 sizeof (struct lease),
83 0, RC_LEASE);
84 if (status != ISC_R_SUCCESS)
85 log_fatal ("Can't register lease object type: %s",
86 isc_result_totext (status));
88 status = omapi_object_type_register (&dhcp_type_class,
89 "class",
90 dhcp_class_set_value,
91 dhcp_class_get_value,
92 dhcp_class_destroy,
93 dhcp_class_signal_handler,
94 dhcp_class_stuff_values,
95 dhcp_class_lookup,
96 dhcp_class_create,
97 dhcp_class_remove, 0, 0, 0,
98 sizeof (struct class), 0,
99 RC_MISC);
100 if (status != ISC_R_SUCCESS)
101 log_fatal ("Can't register class object type: %s",
102 isc_result_totext (status));
104 status = omapi_object_type_register (&dhcp_type_subclass,
105 "subclass",
106 dhcp_subclass_set_value,
107 dhcp_subclass_get_value,
108 dhcp_class_destroy,
109 dhcp_subclass_signal_handler,
110 dhcp_subclass_stuff_values,
111 dhcp_subclass_lookup,
112 dhcp_subclass_create,
113 dhcp_subclass_remove, 0, 0, 0,
114 sizeof (struct class), 0, RC_MISC);
115 if (status != ISC_R_SUCCESS)
116 log_fatal ("Can't register subclass object type: %s",
117 isc_result_totext (status));
119 status = omapi_object_type_register (&dhcp_type_pool,
120 "pool",
121 dhcp_pool_set_value,
122 dhcp_pool_get_value,
123 dhcp_pool_destroy,
124 dhcp_pool_signal_handler,
125 dhcp_pool_stuff_values,
126 dhcp_pool_lookup,
127 dhcp_pool_create,
128 dhcp_pool_remove, 0, 0, 0,
129 sizeof (struct pool), 0, RC_MISC);
131 if (status != ISC_R_SUCCESS)
132 log_fatal ("Can't register pool object type: %s",
133 isc_result_totext (status));
135 status = omapi_object_type_register (&dhcp_type_host,
136 "host",
137 dhcp_host_set_value,
138 dhcp_host_get_value,
139 dhcp_host_destroy,
140 dhcp_host_signal_handler,
141 dhcp_host_stuff_values,
142 dhcp_host_lookup,
143 dhcp_host_create,
144 dhcp_host_remove, 0, 0, 0,
145 sizeof (struct host_decl),
146 0, RC_MISC);
148 if (status != ISC_R_SUCCESS)
149 log_fatal ("Can't register host object type: %s",
150 isc_result_totext (status));
152 #if defined (FAILOVER_PROTOCOL)
153 status = omapi_object_type_register (&dhcp_type_failover_state,
154 "failover-state",
155 dhcp_failover_state_set_value,
156 dhcp_failover_state_get_value,
157 dhcp_failover_state_destroy,
158 dhcp_failover_state_signal,
159 dhcp_failover_state_stuff,
160 dhcp_failover_state_lookup,
161 dhcp_failover_state_create,
162 dhcp_failover_state_remove,
163 0, 0, 0,
164 sizeof (dhcp_failover_state_t),
165 0, RC_MISC);
167 if (status != ISC_R_SUCCESS)
168 log_fatal ("Can't register failover state object type: %s",
169 isc_result_totext (status));
171 status = omapi_object_type_register (&dhcp_type_failover_link,
172 "failover-link",
173 dhcp_failover_link_set_value,
174 dhcp_failover_link_get_value,
175 dhcp_failover_link_destroy,
176 dhcp_failover_link_signal,
177 dhcp_failover_link_stuff_values,
178 0, 0, 0, 0, 0, 0,
179 sizeof (dhcp_failover_link_t), 0,
180 RC_MISC);
182 if (status != ISC_R_SUCCESS)
183 log_fatal ("Can't register failover link object type: %s",
184 isc_result_totext (status));
186 status = omapi_object_type_register (&dhcp_type_failover_listener,
187 "failover-listener",
188 dhcp_failover_listener_set_value,
189 dhcp_failover_listener_get_value,
190 dhcp_failover_listener_destroy,
191 dhcp_failover_listener_signal,
192 dhcp_failover_listener_stuff,
193 0, 0, 0, 0, 0, 0,
194 sizeof
195 (dhcp_failover_listener_t), 0,
196 RC_MISC);
198 if (status != ISC_R_SUCCESS)
199 log_fatal ("Can't register failover listener object type: %s",
200 isc_result_totext (status));
201 #endif /* FAILOVER_PROTOCOL */
204 isc_result_t dhcp_lease_set_value (omapi_object_t *h,
205 omapi_object_t *id,
206 omapi_data_string_t *name,
207 omapi_typed_data_t *value)
209 struct lease *lease;
210 isc_result_t status;
211 int foo;
213 if (h -> type != dhcp_type_lease)
214 return ISC_R_INVALIDARG;
215 lease = (struct lease *)h;
217 /* We're skipping a lot of things it might be interesting to
218 set - for now, we just make it possible to whack the state. */
219 if (!omapi_ds_strcmp (name, "state")) {
220 unsigned long bar;
221 const char *ols, *nls;
222 status = omapi_get_int_value (&bar, value);
223 if (status != ISC_R_SUCCESS)
224 return status;
226 if (bar < 1 || bar > FTS_LAST)
227 return ISC_R_INVALIDARG;
228 nls = binding_state_names [bar - 1];
229 if (lease -> binding_state >= 1 &&
230 lease -> binding_state <= FTS_LAST)
231 ols = binding_state_names [lease -> binding_state - 1];
232 else
233 ols = "unknown state";
235 if (lease -> binding_state != bar) {
236 lease -> next_binding_state = bar;
237 if (supersede_lease (lease, 0, 1, 1, 1)) {
238 log_info ("lease %s state changed from %s to %s",
239 piaddr(lease->ip_addr), ols, nls);
240 return ISC_R_SUCCESS;
242 log_info ("lease %s state change from %s to %s failed.",
243 piaddr (lease -> ip_addr), ols, nls);
244 return ISC_R_IOERROR;
246 return ISC_R_UNCHANGED;
247 } else if (!omapi_ds_strcmp (name, "ip-address")) {
248 return ISC_R_NOPERM;
249 } else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
250 return ISC_R_UNCHANGED; /* XXX take change. */
251 } else if (!omapi_ds_strcmp (name, "hostname")) {
252 return ISC_R_UNCHANGED; /* XXX take change. */
253 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
254 return ISC_R_UNCHANGED; /* XXX take change. */
255 } else if (!omapi_ds_strcmp (name, "host")) {
256 return ISC_R_UNCHANGED; /* XXX take change. */
257 } else if (!omapi_ds_strcmp (name, "subnet")) {
258 return ISC_R_INVALIDARG;
259 } else if (!omapi_ds_strcmp (name, "pool")) {
260 return ISC_R_NOPERM;
261 } else if (!omapi_ds_strcmp (name, "starts")) {
262 return ISC_R_NOPERM;
263 } else if (!omapi_ds_strcmp (name, "ends")) {
264 return ISC_R_NOPERM;
265 } else if (!omapi_ds_strcmp (name, "billing-class")) {
266 return ISC_R_UNCHANGED; /* XXX carefully allow change. */
267 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
268 return ISC_R_UNCHANGED; /* XXX take change. */
269 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
270 return ISC_R_UNCHANGED; /* XXX take change. */
271 } else if (lease -> scope) {
272 status = binding_scope_set_value (lease -> scope, 0, name, value);
273 if (status == ISC_R_SUCCESS) {
274 if (write_lease (lease) && commit_leases ())
275 return ISC_R_SUCCESS;
276 return ISC_R_IOERROR;
280 /* Try to find some inner object that can take the value. */
281 if (h -> inner && h -> inner -> type -> set_value) {
282 status = ((*(h -> inner -> type -> set_value))
283 (h -> inner, id, name, value));
284 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
285 return status;
288 if (!lease -> scope) {
289 if (!binding_scope_allocate (&lease -> scope, MDL))
290 return ISC_R_NOMEMORY;
292 status = binding_scope_set_value (lease -> scope, 1, name, value);
293 if (status != ISC_R_SUCCESS)
294 return status;
296 if (write_lease (lease) && commit_leases ())
297 return ISC_R_SUCCESS;
298 return ISC_R_IOERROR;
302 isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
303 omapi_data_string_t *name,
304 omapi_value_t **value)
306 struct lease *lease;
307 isc_result_t status;
309 if (h -> type != dhcp_type_lease)
310 return ISC_R_INVALIDARG;
311 lease = (struct lease *)h;
313 if (!omapi_ds_strcmp (name, "state"))
314 return omapi_make_int_value (value, name,
315 (int)lease -> binding_state, MDL);
316 else if (!omapi_ds_strcmp (name, "ip-address"))
317 return omapi_make_const_value (value, name,
318 lease -> ip_addr.iabuf,
319 lease -> ip_addr.len, MDL);
320 else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
321 return omapi_make_const_value (value, name,
322 lease -> uid,
323 lease -> uid_len, MDL);
324 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
325 if (lease -> client_hostname)
326 return omapi_make_string_value
327 (value, name, lease -> client_hostname, MDL);
328 return ISC_R_NOTFOUND;
329 } else if (!omapi_ds_strcmp (name, "host")) {
330 if (lease -> host)
331 return omapi_make_handle_value
332 (value, name,
333 ((omapi_object_t *)lease -> host), MDL);
334 } else if (!omapi_ds_strcmp (name, "subnet"))
335 return omapi_make_handle_value (value, name,
336 ((omapi_object_t *)
337 lease -> subnet), MDL);
338 else if (!omapi_ds_strcmp (name, "pool"))
339 return omapi_make_handle_value (value, name,
340 ((omapi_object_t *)
341 lease -> pool), MDL);
342 else if (!omapi_ds_strcmp (name, "billing-class")) {
343 if (lease -> billing_class)
344 return omapi_make_handle_value
345 (value, name,
346 ((omapi_object_t *)lease -> billing_class),
347 MDL);
348 return ISC_R_NOTFOUND;
349 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
350 if (lease -> hardware_addr.hlen)
351 return omapi_make_const_value
352 (value, name, &lease -> hardware_addr.hbuf [1],
353 (unsigned)(lease -> hardware_addr.hlen - 1),
354 MDL);
355 return ISC_R_NOTFOUND;
356 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
357 if (lease -> hardware_addr.hlen)
358 return omapi_make_int_value
359 (value, name, lease -> hardware_addr.hbuf [0],
360 MDL);
361 return ISC_R_NOTFOUND;
362 } else if (lease -> scope) {
363 status = binding_scope_get_value (value, lease -> scope, name);
364 if (status != ISC_R_NOTFOUND)
365 return status;
368 /* Try to find some inner object that can take the value. */
369 if (h -> inner && h -> inner -> type -> get_value) {
370 status = ((*(h -> inner -> type -> get_value))
371 (h -> inner, id, name, value));
372 if (status == ISC_R_SUCCESS)
373 return status;
375 return ISC_R_UNKNOWNATTRIBUTE;
378 isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
380 struct lease *lease;
381 isc_result_t status;
383 if (h -> type != dhcp_type_lease)
384 return ISC_R_INVALIDARG;
385 lease = (struct lease *)h;
387 if (lease -> uid)
388 uid_hash_delete (lease);
389 hw_hash_delete (lease);
391 if (lease -> on_release)
392 executable_statement_dereference (&lease -> on_release,
393 file, line);
394 if (lease -> on_expiry)
395 executable_statement_dereference (&lease -> on_expiry,
396 file, line);
397 if (lease -> on_commit)
398 executable_statement_dereference (&lease -> on_commit,
399 file, line);
400 if (lease -> scope)
401 binding_scope_dereference (&lease -> scope, file, line);
403 if (lease -> agent_options)
404 option_chain_head_dereference (&lease -> agent_options,
405 file, line);
406 if (lease -> uid && lease -> uid != lease -> uid_buf) {
407 dfree (lease -> uid, MDL);
408 lease -> uid = &lease -> uid_buf [0];
409 lease -> uid_len = 0;
412 if (lease -> client_hostname) {
413 dfree (lease -> client_hostname, MDL);
414 lease -> client_hostname = (char *)0;
417 if (lease -> host)
418 host_dereference (&lease -> host, file, line);
419 if (lease -> subnet)
420 subnet_dereference (&lease -> subnet, file, line);
421 if (lease -> pool)
422 pool_dereference (&lease -> pool, file, line);
424 if (lease -> state) {
425 free_lease_state (lease -> state, file, line);
426 lease -> state = (struct lease_state *)0;
428 cancel_timeout (lease_ping_timeout, lease);
429 --outstanding_pings; /* XXX */
432 if (lease -> billing_class)
433 class_dereference
434 (&lease -> billing_class, file, line);
436 #if defined (DEBUG_MEMORY_LEAKAGE) || \
437 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
438 /* XXX we should never be destroying a lease with a next
439 XXX pointer except on exit... */
440 if (lease -> next)
441 lease_dereference (&lease -> next, file, line);
442 if (lease -> n_hw)
443 lease_dereference (&lease -> n_hw, file, line);
444 if (lease -> n_uid)
445 lease_dereference (&lease -> n_uid, file, line);
446 if (lease -> next_pending)
447 lease_dereference (&lease -> next_pending, file, line);
448 #endif
450 return ISC_R_SUCCESS;
453 isc_result_t dhcp_lease_signal_handler (omapi_object_t *h,
454 const char *name, va_list ap)
456 struct lease *lease;
457 isc_result_t status;
458 int updatep = 0;
460 if (h -> type != dhcp_type_lease)
461 return ISC_R_INVALIDARG;
462 lease = (struct lease *)h;
464 if (!strcmp (name, "updated"))
465 return ISC_R_SUCCESS;
467 /* Try to find some inner object that can take the value. */
468 if (h -> inner && h -> inner -> type -> signal_handler) {
469 status = ((*(h -> inner -> type -> signal_handler))
470 (h -> inner, name, ap));
471 if (status == ISC_R_SUCCESS)
472 return status;
474 return ISC_R_NOTFOUND;
477 isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
478 omapi_object_t *id,
479 omapi_object_t *h)
481 struct lease *lease;
482 isc_result_t status;
484 if (h -> type != dhcp_type_lease)
485 return ISC_R_INVALIDARG;
486 lease = (struct lease *)h;
488 /* Write out all the values. */
490 status = omapi_connection_put_name (c, "state");
491 if (status != ISC_R_SUCCESS)
492 return status;
493 status = omapi_connection_put_uint32 (c, sizeof (int));
494 if (status != ISC_R_SUCCESS)
495 return status;
496 status = omapi_connection_put_uint32 (c, lease -> binding_state);
497 if (status != ISC_R_SUCCESS)
498 return status;
500 status = omapi_connection_put_name (c, "ip-address");
501 if (status != ISC_R_SUCCESS)
502 return status;
503 status = omapi_connection_put_uint32 (c, lease -> ip_addr.len);
504 if (status != ISC_R_SUCCESS)
505 return status;
506 status = omapi_connection_copyin (c, lease -> ip_addr.iabuf,
507 lease -> ip_addr.len);
508 if (status != ISC_R_SUCCESS)
509 return status;
511 if (lease -> uid_len) {
512 status = omapi_connection_put_name (c,
513 "dhcp-client-identifier");
514 if (status != ISC_R_SUCCESS)
515 return status;
516 status = omapi_connection_put_uint32 (c, lease -> uid_len);
517 if (status != ISC_R_SUCCESS)
518 return status;
519 if (lease -> uid_len) {
520 status = omapi_connection_copyin (c, lease -> uid,
521 lease -> uid_len);
522 if (status != ISC_R_SUCCESS)
523 return status;
527 if (lease -> client_hostname) {
528 status = omapi_connection_put_name (c, "client-hostname");
529 if (status != ISC_R_SUCCESS)
530 return status;
531 status =
532 omapi_connection_put_string (c,
533 lease -> client_hostname);
534 if (status != ISC_R_SUCCESS)
535 return status;
538 if (lease -> host) {
539 status = omapi_connection_put_name (c, "host");
540 if (status != ISC_R_SUCCESS)
541 return status;
542 status = omapi_connection_put_handle (c,
543 (omapi_object_t *)
544 lease -> host);
545 if (status != ISC_R_SUCCESS)
546 return status;
549 status = omapi_connection_put_name (c, "subnet");
550 if (status != ISC_R_SUCCESS)
551 return status;
552 status = omapi_connection_put_handle
553 (c, (omapi_object_t *)lease -> subnet);
554 if (status != ISC_R_SUCCESS)
555 return status;
557 status = omapi_connection_put_name (c, "pool");
558 if (status != ISC_R_SUCCESS)
559 return status;
560 status = omapi_connection_put_handle (c,
561 (omapi_object_t *)lease -> pool);
562 if (status != ISC_R_SUCCESS)
563 return status;
565 if (lease -> billing_class) {
566 status = omapi_connection_put_name (c, "billing-class");
567 if (status != ISC_R_SUCCESS)
568 return status;
569 status = omapi_connection_put_handle
570 (c, (omapi_object_t *)lease -> billing_class);
571 if (status != ISC_R_SUCCESS)
572 return status;
575 if (lease -> hardware_addr.hlen) {
576 status = omapi_connection_put_name (c, "hardware-address");
577 if (status != ISC_R_SUCCESS)
578 return status;
579 status = (omapi_connection_put_uint32
581 (unsigned long)(lease -> hardware_addr.hlen - 1)));
582 if (status != ISC_R_SUCCESS)
583 return status;
584 status = (omapi_connection_copyin
585 (c, &lease -> hardware_addr.hbuf [1],
586 (unsigned long)(lease -> hardware_addr.hlen - 1)));
588 if (status != ISC_R_SUCCESS)
589 return status;
591 status = omapi_connection_put_name (c, "hardware-type");
592 if (status != ISC_R_SUCCESS)
593 return status;
594 status = omapi_connection_put_uint32 (c, sizeof (int));
595 if (status != ISC_R_SUCCESS)
596 return status;
597 status = omapi_connection_put_uint32
598 (c, lease -> hardware_addr.hbuf [0]);
599 if (status != ISC_R_SUCCESS)
600 return status;
604 status = omapi_connection_put_name (c, "ends");
605 if (status != ISC_R_SUCCESS)
606 return status;
607 status = omapi_connection_put_uint32 (c, sizeof (TIME));
608 if (status != ISC_R_SUCCESS)
609 return status;
610 status = (omapi_connection_copyin
611 (c, (const unsigned char *)&(lease -> ends), sizeof(TIME)));
612 if (status != ISC_R_SUCCESS)
613 return status;
615 status = omapi_connection_put_name (c, "starts");
616 if (status != ISC_R_SUCCESS)
617 return status;
618 status = omapi_connection_put_uint32 (c, sizeof (TIME));
619 if (status != ISC_R_SUCCESS)
620 return status;
621 status = (omapi_connection_copyin
623 (const unsigned char *)&(lease -> starts), sizeof (TIME)));
624 if (status != ISC_R_SUCCESS)
625 return status;
627 status = omapi_connection_put_name (c, "tstp");
628 if (status != ISC_R_SUCCESS)
629 return status;
630 status = omapi_connection_put_uint32 (c, sizeof (TIME));
631 if (status != ISC_R_SUCCESS)
632 return status;
633 status = (omapi_connection_copyin
635 (const unsigned char *)&(lease -> tstp), sizeof (TIME)));
636 if (status != ISC_R_SUCCESS)
637 return status;
639 status = omapi_connection_put_name (c, "tsfp");
640 if (status != ISC_R_SUCCESS)
641 return status;
642 status = omapi_connection_put_uint32 (c, sizeof (TIME));
643 if (status != ISC_R_SUCCESS)
644 return status;
645 status = (omapi_connection_copyin
647 (const unsigned char *)&(lease -> tsfp), sizeof (TIME)));
648 if (status != ISC_R_SUCCESS)
649 return status;
651 status = omapi_connection_put_name (c, "cltt");
652 if (status != ISC_R_SUCCESS)
653 return status;
654 status = omapi_connection_put_uint32 (c, sizeof (TIME));
655 if (status != ISC_R_SUCCESS)
656 return status;
657 status = (omapi_connection_copyin
659 (const unsigned char *)&(lease -> cltt), sizeof (TIME)));
660 if (status != ISC_R_SUCCESS)
661 return status;
663 if (lease -> scope) {
664 status = binding_scope_stuff_values (c, lease -> scope);
665 if (status != ISC_R_SUCCESS)
666 return status;
669 /* Write out the inner object, if any. */
670 if (h -> inner && h -> inner -> type -> stuff_values) {
671 status = ((*(h -> inner -> type -> stuff_values))
672 (c, id, h -> inner));
673 if (status == ISC_R_SUCCESS)
674 return status;
677 return ISC_R_SUCCESS;
680 isc_result_t dhcp_lease_lookup (omapi_object_t **lp,
681 omapi_object_t *id, omapi_object_t *ref)
683 omapi_value_t *tv = (omapi_value_t *)0;
684 isc_result_t status;
685 struct lease *lease;
687 if (!ref)
688 return ISC_R_NOKEYS;
690 /* First see if we were sent a handle. */
691 status = omapi_get_value_str (ref, id, "handle", &tv);
692 if (status == ISC_R_SUCCESS) {
693 status = omapi_handle_td_lookup (lp, tv -> value);
695 omapi_value_dereference (&tv, MDL);
696 if (status != ISC_R_SUCCESS)
697 return status;
699 /* Don't return the object if the type is wrong. */
700 if ((*lp) -> type != dhcp_type_lease) {
701 omapi_object_dereference (lp, MDL);
702 return ISC_R_INVALIDARG;
706 /* Now look for an IP address. */
707 status = omapi_get_value_str (ref, id, "ip-address", &tv);
708 if (status == ISC_R_SUCCESS) {
709 lease = (struct lease *)0;
710 lease_hash_lookup (&lease, lease_ip_addr_hash,
711 tv -> value -> u.buffer.value,
712 tv -> value -> u.buffer.len, MDL);
714 omapi_value_dereference (&tv, MDL);
716 /* If we already have a lease, and it's not the same one,
717 then the query was invalid. */
718 if (*lp && *lp != (omapi_object_t *)lease) {
719 omapi_object_dereference (lp, MDL);
720 lease_dereference (&lease, MDL);
721 return ISC_R_KEYCONFLICT;
722 } else if (!lease) {
723 if (*lp)
724 omapi_object_dereference (lp, MDL);
725 return ISC_R_NOTFOUND;
726 } else if (!*lp) {
727 /* XXX fix so that hash lookup itself creates
728 XXX the reference. */
729 omapi_object_reference (lp,
730 (omapi_object_t *)lease, MDL);
731 lease_dereference (&lease, MDL);
735 /* Now look for a client identifier. */
736 status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
737 if (status == ISC_R_SUCCESS) {
738 lease = (struct lease *)0;
739 lease_hash_lookup (&lease, lease_uid_hash,
740 tv -> value -> u.buffer.value,
741 tv -> value -> u.buffer.len, MDL);
742 omapi_value_dereference (&tv, MDL);
744 if (*lp && *lp != (omapi_object_t *)lease) {
745 omapi_object_dereference (lp, MDL);
746 lease_dereference (&lease, MDL);
747 return ISC_R_KEYCONFLICT;
748 } else if (!lease) {
749 if (*lp)
750 omapi_object_dereference (lp, MDL);
751 return ISC_R_NOTFOUND;
752 } else if (lease -> n_uid) {
753 if (*lp)
754 omapi_object_dereference (lp, MDL);
755 return ISC_R_MULTIPLE;
756 } else if (!*lp) {
757 /* XXX fix so that hash lookup itself creates
758 XXX the reference. */
759 omapi_object_reference (lp,
760 (omapi_object_t *)lease, MDL);
761 lease_dereference (&lease, MDL);
765 /* Now look for a hardware address. */
766 status = omapi_get_value_str (ref, id, "hardware-address", &tv);
767 if (status == ISC_R_SUCCESS) {
768 unsigned char *haddr;
769 unsigned int len;
771 len = tv -> value -> u.buffer.len + 1;
772 haddr = dmalloc (len, MDL);
773 if (!haddr) {
774 omapi_value_dereference (&tv, MDL);
775 return ISC_R_NOMEMORY;
778 memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
779 omapi_value_dereference (&tv, MDL);
781 status = omapi_get_value_str (ref, id, "hardware-type", &tv);
782 if (status == ISC_R_SUCCESS) {
783 if (tv -> value -> type == omapi_datatype_data) {
784 if ((tv -> value -> u.buffer.len != 4) ||
785 (tv -> value -> u.buffer.value[0] != 0) ||
786 (tv -> value -> u.buffer.value[1] != 0) ||
787 (tv -> value -> u.buffer.value[2] != 0)) {
788 omapi_value_dereference (&tv, MDL);
789 dfree (haddr, MDL);
790 return ISC_R_INVALIDARG;
793 haddr[0] = tv -> value -> u.buffer.value[3];
794 } else if (tv -> value -> type == omapi_datatype_int) {
795 haddr[0] = (unsigned char)
796 tv -> value -> u.integer;
797 } else {
798 omapi_value_dereference (&tv, MDL);
799 dfree (haddr, MDL);
800 return ISC_R_INVALIDARG;
803 omapi_value_dereference (&tv, MDL);
804 } else {
805 /* If no hardware-type is specified, default to
806 ethernet. This may or may not be a good idea,
807 but Telus is currently relying on this behavior.
808 - DPN */
809 haddr[0] = HTYPE_ETHER;
812 lease = (struct lease *)0;
813 lease_hash_lookup (&lease, lease_hw_addr_hash, haddr, len, MDL);
814 dfree (haddr, MDL);
816 if (*lp && *lp != (omapi_object_t *)lease) {
817 omapi_object_dereference (lp, MDL);
818 lease_dereference (&lease, MDL);
819 return ISC_R_KEYCONFLICT;
820 } else if (!lease) {
821 if (*lp)
822 omapi_object_dereference (lp, MDL);
823 return ISC_R_NOTFOUND;
824 } else if (lease -> n_hw) {
825 if (*lp)
826 omapi_object_dereference (lp, MDL);
827 lease_dereference (&lease, MDL);
828 return ISC_R_MULTIPLE;
829 } else if (!*lp) {
830 /* XXX fix so that hash lookup itself creates
831 XXX the reference. */
832 omapi_object_reference (lp,
833 (omapi_object_t *)lease, MDL);
834 lease_dereference (&lease, MDL);
838 /* If we get to here without finding a lease, no valid key was
839 specified. */
840 if (!*lp)
841 return ISC_R_NOKEYS;
842 return ISC_R_SUCCESS;
845 isc_result_t dhcp_lease_create (omapi_object_t **lp,
846 omapi_object_t *id)
848 return ISC_R_NOTIMPLEMENTED;
851 isc_result_t dhcp_lease_remove (omapi_object_t *lp,
852 omapi_object_t *id)
854 return ISC_R_NOTIMPLEMENTED;
857 isc_result_t dhcp_host_set_value (omapi_object_t *h,
858 omapi_object_t *id,
859 omapi_data_string_t *name,
860 omapi_typed_data_t *value)
862 struct host_decl *host, *hp;
863 isc_result_t status;
864 int foo;
866 if (h -> type != dhcp_type_host)
867 return ISC_R_INVALIDARG;
868 host = (struct host_decl *)h;
870 /* XXX For now, we can only set these values on new host objects.
871 XXX Soon, we need to be able to update host objects. */
872 if (!omapi_ds_strcmp (name, "name")) {
873 if (host -> name)
874 return ISC_R_EXISTS;
875 if (value && (value -> type == omapi_datatype_data ||
876 value -> type == omapi_datatype_string)) {
877 host -> name = dmalloc (value -> u.buffer.len + 1,
878 MDL);
879 if (!host -> name)
880 return ISC_R_NOMEMORY;
881 memcpy (host -> name,
882 value -> u.buffer.value,
883 value -> u.buffer.len);
884 host -> name [value -> u.buffer.len] = 0;
885 } else
886 return ISC_R_INVALIDARG;
887 return ISC_R_SUCCESS;
890 if (!omapi_ds_strcmp (name, "group")) {
891 if (value && (value -> type == omapi_datatype_data ||
892 value -> type == omapi_datatype_string)) {
893 struct group_object *group;
894 group = (struct group_object *)0;
895 group_hash_lookup (&group, group_name_hash,
896 (char *)value -> u.buffer.value,
897 value -> u.buffer.len, MDL);
898 if (!group || (group -> flags & GROUP_OBJECT_DELETED))
899 return ISC_R_NOTFOUND;
900 if (host -> group)
901 group_dereference (&host -> group, MDL);
902 group_reference (&host -> group, group -> group, MDL);
903 if (host -> named_group)
904 group_object_dereference (&host -> named_group,
905 MDL);
906 group_object_reference (&host -> named_group,
907 group, MDL);
908 group_object_dereference (&group, MDL);
909 } else
910 return ISC_R_INVALIDARG;
911 return ISC_R_SUCCESS;
914 if (!omapi_ds_strcmp (name, "hardware-address")) {
915 if (host -> interface.hlen)
916 return ISC_R_EXISTS;
917 if (value && (value -> type == omapi_datatype_data ||
918 value -> type == omapi_datatype_string)) {
919 if (value -> u.buffer.len >
920 (sizeof host -> interface.hbuf) - 1)
921 return ISC_R_INVALIDARG;
922 memcpy (&host -> interface.hbuf [1],
923 value -> u.buffer.value,
924 value -> u.buffer.len);
925 host -> interface.hlen = value -> u.buffer.len + 1;
926 } else
927 return ISC_R_INVALIDARG;
928 return ISC_R_SUCCESS;
931 if (!omapi_ds_strcmp (name, "hardware-type")) {
932 int type;
933 if (value && (value -> type == omapi_datatype_data &&
934 value -> u.buffer.len == sizeof type)) {
935 if (value -> u.buffer.len > sizeof type)
936 return ISC_R_INVALIDARG;
937 memcpy (&type,
938 value -> u.buffer.value,
939 value -> u.buffer.len);
940 type = ntohl (type);
941 } else if (value -> type == omapi_datatype_int)
942 type = value -> u.integer;
943 else
944 return ISC_R_INVALIDARG;
945 host -> interface.hbuf [0] = type;
946 return ISC_R_SUCCESS;
949 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
950 if (host -> client_identifier.data)
951 return ISC_R_EXISTS;
952 if (value && (value -> type == omapi_datatype_data ||
953 value -> type == omapi_datatype_string)) {
954 if (!buffer_allocate (&host -> client_identifier.buffer,
955 value -> u.buffer.len, MDL))
956 return ISC_R_NOMEMORY;
957 host -> client_identifier.data =
958 &host -> client_identifier.buffer -> data [0];
959 memcpy (host -> client_identifier.buffer -> data,
960 value -> u.buffer.value,
961 value -> u.buffer.len);
962 host -> client_identifier.len = value -> u.buffer.len;
963 } else
964 return ISC_R_INVALIDARG;
965 return ISC_R_SUCCESS;
968 if (!omapi_ds_strcmp (name, "ip-address")) {
969 if (host -> fixed_addr)
970 option_cache_dereference (&host -> fixed_addr, MDL);
971 if (!value)
972 return ISC_R_SUCCESS;
973 if (value && (value -> type == omapi_datatype_data ||
974 value -> type == omapi_datatype_string)) {
975 struct data_string ds;
976 memset (&ds, 0, sizeof ds);
977 ds.len = value -> u.buffer.len;
978 if (!buffer_allocate (&ds.buffer, ds.len, MDL))
979 return ISC_R_NOMEMORY;
980 ds.data = (&ds.buffer -> data [0]);
981 memcpy (ds.buffer -> data,
982 value -> u.buffer.value, ds.len);
983 if (!option_cache (&host -> fixed_addr,
984 &ds, (struct expression *)0,
985 (struct option *)0, MDL)) {
986 data_string_forget (&ds, MDL);
987 return ISC_R_NOMEMORY;
989 data_string_forget (&ds, MDL);
990 } else
991 return ISC_R_INVALIDARG;
992 return ISC_R_SUCCESS;
995 if (!omapi_ds_strcmp (name, "statements")) {
996 if (!host -> group) {
997 if (!clone_group (&host -> group, root_group, MDL))
998 return ISC_R_NOMEMORY;
999 } else {
1000 if (host -> group -> statements &&
1001 (!host -> named_group ||
1002 host -> group != host -> named_group -> group) &&
1003 host -> group != root_group)
1004 return ISC_R_EXISTS;
1005 if (!clone_group (&host -> group, host -> group, MDL))
1006 return ISC_R_NOMEMORY;
1008 if (!host -> group)
1009 return ISC_R_NOMEMORY;
1010 if (value && (value -> type == omapi_datatype_data ||
1011 value -> type == omapi_datatype_string)) {
1012 struct parse *parse;
1013 int lose = 0;
1014 parse = (struct parse *)0;
1015 status = new_parse (&parse, -1,
1016 (char *)value -> u.buffer.value,
1017 value -> u.buffer.len,
1018 "network client", 0);
1019 if (status != ISC_R_SUCCESS)
1020 return status;
1021 if (!(parse_executable_statements
1022 (&host -> group -> statements, parse, &lose,
1023 context_any))) {
1024 end_parse (&parse);
1025 return ISC_R_BADPARSE;
1027 end_parse (&parse);
1028 } else
1029 return ISC_R_INVALIDARG;
1030 return ISC_R_SUCCESS;
1033 /* The "known" flag isn't supported in the database yet, but it's
1034 legitimate. */
1035 if (!omapi_ds_strcmp (name, "known")) {
1036 return ISC_R_SUCCESS;
1039 /* Try to find some inner object that can take the value. */
1040 if (h -> inner && h -> inner -> type -> set_value) {
1041 status = ((*(h -> inner -> type -> set_value))
1042 (h -> inner, id, name, value));
1043 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1044 return status;
1047 return ISC_R_UNKNOWNATTRIBUTE;
1051 isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id,
1052 omapi_data_string_t *name,
1053 omapi_value_t **value)
1055 struct host_decl *host;
1056 isc_result_t status;
1057 struct data_string ip_addrs;
1059 if (h -> type != dhcp_type_host)
1060 return ISC_R_INVALIDARG;
1061 host = (struct host_decl *)h;
1063 if (!omapi_ds_strcmp (name, "ip-addresses")) {
1064 memset (&ip_addrs, 0, sizeof ip_addrs);
1065 if (host -> fixed_addr &&
1066 evaluate_option_cache (&ip_addrs, (struct packet *)0,
1067 (struct lease *)0,
1068 (struct client_state *)0,
1069 (struct option_state *)0,
1070 (struct option_state *)0,
1071 &global_scope,
1072 host -> fixed_addr, MDL)) {
1073 status = omapi_make_const_value (value, name,
1074 ip_addrs.data,
1075 ip_addrs.len, MDL);
1076 data_string_forget (&ip_addrs, MDL);
1077 return status;
1079 return ISC_R_NOTFOUND;
1082 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
1083 if (!host -> client_identifier.len)
1084 return ISC_R_NOTFOUND;
1085 return omapi_make_const_value (value, name,
1086 host -> client_identifier.data,
1087 host -> client_identifier.len,
1088 MDL);
1091 if (!omapi_ds_strcmp (name, "name"))
1092 return omapi_make_string_value (value, name, host -> name,
1093 MDL);
1095 if (!omapi_ds_strcmp (name, "hardware-address")) {
1096 if (!host -> interface.hlen)
1097 return ISC_R_NOTFOUND;
1098 return (omapi_make_const_value
1099 (value, name, &host -> interface.hbuf [1],
1100 (unsigned long)(host -> interface.hlen - 1), MDL));
1103 if (!omapi_ds_strcmp (name, "hardware-type")) {
1104 if (!host -> interface.hlen)
1105 return ISC_R_NOTFOUND;
1106 return omapi_make_int_value (value, name,
1107 host -> interface.hbuf [0], MDL);
1110 /* Try to find some inner object that can take the value. */
1111 if (h -> inner && h -> inner -> type -> get_value) {
1112 status = ((*(h -> inner -> type -> get_value))
1113 (h -> inner, id, name, value));
1114 if (status == ISC_R_SUCCESS)
1115 return status;
1117 return ISC_R_UNKNOWNATTRIBUTE;
1120 isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
1122 struct host_decl *host;
1123 isc_result_t status;
1125 if (h -> type != dhcp_type_host)
1126 return ISC_R_INVALIDARG;
1127 host = (struct host_decl *)h;
1129 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1130 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1131 if (host -> n_ipaddr)
1132 host_dereference (&host -> n_ipaddr, file, line);
1133 if (host -> n_dynamic)
1134 host_dereference (&host -> n_dynamic, file, line);
1135 if (host -> name) {
1136 dfree (host -> name, file, line);
1137 host -> name = (char *)0;
1139 data_string_forget (&host -> client_identifier, file, line);
1140 if (host -> fixed_addr)
1141 option_cache_dereference (&host -> fixed_addr, file, line);
1142 if (host -> group)
1143 group_dereference (&host -> group, file, line);
1144 if (host -> named_group)
1145 omapi_object_dereference ((omapi_object_t **)
1146 &host -> named_group, file, line);
1147 data_string_forget (&host -> auth_key_id, file, line);
1148 #endif
1150 return ISC_R_SUCCESS;
1153 isc_result_t dhcp_host_signal_handler (omapi_object_t *h,
1154 const char *name, va_list ap)
1156 struct host_decl *host;
1157 isc_result_t status;
1158 int updatep = 0;
1160 if (h -> type != dhcp_type_host)
1161 return ISC_R_INVALIDARG;
1162 host = (struct host_decl *)h;
1164 if (!strcmp (name, "updated")) {
1165 /* There must be a client identifier of some sort. */
1166 if (host -> interface.hlen == 0 &&
1167 !host -> client_identifier.len)
1168 return ISC_R_INVALIDARG;
1170 if (!host -> name) {
1171 char hnbuf [64];
1172 sprintf (hnbuf, "nh%08lx%08lx",
1173 (unsigned long)cur_time, (unsigned long)host);
1174 host -> name = dmalloc (strlen (hnbuf) + 1, MDL);
1175 if (!host -> name)
1176 return ISC_R_NOMEMORY;
1177 strcpy (host -> name, hnbuf);
1180 #ifdef DEBUG_OMAPI
1181 log_debug ("OMAPI added host %s", host -> name);
1182 #endif
1183 status = enter_host (host, 1, 1);
1184 if (status != ISC_R_SUCCESS)
1185 return status;
1186 updatep = 1;
1189 /* Try to find some inner object that can take the value. */
1190 if (h -> inner && h -> inner -> type -> signal_handler) {
1191 status = ((*(h -> inner -> type -> signal_handler))
1192 (h -> inner, name, ap));
1193 if (status == ISC_R_SUCCESS)
1194 return status;
1196 if (updatep)
1197 return ISC_R_SUCCESS;
1198 return ISC_R_NOTFOUND;
1201 isc_result_t dhcp_host_stuff_values (omapi_object_t *c,
1202 omapi_object_t *id,
1203 omapi_object_t *h)
1205 struct host_decl *host;
1206 isc_result_t status;
1207 struct data_string ip_addrs;
1209 if (h -> type != dhcp_type_host)
1210 return ISC_R_INVALIDARG;
1211 host = (struct host_decl *)h;
1213 /* Write out all the values. */
1215 memset (&ip_addrs, 0, sizeof ip_addrs);
1216 if (host -> fixed_addr &&
1217 evaluate_option_cache (&ip_addrs, (struct packet *)0,
1218 (struct lease *)0,
1219 (struct client_state *)0,
1220 (struct option_state *)0,
1221 (struct option_state *)0,
1222 &global_scope,
1223 host -> fixed_addr, MDL)) {
1224 status = omapi_connection_put_name (c, "ip-address");
1225 if (status != ISC_R_SUCCESS)
1226 return status;
1227 status = omapi_connection_put_uint32 (c, ip_addrs.len);
1228 if (status != ISC_R_SUCCESS)
1229 return status;
1230 status = omapi_connection_copyin (c,
1231 ip_addrs.data, ip_addrs.len);
1232 if (status != ISC_R_SUCCESS)
1233 return status;
1236 if (host -> client_identifier.len) {
1237 status = omapi_connection_put_name (c,
1238 "dhcp-client-identifier");
1239 if (status != ISC_R_SUCCESS)
1240 return status;
1241 status = (omapi_connection_put_uint32
1242 (c, host -> client_identifier.len));
1243 if (status != ISC_R_SUCCESS)
1244 return status;
1245 status = (omapi_connection_copyin
1247 host -> client_identifier.data,
1248 host -> client_identifier.len));
1249 if (status != ISC_R_SUCCESS)
1250 return status;
1253 if (host -> name) {
1254 status = omapi_connection_put_name (c, "name");
1255 if (status != ISC_R_SUCCESS)
1256 return status;
1257 status = omapi_connection_put_string (c, host -> name);
1258 if (status != ISC_R_SUCCESS)
1259 return status;
1262 if (host -> interface.hlen) {
1263 status = omapi_connection_put_name (c, "hardware-address");
1264 if (status != ISC_R_SUCCESS)
1265 return status;
1266 status = (omapi_connection_put_uint32
1267 (c, (unsigned long)(host -> interface.hlen - 1)));
1268 if (status != ISC_R_SUCCESS)
1269 return status;
1270 status = (omapi_connection_copyin
1271 (c, &host -> interface.hbuf [1],
1272 (unsigned long)(host -> interface.hlen - 1)));
1273 if (status != ISC_R_SUCCESS)
1274 return status;
1276 status = omapi_connection_put_name (c, "hardware-type");
1277 if (status != ISC_R_SUCCESS)
1278 return status;
1279 status = omapi_connection_put_uint32 (c, sizeof (int));
1280 if (status != ISC_R_SUCCESS)
1281 return status;
1282 status = (omapi_connection_put_uint32
1283 (c, host -> interface.hbuf [0]));
1284 if (status != ISC_R_SUCCESS)
1285 return status;
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)
1293 return status;
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;
1306 if (!ref)
1307 return ISC_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)
1316 return status;
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 ISC_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);
1339 if (host)
1340 host_dereference (&host, MDL);
1341 return ISC_R_KEYCONFLICT;
1342 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
1343 if (*lp)
1344 omapi_object_dereference (lp, MDL);
1345 if (host)
1346 host_dereference (&host, MDL);
1347 return ISC_R_NOTFOUND;
1348 } else if (!*lp) {
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;
1361 unsigned int len;
1363 len = tv -> value -> u.buffer.len + 1;
1364 haddr = dmalloc (len, MDL);
1365 if (!haddr) {
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);
1381 dfree (haddr, MDL);
1382 return ISC_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;
1389 } else {
1390 omapi_value_dereference (&tv, MDL);
1391 dfree (haddr, MDL);
1392 return ISC_R_INVALIDARG;
1395 omapi_value_dereference (&tv, MDL);
1396 } else {
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.
1400 - DPN */
1401 haddr[0] = HTYPE_ETHER;
1404 host = (struct host_decl *)0;
1405 host_hash_lookup (&host, host_hw_addr_hash, haddr, len, MDL);
1406 dfree (haddr, MDL);
1408 if (*lp && *lp != (omapi_object_t *)host) {
1409 omapi_object_dereference (lp, MDL);
1410 if (host)
1411 host_dereference (&host, MDL);
1412 return ISC_R_KEYCONFLICT;
1413 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
1414 if (*lp)
1415 omapi_object_dereference (lp, MDL);
1416 if (host)
1417 host_dereference (&host, MDL);
1418 return ISC_R_NOTFOUND;
1419 } else if (!*lp) {
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) {
1431 struct lease *l;
1433 /* first find the lease for this ip address */
1434 l = (struct lease *)0;
1435 lease_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);
1440 if (!l && !*lp)
1441 return ISC_R_NOTFOUND;
1443 if (l) {
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);
1452 if (host)
1453 host_dereference (&host, MDL);
1454 return ISC_R_KEYCONFLICT;
1455 } else if (!host || (host -> flags &
1456 HOST_DECL_DELETED)) {
1457 if (host)
1458 host_dereference (&host, MDL);
1459 if (!*lp)
1460 return ISC_R_NOTFOUND;
1461 } else if (!*lp) {
1462 /* XXX fix so that hash lookup itself creates
1463 XXX the reference. */
1464 omapi_object_reference (lp, (omapi_object_t *)host,
1465 MDL);
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);
1483 if (host)
1484 host_dereference (&host, MDL);
1485 return ISC_R_KEYCONFLICT;
1486 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
1487 if (host)
1488 host_dereference (&host, MDL);
1489 return ISC_R_NOTFOUND;
1490 } else if (!*lp) {
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
1500 specified. */
1501 if (!*lp)
1502 return ISC_R_NOKEYS;
1503 return ISC_R_SUCCESS;
1506 isc_result_t dhcp_host_create (omapi_object_t **lp,
1507 omapi_object_t *id)
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)
1514 return status;
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);
1519 return status;
1522 isc_result_t dhcp_host_remove (omapi_object_t *lp,
1523 omapi_object_t *id)
1525 struct host_decl *hp;
1526 if (lp -> type != dhcp_type_host)
1527 return ISC_R_INVALIDARG;
1528 hp = (struct host_decl *)lp;
1530 #ifdef DEBUG_OMAPI
1531 log_debug ("OMAPI delete host %s", hp -> name);
1532 #endif
1533 delete_host (hp, 1);
1534 return ISC_R_SUCCESS;
1537 isc_result_t dhcp_pool_set_value (omapi_object_t *h,
1538 omapi_object_t *id,
1539 omapi_data_string_t *name,
1540 omapi_typed_data_t *value)
1542 struct pool *pool;
1543 isc_result_t status;
1544 int foo;
1546 if (h -> type != dhcp_type_pool)
1547 return ISC_R_INVALIDARG;
1548 pool = (struct pool *)h;
1550 /* No values to set yet. */
1552 /* Try to find some inner object that can take the value. */
1553 if (h -> inner && h -> inner -> type -> set_value) {
1554 status = ((*(h -> inner -> type -> set_value))
1555 (h -> inner, id, name, value));
1556 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1557 return status;
1560 return ISC_R_UNKNOWNATTRIBUTE;
1564 isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id,
1565 omapi_data_string_t *name,
1566 omapi_value_t **value)
1568 struct pool *pool;
1569 isc_result_t status;
1571 if (h -> type != dhcp_type_pool)
1572 return ISC_R_INVALIDARG;
1573 pool = (struct pool *)h;
1575 /* No values to get yet. */
1577 /* Try to find some inner object that can provide the value. */
1578 if (h -> inner && h -> inner -> type -> get_value) {
1579 status = ((*(h -> inner -> type -> get_value))
1580 (h -> inner, id, name, value));
1581 if (status == ISC_R_SUCCESS)
1582 return status;
1584 return ISC_R_UNKNOWNATTRIBUTE;
1587 isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line)
1589 struct pool *pool;
1590 isc_result_t status;
1591 struct permit *pc, *pn;
1593 if (h -> type != dhcp_type_pool)
1594 return ISC_R_INVALIDARG;
1595 pool = (struct pool *)h;
1597 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1598 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1599 if (pool -> next)
1600 pool_dereference (&pool -> next, file, line);
1601 if (pool -> group)
1602 group_dereference (&pool -> group, file, line);
1603 if (pool -> shared_network)
1604 shared_network_dereference (&pool -> shared_network, file, line);
1605 if (pool -> active)
1606 lease_dereference (&pool -> active, file, line);
1607 if (pool -> expired)
1608 lease_dereference (&pool -> expired, file, line);
1609 if (pool -> free)
1610 lease_dereference (&pool -> free, file, line);
1611 if (pool -> backup)
1612 lease_dereference (&pool -> backup, file, line);
1613 if (pool -> abandoned)
1614 lease_dereference (&pool -> abandoned, file, line);
1615 #if defined (FAILOVER_PROTOCOL)
1616 if (pool -> failover_peer)
1617 dhcp_failover_state_dereference (&pool -> failover_peer,
1618 file, line);
1619 #endif
1620 for (pc = pool -> permit_list; pc; pc = pn) {
1621 pn = pc -> next;
1622 free_permit (pc, file, line);
1624 pool -> permit_list = (struct permit *)0;
1626 for (pc = pool -> prohibit_list; pc; pc = pn) {
1627 pn = pc -> next;
1628 free_permit (pc, file, line);
1630 pool -> prohibit_list = (struct permit *)0;
1631 #endif
1633 return ISC_R_SUCCESS;
1636 isc_result_t dhcp_pool_signal_handler (omapi_object_t *h,
1637 const char *name, va_list ap)
1639 struct pool *pool;
1640 isc_result_t status;
1641 int updatep = 0;
1643 if (h -> type != dhcp_type_pool)
1644 return ISC_R_INVALIDARG;
1645 pool = (struct pool *)h;
1647 /* Can't write pools yet. */
1649 /* Try to find some inner object that can take the value. */
1650 if (h -> inner && h -> inner -> type -> signal_handler) {
1651 status = ((*(h -> inner -> type -> signal_handler))
1652 (h -> inner, name, ap));
1653 if (status == ISC_R_SUCCESS)
1654 return status;
1656 if (updatep)
1657 return ISC_R_SUCCESS;
1658 return ISC_R_NOTFOUND;
1661 isc_result_t dhcp_pool_stuff_values (omapi_object_t *c,
1662 omapi_object_t *id,
1663 omapi_object_t *h)
1665 struct pool *pool;
1666 isc_result_t status;
1668 if (h -> type != dhcp_type_pool)
1669 return ISC_R_INVALIDARG;
1670 pool = (struct pool *)h;
1672 /* Can't stuff pool values yet. */
1674 /* Write out the inner object, if any. */
1675 if (h -> inner && h -> inner -> type -> stuff_values) {
1676 status = ((*(h -> inner -> type -> stuff_values))
1677 (c, id, h -> inner));
1678 if (status == ISC_R_SUCCESS)
1679 return status;
1682 return ISC_R_SUCCESS;
1685 isc_result_t dhcp_pool_lookup (omapi_object_t **lp,
1686 omapi_object_t *id, omapi_object_t *ref)
1688 omapi_value_t *tv = (omapi_value_t *)0;
1689 isc_result_t status;
1690 struct pool *pool;
1692 /* Can't look up pools yet. */
1694 /* If we get to here without finding a pool, no valid key was
1695 specified. */
1696 if (!*lp)
1697 return ISC_R_NOKEYS;
1698 return ISC_R_SUCCESS;
1701 isc_result_t dhcp_pool_create (omapi_object_t **lp,
1702 omapi_object_t *id)
1704 return ISC_R_NOTIMPLEMENTED;
1707 isc_result_t dhcp_pool_remove (omapi_object_t *lp,
1708 omapi_object_t *id)
1710 return ISC_R_NOTIMPLEMENTED;
1713 isc_result_t dhcp_class_set_value (omapi_object_t *h,
1714 omapi_object_t *id,
1715 omapi_data_string_t *name,
1716 omapi_typed_data_t *value)
1718 struct class *class;
1719 isc_result_t status;
1720 int foo;
1722 if (h -> type != dhcp_type_class)
1723 return ISC_R_INVALIDARG;
1724 class = (struct class *)h;
1726 /* No values to set yet. */
1728 /* Try to find some inner object that can take the value. */
1729 if (h -> inner && h -> inner -> type -> set_value) {
1730 status = ((*(h -> inner -> type -> set_value))
1731 (h -> inner, id, name, value));
1732 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1733 return status;
1736 return ISC_R_UNKNOWNATTRIBUTE;
1740 isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id,
1741 omapi_data_string_t *name,
1742 omapi_value_t **value)
1744 struct class *class;
1745 isc_result_t status;
1747 if (h -> type != dhcp_type_class)
1748 return ISC_R_INVALIDARG;
1749 class = (struct class *)h;
1751 /* No values to get yet. */
1753 /* Try to find some inner object that can provide the value. */
1754 if (h -> inner && h -> inner -> type -> get_value) {
1755 status = ((*(h -> inner -> type -> get_value))
1756 (h -> inner, id, name, value));
1757 if (status == ISC_R_SUCCESS)
1758 return status;
1760 return ISC_R_UNKNOWNATTRIBUTE;
1763 isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
1765 struct class *class;
1766 isc_result_t status;
1767 int i;
1769 if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass)
1770 return ISC_R_INVALIDARG;
1771 class = (struct class *)h;
1773 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1774 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1775 if (class -> nic)
1776 class_dereference (&class -> nic, file, line);
1777 if (class -> superclass)
1778 class_dereference (&class -> superclass, file, line);
1779 if (class -> name) {
1780 dfree (class -> name, file, line);
1781 class -> name = (char *)0;
1783 if (class -> billed_leases) {
1784 for (i = 0; i < class -> lease_limit; i++) {
1785 if (class -> billed_leases [i]) {
1786 lease_dereference (&class -> billed_leases [i],
1787 file, line);
1790 dfree (class -> billed_leases, file, line);
1791 class -> billed_leases = (struct lease **)0;
1793 if (class -> hash) {
1794 class_free_hash_table (&class -> hash, file, line);
1795 class -> hash = (class_hash_t *)0;
1797 data_string_forget (&class -> hash_string, file, line);
1799 if (class -> expr)
1800 expression_dereference (&class -> expr, file, line);
1801 if (class -> submatch)
1802 expression_dereference (&class -> submatch, file, line);
1803 if (class -> group)
1804 group_dereference (&class -> group, file, line);
1805 if (class -> statements)
1806 executable_statement_dereference (&class -> statements,
1807 file, line);
1808 if (class -> superclass)
1809 class_dereference (&class -> superclass, file, line);
1810 #endif
1812 return ISC_R_SUCCESS;
1815 isc_result_t dhcp_class_signal_handler (omapi_object_t *h,
1816 const char *name, va_list ap)
1818 struct class *class;
1819 isc_result_t status;
1820 int updatep = 0;
1822 if (h -> type != dhcp_type_class)
1823 return ISC_R_INVALIDARG;
1824 class = (struct class *)h;
1826 /* Can't write classs yet. */
1828 /* Try to find some inner object that can take the value. */
1829 if (h -> inner && h -> inner -> type -> signal_handler) {
1830 status = ((*(h -> inner -> type -> signal_handler))
1831 (h -> inner, name, ap));
1832 if (status == ISC_R_SUCCESS)
1833 return status;
1835 if (updatep)
1836 return ISC_R_SUCCESS;
1837 return ISC_R_NOTFOUND;
1840 isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
1841 omapi_object_t *id,
1842 omapi_object_t *h)
1844 struct class *class;
1845 isc_result_t status;
1847 if (h -> type != dhcp_type_class)
1848 return ISC_R_INVALIDARG;
1849 class = (struct class *)h;
1851 /* Can't stuff class values yet. */
1853 /* Write out the inner object, if any. */
1854 if (h -> inner && h -> inner -> type -> stuff_values) {
1855 status = ((*(h -> inner -> type -> stuff_values))
1856 (c, id, h -> inner));
1857 if (status == ISC_R_SUCCESS)
1858 return status;
1861 return ISC_R_SUCCESS;
1864 isc_result_t dhcp_class_lookup (omapi_object_t **lp,
1865 omapi_object_t *id, omapi_object_t *ref)
1867 omapi_value_t *tv = (omapi_value_t *)0;
1868 isc_result_t status;
1869 struct class *class;
1871 /* Can't look up classs yet. */
1873 /* If we get to here without finding a class, no valid key was
1874 specified. */
1875 if (!*lp)
1876 return ISC_R_NOKEYS;
1877 return ISC_R_SUCCESS;
1880 isc_result_t dhcp_class_create (omapi_object_t **lp,
1881 omapi_object_t *id)
1883 return ISC_R_NOTIMPLEMENTED;
1886 isc_result_t dhcp_class_remove (omapi_object_t *lp,
1887 omapi_object_t *id)
1889 return ISC_R_NOTIMPLEMENTED;
1892 isc_result_t dhcp_subclass_set_value (omapi_object_t *h,
1893 omapi_object_t *id,
1894 omapi_data_string_t *name,
1895 omapi_typed_data_t *value)
1897 struct subclass *subclass;
1898 isc_result_t status;
1899 int foo;
1901 if (h -> type != dhcp_type_subclass)
1902 return ISC_R_INVALIDARG;
1903 subclass = (struct subclass *)h;
1905 /* No values to set yet. */
1907 /* Try to find some inner object that can take the value. */
1908 if (h -> inner && h -> inner -> type -> set_value) {
1909 status = ((*(h -> inner -> type -> set_value))
1910 (h -> inner, id, name, value));
1911 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1912 return status;
1915 return ISC_R_UNKNOWNATTRIBUTE;
1919 isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id,
1920 omapi_data_string_t *name,
1921 omapi_value_t **value)
1923 struct subclass *subclass;
1924 isc_result_t status;
1926 if (h -> type != dhcp_type_subclass)
1927 return ISC_R_INVALIDARG;
1928 subclass = (struct subclass *)h;
1930 /* No values to get yet. */
1932 /* Try to find some inner object that can provide the value. */
1933 if (h -> inner && h -> inner -> type -> get_value) {
1934 status = ((*(h -> inner -> type -> get_value))
1935 (h -> inner, id, name, value));
1936 if (status == ISC_R_SUCCESS)
1937 return status;
1939 return ISC_R_UNKNOWNATTRIBUTE;
1942 isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h,
1943 const char *name, va_list ap)
1945 struct subclass *subclass;
1946 isc_result_t status;
1947 int updatep = 0;
1949 if (h -> type != dhcp_type_subclass)
1950 return ISC_R_INVALIDARG;
1951 subclass = (struct subclass *)h;
1953 /* Can't write subclasss yet. */
1955 /* Try to find some inner object that can take the value. */
1956 if (h -> inner && h -> inner -> type -> signal_handler) {
1957 status = ((*(h -> inner -> type -> signal_handler))
1958 (h -> inner, name, ap));
1959 if (status == ISC_R_SUCCESS)
1960 return status;
1962 if (updatep)
1963 return ISC_R_SUCCESS;
1964 return ISC_R_NOTFOUND;
1967 isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c,
1968 omapi_object_t *id,
1969 omapi_object_t *h)
1971 struct subclass *subclass;
1972 isc_result_t status;
1974 if (h -> type != dhcp_type_subclass)
1975 return ISC_R_INVALIDARG;
1976 subclass = (struct subclass *)h;
1978 /* Can't stuff subclass values yet. */
1980 /* Write out the inner object, if any. */
1981 if (h -> inner && h -> inner -> type -> stuff_values) {
1982 status = ((*(h -> inner -> type -> stuff_values))
1983 (c, id, h -> inner));
1984 if (status == ISC_R_SUCCESS)
1985 return status;
1988 return ISC_R_SUCCESS;
1991 isc_result_t dhcp_subclass_lookup (omapi_object_t **lp,
1992 omapi_object_t *id, omapi_object_t *ref)
1994 omapi_value_t *tv = (omapi_value_t *)0;
1995 isc_result_t status;
1996 struct subclass *subclass;
1998 /* Can't look up subclasss yet. */
2000 /* If we get to here without finding a subclass, no valid key was
2001 specified. */
2002 if (!*lp)
2003 return ISC_R_NOKEYS;
2004 return ISC_R_SUCCESS;
2007 isc_result_t dhcp_subclass_create (omapi_object_t **lp,
2008 omapi_object_t *id)
2010 return ISC_R_NOTIMPLEMENTED;
2013 isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
2014 omapi_object_t *id)
2016 return ISC_R_NOTIMPLEMENTED;
2019 isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp,
2020 omapi_data_string_t *name,
2021 omapi_typed_data_t *value)
2023 struct binding *bp;
2024 char *nname;
2025 struct binding_value *nv;
2026 nname = dmalloc (name -> len + 1, MDL);
2027 if (!nname)
2028 return ISC_R_NOMEMORY;
2029 memcpy (nname, name -> value, name -> len);
2030 nname [name -> len] = 0;
2031 bp = find_binding (scope, nname);
2032 if (!bp && !createp) {
2033 dfree (nname, MDL);
2034 return ISC_R_UNKNOWNATTRIBUTE;
2036 if (!value) {
2037 dfree (nname, MDL);
2038 if (!bp)
2039 return ISC_R_UNKNOWNATTRIBUTE;
2040 binding_value_dereference (&bp -> value, MDL);
2041 return ISC_R_SUCCESS;
2044 nv = (struct binding_value *)0;
2045 if (!binding_value_allocate (&nv, MDL)) {
2046 dfree (nname, MDL);
2047 return ISC_R_NOMEMORY;
2049 switch (value -> type) {
2050 case omapi_datatype_int:
2051 nv -> type = binding_numeric;
2052 nv -> value.intval = value -> u.integer;
2053 break;
2055 case omapi_datatype_string:
2056 case omapi_datatype_data:
2057 if (!buffer_allocate (&nv -> value.data.buffer,
2058 value -> u.buffer.len, MDL)) {
2059 binding_value_dereference (&nv, MDL);
2060 dfree (nname, MDL);
2061 return ISC_R_NOMEMORY;
2063 memcpy (&nv -> value.data.buffer -> data [1],
2064 value -> u.buffer.value, value -> u.buffer.len);
2065 nv -> value.data.len = value -> u.buffer.len;
2066 break;
2068 case omapi_datatype_object:
2069 binding_value_dereference (&nv, MDL);
2070 dfree (nname, MDL);
2071 return ISC_R_INVALIDARG;
2074 if (!bp) {
2075 bp = dmalloc (sizeof *bp, MDL);
2076 if (!bp) {
2077 binding_value_dereference (&nv, MDL);
2078 dfree (nname, MDL);
2079 return ISC_R_NOMEMORY;
2081 memset (bp, 0, sizeof *bp);
2082 bp -> name = nname;
2083 nname = (char *)0;
2084 bp -> next = scope -> bindings;
2085 scope -> bindings = bp;
2086 } else {
2087 if (bp -> value)
2088 binding_value_dereference (&bp -> value, MDL);
2089 dfree (nname, MDL);
2091 binding_value_reference (&bp -> value, nv, MDL);
2092 binding_value_dereference (&nv, MDL);
2093 return ISC_R_SUCCESS;
2096 isc_result_t binding_scope_get_value (omapi_value_t **value,
2097 struct binding_scope *scope,
2098 omapi_data_string_t *name)
2100 struct binding *bp;
2101 omapi_typed_data_t *td;
2102 isc_result_t status;
2103 char *nname;
2104 nname = dmalloc (name -> len + 1, MDL);
2105 if (!nname)
2106 return ISC_R_NOMEMORY;
2107 memcpy (nname, name -> value, name -> len);
2108 nname [name -> len] = 0;
2109 bp = find_binding (scope, nname);
2110 dfree (nname, MDL);
2111 if (!bp)
2112 return ISC_R_UNKNOWNATTRIBUTE;
2113 if (!bp -> value)
2114 return ISC_R_UNKNOWNATTRIBUTE;
2116 switch (bp -> value -> type) {
2117 case binding_boolean:
2118 td = (omapi_typed_data_t *)0;
2119 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
2120 bp -> value -> value.boolean);
2121 break;
2123 case binding_numeric:
2124 td = (omapi_typed_data_t *)0;
2125 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
2126 (int)
2127 bp -> value -> value.intval);
2128 break;
2130 case binding_data:
2131 td = (omapi_typed_data_t *)0;
2132 status = omapi_typed_data_new (MDL, &td, omapi_datatype_data,
2133 bp -> value -> value.data.len);
2134 if (status != ISC_R_SUCCESS)
2135 return status;
2136 memcpy (&td -> u.buffer.value [0],
2137 bp -> value -> value.data.data,
2138 bp -> value -> value.data.len);
2139 break;
2141 /* Can't return values for these two (yet?). */
2142 case binding_dns:
2143 case binding_function:
2144 return ISC_R_INVALIDARG;
2146 default:
2147 log_fatal ("Impossible case at %s:%d.", MDL);
2148 return ISC_R_FAILURE;
2151 if (status != ISC_R_SUCCESS)
2152 return status;
2153 status = omapi_value_new (value, MDL);
2154 if (status != ISC_R_SUCCESS) {
2155 omapi_typed_data_dereference (&td, MDL);
2156 return status;
2159 omapi_data_string_reference (&(*value) -> name, name, MDL);
2160 omapi_typed_data_reference (&(*value) -> value, td, MDL);
2161 omapi_typed_data_dereference (&td, MDL);
2163 return ISC_R_SUCCESS;
2166 isc_result_t binding_scope_stuff_values (omapi_object_t *c,
2167 struct binding_scope *scope)
2169 struct binding *bp;
2170 unsigned len;
2171 isc_result_t status;
2173 for (bp = scope -> bindings; bp; bp = bp -> next) {
2174 if (bp -> value) {
2175 if (bp -> value -> type == binding_dns ||
2176 bp -> value -> type == binding_function)
2177 continue;
2179 /* Stuff the name. */
2180 len = strlen (bp -> name);
2181 status = omapi_connection_put_uint16 (c, len);
2182 if (status != ISC_R_SUCCESS)
2183 return status;
2184 status = omapi_connection_copyin (c,
2185 (unsigned char *)bp -> name,
2186 len);
2187 if (status != ISC_R_SUCCESS)
2188 return status;
2190 switch (bp -> value -> type) {
2191 case binding_boolean:
2192 status = omapi_connection_put_uint32 (c,
2193 sizeof (u_int32_t));
2194 if (status != ISC_R_SUCCESS)
2195 return status;
2196 status = (omapi_connection_put_uint32
2198 ((u_int32_t)(bp -> value -> value.boolean))));
2199 break;
2201 case binding_data:
2202 status = (omapi_connection_put_uint32
2203 (c, bp -> value -> value.data.len));
2204 if (status != ISC_R_SUCCESS)
2205 return status;
2206 if (bp -> value -> value.data.len) {
2207 status = (omapi_connection_copyin
2208 (c, bp -> value -> value.data.data,
2209 bp -> value -> value.data.len));
2210 if (status != ISC_R_SUCCESS)
2211 return status;
2213 break;
2215 case binding_numeric:
2216 status = (omapi_connection_put_uint32
2217 (c, sizeof (u_int32_t)));
2218 if (status != ISC_R_SUCCESS)
2219 return status;
2220 status = (omapi_connection_put_uint32
2221 (c, ((u_int32_t)
2222 (bp -> value -> value.intval))));
2223 break;
2226 /* NOTREACHED */
2227 case binding_dns:
2228 case binding_function:
2229 break;
2233 return ISC_R_SUCCESS;
2236 /* vim: set tabstop=8: */