comapi.c revision 1.1 1 1.1 christos /* $NetBSD: comapi.c,v 1.1 2018/04/07 22:34:25 christos Exp $ */
2 1.1 christos
3 1.1 christos /* omapi.c
4 1.1 christos
5 1.1 christos OMAPI object interfaces for the DHCP server. */
6 1.1 christos
7 1.1 christos /*
8 1.1 christos * Copyright (c) 2004-2017 Internet Systems Consortium, Inc. ("ISC")
9 1.1 christos * Copyright (c) 1999-2003 by Internet Software Consortium
10 1.1 christos *
11 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public
12 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this
13 1.1 christos * file, You can obtain one at http://mozilla.org/MPL/2.0/.
14 1.1 christos *
15 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16 1.1 christos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 1.1 christos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18 1.1 christos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 1.1 christos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 1.1 christos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 1.1 christos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 1.1 christos *
23 1.1 christos * Internet Systems Consortium, Inc.
24 1.1 christos * 950 Charter Street
25 1.1 christos * Redwood City, CA 94063
26 1.1 christos * <info (at) isc.org>
27 1.1 christos * https://www.isc.org/
28 1.1 christos *
29 1.1 christos */
30 1.1 christos
31 1.1 christos #include <sys/cdefs.h>
32 1.1 christos __RCSID("$NetBSD: comapi.c,v 1.1 2018/04/07 22:34:25 christos Exp $");
33 1.1 christos
34 1.1 christos /* Many, many thanks to Brian Murrell and BCtel for this code - BCtel
35 1.1 christos provided the funding that resulted in this code and the entire
36 1.1 christos OMAPI support library being written, and Brian helped brainstorm
37 1.1 christos and refine the requirements. To the extent that this code is
38 1.1 christos useful, you have Brian and BCtel to thank. Any limitations in the
39 1.1 christos code are a result of mistakes on my part. -- Ted Lemon */
40 1.1 christos
41 1.1 christos #include "dhcpd.h"
42 1.1 christos #include <omapip/omapip_p.h>
43 1.1 christos
44 1.1 christos OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet)
45 1.1 christos OMAPI_OBJECT_ALLOC (shared_network, struct shared_network,
46 1.1 christos dhcp_type_shared_network)
47 1.1 christos OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group)
48 1.1 christos OMAPI_OBJECT_ALLOC (dhcp_control, dhcp_control_object_t, dhcp_type_control)
49 1.1 christos
50 1.1 christos omapi_object_type_t *dhcp_type_group;
51 1.1 christos omapi_object_type_t *dhcp_type_shared_network;
52 1.1 christos omapi_object_type_t *dhcp_type_subnet;
53 1.1 christos omapi_object_type_t *dhcp_type_control;
54 1.1 christos dhcp_control_object_t *dhcp_control_object;
55 1.1 christos
56 1.1 christos void dhcp_common_objects_setup ()
57 1.1 christos {
58 1.1 christos isc_result_t status;
59 1.1 christos
60 1.1 christos status = omapi_object_type_register (&dhcp_type_control,
61 1.1 christos "control",
62 1.1 christos dhcp_control_set_value,
63 1.1 christos dhcp_control_get_value,
64 1.1 christos dhcp_control_destroy,
65 1.1 christos dhcp_control_signal_handler,
66 1.1 christos dhcp_control_stuff_values,
67 1.1 christos dhcp_control_lookup,
68 1.1 christos dhcp_control_create,
69 1.1 christos dhcp_control_remove, 0, 0, 0,
70 1.1 christos sizeof (dhcp_control_object_t),
71 1.1 christos 0, RC_MISC);
72 1.1 christos if (status != ISC_R_SUCCESS)
73 1.1 christos log_fatal ("Can't register control object type: %s",
74 1.1 christos isc_result_totext (status));
75 1.1 christos status = dhcp_control_allocate (&dhcp_control_object, MDL);
76 1.1 christos if (status != ISC_R_SUCCESS)
77 1.1 christos log_fatal ("Can't make initial control object: %s",
78 1.1 christos isc_result_totext (status));
79 1.1 christos dhcp_control_object -> state = server_startup;
80 1.1 christos
81 1.1 christos status = omapi_object_type_register (&dhcp_type_group,
82 1.1 christos "group",
83 1.1 christos dhcp_group_set_value,
84 1.1 christos dhcp_group_get_value,
85 1.1 christos dhcp_group_destroy,
86 1.1 christos dhcp_group_signal_handler,
87 1.1 christos dhcp_group_stuff_values,
88 1.1 christos dhcp_group_lookup,
89 1.1 christos dhcp_group_create,
90 1.1 christos dhcp_group_remove, 0, 0, 0,
91 1.1 christos sizeof (struct group_object), 0,
92 1.1 christos RC_MISC);
93 1.1 christos if (status != ISC_R_SUCCESS)
94 1.1 christos log_fatal ("Can't register group object type: %s",
95 1.1 christos isc_result_totext (status));
96 1.1 christos
97 1.1 christos status = omapi_object_type_register (&dhcp_type_subnet,
98 1.1 christos "subnet",
99 1.1 christos dhcp_subnet_set_value,
100 1.1 christos dhcp_subnet_get_value,
101 1.1 christos dhcp_subnet_destroy,
102 1.1 christos dhcp_subnet_signal_handler,
103 1.1 christos dhcp_subnet_stuff_values,
104 1.1 christos dhcp_subnet_lookup,
105 1.1 christos dhcp_subnet_create,
106 1.1 christos dhcp_subnet_remove, 0, 0, 0,
107 1.1 christos sizeof (struct subnet), 0,
108 1.1 christos RC_MISC);
109 1.1 christos if (status != ISC_R_SUCCESS)
110 1.1 christos log_fatal ("Can't register subnet object type: %s",
111 1.1 christos isc_result_totext (status));
112 1.1 christos
113 1.1 christos status = omapi_object_type_register
114 1.1 christos (&dhcp_type_shared_network,
115 1.1 christos "shared-network",
116 1.1 christos dhcp_shared_network_set_value,
117 1.1 christos dhcp_shared_network_get_value,
118 1.1 christos dhcp_shared_network_destroy,
119 1.1 christos dhcp_shared_network_signal_handler,
120 1.1 christos dhcp_shared_network_stuff_values,
121 1.1 christos dhcp_shared_network_lookup,
122 1.1 christos dhcp_shared_network_create,
123 1.1 christos dhcp_shared_network_remove, 0, 0, 0,
124 1.1 christos sizeof (struct shared_network), 0, RC_MISC);
125 1.1 christos if (status != ISC_R_SUCCESS)
126 1.1 christos log_fatal ("Can't register shared network object type: %s",
127 1.1 christos isc_result_totext (status));
128 1.1 christos
129 1.1 christos interface_setup ();
130 1.1 christos }
131 1.1 christos
132 1.1 christos isc_result_t dhcp_group_set_value (omapi_object_t *h,
133 1.1 christos omapi_object_t *id,
134 1.1 christos omapi_data_string_t *name,
135 1.1 christos omapi_typed_data_t *value)
136 1.1 christos {
137 1.1 christos struct group_object *group;
138 1.1 christos isc_result_t status;
139 1.1 christos
140 1.1 christos if (h -> type != dhcp_type_group)
141 1.1 christos return DHCP_R_INVALIDARG;
142 1.1 christos group = (struct group_object *)h;
143 1.1 christos
144 1.1 christos /* XXX For now, we can only set these values on new group objects.
145 1.1 christos XXX Soon, we need to be able to update group objects. */
146 1.1 christos if (!omapi_ds_strcmp (name, "name")) {
147 1.1 christos if (group -> name)
148 1.1 christos return ISC_R_EXISTS;
149 1.1 christos if (value -> type == omapi_datatype_data ||
150 1.1 christos value -> type == omapi_datatype_string) {
151 1.1 christos group -> name = dmalloc (value -> u.buffer.len + 1,
152 1.1 christos MDL);
153 1.1 christos if (!group -> name)
154 1.1 christos return ISC_R_NOMEMORY;
155 1.1 christos memcpy (group -> name,
156 1.1 christos value -> u.buffer.value,
157 1.1 christos value -> u.buffer.len);
158 1.1 christos group -> name [value -> u.buffer.len] = 0;
159 1.1 christos } else
160 1.1 christos return DHCP_R_INVALIDARG;
161 1.1 christos return ISC_R_SUCCESS;
162 1.1 christos }
163 1.1 christos
164 1.1 christos if (!omapi_ds_strcmp (name, "statements")) {
165 1.1 christos if (group -> group && group -> group -> statements)
166 1.1 christos return ISC_R_EXISTS;
167 1.1 christos if (!group -> group) {
168 1.1 christos if (!clone_group (&group -> group, root_group, MDL))
169 1.1 christos return ISC_R_NOMEMORY;
170 1.1 christos }
171 1.1 christos if (value -> type == omapi_datatype_data ||
172 1.1 christos value -> type == omapi_datatype_string) {
173 1.1 christos struct parse *parse;
174 1.1 christos int lose = 0;
175 1.1 christos parse = NULL;
176 1.1 christos status = new_parse(&parse, -1,
177 1.1 christos (char *) value->u.buffer.value,
178 1.1 christos value->u.buffer.len,
179 1.1 christos "network client", 0);
180 1.1 christos if (status != ISC_R_SUCCESS || parse == NULL)
181 1.1 christos return status;
182 1.1 christos if (!(parse_executable_statements
183 1.1 christos (&group -> group -> statements, parse, &lose,
184 1.1 christos context_any))) {
185 1.1 christos end_parse (&parse);
186 1.1 christos return DHCP_R_BADPARSE;
187 1.1 christos }
188 1.1 christos end_parse (&parse);
189 1.1 christos return ISC_R_SUCCESS;
190 1.1 christos } else
191 1.1 christos return DHCP_R_INVALIDARG;
192 1.1 christos }
193 1.1 christos
194 1.1 christos /* Try to find some inner object that can take the value. */
195 1.1 christos if (h -> inner && h -> inner -> type -> set_value) {
196 1.1 christos status = ((*(h -> inner -> type -> set_value))
197 1.1 christos (h -> inner, id, name, value));
198 1.1 christos if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
199 1.1 christos return status;
200 1.1 christos }
201 1.1 christos
202 1.1 christos return ISC_R_NOTFOUND;
203 1.1 christos }
204 1.1 christos
205 1.1 christos
206 1.1 christos isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id,
207 1.1 christos omapi_data_string_t *name,
208 1.1 christos omapi_value_t **value)
209 1.1 christos {
210 1.1 christos struct group_object *group;
211 1.1 christos isc_result_t status;
212 1.1 christos
213 1.1 christos if (h -> type != dhcp_type_group)
214 1.1 christos return DHCP_R_INVALIDARG;
215 1.1 christos group = (struct group_object *)h;
216 1.1 christos
217 1.1 christos if (!omapi_ds_strcmp (name, "name"))
218 1.1 christos return omapi_make_string_value (value,
219 1.1 christos name, group -> name, MDL);
220 1.1 christos
221 1.1 christos /* Try to find some inner object that can take the value. */
222 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
223 1.1 christos status = ((*(h -> inner -> type -> get_value))
224 1.1 christos (h -> inner, id, name, value));
225 1.1 christos if (status == ISC_R_SUCCESS)
226 1.1 christos return status;
227 1.1 christos }
228 1.1 christos return ISC_R_NOTFOUND;
229 1.1 christos }
230 1.1 christos
231 1.1 christos isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line)
232 1.1 christos {
233 1.1 christos struct group_object *group, *t;
234 1.1 christos
235 1.1 christos if (h -> type != dhcp_type_group)
236 1.1 christos return DHCP_R_INVALIDARG;
237 1.1 christos group = (struct group_object *)h;
238 1.1 christos
239 1.1 christos if (group -> name) {
240 1.1 christos if (group_name_hash) {
241 1.1 christos t = (struct group_object *)0;
242 1.1 christos if (group_hash_lookup (&t, group_name_hash,
243 1.1 christos group -> name,
244 1.1 christos strlen (group -> name), MDL)) {
245 1.1 christos group_hash_delete (group_name_hash,
246 1.1 christos group -> name,
247 1.1 christos strlen (group -> name),
248 1.1 christos MDL);
249 1.1 christos group_object_dereference (&t, MDL);
250 1.1 christos }
251 1.1 christos }
252 1.1 christos dfree (group -> name, file, line);
253 1.1 christos group -> name = (char *)0;
254 1.1 christos }
255 1.1 christos if (group -> group)
256 1.1 christos group_dereference (&group -> group, MDL);
257 1.1 christos
258 1.1 christos return ISC_R_SUCCESS;
259 1.1 christos }
260 1.1 christos
261 1.1 christos isc_result_t dhcp_group_signal_handler (omapi_object_t *h,
262 1.1 christos const char *name, va_list ap)
263 1.1 christos {
264 1.1 christos struct group_object *group;
265 1.1 christos isc_result_t status;
266 1.1 christos int updatep = 0;
267 1.1 christos
268 1.1 christos if (h -> type != dhcp_type_group)
269 1.1 christos return DHCP_R_INVALIDARG;
270 1.1 christos group = (struct group_object *)h;
271 1.1 christos
272 1.1 christos if (!strcmp (name, "updated")) {
273 1.1 christos /* A group object isn't valid if a subgroup hasn't yet been
274 1.1 christos associated with it. */
275 1.1 christos if (!group -> group)
276 1.1 christos return DHCP_R_INVALIDARG;
277 1.1 christos
278 1.1 christos /* Group objects always have to have names. */
279 1.1 christos if (!group -> name) {
280 1.1 christos char hnbuf [64];
281 1.1 christos sprintf (hnbuf, "ng%08lx%08lx",
282 1.1 christos (unsigned long)cur_time,
283 1.1 christos (unsigned long)group);
284 1.1 christos group -> name = dmalloc (strlen (hnbuf) + 1, MDL);
285 1.1 christos if (!group -> name)
286 1.1 christos return ISC_R_NOMEMORY;
287 1.1 christos strcpy (group -> name, hnbuf);
288 1.1 christos }
289 1.1 christos
290 1.1 christos supersede_group (group, 1);
291 1.1 christos updatep = 1;
292 1.1 christos }
293 1.1 christos
294 1.1 christos /* Try to find some inner object that can take the value. */
295 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
296 1.1 christos status = ((*(h -> inner -> type -> signal_handler))
297 1.1 christos (h -> inner, name, ap));
298 1.1 christos if (status == ISC_R_SUCCESS)
299 1.1 christos return status;
300 1.1 christos }
301 1.1 christos if (updatep)
302 1.1 christos return ISC_R_SUCCESS;
303 1.1 christos return ISC_R_NOTFOUND;
304 1.1 christos }
305 1.1 christos
306 1.1 christos isc_result_t dhcp_group_stuff_values (omapi_object_t *c,
307 1.1 christos omapi_object_t *id,
308 1.1 christos omapi_object_t *h)
309 1.1 christos {
310 1.1 christos struct group_object *group;
311 1.1 christos isc_result_t status;
312 1.1 christos
313 1.1 christos if (h -> type != dhcp_type_group)
314 1.1 christos return DHCP_R_INVALIDARG;
315 1.1 christos group = (struct group_object *)h;
316 1.1 christos
317 1.1 christos /* Write out all the values. */
318 1.1 christos if (group -> name) {
319 1.1 christos status = omapi_connection_put_name (c, "name");
320 1.1 christos if (status != ISC_R_SUCCESS)
321 1.1 christos return status;
322 1.1 christos status = omapi_connection_put_string (c, group -> name);
323 1.1 christos if (status != ISC_R_SUCCESS)
324 1.1 christos return status;
325 1.1 christos }
326 1.1 christos
327 1.1 christos /* Write out the inner object, if any. */
328 1.1 christos if (h -> inner && h -> inner -> type -> stuff_values) {
329 1.1 christos status = ((*(h -> inner -> type -> stuff_values))
330 1.1 christos (c, id, h -> inner));
331 1.1 christos if (status == ISC_R_SUCCESS)
332 1.1 christos return status;
333 1.1 christos }
334 1.1 christos
335 1.1 christos return ISC_R_SUCCESS;
336 1.1 christos }
337 1.1 christos
338 1.1 christos isc_result_t dhcp_group_lookup (omapi_object_t **lp,
339 1.1 christos omapi_object_t *id, omapi_object_t *ref)
340 1.1 christos {
341 1.1 christos omapi_value_t *tv = (omapi_value_t *)0;
342 1.1 christos isc_result_t status;
343 1.1 christos struct group_object *group;
344 1.1 christos
345 1.1 christos if (!ref)
346 1.1 christos return DHCP_R_NOKEYS;
347 1.1 christos
348 1.1 christos /* First see if we were sent a handle. */
349 1.1 christos status = omapi_get_value_str (ref, id, "handle", &tv);
350 1.1 christos if (status == ISC_R_SUCCESS) {
351 1.1 christos status = omapi_handle_td_lookup (lp, tv -> value);
352 1.1 christos
353 1.1 christos omapi_value_dereference (&tv, MDL);
354 1.1 christos if (status != ISC_R_SUCCESS)
355 1.1 christos return status;
356 1.1 christos
357 1.1 christos /* Don't return the object if the type is wrong. */
358 1.1 christos if ((*lp) -> type != dhcp_type_group) {
359 1.1 christos omapi_object_dereference (lp, MDL);
360 1.1 christos return DHCP_R_INVALIDARG;
361 1.1 christos }
362 1.1 christos }
363 1.1 christos
364 1.1 christos /* Now look for a name. */
365 1.1 christos status = omapi_get_value_str (ref, id, "name", &tv);
366 1.1 christos if (status == ISC_R_SUCCESS) {
367 1.1 christos group = (struct group_object *)0;
368 1.1 christos if (group_name_hash &&
369 1.1 christos group_hash_lookup (&group, group_name_hash,
370 1.1 christos (const char *)
371 1.1 christos tv -> value -> u.buffer.value,
372 1.1 christos tv -> value -> u.buffer.len, MDL)) {
373 1.1 christos omapi_value_dereference (&tv, MDL);
374 1.1 christos
375 1.1 christos if (*lp && *lp != (omapi_object_t *)group) {
376 1.1 christos group_object_dereference (&group, MDL);
377 1.1 christos omapi_object_dereference (lp, MDL);
378 1.1 christos return DHCP_R_KEYCONFLICT;
379 1.1 christos } else if (!*lp) {
380 1.1 christos /* XXX fix so that hash lookup itself creates
381 1.1 christos XXX the reference. */
382 1.1 christos omapi_object_reference (lp,
383 1.1 christos (omapi_object_t *)group,
384 1.1 christos MDL);
385 1.1 christos group_object_dereference (&group, MDL);
386 1.1 christos }
387 1.1 christos } else if (!*lp)
388 1.1 christos return ISC_R_NOTFOUND;
389 1.1 christos }
390 1.1 christos
391 1.1 christos /* If we get to here without finding a group, no valid key was
392 1.1 christos specified. */
393 1.1 christos if (!*lp)
394 1.1 christos return DHCP_R_NOKEYS;
395 1.1 christos
396 1.1 christos if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) {
397 1.1 christos omapi_object_dereference (lp, MDL);
398 1.1 christos return ISC_R_NOTFOUND;
399 1.1 christos }
400 1.1 christos return ISC_R_SUCCESS;
401 1.1 christos }
402 1.1 christos
403 1.1 christos isc_result_t dhcp_group_create (omapi_object_t **lp,
404 1.1 christos omapi_object_t *id)
405 1.1 christos {
406 1.1 christos struct group_object *group;
407 1.1 christos isc_result_t status;
408 1.1 christos group = (struct group_object *)0;
409 1.1 christos
410 1.1 christos status = group_object_allocate (&group, MDL);
411 1.1 christos if (status != ISC_R_SUCCESS)
412 1.1 christos return status;
413 1.1 christos group -> flags = GROUP_OBJECT_DYNAMIC;
414 1.1 christos status = omapi_object_reference (lp, (omapi_object_t *)group, MDL);
415 1.1 christos group_object_dereference (&group, MDL);
416 1.1 christos return status;
417 1.1 christos }
418 1.1 christos
419 1.1 christos isc_result_t dhcp_group_remove (omapi_object_t *lp,
420 1.1 christos omapi_object_t *id)
421 1.1 christos {
422 1.1 christos struct group_object *group;
423 1.1 christos isc_result_t status;
424 1.1 christos if (lp -> type != dhcp_type_group)
425 1.1 christos return DHCP_R_INVALIDARG;
426 1.1 christos group = (struct group_object *)lp;
427 1.1 christos
428 1.1 christos group -> flags |= GROUP_OBJECT_DELETED;
429 1.1 christos if (group_write_hook) {
430 1.1 christos if (!(*group_write_hook) (group))
431 1.1 christos return ISC_R_IOERROR;
432 1.1 christos }
433 1.1 christos
434 1.1 christos status = dhcp_group_destroy ((omapi_object_t *)group, MDL);
435 1.1 christos
436 1.1 christos return status;
437 1.1 christos }
438 1.1 christos
439 1.1 christos isc_result_t dhcp_control_set_value (omapi_object_t *h,
440 1.1 christos omapi_object_t *id,
441 1.1 christos omapi_data_string_t *name,
442 1.1 christos omapi_typed_data_t *value)
443 1.1 christos {
444 1.1 christos dhcp_control_object_t *control;
445 1.1 christos isc_result_t status;
446 1.1 christos unsigned long newstate;
447 1.1 christos
448 1.1 christos if (h -> type != dhcp_type_control)
449 1.1 christos return DHCP_R_INVALIDARG;
450 1.1 christos control = (dhcp_control_object_t *)h;
451 1.1 christos
452 1.1 christos if (!omapi_ds_strcmp (name, "state")) {
453 1.1 christos status = omapi_get_int_value (&newstate, value);
454 1.1 christos if (status != ISC_R_SUCCESS)
455 1.1 christos return status;
456 1.1 christos status = dhcp_set_control_state (control -> state, newstate);
457 1.1 christos if (status == ISC_R_SUCCESS)
458 1.1 christos control -> state = value -> u.integer;
459 1.1 christos return status;
460 1.1 christos }
461 1.1 christos
462 1.1 christos /* Try to find some inner object that can take the value. */
463 1.1 christos if (h -> inner && h -> inner -> type -> set_value) {
464 1.1 christos status = ((*(h -> inner -> type -> set_value))
465 1.1 christos (h -> inner, id, name, value));
466 1.1 christos if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
467 1.1 christos return status;
468 1.1 christos }
469 1.1 christos
470 1.1 christos return ISC_R_NOTFOUND;
471 1.1 christos }
472 1.1 christos
473 1.1 christos
474 1.1 christos isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id,
475 1.1 christos omapi_data_string_t *name,
476 1.1 christos omapi_value_t **value)
477 1.1 christos {
478 1.1 christos dhcp_control_object_t *control;
479 1.1 christos isc_result_t status;
480 1.1 christos
481 1.1 christos if (h -> type != dhcp_type_control)
482 1.1 christos return DHCP_R_INVALIDARG;
483 1.1 christos control = (dhcp_control_object_t *)h;
484 1.1 christos
485 1.1 christos if (!omapi_ds_strcmp (name, "state"))
486 1.1 christos return omapi_make_int_value (value,
487 1.1 christos name, (int)control -> state, MDL);
488 1.1 christos
489 1.1 christos /* Try to find some inner object that can take the value. */
490 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
491 1.1 christos status = ((*(h -> inner -> type -> get_value))
492 1.1 christos (h -> inner, id, name, value));
493 1.1 christos if (status == ISC_R_SUCCESS)
494 1.1 christos return status;
495 1.1 christos }
496 1.1 christos return ISC_R_NOTFOUND;
497 1.1 christos }
498 1.1 christos
499 1.1 christos isc_result_t dhcp_control_destroy (omapi_object_t *h,
500 1.1 christos const char *file, int line)
501 1.1 christos {
502 1.1 christos if (h -> type != dhcp_type_control)
503 1.1 christos return DHCP_R_INVALIDARG;
504 1.1 christos
505 1.1 christos /* Can't destroy the control object. */
506 1.1 christos return ISC_R_NOPERM;
507 1.1 christos }
508 1.1 christos
509 1.1 christos isc_result_t dhcp_control_signal_handler (omapi_object_t *h,
510 1.1 christos const char *name, va_list ap)
511 1.1 christos {
512 1.1 christos /* In this function h should be a (dhcp_control_object_t *) */
513 1.1 christos
514 1.1 christos isc_result_t status;
515 1.1 christos
516 1.1 christos if (h -> type != dhcp_type_control)
517 1.1 christos return DHCP_R_INVALIDARG;
518 1.1 christos
519 1.1 christos /* Try to find some inner object that can take the value. */
520 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
521 1.1 christos status = ((*(h -> inner -> type -> signal_handler))
522 1.1 christos (h -> inner, name, ap));
523 1.1 christos if (status == ISC_R_SUCCESS)
524 1.1 christos return status;
525 1.1 christos }
526 1.1 christos return ISC_R_NOTFOUND;
527 1.1 christos }
528 1.1 christos
529 1.1 christos isc_result_t dhcp_control_stuff_values (omapi_object_t *c,
530 1.1 christos omapi_object_t *id,
531 1.1 christos omapi_object_t *h)
532 1.1 christos {
533 1.1 christos dhcp_control_object_t *control;
534 1.1 christos isc_result_t status;
535 1.1 christos
536 1.1 christos if (h -> type != dhcp_type_control)
537 1.1 christos return DHCP_R_INVALIDARG;
538 1.1 christos control = (dhcp_control_object_t *)h;
539 1.1 christos
540 1.1 christos /* Write out all the values. */
541 1.1 christos status = omapi_connection_put_name (c, "state");
542 1.1 christos if (status != ISC_R_SUCCESS)
543 1.1 christos return status;
544 1.1 christos status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
545 1.1 christos if (status != ISC_R_SUCCESS)
546 1.1 christos return status;
547 1.1 christos status = omapi_connection_put_uint32 (c, control -> state);
548 1.1 christos if (status != ISC_R_SUCCESS)
549 1.1 christos return status;
550 1.1 christos
551 1.1 christos /* Write out the inner object, if any. */
552 1.1 christos if (h -> inner && h -> inner -> type -> stuff_values) {
553 1.1 christos status = ((*(h -> inner -> type -> stuff_values))
554 1.1 christos (c, id, h -> inner));
555 1.1 christos if (status == ISC_R_SUCCESS)
556 1.1 christos return status;
557 1.1 christos }
558 1.1 christos
559 1.1 christos return ISC_R_SUCCESS;
560 1.1 christos }
561 1.1 christos
562 1.1 christos isc_result_t dhcp_control_lookup (omapi_object_t **lp,
563 1.1 christos omapi_object_t *id, omapi_object_t *ref)
564 1.1 christos {
565 1.1 christos omapi_value_t *tv = (omapi_value_t *)0;
566 1.1 christos isc_result_t status;
567 1.1 christos
568 1.1 christos /* First see if we were sent a handle. */
569 1.1 christos if (ref) {
570 1.1 christos status = omapi_get_value_str (ref, id, "handle", &tv);
571 1.1 christos if (status == ISC_R_SUCCESS) {
572 1.1 christos status = omapi_handle_td_lookup (lp, tv -> value);
573 1.1 christos
574 1.1 christos omapi_value_dereference (&tv, MDL);
575 1.1 christos if (status != ISC_R_SUCCESS)
576 1.1 christos return status;
577 1.1 christos
578 1.1 christos /* Don't return the object if the type is wrong. */
579 1.1 christos if ((*lp) -> type != dhcp_type_control) {
580 1.1 christos omapi_object_dereference (lp, MDL);
581 1.1 christos return DHCP_R_INVALIDARG;
582 1.1 christos }
583 1.1 christos }
584 1.1 christos }
585 1.1 christos
586 1.1 christos /* Otherwise, stop playing coy - there's only one control object,
587 1.1 christos so we can just return it. */
588 1.1 christos dhcp_control_reference ((dhcp_control_object_t **)lp,
589 1.1 christos dhcp_control_object, MDL);
590 1.1 christos return ISC_R_SUCCESS;
591 1.1 christos }
592 1.1 christos
593 1.1 christos isc_result_t dhcp_control_create (omapi_object_t **lp,
594 1.1 christos omapi_object_t *id)
595 1.1 christos {
596 1.1 christos /* Can't create a control object - there can be only one. */
597 1.1 christos return ISC_R_NOPERM;
598 1.1 christos }
599 1.1 christos
600 1.1 christos isc_result_t dhcp_control_remove (omapi_object_t *lp,
601 1.1 christos omapi_object_t *id)
602 1.1 christos {
603 1.1 christos /* Form is emptiness; emptiness form. The control object
604 1.1 christos cannot go out of existance. */
605 1.1 christos return ISC_R_NOPERM;
606 1.1 christos }
607 1.1 christos
608 1.1 christos isc_result_t dhcp_subnet_set_value (omapi_object_t *h,
609 1.1 christos omapi_object_t *id,
610 1.1 christos omapi_data_string_t *name,
611 1.1 christos omapi_typed_data_t *value)
612 1.1 christos {
613 1.1 christos /* In this function h should be a (struct subnet *) */
614 1.1 christos
615 1.1 christos isc_result_t status;
616 1.1 christos
617 1.1 christos if (h -> type != dhcp_type_subnet)
618 1.1 christos return DHCP_R_INVALIDARG;
619 1.1 christos
620 1.1 christos /* No values to set yet. */
621 1.1 christos
622 1.1 christos /* Try to find some inner object that can take the value. */
623 1.1 christos if (h -> inner && h -> inner -> type -> set_value) {
624 1.1 christos status = ((*(h -> inner -> type -> set_value))
625 1.1 christos (h -> inner, id, name, value));
626 1.1 christos if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
627 1.1 christos return status;
628 1.1 christos }
629 1.1 christos
630 1.1 christos return ISC_R_NOTFOUND;
631 1.1 christos }
632 1.1 christos
633 1.1 christos
634 1.1 christos isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id,
635 1.1 christos omapi_data_string_t *name,
636 1.1 christos omapi_value_t **value)
637 1.1 christos {
638 1.1 christos /* In this function h should be a (struct subnet *) */
639 1.1 christos
640 1.1 christos isc_result_t status;
641 1.1 christos
642 1.1 christos if (h -> type != dhcp_type_subnet)
643 1.1 christos return DHCP_R_INVALIDARG;
644 1.1 christos
645 1.1 christos /* No values to get yet. */
646 1.1 christos
647 1.1 christos /* Try to find some inner object that can provide the value. */
648 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
649 1.1 christos status = ((*(h -> inner -> type -> get_value))
650 1.1 christos (h -> inner, id, name, value));
651 1.1 christos if (status == ISC_R_SUCCESS)
652 1.1 christos return status;
653 1.1 christos }
654 1.1 christos return ISC_R_NOTFOUND;
655 1.1 christos }
656 1.1 christos
657 1.1 christos isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line)
658 1.1 christos {
659 1.1 christos struct subnet *subnet;
660 1.1 christos
661 1.1 christos if (h -> type != dhcp_type_subnet)
662 1.1 christos return DHCP_R_INVALIDARG;
663 1.1 christos
664 1.1 christos subnet = (struct subnet *)h;
665 1.1 christos if (subnet -> next_subnet)
666 1.1 christos subnet_dereference (&subnet -> next_subnet, file, line);
667 1.1 christos if (subnet -> next_sibling)
668 1.1 christos subnet_dereference (&subnet -> next_sibling, file, line);
669 1.1 christos if (subnet -> shared_network)
670 1.1 christos shared_network_dereference (&subnet -> shared_network,
671 1.1 christos file, line);
672 1.1 christos if (subnet -> interface)
673 1.1 christos interface_dereference (&subnet -> interface, file, line);
674 1.1 christos if (subnet -> group)
675 1.1 christos group_dereference (&subnet -> group, file, line);
676 1.1 christos
677 1.1 christos return ISC_R_SUCCESS;
678 1.1 christos }
679 1.1 christos
680 1.1 christos isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h,
681 1.1 christos const char *name, va_list ap)
682 1.1 christos {
683 1.1 christos /* In this function h should be a (struct subnet *) */
684 1.1 christos
685 1.1 christos isc_result_t status;
686 1.1 christos
687 1.1 christos if (h -> type != dhcp_type_subnet)
688 1.1 christos return DHCP_R_INVALIDARG;
689 1.1 christos
690 1.1 christos /* Can't write subnets yet. */
691 1.1 christos
692 1.1 christos /* Try to find some inner object that can take the value. */
693 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
694 1.1 christos status = ((*(h -> inner -> type -> signal_handler))
695 1.1 christos (h -> inner, name, ap));
696 1.1 christos if (status == ISC_R_SUCCESS)
697 1.1 christos return status;
698 1.1 christos }
699 1.1 christos
700 1.1 christos return ISC_R_NOTFOUND;
701 1.1 christos }
702 1.1 christos
703 1.1 christos isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c,
704 1.1 christos omapi_object_t *id,
705 1.1 christos omapi_object_t *h)
706 1.1 christos {
707 1.1 christos /* In this function h should be a (struct subnet *) */
708 1.1 christos
709 1.1 christos isc_result_t status;
710 1.1 christos
711 1.1 christos if (h -> type != dhcp_type_subnet)
712 1.1 christos return DHCP_R_INVALIDARG;
713 1.1 christos
714 1.1 christos /* Can't stuff subnet values yet. */
715 1.1 christos
716 1.1 christos /* Write out the inner object, if any. */
717 1.1 christos if (h -> inner && h -> inner -> type -> stuff_values) {
718 1.1 christos status = ((*(h -> inner -> type -> stuff_values))
719 1.1 christos (c, id, h -> inner));
720 1.1 christos if (status == ISC_R_SUCCESS)
721 1.1 christos return status;
722 1.1 christos }
723 1.1 christos
724 1.1 christos return ISC_R_SUCCESS;
725 1.1 christos }
726 1.1 christos
727 1.1 christos isc_result_t dhcp_subnet_lookup (omapi_object_t **lp,
728 1.1 christos omapi_object_t *id,
729 1.1 christos omapi_object_t *ref)
730 1.1 christos {
731 1.1 christos /* Can't look up subnets yet. */
732 1.1 christos
733 1.1 christos /* If we get to here without finding a subnet, no valid key was
734 1.1 christos specified. */
735 1.1 christos if (!*lp)
736 1.1 christos return DHCP_R_NOKEYS;
737 1.1 christos return ISC_R_SUCCESS;
738 1.1 christos }
739 1.1 christos
740 1.1 christos isc_result_t dhcp_subnet_create (omapi_object_t **lp,
741 1.1 christos omapi_object_t *id)
742 1.1 christos {
743 1.1 christos return ISC_R_NOTIMPLEMENTED;
744 1.1 christos }
745 1.1 christos
746 1.1 christos isc_result_t dhcp_subnet_remove (omapi_object_t *lp,
747 1.1 christos omapi_object_t *id)
748 1.1 christos {
749 1.1 christos return ISC_R_NOTIMPLEMENTED;
750 1.1 christos }
751 1.1 christos
752 1.1 christos isc_result_t dhcp_shared_network_set_value (omapi_object_t *h,
753 1.1 christos omapi_object_t *id,
754 1.1 christos omapi_data_string_t *name,
755 1.1 christos omapi_typed_data_t *value)
756 1.1 christos {
757 1.1 christos /* In this function h should be a (struct shared_network *) */
758 1.1 christos
759 1.1 christos isc_result_t status;
760 1.1 christos
761 1.1 christos if (h -> type != dhcp_type_shared_network)
762 1.1 christos return DHCP_R_INVALIDARG;
763 1.1 christos
764 1.1 christos /* No values to set yet. */
765 1.1 christos
766 1.1 christos /* Try to find some inner object that can take the value. */
767 1.1 christos if (h -> inner && h -> inner -> type -> set_value) {
768 1.1 christos status = ((*(h -> inner -> type -> set_value))
769 1.1 christos (h -> inner, id, name, value));
770 1.1 christos if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED)
771 1.1 christos return status;
772 1.1 christos }
773 1.1 christos
774 1.1 christos return ISC_R_NOTFOUND;
775 1.1 christos }
776 1.1 christos
777 1.1 christos
778 1.1 christos isc_result_t dhcp_shared_network_get_value (omapi_object_t *h,
779 1.1 christos omapi_object_t *id,
780 1.1 christos omapi_data_string_t *name,
781 1.1 christos omapi_value_t **value)
782 1.1 christos {
783 1.1 christos /* In this function h should be a (struct shared_network *) */
784 1.1 christos
785 1.1 christos isc_result_t status;
786 1.1 christos
787 1.1 christos if (h -> type != dhcp_type_shared_network)
788 1.1 christos return DHCP_R_INVALIDARG;
789 1.1 christos
790 1.1 christos /* No values to get yet. */
791 1.1 christos
792 1.1 christos /* Try to find some inner object that can provide the value. */
793 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
794 1.1 christos status = ((*(h -> inner -> type -> get_value))
795 1.1 christos (h -> inner, id, name, value));
796 1.1 christos if (status == ISC_R_SUCCESS)
797 1.1 christos return status;
798 1.1 christos }
799 1.1 christos return ISC_R_NOTFOUND;
800 1.1 christos }
801 1.1 christos
802 1.1 christos isc_result_t dhcp_shared_network_destroy (omapi_object_t *h,
803 1.1 christos const char *file, int line)
804 1.1 christos {
805 1.1 christos /* In this function h should be a (struct shared_network *) */
806 1.1 christos
807 1.1 christos struct shared_network *shared_network;
808 1.1 christos
809 1.1 christos if (h -> type != dhcp_type_shared_network)
810 1.1 christos return DHCP_R_INVALIDARG;
811 1.1 christos
812 1.1 christos shared_network = (struct shared_network *)h;
813 1.1 christos if (shared_network -> next)
814 1.1 christos shared_network_dereference (&shared_network -> next,
815 1.1 christos file, line);
816 1.1 christos if (shared_network -> name) {
817 1.1 christos dfree (shared_network -> name, file, line);
818 1.1 christos shared_network -> name = 0;
819 1.1 christos }
820 1.1 christos if (shared_network -> subnets)
821 1.1 christos subnet_dereference (&shared_network -> subnets, file, line);
822 1.1 christos if (shared_network -> interface)
823 1.1 christos interface_dereference (&shared_network -> interface,
824 1.1 christos file, line);
825 1.1 christos if (shared_network -> pools)
826 1.1 christos omapi_object_dereference ((omapi_object_t **)
827 1.1 christos &shared_network -> pools, file, line);
828 1.1 christos if (shared_network -> group)
829 1.1 christos group_dereference (&shared_network -> group, file, line);
830 1.1 christos #if defined (FAILOVER_PROTOCOL)
831 1.1 christos if (shared_network -> failover_peer)
832 1.1 christos omapi_object_dereference ((omapi_object_t **)
833 1.1 christos &shared_network -> failover_peer,
834 1.1 christos file, line);
835 1.1 christos #endif
836 1.1 christos
837 1.1 christos return ISC_R_SUCCESS;
838 1.1 christos }
839 1.1 christos
840 1.1 christos isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h,
841 1.1 christos const char *name,
842 1.1 christos va_list ap)
843 1.1 christos {
844 1.1 christos /* In this function h should be a (struct shared_network *) */
845 1.1 christos
846 1.1 christos isc_result_t status;
847 1.1 christos
848 1.1 christos if (h -> type != dhcp_type_shared_network)
849 1.1 christos return DHCP_R_INVALIDARG;
850 1.1 christos
851 1.1 christos /* Can't write shared_networks yet. */
852 1.1 christos
853 1.1 christos /* Try to find some inner object that can take the value. */
854 1.1 christos if (h -> inner && h -> inner -> type -> get_value) {
855 1.1 christos status = ((*(h -> inner -> type -> signal_handler))
856 1.1 christos (h -> inner, name, ap));
857 1.1 christos if (status == ISC_R_SUCCESS)
858 1.1 christos return status;
859 1.1 christos }
860 1.1 christos
861 1.1 christos return ISC_R_NOTFOUND;
862 1.1 christos }
863 1.1 christos
864 1.1 christos isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c,
865 1.1 christos omapi_object_t *id,
866 1.1 christos omapi_object_t *h)
867 1.1 christos {
868 1.1 christos /* In this function h should be a (struct shared_network *) */
869 1.1 christos
870 1.1 christos isc_result_t status;
871 1.1 christos
872 1.1 christos if (h -> type != dhcp_type_shared_network)
873 1.1 christos return DHCP_R_INVALIDARG;
874 1.1 christos
875 1.1 christos /* Can't stuff shared_network values yet. */
876 1.1 christos
877 1.1 christos /* Write out the inner object, if any. */
878 1.1 christos if (h -> inner && h -> inner -> type -> stuff_values) {
879 1.1 christos status = ((*(h -> inner -> type -> stuff_values))
880 1.1 christos (c, id, h -> inner));
881 1.1 christos if (status == ISC_R_SUCCESS)
882 1.1 christos return status;
883 1.1 christos }
884 1.1 christos
885 1.1 christos return ISC_R_SUCCESS;
886 1.1 christos }
887 1.1 christos
888 1.1 christos isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp,
889 1.1 christos omapi_object_t *id,
890 1.1 christos omapi_object_t *ref)
891 1.1 christos {
892 1.1 christos /* Can't look up shared_networks yet. */
893 1.1 christos
894 1.1 christos /* If we get to here without finding a shared_network, no valid key was
895 1.1 christos specified. */
896 1.1 christos if (!*lp)
897 1.1 christos return DHCP_R_NOKEYS;
898 1.1 christos return ISC_R_SUCCESS;
899 1.1 christos }
900 1.1 christos
901 1.1 christos isc_result_t dhcp_shared_network_create (omapi_object_t **lp,
902 1.1 christos omapi_object_t *id)
903 1.1 christos {
904 1.1 christos return ISC_R_NOTIMPLEMENTED;
905 1.1 christos }
906 1.1 christos
907 1.1 christos isc_result_t dhcp_shared_network_remove (omapi_object_t *lp,
908 1.1 christos omapi_object_t *id)
909 1.1 christos {
910 1.1 christos return ISC_R_NOTIMPLEMENTED;
911 1.1 christos }
912 1.1 christos
913