use_mcd.h, use_scd.h no longer exist.
[dragonfly/vkernel-mp.git] / contrib / dhcp-3.0 / dhcpctl / dhcpctl.c
blobb596b751b32ca26e8b8459f952c98c32d2260809
1 /* dhcpctl.c
3 Subroutines providing general support for objects. */
5 /*
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1999-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
35 #ifndef lint
36 static char copyright[] =
37 "$Id: dhcpctl.c,v 1.22.2.7 2004/06/10 17:59:24 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
38 #endif /* not lint */
40 #include <omapip/omapip_p.h>
41 #include "dhcpctl.h"
43 omapi_object_type_t *dhcpctl_callback_type;
44 omapi_object_type_t *dhcpctl_remote_type;
46 /* dhcpctl_initialize ()
48 Must be called before any other dhcpctl function. */
50 dhcpctl_status dhcpctl_initialize ()
52 isc_result_t status;
54 status = omapi_init();
55 if (status != ISC_R_SUCCESS)
56 return status;
58 status = omapi_object_type_register (&dhcpctl_callback_type,
59 "dhcpctl-callback",
60 dhcpctl_callback_set_value,
61 dhcpctl_callback_get_value,
62 dhcpctl_callback_destroy,
63 dhcpctl_callback_signal_handler,
64 dhcpctl_callback_stuff_values,
65 0, 0, 0, 0, 0, 0,
66 sizeof
67 (dhcpctl_callback_object_t), 0,
68 RC_MISC);
69 if (status != ISC_R_SUCCESS)
70 return status;
72 status = omapi_object_type_register (&dhcpctl_remote_type,
73 "dhcpctl-remote",
74 dhcpctl_remote_set_value,
75 dhcpctl_remote_get_value,
76 dhcpctl_remote_destroy,
77 dhcpctl_remote_signal_handler,
78 dhcpctl_remote_stuff_values,
79 0, 0, 0, 0, 0, 0,
80 sizeof (dhcpctl_remote_object_t),
81 0, RC_MISC);
82 if (status != ISC_R_SUCCESS)
83 return status;
85 return ISC_R_SUCCESS;
88 /* dhcpctl_connect
90 synchronous
91 returns nonzero status code if it didn't connect, zero otherwise
92 stores connection handle through connection, which can be used
93 for subsequent access to the specified server.
94 server_name is the name of the server, and port is the TCP
95 port on which it is listening.
96 authinfo is the handle to an object containing authentication
97 information. */
99 dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
100 const char *server_name, int port,
101 dhcpctl_handle authinfo)
103 isc_result_t status;
104 dhcpctl_status waitstatus;
106 status = omapi_generic_new (connection, MDL);
107 if (status != ISC_R_SUCCESS) {
108 return status;
111 status = omapi_protocol_connect (*connection, server_name,
112 (unsigned)port, authinfo);
113 if (status == ISC_R_SUCCESS)
114 return status;
115 if (status != ISC_R_INCOMPLETE) {
116 omapi_object_dereference (connection, MDL);
117 return status;
120 status = omapi_wait_for_completion (*connection, 0);
121 if (status != ISC_R_SUCCESS) {
122 omapi_object_dereference (connection, MDL);
123 return status;
126 return status;
129 /* dhcpctl_wait_for_completion
131 synchronous
132 returns zero if the callback completes, a nonzero status if
133 there was some problem relating to the wait operation. The
134 status of the queued request will be stored through s, and
135 will also be either zero for success or nonzero for some kind
136 of failure. Never returns until completion or until the
137 connection to the server is lost. This performs the same
138 function as dhcpctl_set_callback and the subsequent callback,
139 for programs that want to do inline execution instead of using
140 callbacks. */
142 dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
143 dhcpctl_status *s)
145 isc_result_t status;
146 status = omapi_wait_for_completion (h, 0);
147 if (status != ISC_R_SUCCESS)
148 return status;
149 if (h -> type == dhcpctl_remote_type)
150 *s = ((dhcpctl_remote_object_t *)h) -> waitstatus;
151 return ISC_R_SUCCESS;
154 /* dhcpctl_get_value
156 synchronous
157 returns zero if the call succeeded, a nonzero status code if
158 it didn't.
159 result is the address of an empty data string (initialized
160 with bzero or cleared with data_string_forget). On
161 successful completion, the addressed data string will contain
162 the value that was fetched.
163 dhcpctl_handle refers to some dhcpctl item
164 value_name refers to some value related to that item - e.g.,
165 for a handle associated with a completed host lookup, value
166 could be one of "hardware-address", "dhcp-client-identifier",
167 "known" or "client-hostname". */
169 dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result,
170 dhcpctl_handle h, const char *value_name)
172 isc_result_t status;
173 omapi_value_t *tv = (omapi_value_t *)0;
174 omapi_data_string_t *value = (omapi_data_string_t *)0;
175 unsigned len;
176 int ip;
178 status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv);
179 if (status != ISC_R_SUCCESS)
180 return status;
182 switch (tv -> value -> type) {
183 case omapi_datatype_int:
184 len = sizeof (int);
185 break;
187 case omapi_datatype_string:
188 case omapi_datatype_data:
189 len = tv -> value -> u.buffer.len;
190 break;
192 case omapi_datatype_object:
193 len = sizeof (omapi_handle_t);
194 break;
196 default:
197 omapi_typed_data_dereference (&tv -> value, MDL);
198 return ISC_R_UNEXPECTED;
201 status = omapi_data_string_new (result, len, MDL);
202 if (status != ISC_R_SUCCESS) {
203 omapi_typed_data_dereference (&tv -> value, MDL);
204 return status;
207 switch (tv -> value -> type) {
208 case omapi_datatype_int:
209 ip = htonl (tv -> value -> u.integer);
210 memcpy ((*result) -> value, &ip, sizeof ip);
211 break;
213 case omapi_datatype_string:
214 case omapi_datatype_data:
215 memcpy ((*result) -> value,
216 tv -> value -> u.buffer.value,
217 tv -> value -> u.buffer.len);
218 break;
220 case omapi_datatype_object:
221 ip = htonl (tv -> value -> u.object -> handle);
222 memcpy ((*result) -> value, &ip, sizeof ip);
223 break;
226 omapi_value_dereference (&tv, MDL);
227 return ISC_R_SUCCESS;
230 /* dhcpctl_get_boolean
232 like dhcpctl_get_value, but more convenient for boolean
233 values, since no data_string needs to be dealt with. */
235 dhcpctl_status dhcpctl_get_boolean (int *result,
236 dhcpctl_handle h, const char *value_name)
238 isc_result_t status;
239 dhcpctl_data_string data = (dhcpctl_data_string)0;
240 int rv;
242 status = dhcpctl_get_value (&data, h, value_name);
243 if (status != ISC_R_SUCCESS)
244 return status;
245 if (data -> len != sizeof rv) {
246 omapi_data_string_dereference (&data, MDL);
247 return ISC_R_UNEXPECTED;
249 memcpy (&rv, data -> value, sizeof rv);
250 *result = ntohl (rv);
251 return ISC_R_SUCCESS;
254 /* dhcpctl_set_value
256 Sets a value on an object referred to by a dhcpctl_handle.
257 The opposite of dhcpctl_get_value. Does not update the
258 server - just sets the value on the handle. */
260 dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value,
261 const char *value_name)
263 isc_result_t status;
264 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
265 omapi_data_string_t *name = (omapi_data_string_t *)0;
266 int len;
268 status = omapi_data_string_new (&name, strlen (value_name), MDL);
269 if (status != ISC_R_SUCCESS)
270 return status;
271 memcpy (name -> value, value_name, strlen (value_name));
273 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_data,
274 value -> len);
275 if (status != ISC_R_SUCCESS) {
276 omapi_data_string_dereference (&name, MDL);
277 return status;
279 memcpy (tv -> u.buffer.value, value -> value, value -> len);
281 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
282 omapi_data_string_dereference (&name, MDL);
283 omapi_typed_data_dereference (&tv, MDL);
284 return status;
287 /* dhcpctl_set_string_value
289 Sets a NUL-terminated ASCII value on an object referred to by
290 a dhcpctl_handle. like dhcpctl_set_value, but saves the
291 trouble of creating a data_string for a NUL-terminated string.
292 Does not update the server - just sets the value on the handle. */
294 dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
295 const char *value_name)
297 isc_result_t status;
298 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
299 omapi_data_string_t *name = (omapi_data_string_t *)0;
300 int len;
302 status = omapi_data_string_new (&name, strlen (value_name), MDL);
303 if (status != ISC_R_SUCCESS)
304 return status;
305 memcpy (name -> value, value_name, strlen (value_name));
307 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
308 if (status != ISC_R_SUCCESS) {
309 omapi_data_string_dereference (&name, MDL);
310 return status;
313 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
314 omapi_data_string_dereference (&name, MDL);
315 omapi_typed_data_dereference (&tv, MDL);
316 return status;
319 /* dhcpctl_set_buffer_value
321 Sets a value on an object referred to by a dhcpctl_handle. like
322 dhcpctl_set_value, but saves the trouble of creating a data_string
323 for string for which we have a buffer and length. Does not update
324 the server - just sets the value on the handle. */
326 dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
327 const char *value, unsigned len,
328 const char *value_name)
330 isc_result_t status;
331 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
332 omapi_data_string_t *name = (omapi_data_string_t *)0;
333 unsigned ll;
335 ll = strlen (value_name);
336 status = omapi_data_string_new (&name, ll, MDL);
337 if (status != ISC_R_SUCCESS)
338 return status;
339 memcpy (name -> value, value_name, ll);
341 status = omapi_typed_data_new (MDL, &tv,
342 omapi_datatype_data, len, value);
343 if (status != ISC_R_SUCCESS) {
344 omapi_data_string_dereference (&name, MDL);
345 return status;
347 memcpy (tv -> u.buffer.value, value, len);
349 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
350 omapi_data_string_dereference (&name, MDL);
351 omapi_typed_data_dereference (&tv, MDL);
352 return status;
355 /* dhcpctl_set_null_value
357 Sets a null value on an object referred to by a dhcpctl_handle. */
359 dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h,
360 const char *value_name)
362 isc_result_t status;
363 omapi_data_string_t *name = (omapi_data_string_t *)0;
364 unsigned ll;
366 ll = strlen (value_name);
367 status = omapi_data_string_new (&name, ll, MDL);
368 if (status != ISC_R_SUCCESS)
369 return status;
370 memcpy (name -> value, value_name, ll);
372 status = omapi_set_value (h, (omapi_object_t *)0, name,
373 (omapi_typed_data_t *)0);
374 omapi_data_string_dereference (&name, MDL);
375 return status;
378 /* dhcpctl_set_boolean_value
380 Sets a boolean value on an object - like dhcpctl_set_value,
381 only more convenient for booleans. */
383 dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value,
384 const char *value_name)
386 isc_result_t status;
387 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
388 omapi_data_string_t *name = (omapi_data_string_t *)0;
389 int len;
391 status = omapi_data_string_new (&name, strlen (value_name), MDL);
392 if (status != ISC_R_SUCCESS)
393 return status;
394 memcpy (name -> value, value_name, strlen (value_name));
396 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
397 if (status != ISC_R_SUCCESS) {
398 omapi_data_string_dereference (&name, MDL);
399 return status;
402 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
403 omapi_data_string_dereference (&name, MDL);
404 omapi_typed_data_dereference (&tv, MDL);
405 return status;
408 /* dhcpctl_set_int_value
410 Sets a boolean value on an object - like dhcpctl_set_value,
411 only more convenient for booleans. */
413 dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
414 const char *value_name)
416 isc_result_t status;
417 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
418 omapi_data_string_t *name = (omapi_data_string_t *)0;
419 int len;
421 status = omapi_data_string_new (&name, strlen (value_name), MDL);
422 if (status != ISC_R_SUCCESS)
423 return status;
424 memcpy (name -> value, value_name, strlen (value_name));
426 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
427 if (status != ISC_R_SUCCESS) {
428 omapi_data_string_dereference (&name, MDL);
429 return status;
432 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
433 omapi_data_string_dereference (&name, MDL);
434 omapi_typed_data_dereference (&tv, MDL);
435 return status;
438 /* dhcpctl_object_update
440 Queues an update on the object referenced by the handle (there
441 can't be any other work in progress on the handle). An
442 update means local parameters will be sent to the server. */
444 dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection,
445 dhcpctl_handle h)
447 isc_result_t status;
448 omapi_object_t *message = (omapi_object_t *)0;
449 dhcpctl_remote_object_t *ro;
451 if (h -> type != dhcpctl_remote_type)
452 return ISC_R_INVALIDARG;
453 ro = (dhcpctl_remote_object_t *)h;
455 status = omapi_message_new (&message, MDL);
456 if (status != ISC_R_SUCCESS) {
457 omapi_object_dereference (&message, MDL);
458 return status;
460 status = omapi_set_int_value (message, (omapi_object_t *)0,
461 "op", OMAPI_OP_UPDATE);
462 if (status != ISC_R_SUCCESS) {
463 omapi_object_dereference (&message, MDL);
464 return status;
467 status = omapi_set_object_value (message, (omapi_object_t *)0,
468 "object", h);
469 if (status != ISC_R_SUCCESS) {
470 omapi_object_dereference (&message, MDL);
471 return status;
474 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
475 (int)(ro -> remote_handle));
476 if (status != ISC_R_SUCCESS) {
477 omapi_object_dereference (&message, MDL);
478 return status;
481 omapi_message_register (message);
482 status = omapi_protocol_send_message (connection -> outer,
483 (omapi_object_t *)0,
484 message, (omapi_object_t *)0);
485 omapi_object_dereference (&message, MDL);
486 return status;
489 /* Requests a refresh on the object referenced by the handle (there
490 can't be any other work in progress on the handle). A
491 refresh means local parameters are updated from the server. */
493 dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection,
494 dhcpctl_handle h)
496 isc_result_t status;
497 omapi_object_t *message = (omapi_object_t *)0;
498 dhcpctl_remote_object_t *ro;
500 if (h -> type != dhcpctl_remote_type)
501 return ISC_R_INVALIDARG;
502 ro = (dhcpctl_remote_object_t *)h;
504 status = omapi_message_new (&message, MDL);
505 if (status != ISC_R_SUCCESS) {
506 omapi_object_dereference (&message, MDL);
507 return status;
509 status = omapi_set_int_value (message, (omapi_object_t *)0,
510 "op", OMAPI_OP_REFRESH);
511 if (status != ISC_R_SUCCESS) {
512 omapi_object_dereference (&message, MDL);
513 return status;
515 status = omapi_set_int_value (message, (omapi_object_t *)0,
516 "handle", (int)(ro -> remote_handle));
517 if (status != ISC_R_SUCCESS) {
518 omapi_object_dereference (&message, MDL);
519 return status;
522 omapi_message_register (message);
523 status = omapi_protocol_send_message (connection -> outer,
524 (omapi_object_t *)0,
525 message, (omapi_object_t *)0);
527 /* We don't want to send the contents of the object down the
528 wire, but we do need to reference it so that we know what
529 to do with the update. */
530 status = omapi_set_object_value (message, (omapi_object_t *)0,
531 "object", h);
532 if (status != ISC_R_SUCCESS) {
533 omapi_object_dereference (&message, MDL);
534 return status;
537 omapi_object_dereference (&message, MDL);
538 return status;
541 /* Requests the removal of the object referenced by the handle (there
542 can't be any other work in progress on the handle). A
543 removal means that all searchable references to the object on the
544 server are deleted. */
546 dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection,
547 dhcpctl_handle h)
549 isc_result_t status;
550 omapi_object_t *message = (omapi_object_t *)0;
551 dhcpctl_remote_object_t *ro;
553 if (h -> type != dhcpctl_remote_type)
554 return ISC_R_INVALIDARG;
555 ro = (dhcpctl_remote_object_t *)h;
557 status = omapi_message_new (&message, MDL);
558 if (status != ISC_R_SUCCESS) {
559 omapi_object_dereference (&message, MDL);
560 return status;
562 status = omapi_set_int_value (message, (omapi_object_t *)0,
563 "op", OMAPI_OP_DELETE);
564 if (status != ISC_R_SUCCESS) {
565 omapi_object_dereference (&message, MDL);
566 return status;
569 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
570 (int)(ro -> remote_handle));
571 if (status != ISC_R_SUCCESS) {
572 omapi_object_dereference (&message, MDL);
573 return status;
576 status = omapi_set_object_value (message, (omapi_object_t *)0,
577 "notify-object", h);
578 if (status != ISC_R_SUCCESS) {
579 omapi_object_dereference (&message, MDL);
580 return status;
583 omapi_message_register (message);
584 status = omapi_protocol_send_message (connection -> outer,
585 (omapi_object_t *)0,
586 message, (omapi_object_t *)0);
587 omapi_object_dereference (&message, MDL);
588 return status;
591 isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *vp,
592 const char *file, int line)
594 return omapi_data_string_dereference (vp, file, line);