Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / dhcp / dhcpctl / dhcpctl.c
blob8211d1834d525d3493fe7140ffd6d4407d7c51f5
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.5 2005/08/11 17:13:21 drochner 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;
105 status = omapi_generic_new (connection, MDL);
106 if (status != ISC_R_SUCCESS) {
107 return status;
110 status = omapi_protocol_connect (*connection, server_name,
111 (unsigned)port, authinfo);
112 if (status == ISC_R_SUCCESS)
113 return status;
114 if (status != ISC_R_INCOMPLETE) {
115 omapi_object_dereference (connection, MDL);
116 return status;
119 status = omapi_wait_for_completion (*connection, 0);
120 if (status != ISC_R_SUCCESS) {
121 omapi_object_dereference (connection, MDL);
122 return status;
125 return status;
128 /* dhcpctl_wait_for_completion
130 synchronous
131 returns zero if the callback completes, a nonzero status if
132 there was some problem relating to the wait operation. The
133 status of the queued request will be stored through s, and
134 will also be either zero for success or nonzero for some kind
135 of failure. Never returns until completion or until the
136 connection to the server is lost. This performs the same
137 function as dhcpctl_set_callback and the subsequent callback,
138 for programs that want to do inline execution instead of using
139 callbacks. */
141 dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
142 dhcpctl_status *s)
144 isc_result_t status;
145 status = omapi_wait_for_completion (h, 0);
146 if (status != ISC_R_SUCCESS)
147 return status;
148 if (h -> type == dhcpctl_remote_type)
149 *s = ((dhcpctl_remote_object_t *)h) -> waitstatus;
150 return ISC_R_SUCCESS;
153 /* dhcpctl_get_value
155 synchronous
156 returns zero if the call succeeded, a nonzero status code if
157 it didn't.
158 result is the address of an empty data string (initialized
159 with bzero or cleared with data_string_forget). On
160 successful completion, the addressed data string will contain
161 the value that was fetched.
162 dhcpctl_handle refers to some dhcpctl item
163 value_name refers to some value related to that item - e.g.,
164 for a handle associated with a completed host lookup, value
165 could be one of "hardware-address", "dhcp-client-identifier",
166 "known" or "client-hostname". */
168 dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result,
169 dhcpctl_handle h, const char *value_name)
171 isc_result_t status;
172 omapi_value_t *tv = (omapi_value_t *)0;
173 unsigned len;
174 int ip;
176 status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv);
177 if (status != ISC_R_SUCCESS)
178 return status;
180 switch (tv -> value -> type) {
181 case omapi_datatype_int:
182 len = sizeof (int);
183 break;
185 case omapi_datatype_string:
186 case omapi_datatype_data:
187 len = tv -> value -> u.buffer.len;
188 break;
190 case omapi_datatype_object:
191 len = sizeof (omapi_handle_t);
192 break;
194 default:
195 omapi_typed_data_dereference (&tv -> value, MDL);
196 return ISC_R_UNEXPECTED;
199 status = omapi_data_string_new (result, len, MDL);
200 if (status != ISC_R_SUCCESS) {
201 omapi_typed_data_dereference (&tv -> value, MDL);
202 return status;
205 switch (tv -> value -> type) {
206 case omapi_datatype_int:
207 ip = htonl (tv -> value -> u.integer);
208 memcpy ((*result) -> value, &ip, sizeof ip);
209 break;
211 case omapi_datatype_string:
212 case omapi_datatype_data:
213 memcpy ((*result) -> value,
214 tv -> value -> u.buffer.value,
215 tv -> value -> u.buffer.len);
216 break;
218 case omapi_datatype_object:
219 ip = htonl (tv -> value -> u.object -> handle);
220 memcpy ((*result) -> value, &ip, sizeof ip);
221 break;
224 omapi_value_dereference (&tv, MDL);
225 return ISC_R_SUCCESS;
228 /* dhcpctl_get_boolean
230 like dhcpctl_get_value, but more convenient for boolean
231 values, since no data_string needs to be dealt with. */
233 dhcpctl_status dhcpctl_get_boolean (int *result,
234 dhcpctl_handle h, const char *value_name)
236 isc_result_t status;
237 dhcpctl_data_string data = (dhcpctl_data_string)0;
238 int rv;
240 status = dhcpctl_get_value (&data, h, value_name);
241 if (status != ISC_R_SUCCESS)
242 return status;
243 if (data -> len != sizeof rv) {
244 omapi_data_string_dereference (&data, MDL);
245 return ISC_R_UNEXPECTED;
247 memcpy (&rv, data -> value, sizeof rv);
248 *result = ntohl (rv);
249 return ISC_R_SUCCESS;
252 /* dhcpctl_set_value
254 Sets a value on an object referred to by a dhcpctl_handle.
255 The opposite of dhcpctl_get_value. Does not update the
256 server - just sets the value on the handle. */
258 dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value,
259 const char *value_name)
261 isc_result_t status;
262 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
263 omapi_data_string_t *name = (omapi_data_string_t *)0;
265 status = omapi_data_string_new (&name, strlen (value_name), MDL);
266 if (status != ISC_R_SUCCESS)
267 return status;
268 memcpy (name -> value, value_name, strlen (value_name));
270 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_data,
271 value -> len);
272 if (status != ISC_R_SUCCESS) {
273 omapi_data_string_dereference (&name, MDL);
274 return status;
276 memcpy (tv -> u.buffer.value, value -> value, value -> len);
278 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
279 omapi_data_string_dereference (&name, MDL);
280 omapi_typed_data_dereference (&tv, MDL);
281 return status;
284 /* dhcpctl_set_string_value
286 Sets a NUL-terminated ASCII value on an object referred to by
287 a dhcpctl_handle. like dhcpctl_set_value, but saves the
288 trouble of creating a data_string for a NUL-terminated string.
289 Does not update the server - just sets the value on the handle. */
291 dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
292 const char *value_name)
294 isc_result_t status;
295 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
296 omapi_data_string_t *name = (omapi_data_string_t *)0;
298 status = omapi_data_string_new (&name, strlen (value_name), MDL);
299 if (status != ISC_R_SUCCESS)
300 return status;
301 memcpy (name -> value, value_name, strlen (value_name));
303 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
304 if (status != ISC_R_SUCCESS) {
305 omapi_data_string_dereference (&name, MDL);
306 return status;
309 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
310 omapi_data_string_dereference (&name, MDL);
311 omapi_typed_data_dereference (&tv, MDL);
312 return status;
315 /* dhcpctl_set_buffer_value
317 Sets a value on an object referred to by a dhcpctl_handle. like
318 dhcpctl_set_value, but saves the trouble of creating a data_string
319 for string for which we have a buffer and length. Does not update
320 the server - just sets the value on the handle. */
322 dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
323 const char *value, unsigned len,
324 const char *value_name)
326 isc_result_t status;
327 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
328 omapi_data_string_t *name = (omapi_data_string_t *)0;
329 unsigned ll;
331 ll = strlen (value_name);
332 status = omapi_data_string_new (&name, ll, MDL);
333 if (status != ISC_R_SUCCESS)
334 return status;
335 memcpy (name -> value, value_name, ll);
337 status = omapi_typed_data_new (MDL, &tv,
338 omapi_datatype_data, len, value);
339 if (status != ISC_R_SUCCESS) {
340 omapi_data_string_dereference (&name, MDL);
341 return status;
343 memcpy (tv -> u.buffer.value, value, len);
345 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
346 omapi_data_string_dereference (&name, MDL);
347 omapi_typed_data_dereference (&tv, MDL);
348 return status;
351 /* dhcpctl_set_null_value
353 Sets a null value on an object referred to by a dhcpctl_handle. */
355 dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h,
356 const char *value_name)
358 isc_result_t status;
359 omapi_data_string_t *name = (omapi_data_string_t *)0;
360 unsigned ll;
362 ll = strlen (value_name);
363 status = omapi_data_string_new (&name, ll, MDL);
364 if (status != ISC_R_SUCCESS)
365 return status;
366 memcpy (name -> value, value_name, ll);
368 status = omapi_set_value (h, (omapi_object_t *)0, name,
369 (omapi_typed_data_t *)0);
370 omapi_data_string_dereference (&name, MDL);
371 return status;
374 /* dhcpctl_set_boolean_value
376 Sets a boolean value on an object - like dhcpctl_set_value,
377 only more convenient for booleans. */
379 dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value,
380 const char *value_name)
382 isc_result_t status;
383 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
384 omapi_data_string_t *name = (omapi_data_string_t *)0;
386 status = omapi_data_string_new (&name, strlen (value_name), MDL);
387 if (status != ISC_R_SUCCESS)
388 return status;
389 memcpy (name -> value, value_name, strlen (value_name));
391 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
392 if (status != ISC_R_SUCCESS) {
393 omapi_data_string_dereference (&name, MDL);
394 return status;
397 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
398 omapi_data_string_dereference (&name, MDL);
399 omapi_typed_data_dereference (&tv, MDL);
400 return status;
403 /* dhcpctl_set_int_value
405 Sets a boolean value on an object - like dhcpctl_set_value,
406 only more convenient for booleans. */
408 dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
409 const char *value_name)
411 isc_result_t status;
412 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
413 omapi_data_string_t *name = (omapi_data_string_t *)0;
415 status = omapi_data_string_new (&name, strlen (value_name), MDL);
416 if (status != ISC_R_SUCCESS)
417 return status;
418 memcpy (name -> value, value_name, strlen (value_name));
420 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
421 if (status != ISC_R_SUCCESS) {
422 omapi_data_string_dereference (&name, MDL);
423 return status;
426 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
427 omapi_data_string_dereference (&name, MDL);
428 omapi_typed_data_dereference (&tv, MDL);
429 return status;
432 /* dhcpctl_object_update
434 Queues an update on the object referenced by the handle (there
435 can't be any other work in progress on the handle). An
436 update means local parameters will be sent to the server. */
438 dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection,
439 dhcpctl_handle h)
441 isc_result_t status;
442 omapi_object_t *message = (omapi_object_t *)0;
443 dhcpctl_remote_object_t *ro;
445 if (h -> type != dhcpctl_remote_type)
446 return ISC_R_INVALIDARG;
447 ro = (dhcpctl_remote_object_t *)h;
449 status = omapi_message_new (&message, MDL);
450 if (status != ISC_R_SUCCESS) {
451 omapi_object_dereference (&message, MDL);
452 return status;
454 status = omapi_set_int_value (message, (omapi_object_t *)0,
455 "op", OMAPI_OP_UPDATE);
456 if (status != ISC_R_SUCCESS) {
457 omapi_object_dereference (&message, MDL);
458 return status;
461 status = omapi_set_object_value (message, (omapi_object_t *)0,
462 "object", h);
463 if (status != ISC_R_SUCCESS) {
464 omapi_object_dereference (&message, MDL);
465 return status;
468 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
469 (int)(ro -> remote_handle));
470 if (status != ISC_R_SUCCESS) {
471 omapi_object_dereference (&message, MDL);
472 return status;
475 omapi_message_register (message);
476 status = omapi_protocol_send_message (connection -> outer,
477 (omapi_object_t *)0,
478 message, (omapi_object_t *)0);
479 omapi_object_dereference (&message, MDL);
480 return status;
483 /* Requests a refresh on the object referenced by the handle (there
484 can't be any other work in progress on the handle). A
485 refresh means local parameters are updated from the server. */
487 dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection,
488 dhcpctl_handle h)
490 isc_result_t status;
491 omapi_object_t *message = (omapi_object_t *)0;
492 dhcpctl_remote_object_t *ro;
494 if (h -> type != dhcpctl_remote_type)
495 return ISC_R_INVALIDARG;
496 ro = (dhcpctl_remote_object_t *)h;
498 status = omapi_message_new (&message, MDL);
499 if (status != ISC_R_SUCCESS) {
500 omapi_object_dereference (&message, MDL);
501 return status;
503 status = omapi_set_int_value (message, (omapi_object_t *)0,
504 "op", OMAPI_OP_REFRESH);
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 "handle", (int)(ro -> remote_handle));
511 if (status != ISC_R_SUCCESS) {
512 omapi_object_dereference (&message, MDL);
513 return status;
516 omapi_message_register (message);
517 status = omapi_protocol_send_message (connection -> outer,
518 (omapi_object_t *)0,
519 message, (omapi_object_t *)0);
521 /* We don't want to send the contents of the object down the
522 wire, but we do need to reference it so that we know what
523 to do with the update. */
524 status = omapi_set_object_value (message, (omapi_object_t *)0,
525 "object", h);
526 if (status != ISC_R_SUCCESS) {
527 omapi_object_dereference (&message, MDL);
528 return status;
531 omapi_object_dereference (&message, MDL);
532 return status;
535 /* Requests the removal of the object referenced by the handle (there
536 can't be any other work in progress on the handle). A
537 removal means that all searchable references to the object on the
538 server are deleted. */
540 dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection,
541 dhcpctl_handle h)
543 isc_result_t status;
544 omapi_object_t *message = (omapi_object_t *)0;
545 dhcpctl_remote_object_t *ro;
547 if (h -> type != dhcpctl_remote_type)
548 return ISC_R_INVALIDARG;
549 ro = (dhcpctl_remote_object_t *)h;
551 status = omapi_message_new (&message, MDL);
552 if (status != ISC_R_SUCCESS) {
553 omapi_object_dereference (&message, MDL);
554 return status;
556 status = omapi_set_int_value (message, (omapi_object_t *)0,
557 "op", OMAPI_OP_DELETE);
558 if (status != ISC_R_SUCCESS) {
559 omapi_object_dereference (&message, MDL);
560 return status;
563 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
564 (int)(ro -> remote_handle));
565 if (status != ISC_R_SUCCESS) {
566 omapi_object_dereference (&message, MDL);
567 return status;
570 status = omapi_set_object_value (message, (omapi_object_t *)0,
571 "notify-object", h);
572 if (status != ISC_R_SUCCESS) {
573 omapi_object_dereference (&message, MDL);
574 return status;
577 omapi_message_register (message);
578 status = omapi_protocol_send_message (connection -> outer,
579 (omapi_object_t *)0,
580 message, (omapi_object_t *)0);
581 omapi_object_dereference (&message, MDL);
582 return status;
585 isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *vp,
586 const char *file, int line)
588 return omapi_data_string_dereference (vp, file, line);