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