3 Subroutines providing general support for objects. */
6 * Copyright (c) 1999-2002 Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
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''.
44 #include <omapip/omapip_p.h>
47 omapi_object_type_t *dhcpctl_callback_type;
48 omapi_object_type_t *dhcpctl_remote_type;
50 /* dhcpctl_initialize ()
52 Must be called before any other dhcpctl function. */
54 dhcpctl_status dhcpctl_initialize ()
58 status = omapi_init();
59 if (status != ISC_R_SUCCESS)
62 status = omapi_object_type_register (&dhcpctl_callback_type,
64 dhcpctl_callback_set_value,
65 dhcpctl_callback_get_value,
66 dhcpctl_callback_destroy,
67 dhcpctl_callback_signal_handler,
68 dhcpctl_callback_stuff_values,
71 (dhcpctl_callback_object_t), 0,
73 if (status != ISC_R_SUCCESS)
76 status = omapi_object_type_register (&dhcpctl_remote_type,
78 dhcpctl_remote_set_value,
79 dhcpctl_remote_get_value,
80 dhcpctl_remote_destroy,
81 dhcpctl_remote_signal_handler,
82 dhcpctl_remote_stuff_values,
84 sizeof (dhcpctl_remote_object_t),
86 if (status != ISC_R_SUCCESS)
95 returns nonzero status code if it didn't connect, zero otherwise
96 stores connection handle through connection, which can be used
97 for subsequent access to the specified server.
98 server_name is the name of the server, and port is the TCP
99 port on which it is listening.
100 authinfo is the handle to an object containing authentication
103 dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
104 const char *server_name, int port,
105 dhcpctl_handle authinfo)
108 dhcpctl_status waitstatus;
110 status = omapi_generic_new (connection, MDL);
111 if (status != ISC_R_SUCCESS) {
115 status = omapi_protocol_connect (*connection, server_name,
116 (unsigned)port, authinfo);
117 if (status == ISC_R_SUCCESS)
119 if (status != ISC_R_INCOMPLETE) {
120 omapi_object_dereference (connection, MDL);
124 status = omapi_wait_for_completion (*connection, 0);
125 if (status != ISC_R_SUCCESS) {
126 omapi_object_dereference (connection, MDL);
133 /* dhcpctl_wait_for_completion
136 returns zero if the callback completes, a nonzero status if
137 there was some problem relating to the wait operation. The
138 status of the queued request will be stored through s, and
139 will also be either zero for success or nonzero for some kind
140 of failure. Never returns until completion or until the
141 connection to the server is lost. This performs the same
142 function as dhcpctl_set_callback and the subsequent callback,
143 for programs that want to do inline execution instead of using
146 dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
150 status = omapi_wait_for_completion (h, 0);
151 if (status != ISC_R_SUCCESS)
153 if (h -> type == dhcpctl_remote_type)
154 *s = ((dhcpctl_remote_object_t *)h) -> waitstatus;
155 return ISC_R_SUCCESS;
161 returns zero if the call succeeded, a nonzero status code if
163 result is the address of an empty data string (initialized
164 with bzero or cleared with data_string_forget). On
165 successful completion, the addressed data string will contain
166 the value that was fetched.
167 dhcpctl_handle refers to some dhcpctl item
168 value_name refers to some value related to that item - e.g.,
169 for a handle associated with a completed host lookup, value
170 could be one of "hardware-address", "dhcp-client-identifier",
171 "known" or "client-hostname". */
173 dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result,
174 dhcpctl_handle h, const char *value_name)
177 omapi_value_t *tv = (omapi_value_t *)0;
178 omapi_data_string_t *value = (omapi_data_string_t *)0;
182 status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv);
183 if (status != ISC_R_SUCCESS)
186 switch (tv -> value -> type) {
187 case omapi_datatype_int:
191 case omapi_datatype_string:
192 case omapi_datatype_data:
193 len = tv -> value -> u.buffer.len;
196 case omapi_datatype_object:
197 len = sizeof (omapi_handle_t);
201 omapi_typed_data_dereference (&tv -> value, MDL);
202 return ISC_R_UNEXPECTED;
205 status = omapi_data_string_new (result, len, MDL);
206 if (status != ISC_R_SUCCESS) {
207 omapi_typed_data_dereference (&tv -> value, MDL);
211 switch (tv -> value -> type) {
212 case omapi_datatype_int:
213 ip = htonl (tv -> value -> u.integer);
214 memcpy ((*result) -> value, &ip, sizeof ip);
217 case omapi_datatype_string:
218 case omapi_datatype_data:
219 memcpy ((*result) -> value,
220 tv -> value -> u.buffer.value,
221 tv -> value -> u.buffer.len);
224 case omapi_datatype_object:
225 ip = htonl (tv -> value -> u.object -> handle);
226 memcpy ((*result) -> value, &ip, sizeof ip);
230 omapi_value_dereference (&tv, MDL);
231 return ISC_R_SUCCESS;
234 /* dhcpctl_get_boolean
236 like dhcpctl_get_value, but more convenient for boolean
237 values, since no data_string needs to be dealt with. */
239 dhcpctl_status dhcpctl_get_boolean (int *result,
240 dhcpctl_handle h, const char *value_name)
243 dhcpctl_data_string data = (dhcpctl_data_string)0;
246 status = dhcpctl_get_value (&data, h, value_name);
247 if (status != ISC_R_SUCCESS)
249 if (data -> len != sizeof rv) {
250 omapi_data_string_dereference (&data, MDL);
251 return ISC_R_UNEXPECTED;
253 memcpy (&rv, data -> value, sizeof rv);
254 *result = ntohl (rv);
255 return ISC_R_SUCCESS;
260 Sets a value on an object referred to by a dhcpctl_handle.
261 The opposite of dhcpctl_get_value. Does not update the
262 server - just sets the value on the handle. */
264 dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value,
265 const char *value_name)
268 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
269 omapi_data_string_t *name = (omapi_data_string_t *)0;
272 status = omapi_data_string_new (&name, strlen (value_name), MDL);
273 if (status != ISC_R_SUCCESS)
275 memcpy (name -> value, value_name, strlen (value_name));
277 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_data,
279 if (status != ISC_R_SUCCESS) {
280 omapi_data_string_dereference (&name, MDL);
283 memcpy (tv -> u.buffer.value, value -> value, value -> len);
285 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
286 omapi_data_string_dereference (&name, MDL);
287 omapi_typed_data_dereference (&tv, MDL);
291 /* dhcpctl_set_string_value
293 Sets a NUL-terminated ASCII value on an object referred to by
294 a dhcpctl_handle. like dhcpctl_set_value, but saves the
295 trouble of creating a data_string for a NUL-terminated string.
296 Does not update the server - just sets the value on the handle. */
298 dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
299 const char *value_name)
302 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
303 omapi_data_string_t *name = (omapi_data_string_t *)0;
306 status = omapi_data_string_new (&name, strlen (value_name), MDL);
307 if (status != ISC_R_SUCCESS)
309 memcpy (name -> value, value_name, strlen (value_name));
311 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
312 if (status != ISC_R_SUCCESS) {
313 omapi_data_string_dereference (&name, MDL);
317 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
318 omapi_data_string_dereference (&name, MDL);
319 omapi_typed_data_dereference (&tv, MDL);
323 /* dhcpctl_set_buffer_value
325 Sets a value on an object referred to by a dhcpctl_handle. like
326 dhcpctl_set_value, but saves the trouble of creating a data_string
327 for string for which we have a buffer and length. Does not update
328 the server - just sets the value on the handle. */
330 dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
331 const char *value, unsigned len,
332 const char *value_name)
335 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
336 omapi_data_string_t *name = (omapi_data_string_t *)0;
339 ll = strlen (value_name);
340 status = omapi_data_string_new (&name, ll, MDL);
341 if (status != ISC_R_SUCCESS)
343 memcpy (name -> value, value_name, ll);
345 status = omapi_typed_data_new (MDL, &tv,
346 omapi_datatype_data, len, value);
347 if (status != ISC_R_SUCCESS) {
348 omapi_data_string_dereference (&name, MDL);
351 memcpy (tv -> u.buffer.value, value, len);
353 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
354 omapi_data_string_dereference (&name, MDL);
355 omapi_typed_data_dereference (&tv, MDL);
359 /* dhcpctl_set_null_value
361 Sets a null value on an object referred to by a dhcpctl_handle. */
363 dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h,
364 const char *value_name)
367 omapi_data_string_t *name = (omapi_data_string_t *)0;
370 ll = strlen (value_name);
371 status = omapi_data_string_new (&name, ll, MDL);
372 if (status != ISC_R_SUCCESS)
374 memcpy (name -> value, value_name, ll);
376 status = omapi_set_value (h, (omapi_object_t *)0, name,
377 (omapi_typed_data_t *)0);
378 omapi_data_string_dereference (&name, MDL);
382 /* dhcpctl_set_boolean_value
384 Sets a boolean value on an object - like dhcpctl_set_value,
385 only more convenient for booleans. */
387 dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value,
388 const char *value_name)
391 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
392 omapi_data_string_t *name = (omapi_data_string_t *)0;
395 status = omapi_data_string_new (&name, strlen (value_name), MDL);
396 if (status != ISC_R_SUCCESS)
398 memcpy (name -> value, value_name, strlen (value_name));
400 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
401 if (status != ISC_R_SUCCESS) {
402 omapi_data_string_dereference (&name, MDL);
406 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
407 omapi_data_string_dereference (&name, MDL);
408 omapi_typed_data_dereference (&tv, MDL);
412 /* dhcpctl_set_int_value
414 Sets a boolean value on an object - like dhcpctl_set_value,
415 only more convenient for booleans. */
417 dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
418 const char *value_name)
421 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
422 omapi_data_string_t *name = (omapi_data_string_t *)0;
425 status = omapi_data_string_new (&name, strlen (value_name), MDL);
426 if (status != ISC_R_SUCCESS)
428 memcpy (name -> value, value_name, strlen (value_name));
430 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
431 if (status != ISC_R_SUCCESS) {
432 omapi_data_string_dereference (&name, MDL);
436 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
437 omapi_data_string_dereference (&name, MDL);
438 omapi_typed_data_dereference (&tv, MDL);
442 /* dhcpctl_object_update
444 Queues an update on the object referenced by the handle (there
445 can't be any other work in progress on the handle). An
446 update means local parameters will be sent to the server. */
448 dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection,
452 omapi_object_t *message = (omapi_object_t *)0;
453 dhcpctl_remote_object_t *ro;
455 if (h -> type != dhcpctl_remote_type)
456 return ISC_R_INVALIDARG;
457 ro = (dhcpctl_remote_object_t *)h;
459 status = omapi_message_new (&message, MDL);
460 if (status != ISC_R_SUCCESS) {
461 omapi_object_dereference (&message, MDL);
464 status = omapi_set_int_value (message, (omapi_object_t *)0,
465 "op", OMAPI_OP_UPDATE);
466 if (status != ISC_R_SUCCESS) {
467 omapi_object_dereference (&message, MDL);
471 status = omapi_set_object_value (message, (omapi_object_t *)0,
473 if (status != ISC_R_SUCCESS) {
474 omapi_object_dereference (&message, MDL);
478 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
479 (int)(ro -> remote_handle));
480 if (status != ISC_R_SUCCESS) {
481 omapi_object_dereference (&message, MDL);
485 omapi_message_register (message);
486 status = omapi_protocol_send_message (connection -> outer,
488 message, (omapi_object_t *)0);
489 omapi_object_dereference (&message, MDL);
493 /* Requests a refresh on the object referenced by the handle (there
494 can't be any other work in progress on the handle). A
495 refresh means local parameters are updated from the server. */
497 dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection,
501 omapi_object_t *message = (omapi_object_t *)0;
502 dhcpctl_remote_object_t *ro;
504 if (h -> type != dhcpctl_remote_type)
505 return ISC_R_INVALIDARG;
506 ro = (dhcpctl_remote_object_t *)h;
508 status = omapi_message_new (&message, MDL);
509 if (status != ISC_R_SUCCESS) {
510 omapi_object_dereference (&message, MDL);
513 status = omapi_set_int_value (message, (omapi_object_t *)0,
514 "op", OMAPI_OP_REFRESH);
515 if (status != ISC_R_SUCCESS) {
516 omapi_object_dereference (&message, MDL);
519 status = omapi_set_int_value (message, (omapi_object_t *)0,
520 "handle", (int)(ro -> remote_handle));
521 if (status != ISC_R_SUCCESS) {
522 omapi_object_dereference (&message, MDL);
526 omapi_message_register (message);
527 status = omapi_protocol_send_message (connection -> outer,
529 message, (omapi_object_t *)0);
531 /* We don't want to send the contents of the object down the
532 wire, but we do need to reference it so that we know what
533 to do with the update. */
534 status = omapi_set_object_value (message, (omapi_object_t *)0,
536 if (status != ISC_R_SUCCESS) {
537 omapi_object_dereference (&message, MDL);
541 omapi_object_dereference (&message, MDL);
545 /* Requests the removal of the object referenced by the handle (there
546 can't be any other work in progress on the handle). A
547 removal means that all searchable references to the object on the
548 server are deleted. */
550 dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection,
554 omapi_object_t *message = (omapi_object_t *)0;
555 dhcpctl_remote_object_t *ro;
557 if (h -> type != dhcpctl_remote_type)
558 return ISC_R_INVALIDARG;
559 ro = (dhcpctl_remote_object_t *)h;
561 status = omapi_message_new (&message, MDL);
562 if (status != ISC_R_SUCCESS) {
563 omapi_object_dereference (&message, MDL);
566 status = omapi_set_int_value (message, (omapi_object_t *)0,
567 "op", OMAPI_OP_DELETE);
568 if (status != ISC_R_SUCCESS) {
569 omapi_object_dereference (&message, MDL);
573 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
574 (int)(ro -> remote_handle));
575 if (status != ISC_R_SUCCESS) {
576 omapi_object_dereference (&message, MDL);
580 status = omapi_set_object_value (message, (omapi_object_t *)0,
582 if (status != ISC_R_SUCCESS) {
583 omapi_object_dereference (&message, MDL);
587 omapi_message_register (message);
588 status = omapi_protocol_send_message (connection -> outer,
590 message, (omapi_object_t *)0);
591 omapi_object_dereference (&message, MDL);
595 isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *vp,
596 const char *file, int line)
598 return omapi_data_string_dereference (vp, file, line);