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