Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / dhcp / server / omapi.c
blobba284317deab0e037a99607d04ba22a50e0fa477
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.7 2005/08/11 17:13:30 drochner 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;
212 if (h -> type != dhcp_type_lease)
213 return ISC_R_INVALIDARG;
214 lease = (struct lease *)h;
216 /* We're skipping a lot of things it might be interesting to
217 set - for now, we just make it possible to whack the state. */
218 if (!omapi_ds_strcmp (name, "state")) {
219 unsigned long bar;
220 const char *ols, *nls;
221 status = omapi_get_int_value (&bar, value);
222 if (status != ISC_R_SUCCESS)
223 return status;
225 if (bar < 1 || bar > FTS_LAST)
226 return ISC_R_INVALIDARG;
227 nls = binding_state_names [bar - 1];
228 if (lease -> binding_state >= 1 &&
229 lease -> binding_state <= FTS_LAST)
230 ols = binding_state_names [lease -> binding_state - 1];
231 else
232 ols = "unknown state";
234 if (lease -> binding_state != bar) {
235 lease -> next_binding_state = bar;
236 if (supersede_lease (lease, 0, 1, 1, 1)) {
237 log_info ("lease %s state changed from %s to %s",
238 piaddr(lease->ip_addr), ols, nls);
239 return ISC_R_SUCCESS;
241 log_info ("lease %s state change from %s to %s failed.",
242 piaddr (lease -> ip_addr), ols, nls);
243 return ISC_R_IOERROR;
245 return ISC_R_UNCHANGED;
246 } else if (!omapi_ds_strcmp (name, "ip-address")) {
247 return ISC_R_NOPERM;
248 } else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
249 return ISC_R_UNCHANGED; /* XXX take change. */
250 } else if (!omapi_ds_strcmp (name, "hostname")) {
251 return ISC_R_UNCHANGED; /* XXX take change. */
252 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
253 return ISC_R_UNCHANGED; /* XXX take change. */
254 } else if (!omapi_ds_strcmp (name, "host")) {
255 return ISC_R_UNCHANGED; /* XXX take change. */
256 } else if (!omapi_ds_strcmp (name, "subnet")) {
257 return ISC_R_INVALIDARG;
258 } else if (!omapi_ds_strcmp (name, "pool")) {
259 return ISC_R_NOPERM;
260 } else if (!omapi_ds_strcmp (name, "starts")) {
261 return ISC_R_NOPERM;
262 } else if (!omapi_ds_strcmp (name, "ends")) {
263 return ISC_R_NOPERM;
264 } else if (!omapi_ds_strcmp (name, "billing-class")) {
265 return ISC_R_UNCHANGED; /* XXX carefully allow change. */
266 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
267 return ISC_R_UNCHANGED; /* XXX take change. */
268 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
269 return ISC_R_UNCHANGED; /* XXX take change. */
270 } else if (lease -> scope) {
271 status = binding_scope_set_value (lease -> scope, 0, name, value);
272 if (status == ISC_R_SUCCESS) {
273 if (write_lease (lease) && commit_leases ())
274 return ISC_R_SUCCESS;
275 return ISC_R_IOERROR;
279 /* Try to find some inner object that can take the value. */
280 if (h -> inner && h -> inner -> type -> set_value) {
281 status = ((*(h -> inner -> type -> set_value))
282 (h -> inner, id, name, value));
283 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
284 return status;
287 if (!lease -> scope) {
288 if (!binding_scope_allocate (&lease -> scope, MDL))
289 return ISC_R_NOMEMORY;
291 status = binding_scope_set_value (lease -> scope, 1, name, value);
292 if (status != ISC_R_SUCCESS)
293 return status;
295 if (write_lease (lease) && commit_leases ())
296 return ISC_R_SUCCESS;
297 return ISC_R_IOERROR;
301 isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
302 omapi_data_string_t *name,
303 omapi_value_t **value)
305 struct lease *lease;
306 isc_result_t status;
308 if (h -> type != dhcp_type_lease)
309 return ISC_R_INVALIDARG;
310 lease = (struct lease *)h;
312 if (!omapi_ds_strcmp (name, "state"))
313 return omapi_make_int_value (value, name,
314 (int)lease -> binding_state, MDL);
315 else if (!omapi_ds_strcmp (name, "ip-address"))
316 return omapi_make_const_value (value, name,
317 lease -> ip_addr.iabuf,
318 lease -> ip_addr.len, MDL);
319 else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
320 return omapi_make_const_value (value, name,
321 lease -> uid,
322 lease -> uid_len, MDL);
323 } else if (!omapi_ds_strcmp (name, "client-hostname")) {
324 if (lease -> client_hostname)
325 return omapi_make_string_value
326 (value, name, lease -> client_hostname, MDL);
327 return ISC_R_NOTFOUND;
328 } else if (!omapi_ds_strcmp (name, "host")) {
329 if (lease -> host)
330 return omapi_make_handle_value
331 (value, name,
332 ((omapi_object_t *)lease -> host), MDL);
333 } else if (!omapi_ds_strcmp (name, "subnet"))
334 return omapi_make_handle_value (value, name,
335 ((omapi_object_t *)
336 lease -> subnet), MDL);
337 else if (!omapi_ds_strcmp (name, "pool"))
338 return omapi_make_handle_value (value, name,
339 ((omapi_object_t *)
340 lease -> pool), MDL);
341 else if (!omapi_ds_strcmp (name, "billing-class")) {
342 if (lease -> billing_class)
343 return omapi_make_handle_value
344 (value, name,
345 ((omapi_object_t *)lease -> billing_class),
346 MDL);
347 return ISC_R_NOTFOUND;
348 } else if (!omapi_ds_strcmp (name, "hardware-address")) {
349 if (lease -> hardware_addr.hlen)
350 return omapi_make_const_value
351 (value, name, &lease -> hardware_addr.hbuf [1],
352 (unsigned)(lease -> hardware_addr.hlen - 1),
353 MDL);
354 return ISC_R_NOTFOUND;
355 } else if (!omapi_ds_strcmp (name, "hardware-type")) {
356 if (lease -> hardware_addr.hlen)
357 return omapi_make_int_value
358 (value, name, lease -> hardware_addr.hbuf [0],
359 MDL);
360 return ISC_R_NOTFOUND;
361 } else if (lease -> scope) {
362 status = binding_scope_get_value (value, lease -> scope, name);
363 if (status != ISC_R_NOTFOUND)
364 return status;
367 /* Try to find some inner object that can take the value. */
368 if (h -> inner && h -> inner -> type -> get_value) {
369 status = ((*(h -> inner -> type -> get_value))
370 (h -> inner, id, name, value));
371 if (status == ISC_R_SUCCESS)
372 return status;
374 return ISC_R_UNKNOWNATTRIBUTE;
377 isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
379 struct lease *lease;
381 if (h -> type != dhcp_type_lease)
382 return ISC_R_INVALIDARG;
383 lease = (struct lease *)h;
385 if (lease -> uid)
386 uid_hash_delete (lease);
387 hw_hash_delete (lease);
389 if (lease -> on_release)
390 executable_statement_dereference (&lease -> on_release,
391 file, line);
392 if (lease -> on_expiry)
393 executable_statement_dereference (&lease -> on_expiry,
394 file, line);
395 if (lease -> on_commit)
396 executable_statement_dereference (&lease -> on_commit,
397 file, line);
398 if (lease -> scope)
399 binding_scope_dereference (&lease -> scope, file, line);
401 if (lease -> agent_options)
402 option_chain_head_dereference (&lease -> agent_options,
403 file, line);
404 if (lease -> uid && lease -> uid != lease -> uid_buf) {
405 dfree (lease -> uid, MDL);
406 lease -> uid = &lease -> uid_buf [0];
407 lease -> uid_len = 0;
410 if (lease -> client_hostname) {
411 dfree (lease -> client_hostname, MDL);
412 lease -> client_hostname = (char *)0;
415 if (lease -> host)
416 host_dereference (&lease -> host, file, line);
417 if (lease -> subnet)
418 subnet_dereference (&lease -> subnet, file, line);
419 if (lease -> pool)
420 pool_dereference (&lease -> pool, file, line);
422 if (lease -> state) {
423 free_lease_state (lease -> state, file, line);
424 lease -> state = (struct lease_state *)0;
426 cancel_timeout (lease_ping_timeout, lease);
427 --outstanding_pings; /* XXX */
430 if (lease -> billing_class)
431 class_dereference
432 (&lease -> billing_class, file, line);
434 #if defined (DEBUG_MEMORY_LEAKAGE) || \
435 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
436 /* XXX we should never be destroying a lease with a next
437 XXX pointer except on exit... */
438 if (lease -> next)
439 lease_dereference (&lease -> next, file, line);
440 if (lease -> n_hw)
441 lease_dereference (&lease -> n_hw, file, line);
442 if (lease -> n_uid)
443 lease_dereference (&lease -> n_uid, file, line);
444 if (lease -> next_pending)
445 lease_dereference (&lease -> next_pending, file, line);
446 #endif
448 return ISC_R_SUCCESS;
451 isc_result_t dhcp_lease_signal_handler (omapi_object_t *h,
452 const char *name, va_list ap)
454 struct lease *lease;
455 isc_result_t status;
457 if (h -> type != dhcp_type_lease)
458 return ISC_R_INVALIDARG;
459 lease = (struct lease *)h;
461 if (!strcmp (name, "updated"))
462 return ISC_R_SUCCESS;
464 /* Try to find some inner object that can take the value. */
465 if (h -> inner && h -> inner -> type -> signal_handler) {
466 status = ((*(h -> inner -> type -> signal_handler))
467 (h -> inner, name, ap));
468 if (status == ISC_R_SUCCESS)
469 return status;
471 return ISC_R_NOTFOUND;
474 isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
475 omapi_object_t *id,
476 omapi_object_t *h)
478 struct lease *lease;
479 isc_result_t status;
481 if (h -> type != dhcp_type_lease)
482 return ISC_R_INVALIDARG;
483 lease = (struct lease *)h;
485 /* Write out all the values. */
487 status = omapi_connection_put_name (c, "state");
488 if (status != ISC_R_SUCCESS)
489 return status;
490 status = omapi_connection_put_uint32 (c, sizeof (int));
491 if (status != ISC_R_SUCCESS)
492 return status;
493 status = omapi_connection_put_uint32 (c, lease -> binding_state);
494 if (status != ISC_R_SUCCESS)
495 return status;
497 status = omapi_connection_put_name (c, "ip-address");
498 if (status != ISC_R_SUCCESS)
499 return status;
500 status = omapi_connection_put_uint32 (c, lease -> ip_addr.len);
501 if (status != ISC_R_SUCCESS)
502 return status;
503 status = omapi_connection_copyin (c, lease -> ip_addr.iabuf,
504 lease -> ip_addr.len);
505 if (status != ISC_R_SUCCESS)
506 return status;
508 if (lease -> uid_len) {
509 status = omapi_connection_put_name (c,
510 "dhcp-client-identifier");
511 if (status != ISC_R_SUCCESS)
512 return status;
513 status = omapi_connection_put_uint32 (c, lease -> uid_len);
514 if (status != ISC_R_SUCCESS)
515 return status;
516 if (lease -> uid_len) {
517 status = omapi_connection_copyin (c, lease -> uid,
518 lease -> uid_len);
519 if (status != ISC_R_SUCCESS)
520 return status;
524 if (lease -> client_hostname) {
525 status = omapi_connection_put_name (c, "client-hostname");
526 if (status != ISC_R_SUCCESS)
527 return status;
528 status =
529 omapi_connection_put_string (c,
530 lease -> client_hostname);
531 if (status != ISC_R_SUCCESS)
532 return status;
535 if (lease -> host) {
536 status = omapi_connection_put_name (c, "host");
537 if (status != ISC_R_SUCCESS)
538 return status;
539 status = omapi_connection_put_handle (c,
540 (omapi_object_t *)
541 lease -> host);
542 if (status != ISC_R_SUCCESS)
543 return status;
546 status = omapi_connection_put_name (c, "subnet");
547 if (status != ISC_R_SUCCESS)
548 return status;
549 status = omapi_connection_put_handle
550 (c, (omapi_object_t *)lease -> subnet);
551 if (status != ISC_R_SUCCESS)
552 return status;
554 status = omapi_connection_put_name (c, "pool");
555 if (status != ISC_R_SUCCESS)
556 return status;
557 status = omapi_connection_put_handle (c,
558 (omapi_object_t *)lease -> pool);
559 if (status != ISC_R_SUCCESS)
560 return status;
562 if (lease -> billing_class) {
563 status = omapi_connection_put_name (c, "billing-class");
564 if (status != ISC_R_SUCCESS)
565 return status;
566 status = omapi_connection_put_handle
567 (c, (omapi_object_t *)lease -> billing_class);
568 if (status != ISC_R_SUCCESS)
569 return status;
572 if (lease -> hardware_addr.hlen) {
573 status = omapi_connection_put_name (c, "hardware-address");
574 if (status != ISC_R_SUCCESS)
575 return status;
576 status = (omapi_connection_put_uint32
578 (unsigned long)(lease -> hardware_addr.hlen - 1)));
579 if (status != ISC_R_SUCCESS)
580 return status;
581 status = (omapi_connection_copyin
582 (c, &lease -> hardware_addr.hbuf [1],
583 (unsigned long)(lease -> hardware_addr.hlen - 1)));
585 if (status != ISC_R_SUCCESS)
586 return status;
588 status = omapi_connection_put_name (c, "hardware-type");
589 if (status != ISC_R_SUCCESS)
590 return status;
591 status = omapi_connection_put_uint32 (c, sizeof (int));
592 if (status != ISC_R_SUCCESS)
593 return status;
594 status = omapi_connection_put_uint32
595 (c, lease -> hardware_addr.hbuf [0]);
596 if (status != ISC_R_SUCCESS)
597 return status;
601 status = omapi_connection_put_name (c, "ends");
602 if (status != ISC_R_SUCCESS)
603 return status;
604 status = omapi_connection_put_uint32 (c, sizeof (TIME));
605 if (status != ISC_R_SUCCESS)
606 return status;
607 status = (omapi_connection_copyin
608 (c, (const unsigned char *)&(lease -> ends), sizeof(TIME)));
609 if (status != ISC_R_SUCCESS)
610 return status;
612 status = omapi_connection_put_name (c, "starts");
613 if (status != ISC_R_SUCCESS)
614 return status;
615 status = omapi_connection_put_uint32 (c, sizeof (TIME));
616 if (status != ISC_R_SUCCESS)
617 return status;
618 status = (omapi_connection_copyin
620 (const unsigned char *)&(lease -> starts), sizeof (TIME)));
621 if (status != ISC_R_SUCCESS)
622 return status;
624 status = omapi_connection_put_name (c, "tstp");
625 if (status != ISC_R_SUCCESS)
626 return status;
627 status = omapi_connection_put_uint32 (c, sizeof (TIME));
628 if (status != ISC_R_SUCCESS)
629 return status;
630 status = (omapi_connection_copyin
632 (const unsigned char *)&(lease -> tstp), sizeof (TIME)));
633 if (status != ISC_R_SUCCESS)
634 return status;
636 status = omapi_connection_put_name (c, "tsfp");
637 if (status != ISC_R_SUCCESS)
638 return status;
639 status = omapi_connection_put_uint32 (c, sizeof (TIME));
640 if (status != ISC_R_SUCCESS)
641 return status;
642 status = (omapi_connection_copyin
644 (const unsigned char *)&(lease -> tsfp), sizeof (TIME)));
645 if (status != ISC_R_SUCCESS)
646 return status;
648 status = omapi_connection_put_name (c, "cltt");
649 if (status != ISC_R_SUCCESS)
650 return status;
651 status = omapi_connection_put_uint32 (c, sizeof (TIME));
652 if (status != ISC_R_SUCCESS)
653 return status;
654 status = (omapi_connection_copyin
656 (const unsigned char *)&(lease -> cltt), sizeof (TIME)));
657 if (status != ISC_R_SUCCESS)
658 return status;
660 if (lease -> scope) {
661 status = binding_scope_stuff_values (c, lease -> scope);
662 if (status != ISC_R_SUCCESS)
663 return status;
666 /* Write out the inner object, if any. */
667 if (h -> inner && h -> inner -> type -> stuff_values) {
668 status = ((*(h -> inner -> type -> stuff_values))
669 (c, id, h -> inner));
670 if (status == ISC_R_SUCCESS)
671 return status;
674 return ISC_R_SUCCESS;
677 isc_result_t dhcp_lease_lookup (omapi_object_t **lp,
678 omapi_object_t *id, omapi_object_t *ref)
680 omapi_value_t *tv = (omapi_value_t *)0;
681 isc_result_t status;
682 struct lease *lease;
684 if (!ref)
685 return ISC_R_NOKEYS;
687 /* First see if we were sent a handle. */
688 status = omapi_get_value_str (ref, id, "handle", &tv);
689 if (status == ISC_R_SUCCESS) {
690 status = omapi_handle_td_lookup (lp, tv -> value);
692 omapi_value_dereference (&tv, MDL);
693 if (status != ISC_R_SUCCESS)
694 return status;
696 /* Don't return the object if the type is wrong. */
697 if ((*lp) -> type != dhcp_type_lease) {
698 omapi_object_dereference (lp, MDL);
699 return ISC_R_INVALIDARG;
703 /* Now look for an IP address. */
704 status = omapi_get_value_str (ref, id, "ip-address", &tv);
705 if (status == ISC_R_SUCCESS) {
706 lease = (struct lease *)0;
707 lease_hash_lookup (&lease, lease_ip_addr_hash,
708 tv -> value -> u.buffer.value,
709 tv -> value -> u.buffer.len, MDL);
711 omapi_value_dereference (&tv, MDL);
713 /* If we already have a lease, and it's not the same one,
714 then the query was invalid. */
715 if (*lp && *lp != (omapi_object_t *)lease) {
716 omapi_object_dereference (lp, MDL);
717 lease_dereference (&lease, MDL);
718 return ISC_R_KEYCONFLICT;
719 } else if (!lease) {
720 if (*lp)
721 omapi_object_dereference (lp, MDL);
722 return ISC_R_NOTFOUND;
723 } else if (!*lp) {
724 /* XXX fix so that hash lookup itself creates
725 XXX the reference. */
726 omapi_object_reference (lp,
727 (omapi_object_t *)lease, MDL);
728 lease_dereference (&lease, MDL);
732 /* Now look for a client identifier. */
733 status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
734 if (status == ISC_R_SUCCESS) {
735 lease = (struct lease *)0;
736 lease_hash_lookup (&lease, lease_uid_hash,
737 tv -> value -> u.buffer.value,
738 tv -> value -> u.buffer.len, MDL);
739 omapi_value_dereference (&tv, MDL);
741 if (*lp && *lp != (omapi_object_t *)lease) {
742 omapi_object_dereference (lp, MDL);
743 lease_dereference (&lease, MDL);
744 return ISC_R_KEYCONFLICT;
745 } else if (!lease) {
746 if (*lp)
747 omapi_object_dereference (lp, MDL);
748 return ISC_R_NOTFOUND;
749 } else if (lease -> n_uid) {
750 if (*lp)
751 omapi_object_dereference (lp, MDL);
752 return ISC_R_MULTIPLE;
753 } else if (!*lp) {
754 /* XXX fix so that hash lookup itself creates
755 XXX the reference. */
756 omapi_object_reference (lp,
757 (omapi_object_t *)lease, MDL);
758 lease_dereference (&lease, MDL);
762 /* Now look for a hardware address. */
763 status = omapi_get_value_str (ref, id, "hardware-address", &tv);
764 if (status == ISC_R_SUCCESS) {
765 unsigned char *haddr;
766 unsigned int len;
768 len = tv -> value -> u.buffer.len + 1;
769 haddr = dmalloc (len, MDL);
770 if (!haddr) {
771 omapi_value_dereference (&tv, MDL);
772 return ISC_R_NOMEMORY;
775 memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
776 omapi_value_dereference (&tv, MDL);
778 status = omapi_get_value_str (ref, id, "hardware-type", &tv);
779 if (status == ISC_R_SUCCESS) {
780 if (tv -> value -> type == omapi_datatype_data) {
781 if ((tv -> value -> u.buffer.len != 4) ||
782 (tv -> value -> u.buffer.value[0] != 0) ||
783 (tv -> value -> u.buffer.value[1] != 0) ||
784 (tv -> value -> u.buffer.value[2] != 0)) {
785 omapi_value_dereference (&tv, MDL);
786 dfree (haddr, MDL);
787 return ISC_R_INVALIDARG;
790 haddr[0] = tv -> value -> u.buffer.value[3];
791 } else if (tv -> value -> type == omapi_datatype_int) {
792 haddr[0] = (unsigned char)
793 tv -> value -> u.integer;
794 } else {
795 omapi_value_dereference (&tv, MDL);
796 dfree (haddr, MDL);
797 return ISC_R_INVALIDARG;
800 omapi_value_dereference (&tv, MDL);
801 } else {
802 /* If no hardware-type is specified, default to
803 ethernet. This may or may not be a good idea,
804 but Telus is currently relying on this behavior.
805 - DPN */
806 haddr[0] = HTYPE_ETHER;
809 lease = (struct lease *)0;
810 lease_hash_lookup (&lease, lease_hw_addr_hash, haddr, len, MDL);
811 dfree (haddr, MDL);
813 if (*lp && *lp != (omapi_object_t *)lease) {
814 omapi_object_dereference (lp, MDL);
815 lease_dereference (&lease, MDL);
816 return ISC_R_KEYCONFLICT;
817 } else if (!lease) {
818 if (*lp)
819 omapi_object_dereference (lp, MDL);
820 return ISC_R_NOTFOUND;
821 } else if (lease -> n_hw) {
822 if (*lp)
823 omapi_object_dereference (lp, MDL);
824 lease_dereference (&lease, MDL);
825 return ISC_R_MULTIPLE;
826 } else if (!*lp) {
827 /* XXX fix so that hash lookup itself creates
828 XXX the reference. */
829 omapi_object_reference (lp,
830 (omapi_object_t *)lease, MDL);
831 lease_dereference (&lease, MDL);
835 /* If we get to here without finding a lease, no valid key was
836 specified. */
837 if (!*lp)
838 return ISC_R_NOKEYS;
839 return ISC_R_SUCCESS;
842 isc_result_t dhcp_lease_create (omapi_object_t **lp,
843 omapi_object_t *id)
845 return ISC_R_NOTIMPLEMENTED;
848 isc_result_t dhcp_lease_remove (omapi_object_t *lp,
849 omapi_object_t *id)
851 return ISC_R_NOTIMPLEMENTED;
854 isc_result_t dhcp_host_set_value (omapi_object_t *h,
855 omapi_object_t *id,
856 omapi_data_string_t *name,
857 omapi_typed_data_t *value)
859 struct host_decl *host;
860 isc_result_t status;
862 if (h -> type != dhcp_type_host)
863 return ISC_R_INVALIDARG;
864 host = (struct host_decl *)h;
866 /* XXX For now, we can only set these values on new host objects.
867 XXX Soon, we need to be able to update host objects. */
868 if (!omapi_ds_strcmp (name, "name")) {
869 if (host -> name)
870 return ISC_R_EXISTS;
871 if (value && (value -> type == omapi_datatype_data ||
872 value -> type == omapi_datatype_string)) {
873 host -> name = dmalloc (value -> u.buffer.len + 1,
874 MDL);
875 if (!host -> name)
876 return ISC_R_NOMEMORY;
877 memcpy (host -> name,
878 value -> u.buffer.value,
879 value -> u.buffer.len);
880 host -> name [value -> u.buffer.len] = 0;
881 } else
882 return ISC_R_INVALIDARG;
883 return ISC_R_SUCCESS;
886 if (!omapi_ds_strcmp (name, "group")) {
887 if (value && (value -> type == omapi_datatype_data ||
888 value -> type == omapi_datatype_string)) {
889 struct group_object *group;
890 group = (struct group_object *)0;
891 group_hash_lookup (&group, group_name_hash,
892 (char *)value -> u.buffer.value,
893 value -> u.buffer.len, MDL);
894 if (!group || (group -> flags & GROUP_OBJECT_DELETED))
895 return ISC_R_NOTFOUND;
896 if (host -> group)
897 group_dereference (&host -> group, MDL);
898 group_reference (&host -> group, group -> group, MDL);
899 if (host -> named_group)
900 group_object_dereference (&host -> named_group,
901 MDL);
902 group_object_reference (&host -> named_group,
903 group, MDL);
904 group_object_dereference (&group, MDL);
905 } else
906 return ISC_R_INVALIDARG;
907 return ISC_R_SUCCESS;
910 if (!omapi_ds_strcmp (name, "hardware-address")) {
911 if (host -> interface.hlen)
912 return ISC_R_EXISTS;
913 if (value && (value -> type == omapi_datatype_data ||
914 value -> type == omapi_datatype_string)) {
915 if (value -> u.buffer.len >
916 (sizeof host -> interface.hbuf) - 1)
917 return ISC_R_INVALIDARG;
918 memcpy (&host -> interface.hbuf [1],
919 value -> u.buffer.value,
920 value -> u.buffer.len);
921 host -> interface.hlen = value -> u.buffer.len + 1;
922 } else
923 return ISC_R_INVALIDARG;
924 return ISC_R_SUCCESS;
927 if (!omapi_ds_strcmp (name, "hardware-type")) {
928 int type;
929 if (value && (value -> type == omapi_datatype_data &&
930 value -> u.buffer.len == sizeof type)) {
931 if (value -> u.buffer.len > sizeof type)
932 return ISC_R_INVALIDARG;
933 memcpy (&type,
934 value -> u.buffer.value,
935 value -> u.buffer.len);
936 type = ntohl (type);
937 } else if (value -> type == omapi_datatype_int)
938 type = value -> u.integer;
939 else
940 return ISC_R_INVALIDARG;
941 host -> interface.hbuf [0] = type;
942 return ISC_R_SUCCESS;
945 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
946 if (host -> client_identifier.data)
947 return ISC_R_EXISTS;
948 if (value && (value -> type == omapi_datatype_data ||
949 value -> type == omapi_datatype_string)) {
950 if (!buffer_allocate (&host -> client_identifier.buffer,
951 value -> u.buffer.len, MDL))
952 return ISC_R_NOMEMORY;
953 host -> client_identifier.data =
954 &host -> client_identifier.buffer -> data [0];
955 memcpy (host -> client_identifier.buffer -> data,
956 value -> u.buffer.value,
957 value -> u.buffer.len);
958 host -> client_identifier.len = value -> u.buffer.len;
959 } else
960 return ISC_R_INVALIDARG;
961 return ISC_R_SUCCESS;
964 if (!omapi_ds_strcmp (name, "ip-address")) {
965 if (host -> fixed_addr)
966 option_cache_dereference (&host -> fixed_addr, MDL);
967 if (!value)
968 return ISC_R_SUCCESS;
969 if (value && (value -> type == omapi_datatype_data ||
970 value -> type == omapi_datatype_string)) {
971 struct data_string ds;
972 memset (&ds, 0, sizeof ds);
973 ds.len = value -> u.buffer.len;
974 if (!buffer_allocate (&ds.buffer, ds.len, MDL))
975 return ISC_R_NOMEMORY;
976 ds.data = (&ds.buffer -> data [0]);
977 memcpy (ds.buffer -> data,
978 value -> u.buffer.value, ds.len);
979 if (!option_cache (&host -> fixed_addr,
980 &ds, (struct expression *)0,
981 (struct option *)0, MDL)) {
982 data_string_forget (&ds, MDL);
983 return ISC_R_NOMEMORY;
985 data_string_forget (&ds, MDL);
986 } else
987 return ISC_R_INVALIDARG;
988 return ISC_R_SUCCESS;
991 if (!omapi_ds_strcmp (name, "statements")) {
992 if (!host -> group) {
993 if (!clone_group (&host -> group, root_group, MDL))
994 return ISC_R_NOMEMORY;
995 } else {
996 if (host -> group -> statements &&
997 (!host -> named_group ||
998 host -> group != host -> named_group -> group) &&
999 host -> group != root_group)
1000 return ISC_R_EXISTS;
1001 if (!clone_group (&host -> group, host -> group, MDL))
1002 return ISC_R_NOMEMORY;
1004 if (!host -> group)
1005 return ISC_R_NOMEMORY;
1006 if (value && (value -> type == omapi_datatype_data ||
1007 value -> type == omapi_datatype_string)) {
1008 struct parse *parse;
1009 int lose = 0;
1010 parse = (struct parse *)0;
1011 status = new_parse (&parse, -1,
1012 (char *)value -> u.buffer.value,
1013 value -> u.buffer.len,
1014 "network client", 0);
1015 if (status != ISC_R_SUCCESS)
1016 return status;
1017 if (!(parse_executable_statements
1018 (&host -> group -> statements, parse, &lose,
1019 context_any))) {
1020 end_parse (&parse);
1021 return ISC_R_BADPARSE;
1023 end_parse (&parse);
1024 } else
1025 return ISC_R_INVALIDARG;
1026 return ISC_R_SUCCESS;
1029 /* The "known" flag isn't supported in the database yet, but it's
1030 legitimate. */
1031 if (!omapi_ds_strcmp (name, "known")) {
1032 return ISC_R_SUCCESS;
1035 /* Try to find some inner object that can take the value. */
1036 if (h -> inner && h -> inner -> type -> set_value) {
1037 status = ((*(h -> inner -> type -> set_value))
1038 (h -> inner, id, name, value));
1039 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1040 return status;
1043 return ISC_R_UNKNOWNATTRIBUTE;
1047 isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id,
1048 omapi_data_string_t *name,
1049 omapi_value_t **value)
1051 struct host_decl *host;
1052 isc_result_t status;
1053 struct data_string ip_addrs;
1055 if (h -> type != dhcp_type_host)
1056 return ISC_R_INVALIDARG;
1057 host = (struct host_decl *)h;
1059 if (!omapi_ds_strcmp (name, "ip-addresses")) {
1060 memset (&ip_addrs, 0, sizeof ip_addrs);
1061 if (host -> fixed_addr &&
1062 evaluate_option_cache (&ip_addrs, (struct packet *)0,
1063 (struct lease *)0,
1064 (struct client_state *)0,
1065 (struct option_state *)0,
1066 (struct option_state *)0,
1067 &global_scope,
1068 host -> fixed_addr, MDL)) {
1069 status = omapi_make_const_value (value, name,
1070 ip_addrs.data,
1071 ip_addrs.len, MDL);
1072 data_string_forget (&ip_addrs, MDL);
1073 return status;
1075 return ISC_R_NOTFOUND;
1078 if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) {
1079 if (!host -> client_identifier.len)
1080 return ISC_R_NOTFOUND;
1081 return omapi_make_const_value (value, name,
1082 host -> client_identifier.data,
1083 host -> client_identifier.len,
1084 MDL);
1087 if (!omapi_ds_strcmp (name, "name"))
1088 return omapi_make_string_value (value, name, host -> name,
1089 MDL);
1091 if (!omapi_ds_strcmp (name, "hardware-address")) {
1092 if (!host -> interface.hlen)
1093 return ISC_R_NOTFOUND;
1094 return (omapi_make_const_value
1095 (value, name, &host -> interface.hbuf [1],
1096 (unsigned long)(host -> interface.hlen - 1), MDL));
1099 if (!omapi_ds_strcmp (name, "hardware-type")) {
1100 if (!host -> interface.hlen)
1101 return ISC_R_NOTFOUND;
1102 return omapi_make_int_value (value, name,
1103 host -> interface.hbuf [0], MDL);
1106 /* Try to find some inner object that can take the value. */
1107 if (h -> inner && h -> inner -> type -> get_value) {
1108 status = ((*(h -> inner -> type -> get_value))
1109 (h -> inner, id, name, value));
1110 if (status == ISC_R_SUCCESS)
1111 return status;
1113 return ISC_R_UNKNOWNATTRIBUTE;
1116 isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line)
1118 struct host_decl *host;
1120 if (h -> type != dhcp_type_host)
1121 return ISC_R_INVALIDARG;
1122 host = (struct host_decl *)h;
1124 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1125 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1126 if (host -> n_ipaddr)
1127 host_dereference (&host -> n_ipaddr, file, line);
1128 if (host -> n_dynamic)
1129 host_dereference (&host -> n_dynamic, file, line);
1130 if (host -> name) {
1131 dfree (host -> name, file, line);
1132 host -> name = (char *)0;
1134 data_string_forget (&host -> client_identifier, file, line);
1135 if (host -> fixed_addr)
1136 option_cache_dereference (&host -> fixed_addr, file, line);
1137 if (host -> group)
1138 group_dereference (&host -> group, file, line);
1139 if (host -> named_group)
1140 omapi_object_dereference ((omapi_object_t **)
1141 &host -> named_group, file, line);
1142 data_string_forget (&host -> auth_key_id, file, line);
1143 #endif
1145 return ISC_R_SUCCESS;
1148 isc_result_t dhcp_host_signal_handler (omapi_object_t *h,
1149 const char *name, va_list ap)
1151 struct host_decl *host;
1152 isc_result_t status;
1153 int updatep = 0;
1155 if (h -> type != dhcp_type_host)
1156 return ISC_R_INVALIDARG;
1157 host = (struct host_decl *)h;
1159 if (!strcmp (name, "updated")) {
1160 /* There must be a client identifier of some sort. */
1161 if (host -> interface.hlen == 0 &&
1162 !host -> client_identifier.len)
1163 return ISC_R_INVALIDARG;
1165 if (!host -> name) {
1166 char hnbuf [64];
1167 sprintf (hnbuf, "nh%08lx%08lx",
1168 (unsigned long)cur_time, (unsigned long)host);
1169 host -> name = dmalloc (strlen (hnbuf) + 1, MDL);
1170 if (!host -> name)
1171 return ISC_R_NOMEMORY;
1172 strcpy (host -> name, hnbuf);
1175 #ifdef DEBUG_OMAPI
1176 log_debug ("OMAPI added host %s", host -> name);
1177 #endif
1178 status = enter_host (host, 1, 1);
1179 if (status != ISC_R_SUCCESS)
1180 return status;
1181 updatep = 1;
1184 /* Try to find some inner object that can take the value. */
1185 if (h -> inner && h -> inner -> type -> signal_handler) {
1186 status = ((*(h -> inner -> type -> signal_handler))
1187 (h -> inner, name, ap));
1188 if (status == ISC_R_SUCCESS)
1189 return status;
1191 if (updatep)
1192 return ISC_R_SUCCESS;
1193 return ISC_R_NOTFOUND;
1196 isc_result_t dhcp_host_stuff_values (omapi_object_t *c,
1197 omapi_object_t *id,
1198 omapi_object_t *h)
1200 struct host_decl *host;
1201 isc_result_t status;
1202 struct data_string ip_addrs;
1204 if (h -> type != dhcp_type_host)
1205 return ISC_R_INVALIDARG;
1206 host = (struct host_decl *)h;
1208 /* Write out all the values. */
1210 memset (&ip_addrs, 0, sizeof ip_addrs);
1211 if (host -> fixed_addr &&
1212 evaluate_option_cache (&ip_addrs, (struct packet *)0,
1213 (struct lease *)0,
1214 (struct client_state *)0,
1215 (struct option_state *)0,
1216 (struct option_state *)0,
1217 &global_scope,
1218 host -> fixed_addr, MDL)) {
1219 status = omapi_connection_put_name (c, "ip-address");
1220 if (status != ISC_R_SUCCESS)
1221 return status;
1222 status = omapi_connection_put_uint32 (c, ip_addrs.len);
1223 if (status != ISC_R_SUCCESS)
1224 return status;
1225 status = omapi_connection_copyin (c,
1226 ip_addrs.data, ip_addrs.len);
1227 if (status != ISC_R_SUCCESS)
1228 return status;
1231 if (host -> client_identifier.len) {
1232 status = omapi_connection_put_name (c,
1233 "dhcp-client-identifier");
1234 if (status != ISC_R_SUCCESS)
1235 return status;
1236 status = (omapi_connection_put_uint32
1237 (c, host -> client_identifier.len));
1238 if (status != ISC_R_SUCCESS)
1239 return status;
1240 status = (omapi_connection_copyin
1242 host -> client_identifier.data,
1243 host -> client_identifier.len));
1244 if (status != ISC_R_SUCCESS)
1245 return status;
1248 if (host -> name) {
1249 status = omapi_connection_put_name (c, "name");
1250 if (status != ISC_R_SUCCESS)
1251 return status;
1252 status = omapi_connection_put_string (c, host -> name);
1253 if (status != ISC_R_SUCCESS)
1254 return status;
1257 if (host -> interface.hlen) {
1258 status = omapi_connection_put_name (c, "hardware-address");
1259 if (status != ISC_R_SUCCESS)
1260 return status;
1261 status = (omapi_connection_put_uint32
1262 (c, (unsigned long)(host -> interface.hlen - 1)));
1263 if (status != ISC_R_SUCCESS)
1264 return status;
1265 status = (omapi_connection_copyin
1266 (c, &host -> interface.hbuf [1],
1267 (unsigned long)(host -> interface.hlen - 1)));
1268 if (status != ISC_R_SUCCESS)
1269 return status;
1271 status = omapi_connection_put_name (c, "hardware-type");
1272 if (status != ISC_R_SUCCESS)
1273 return status;
1274 status = omapi_connection_put_uint32 (c, sizeof (int));
1275 if (status != ISC_R_SUCCESS)
1276 return status;
1277 status = (omapi_connection_put_uint32
1278 (c, host -> interface.hbuf [0]));
1279 if (status != ISC_R_SUCCESS)
1280 return status;
1283 /* Write out the inner object, if any. */
1284 if (h -> inner && h -> inner -> type -> stuff_values) {
1285 status = ((*(h -> inner -> type -> stuff_values))
1286 (c, id, h -> inner));
1287 if (status == ISC_R_SUCCESS)
1288 return status;
1291 return ISC_R_SUCCESS;
1294 isc_result_t dhcp_host_lookup (omapi_object_t **lp,
1295 omapi_object_t *id, omapi_object_t *ref)
1297 omapi_value_t *tv = (omapi_value_t *)0;
1298 isc_result_t status;
1299 struct host_decl *host;
1301 if (!ref)
1302 return ISC_R_NOKEYS;
1304 /* First see if we were sent a handle. */
1305 status = omapi_get_value_str (ref, id, "handle", &tv);
1306 if (status == ISC_R_SUCCESS) {
1307 status = omapi_handle_td_lookup (lp, tv -> value);
1309 omapi_value_dereference (&tv, MDL);
1310 if (status != ISC_R_SUCCESS)
1311 return status;
1313 /* Don't return the object if the type is wrong. */
1314 if ((*lp) -> type != dhcp_type_host) {
1315 omapi_object_dereference (lp, MDL);
1316 return ISC_R_INVALIDARG;
1318 if (((struct host_decl *)(*lp)) -> flags & HOST_DECL_DELETED) {
1319 omapi_object_dereference (lp, MDL);
1323 /* Now look for a client identifier. */
1324 status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv);
1325 if (status == ISC_R_SUCCESS) {
1326 host = (struct host_decl *)0;
1327 host_hash_lookup (&host, host_uid_hash,
1328 tv -> value -> u.buffer.value,
1329 tv -> value -> u.buffer.len, MDL);
1330 omapi_value_dereference (&tv, MDL);
1332 if (*lp && *lp != (omapi_object_t *)host) {
1333 omapi_object_dereference (lp, MDL);
1334 if (host)
1335 host_dereference (&host, MDL);
1336 return ISC_R_KEYCONFLICT;
1337 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
1338 if (*lp)
1339 omapi_object_dereference (lp, MDL);
1340 if (host)
1341 host_dereference (&host, MDL);
1342 return ISC_R_NOTFOUND;
1343 } else if (!*lp) {
1344 /* XXX fix so that hash lookup itself creates
1345 XXX the reference. */
1346 omapi_object_reference (lp,
1347 (omapi_object_t *)host, MDL);
1348 host_dereference (&host, MDL);
1352 /* Now look for a hardware address. */
1353 status = omapi_get_value_str (ref, id, "hardware-address", &tv);
1354 if (status == ISC_R_SUCCESS) {
1355 unsigned char *haddr;
1356 unsigned int len;
1358 len = tv -> value -> u.buffer.len + 1;
1359 haddr = dmalloc (len, MDL);
1360 if (!haddr) {
1361 omapi_value_dereference (&tv, MDL);
1362 return ISC_R_NOMEMORY;
1365 memcpy (haddr + 1, tv -> value -> u.buffer.value, len - 1);
1366 omapi_value_dereference (&tv, MDL);
1368 status = omapi_get_value_str (ref, id, "hardware-type", &tv);
1369 if (status == ISC_R_SUCCESS) {
1370 if (tv -> value -> type == omapi_datatype_data) {
1371 if ((tv -> value -> u.buffer.len != 4) ||
1372 (tv -> value -> u.buffer.value[0] != 0) ||
1373 (tv -> value -> u.buffer.value[1] != 0) ||
1374 (tv -> value -> u.buffer.value[2] != 0)) {
1375 omapi_value_dereference (&tv, MDL);
1376 dfree (haddr, MDL);
1377 return ISC_R_INVALIDARG;
1380 haddr[0] = tv -> value -> u.buffer.value[3];
1381 } else if (tv -> value -> type == omapi_datatype_int) {
1382 haddr[0] = (unsigned char)
1383 tv -> value -> u.integer;
1384 } else {
1385 omapi_value_dereference (&tv, MDL);
1386 dfree (haddr, MDL);
1387 return ISC_R_INVALIDARG;
1390 omapi_value_dereference (&tv, MDL);
1391 } else {
1392 /* If no hardware-type is specified, default to
1393 ethernet. This may or may not be a good idea,
1394 but Telus is currently relying on this behavior.
1395 - DPN */
1396 haddr[0] = HTYPE_ETHER;
1399 host = (struct host_decl *)0;
1400 host_hash_lookup (&host, host_hw_addr_hash, haddr, len, MDL);
1401 dfree (haddr, MDL);
1403 if (*lp && *lp != (omapi_object_t *)host) {
1404 omapi_object_dereference (lp, MDL);
1405 if (host)
1406 host_dereference (&host, MDL);
1407 return ISC_R_KEYCONFLICT;
1408 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
1409 if (*lp)
1410 omapi_object_dereference (lp, MDL);
1411 if (host)
1412 host_dereference (&host, MDL);
1413 return ISC_R_NOTFOUND;
1414 } else if (!*lp) {
1415 /* XXX fix so that hash lookup itself creates
1416 XXX the reference. */
1417 omapi_object_reference (lp,
1418 (omapi_object_t *)host, MDL);
1419 host_dereference (&host, MDL);
1423 /* Now look for an ip address. */
1424 status = omapi_get_value_str (ref, id, "ip-address", &tv);
1425 if (status == ISC_R_SUCCESS) {
1426 struct lease *l;
1428 /* first find the lease for this ip address */
1429 l = (struct lease *)0;
1430 lease_hash_lookup (&l, lease_ip_addr_hash,
1431 tv -> value -> u.buffer.value,
1432 tv -> value -> u.buffer.len, MDL);
1433 omapi_value_dereference (&tv, MDL);
1435 if (!l && !*lp)
1436 return ISC_R_NOTFOUND;
1438 if (l) {
1439 /* now use that to get a host */
1440 host = (struct host_decl *)0;
1441 host_hash_lookup (&host, host_hw_addr_hash,
1442 l -> hardware_addr.hbuf,
1443 l -> hardware_addr.hlen, MDL);
1445 if (host && *lp && *lp != (omapi_object_t *)host) {
1446 omapi_object_dereference (lp, MDL);
1447 if (host)
1448 host_dereference (&host, MDL);
1449 return ISC_R_KEYCONFLICT;
1450 } else if (!host || (host -> flags &
1451 HOST_DECL_DELETED)) {
1452 if (host)
1453 host_dereference (&host, MDL);
1454 if (!*lp)
1455 return ISC_R_NOTFOUND;
1456 } else if (!*lp) {
1457 /* XXX fix so that hash lookup itself creates
1458 XXX the reference. */
1459 omapi_object_reference (lp, (omapi_object_t *)host,
1460 MDL);
1461 host_dereference (&host, MDL);
1463 lease_dereference (&l, MDL);
1467 /* Now look for a name. */
1468 status = omapi_get_value_str (ref, id, "name", &tv);
1469 if (status == ISC_R_SUCCESS) {
1470 host = (struct host_decl *)0;
1471 host_hash_lookup (&host, host_name_hash,
1472 tv -> value -> u.buffer.value,
1473 tv -> value -> u.buffer.len, MDL);
1474 omapi_value_dereference (&tv, MDL);
1476 if (*lp && *lp != (omapi_object_t *)host) {
1477 omapi_object_dereference (lp, MDL);
1478 if (host)
1479 host_dereference (&host, MDL);
1480 return ISC_R_KEYCONFLICT;
1481 } else if (!host || (host -> flags & HOST_DECL_DELETED)) {
1482 if (host)
1483 host_dereference (&host, MDL);
1484 return ISC_R_NOTFOUND;
1485 } else if (!*lp) {
1486 /* XXX fix so that hash lookup itself creates
1487 XXX the reference. */
1488 omapi_object_reference (lp,
1489 (omapi_object_t *)host, MDL);
1490 host_dereference (&host, MDL);
1494 /* If we get to here without finding a host, no valid key was
1495 specified. */
1496 if (!*lp)
1497 return ISC_R_NOKEYS;
1498 return ISC_R_SUCCESS;
1501 isc_result_t dhcp_host_create (omapi_object_t **lp,
1502 omapi_object_t *id)
1504 struct host_decl *hp;
1505 isc_result_t status;
1506 hp = (struct host_decl *)0;
1507 status = host_allocate (&hp, MDL);
1508 if (status != ISC_R_SUCCESS)
1509 return status;
1510 group_reference (&hp -> group, root_group, MDL);
1511 hp -> flags = HOST_DECL_DYNAMIC;
1512 status = omapi_object_reference (lp, (omapi_object_t *)hp, MDL);
1513 host_dereference (&hp, MDL);
1514 return status;
1517 isc_result_t dhcp_host_remove (omapi_object_t *lp,
1518 omapi_object_t *id)
1520 struct host_decl *hp;
1521 if (lp -> type != dhcp_type_host)
1522 return ISC_R_INVALIDARG;
1523 hp = (struct host_decl *)lp;
1525 #ifdef DEBUG_OMAPI
1526 log_debug ("OMAPI delete host %s", hp -> name);
1527 #endif
1528 delete_host (hp, 1);
1529 return ISC_R_SUCCESS;
1532 isc_result_t dhcp_pool_set_value (omapi_object_t *h,
1533 omapi_object_t *id,
1534 omapi_data_string_t *name,
1535 omapi_typed_data_t *value)
1537 struct pool *pool;
1538 isc_result_t status;
1540 if (h -> type != dhcp_type_pool)
1541 return ISC_R_INVALIDARG;
1542 pool = (struct pool *)h;
1544 /* No values to set yet. */
1546 /* Try to find some inner object that can take the value. */
1547 if (h -> inner && h -> inner -> type -> set_value) {
1548 status = ((*(h -> inner -> type -> set_value))
1549 (h -> inner, id, name, value));
1550 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1551 return status;
1554 return ISC_R_UNKNOWNATTRIBUTE;
1558 isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id,
1559 omapi_data_string_t *name,
1560 omapi_value_t **value)
1562 struct pool *pool;
1563 isc_result_t status;
1565 if (h -> type != dhcp_type_pool)
1566 return ISC_R_INVALIDARG;
1567 pool = (struct pool *)h;
1569 /* No values to get yet. */
1571 /* Try to find some inner object that can provide the value. */
1572 if (h -> inner && h -> inner -> type -> get_value) {
1573 status = ((*(h -> inner -> type -> get_value))
1574 (h -> inner, id, name, value));
1575 if (status == ISC_R_SUCCESS)
1576 return status;
1578 return ISC_R_UNKNOWNATTRIBUTE;
1581 isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line)
1583 struct pool *pool;
1584 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1585 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1586 struct permit *pc, *pn;
1587 #endif
1589 if (h -> type != dhcp_type_pool)
1590 return ISC_R_INVALIDARG;
1591 pool = (struct pool *)h;
1593 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1594 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1595 if (pool -> next)
1596 pool_dereference (&pool -> next, file, line);
1597 if (pool -> group)
1598 group_dereference (&pool -> group, file, line);
1599 if (pool -> shared_network)
1600 shared_network_dereference (&pool -> shared_network, file, line);
1601 if (pool -> active)
1602 lease_dereference (&pool -> active, file, line);
1603 if (pool -> expired)
1604 lease_dereference (&pool -> expired, file, line);
1605 if (pool -> free)
1606 lease_dereference (&pool -> free, file, line);
1607 if (pool -> backup)
1608 lease_dereference (&pool -> backup, file, line);
1609 if (pool -> abandoned)
1610 lease_dereference (&pool -> abandoned, file, line);
1611 #if defined (FAILOVER_PROTOCOL)
1612 if (pool -> failover_peer)
1613 dhcp_failover_state_dereference (&pool -> failover_peer,
1614 file, line);
1615 #endif
1616 for (pc = pool -> permit_list; pc; pc = pn) {
1617 pn = pc -> next;
1618 free_permit (pc, file, line);
1620 pool -> permit_list = (struct permit *)0;
1622 for (pc = pool -> prohibit_list; pc; pc = pn) {
1623 pn = pc -> next;
1624 free_permit (pc, file, line);
1626 pool -> prohibit_list = (struct permit *)0;
1627 #endif
1629 return ISC_R_SUCCESS;
1632 isc_result_t dhcp_pool_signal_handler (omapi_object_t *h,
1633 const char *name, va_list ap)
1635 struct pool *pool;
1636 isc_result_t status;
1637 int updatep = 0;
1639 if (h -> type != dhcp_type_pool)
1640 return ISC_R_INVALIDARG;
1641 pool = (struct pool *)h;
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)
1650 return status;
1652 if (updatep)
1653 return ISC_R_SUCCESS;
1654 return ISC_R_NOTFOUND;
1657 isc_result_t dhcp_pool_stuff_values (omapi_object_t *c,
1658 omapi_object_t *id,
1659 omapi_object_t *h)
1661 struct pool *pool;
1662 isc_result_t status;
1664 if (h -> type != dhcp_type_pool)
1665 return ISC_R_INVALIDARG;
1666 pool = (struct pool *)h;
1668 /* Can't stuff pool values yet. */
1670 /* Write out the inner object, if any. */
1671 if (h -> inner && h -> inner -> type -> stuff_values) {
1672 status = ((*(h -> inner -> type -> stuff_values))
1673 (c, id, h -> inner));
1674 if (status == ISC_R_SUCCESS)
1675 return status;
1678 return ISC_R_SUCCESS;
1681 isc_result_t dhcp_pool_lookup (omapi_object_t **lp,
1682 omapi_object_t *id, omapi_object_t *ref)
1685 /* Can't look up pools yet. */
1687 /* If we get to here without finding a pool, no valid key was
1688 specified. */
1689 if (!*lp)
1690 return ISC_R_NOKEYS;
1691 return ISC_R_SUCCESS;
1694 isc_result_t dhcp_pool_create (omapi_object_t **lp,
1695 omapi_object_t *id)
1697 return ISC_R_NOTIMPLEMENTED;
1700 isc_result_t dhcp_pool_remove (omapi_object_t *lp,
1701 omapi_object_t *id)
1703 return ISC_R_NOTIMPLEMENTED;
1706 isc_result_t dhcp_class_set_value (omapi_object_t *h,
1707 omapi_object_t *id,
1708 omapi_data_string_t *name,
1709 omapi_typed_data_t *value)
1711 struct class *class;
1712 isc_result_t status;
1714 if (h -> type != dhcp_type_class)
1715 return ISC_R_INVALIDARG;
1716 class = (struct class *)h;
1718 /* No values to set yet. */
1720 /* Try to find some inner object that can take the value. */
1721 if (h -> inner && h -> inner -> type -> set_value) {
1722 status = ((*(h -> inner -> type -> set_value))
1723 (h -> inner, id, name, value));
1724 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1725 return status;
1728 return ISC_R_UNKNOWNATTRIBUTE;
1732 isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id,
1733 omapi_data_string_t *name,
1734 omapi_value_t **value)
1736 struct class *class;
1737 isc_result_t status;
1739 if (h -> type != dhcp_type_class)
1740 return ISC_R_INVALIDARG;
1741 class = (struct class *)h;
1743 /* No values to get yet. */
1745 /* Try to find some inner object that can provide the value. */
1746 if (h -> inner && h -> inner -> type -> get_value) {
1747 status = ((*(h -> inner -> type -> get_value))
1748 (h -> inner, id, name, value));
1749 if (status == ISC_R_SUCCESS)
1750 return status;
1752 return ISC_R_UNKNOWNATTRIBUTE;
1755 isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line)
1757 struct class *class;
1758 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1759 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1760 int i;
1761 #endif
1763 if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass)
1764 return ISC_R_INVALIDARG;
1765 class = (struct class *)h;
1767 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1768 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1769 if (class -> nic)
1770 class_dereference (&class -> nic, file, line);
1771 if (class -> superclass)
1772 class_dereference (&class -> superclass, file, line);
1773 if (class -> name) {
1774 dfree (class -> name, file, line);
1775 class -> name = (char *)0;
1777 if (class -> billed_leases) {
1778 for (i = 0; i < class -> lease_limit; i++) {
1779 if (class -> billed_leases [i]) {
1780 lease_dereference (&class -> billed_leases [i],
1781 file, line);
1784 dfree (class -> billed_leases, file, line);
1785 class -> billed_leases = (struct lease **)0;
1787 if (class -> hash) {
1788 class_free_hash_table (&class -> hash, file, line);
1789 class -> hash = (class_hash_t *)0;
1791 data_string_forget (&class -> hash_string, file, line);
1793 if (class -> expr)
1794 expression_dereference (&class -> expr, file, line);
1795 if (class -> submatch)
1796 expression_dereference (&class -> submatch, file, line);
1797 if (class -> group)
1798 group_dereference (&class -> group, file, line);
1799 if (class -> statements)
1800 executable_statement_dereference (&class -> statements,
1801 file, line);
1802 if (class -> superclass)
1803 class_dereference (&class -> superclass, file, line);
1804 #endif
1806 return ISC_R_SUCCESS;
1809 isc_result_t dhcp_class_signal_handler (omapi_object_t *h,
1810 const char *name, va_list ap)
1812 struct class *class;
1813 isc_result_t status;
1814 int updatep = 0;
1816 if (h -> type != dhcp_type_class)
1817 return ISC_R_INVALIDARG;
1818 class = (struct class *)h;
1820 /* Can't write classs yet. */
1822 /* Try to find some inner object that can take the value. */
1823 if (h -> inner && h -> inner -> type -> signal_handler) {
1824 status = ((*(h -> inner -> type -> signal_handler))
1825 (h -> inner, name, ap));
1826 if (status == ISC_R_SUCCESS)
1827 return status;
1829 if (updatep)
1830 return ISC_R_SUCCESS;
1831 return ISC_R_NOTFOUND;
1834 isc_result_t dhcp_class_stuff_values (omapi_object_t *c,
1835 omapi_object_t *id,
1836 omapi_object_t *h)
1838 struct class *class;
1839 isc_result_t status;
1841 if (h -> type != dhcp_type_class)
1842 return ISC_R_INVALIDARG;
1843 class = (struct class *)h;
1845 /* Can't stuff class values yet. */
1847 /* Write out the inner object, if any. */
1848 if (h -> inner && h -> inner -> type -> stuff_values) {
1849 status = ((*(h -> inner -> type -> stuff_values))
1850 (c, id, h -> inner));
1851 if (status == ISC_R_SUCCESS)
1852 return status;
1855 return ISC_R_SUCCESS;
1858 isc_result_t dhcp_class_lookup (omapi_object_t **lp,
1859 omapi_object_t *id, omapi_object_t *ref)
1862 /* Can't look up classs yet. */
1864 /* If we get to here without finding a class, no valid key was
1865 specified. */
1866 if (!*lp)
1867 return ISC_R_NOKEYS;
1868 return ISC_R_SUCCESS;
1871 isc_result_t dhcp_class_create (omapi_object_t **lp,
1872 omapi_object_t *id)
1874 return ISC_R_NOTIMPLEMENTED;
1877 isc_result_t dhcp_class_remove (omapi_object_t *lp,
1878 omapi_object_t *id)
1880 return ISC_R_NOTIMPLEMENTED;
1883 isc_result_t dhcp_subclass_set_value (omapi_object_t *h,
1884 omapi_object_t *id,
1885 omapi_data_string_t *name,
1886 omapi_typed_data_t *value)
1888 struct subclass *subclass;
1889 isc_result_t status;
1891 if (h -> type != dhcp_type_subclass)
1892 return ISC_R_INVALIDARG;
1893 subclass = (struct subclass *)h;
1895 /* No values to set yet. */
1897 /* Try to find some inner object that can take the value. */
1898 if (h -> inner && h -> inner -> type -> set_value) {
1899 status = ((*(h -> inner -> type -> set_value))
1900 (h -> inner, id, name, value));
1901 if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
1902 return status;
1905 return ISC_R_UNKNOWNATTRIBUTE;
1909 isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id,
1910 omapi_data_string_t *name,
1911 omapi_value_t **value)
1913 struct subclass *subclass;
1914 isc_result_t status;
1916 if (h -> type != dhcp_type_subclass)
1917 return ISC_R_INVALIDARG;
1918 subclass = (struct subclass *)h;
1920 /* No values to get yet. */
1922 /* Try to find some inner object that can provide the value. */
1923 if (h -> inner && h -> inner -> type -> get_value) {
1924 status = ((*(h -> inner -> type -> get_value))
1925 (h -> inner, id, name, value));
1926 if (status == ISC_R_SUCCESS)
1927 return status;
1929 return ISC_R_UNKNOWNATTRIBUTE;
1932 isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h,
1933 const char *name, va_list ap)
1935 struct subclass *subclass;
1936 isc_result_t status;
1937 int updatep = 0;
1939 if (h -> type != dhcp_type_subclass)
1940 return ISC_R_INVALIDARG;
1941 subclass = (struct subclass *)h;
1943 /* Can't write subclasss yet. */
1945 /* Try to find some inner object that can take the value. */
1946 if (h -> inner && h -> inner -> type -> signal_handler) {
1947 status = ((*(h -> inner -> type -> signal_handler))
1948 (h -> inner, name, ap));
1949 if (status == ISC_R_SUCCESS)
1950 return status;
1952 if (updatep)
1953 return ISC_R_SUCCESS;
1954 return ISC_R_NOTFOUND;
1957 isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c,
1958 omapi_object_t *id,
1959 omapi_object_t *h)
1961 struct subclass *subclass;
1962 isc_result_t status;
1964 if (h -> type != dhcp_type_subclass)
1965 return ISC_R_INVALIDARG;
1966 subclass = (struct subclass *)h;
1968 /* Can't stuff subclass values yet. */
1970 /* Write out the inner object, if any. */
1971 if (h -> inner && h -> inner -> type -> stuff_values) {
1972 status = ((*(h -> inner -> type -> stuff_values))
1973 (c, id, h -> inner));
1974 if (status == ISC_R_SUCCESS)
1975 return status;
1978 return ISC_R_SUCCESS;
1981 isc_result_t dhcp_subclass_lookup (omapi_object_t **lp,
1982 omapi_object_t *id, omapi_object_t *ref)
1985 /* Can't look up subclasss yet. */
1987 /* If we get to here without finding a subclass, no valid key was
1988 specified. */
1989 if (!*lp)
1990 return ISC_R_NOKEYS;
1991 return ISC_R_SUCCESS;
1994 isc_result_t dhcp_subclass_create (omapi_object_t **lp,
1995 omapi_object_t *id)
1997 return ISC_R_NOTIMPLEMENTED;
2000 isc_result_t dhcp_subclass_remove (omapi_object_t *lp,
2001 omapi_object_t *id)
2003 return ISC_R_NOTIMPLEMENTED;
2006 isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp,
2007 omapi_data_string_t *name,
2008 omapi_typed_data_t *value)
2010 struct binding *bp;
2011 char *nname;
2012 struct binding_value *nv;
2013 nname = dmalloc (name -> len + 1, MDL);
2014 if (!nname)
2015 return ISC_R_NOMEMORY;
2016 memcpy (nname, name -> value, name -> len);
2017 nname [name -> len] = 0;
2018 bp = find_binding (scope, nname);
2019 if (!bp && !createp) {
2020 dfree (nname, MDL);
2021 return ISC_R_UNKNOWNATTRIBUTE;
2023 if (!value) {
2024 dfree (nname, MDL);
2025 if (!bp)
2026 return ISC_R_UNKNOWNATTRIBUTE;
2027 binding_value_dereference (&bp -> value, MDL);
2028 return ISC_R_SUCCESS;
2031 nv = (struct binding_value *)0;
2032 if (!binding_value_allocate (&nv, MDL)) {
2033 dfree (nname, MDL);
2034 return ISC_R_NOMEMORY;
2036 switch (value -> type) {
2037 case omapi_datatype_int:
2038 nv -> type = binding_numeric;
2039 nv -> value.intval = value -> u.integer;
2040 break;
2042 case omapi_datatype_string:
2043 case omapi_datatype_data:
2044 if (!buffer_allocate (&nv -> value.data.buffer,
2045 value -> u.buffer.len, MDL)) {
2046 binding_value_dereference (&nv, MDL);
2047 dfree (nname, MDL);
2048 return ISC_R_NOMEMORY;
2050 memcpy (&nv -> value.data.buffer -> data [1],
2051 value -> u.buffer.value, value -> u.buffer.len);
2052 nv -> value.data.len = value -> u.buffer.len;
2053 break;
2055 case omapi_datatype_object:
2056 binding_value_dereference (&nv, MDL);
2057 dfree (nname, MDL);
2058 return ISC_R_INVALIDARG;
2061 if (!bp) {
2062 bp = dmalloc (sizeof *bp, MDL);
2063 if (!bp) {
2064 binding_value_dereference (&nv, MDL);
2065 dfree (nname, MDL);
2066 return ISC_R_NOMEMORY;
2068 memset (bp, 0, sizeof *bp);
2069 bp -> name = nname;
2070 nname = (char *)0;
2071 bp -> next = scope -> bindings;
2072 scope -> bindings = bp;
2073 } else {
2074 if (bp -> value)
2075 binding_value_dereference (&bp -> value, MDL);
2076 dfree (nname, MDL);
2078 binding_value_reference (&bp -> value, nv, MDL);
2079 binding_value_dereference (&nv, MDL);
2080 return ISC_R_SUCCESS;
2083 isc_result_t binding_scope_get_value (omapi_value_t **value,
2084 struct binding_scope *scope,
2085 omapi_data_string_t *name)
2087 struct binding *bp;
2088 omapi_typed_data_t *td;
2089 isc_result_t status;
2090 char *nname;
2092 status = ISC_R_FAILURE; /* XXXGCC -Wuninitialized */
2094 nname = dmalloc (name -> len + 1, MDL);
2095 if (!nname)
2096 return ISC_R_NOMEMORY;
2097 memcpy (nname, name -> value, name -> len);
2098 nname [name -> len] = 0;
2099 bp = find_binding (scope, nname);
2100 dfree (nname, MDL);
2101 if (!bp)
2102 return ISC_R_UNKNOWNATTRIBUTE;
2103 if (!bp -> value)
2104 return ISC_R_UNKNOWNATTRIBUTE;
2106 switch (bp -> value -> type) {
2107 case binding_boolean:
2108 td = (omapi_typed_data_t *)0;
2109 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
2110 bp -> value -> value.boolean);
2111 break;
2113 case binding_numeric:
2114 td = (omapi_typed_data_t *)0;
2115 status = omapi_typed_data_new (MDL, &td, omapi_datatype_int,
2116 (int)
2117 bp -> value -> value.intval);
2118 break;
2120 case binding_data:
2121 td = (omapi_typed_data_t *)0;
2122 status = omapi_typed_data_new (MDL, &td, omapi_datatype_data,
2123 bp -> value -> value.data.len);
2124 if (status != ISC_R_SUCCESS)
2125 return status;
2126 memcpy (&td -> u.buffer.value [0],
2127 bp -> value -> value.data.data,
2128 bp -> value -> value.data.len);
2129 break;
2131 /* Can't return values for these two (yet?). */
2132 case binding_dns:
2133 case binding_function:
2134 return ISC_R_INVALIDARG;
2136 default:
2137 log_fatal ("Impossible case at %s:%d.", MDL);
2138 return ISC_R_FAILURE;
2141 if (status != ISC_R_SUCCESS)
2142 return status;
2143 status = omapi_value_new (value, MDL);
2144 if (status != ISC_R_SUCCESS) {
2145 omapi_typed_data_dereference (&td, MDL);
2146 return status;
2149 omapi_data_string_reference (&(*value) -> name, name, MDL);
2150 omapi_typed_data_reference (&(*value) -> value, td, MDL);
2151 omapi_typed_data_dereference (&td, MDL);
2153 return ISC_R_SUCCESS;
2156 isc_result_t binding_scope_stuff_values (omapi_object_t *c,
2157 struct binding_scope *scope)
2159 struct binding *bp;
2160 unsigned len;
2161 isc_result_t status;
2163 for (bp = scope -> bindings; bp; bp = bp -> next) {
2164 if (bp -> value) {
2165 if (bp -> value -> type == binding_dns ||
2166 bp -> value -> type == binding_function)
2167 continue;
2169 /* Stuff the name. */
2170 len = strlen (bp -> name);
2171 status = omapi_connection_put_uint16 (c, len);
2172 if (status != ISC_R_SUCCESS)
2173 return status;
2174 status = omapi_connection_copyin (c,
2175 (unsigned char *)bp -> name,
2176 len);
2177 if (status != ISC_R_SUCCESS)
2178 return status;
2180 switch (bp -> value -> type) {
2181 case binding_boolean:
2182 status = omapi_connection_put_uint32 (c,
2183 sizeof (u_int32_t));
2184 if (status != ISC_R_SUCCESS)
2185 return status;
2186 status = (omapi_connection_put_uint32
2188 ((u_int32_t)(bp -> value -> value.boolean))));
2189 break;
2191 case binding_data:
2192 status = (omapi_connection_put_uint32
2193 (c, bp -> value -> value.data.len));
2194 if (status != ISC_R_SUCCESS)
2195 return status;
2196 if (bp -> value -> value.data.len) {
2197 status = (omapi_connection_copyin
2198 (c, bp -> value -> value.data.data,
2199 bp -> value -> value.data.len));
2200 if (status != ISC_R_SUCCESS)
2201 return status;
2203 break;
2205 case binding_numeric:
2206 status = (omapi_connection_put_uint32
2207 (c, sizeof (u_int32_t)));
2208 if (status != ISC_R_SUCCESS)
2209 return status;
2210 status = (omapi_connection_put_uint32
2211 (c, ((u_int32_t)
2212 (bp -> value -> value.intval))));
2213 break;
2216 /* NOTREACHED */
2217 case binding_dns:
2218 case binding_function:
2219 break;
2223 return ISC_R_SUCCESS;
2226 /* vim: set tabstop=8: */