ISC DHCP 4.4.2b1
A reference DHCPv4 and DHCPv6 implementation
dhcpctl.c
Go to the documentation of this file.
1/* dhcpctl.c
2
3 Subroutines providing general support for objects. */
4
5/*
6 * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1999-2003 by Internet Software Consortium
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
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.
20 *
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * https://www.isc.org/
26 *
27 */
28
29#include "dhcpd.h"
30#include <omapip/omapip_p.h>
31#include "dhcpctl.h"
32
35
36/* dhcpctl_initialize ()
37
38 Must be called before any other dhcpctl function. */
39
41{
42 isc_result_t status;
43
44 /* Set up the isc and dns library managers */
46 NULL, NULL);
47 if (status != ISC_R_SUCCESS)
48 return status;
49
50 status = omapi_init();
51 if (status != ISC_R_SUCCESS)
52 return status;
53
55 "dhcpctl-callback",
61 0, 0, 0, 0, 0, 0,
62 sizeof
64 RC_MISC);
65 if (status != ISC_R_SUCCESS)
66 return status;
67
69 "dhcpctl-remote",
75 0, 0, 0, 0, 0, 0,
77 0, RC_MISC);
78 if (status != ISC_R_SUCCESS)
79 return status;
80
81 return ISC_R_SUCCESS;
82}
83
84/* dhcpctl_connect
85
86 synchronous
87 returns nonzero status code if it didn't connect, zero otherwise
88 stores connection handle through connection, which can be used
89 for subsequent access to the specified server.
90 server_name is the name of the server, and port is the TCP
91 port on which it is listening.
92 authinfo is the handle to an object containing authentication
93 information. */
94
96 const char *server_name, int port,
97 dhcpctl_handle authinfo)
98{
99 isc_result_t status;
100
101 status = omapi_generic_new (connection, MDL);
102 if (status != ISC_R_SUCCESS) {
103 return status;
104 }
105
106 status = omapi_protocol_connect (*connection, server_name,
107 (unsigned)port, authinfo);
108 if (status == ISC_R_SUCCESS)
109 return status;
110 if (status != DHCP_R_INCOMPLETE) {
111 omapi_object_dereference (connection, MDL);
112 return status;
113 }
114
115 status = omapi_wait_for_completion (*connection, 0);
116 if (status != ISC_R_SUCCESS) {
117 omapi_object_dereference (connection, MDL);
118 return status;
119 }
120
121 return status;
122}
123
124/* dhcpctl_wait_for_completion
125
126 synchronous
127 returns zero if the callback completes, a nonzero status if
128 there was some problem relating to the wait operation. The
129 status of the queued request will be stored through s, and
130 will also be either zero for success or nonzero for some kind
131 of failure. Never returns until completion or until the
132 connection to the server is lost. This performs the same
133 function as dhcpctl_set_callback and the subsequent callback,
134 for programs that want to do inline execution instead of using
135 callbacks. */
136
139{
140 isc_result_t status;
141 status = omapi_wait_for_completion (h, 0);
142 if (status != ISC_R_SUCCESS)
143 return status;
144 if (h -> type == dhcpctl_remote_type)
145 *s = ((dhcpctl_remote_object_t *)h) -> waitstatus;
146 return ISC_R_SUCCESS;
147}
148
149/* dhcpctl_get_value
150
151 synchronous
152 returns zero if the call succeeded, a nonzero status code if
153 it didn't.
154 result is the address of an empty data string (initialized
155 with bzero or cleared with data_string_forget). On
156 successful completion, the addressed data string will contain
157 the value that was fetched.
158 dhcpctl_handle refers to some dhcpctl item
159 value_name refers to some value related to that item - e.g.,
160 for a handle associated with a completed host lookup, value
161 could be one of "hardware-address", "dhcp-client-identifier",
162 "known" or "client-hostname". */
163
165 dhcpctl_handle h, const char *value_name)
166{
167 isc_result_t status;
168 omapi_value_t *tv = (omapi_value_t *)0;
169 unsigned len;
170 int ip;
171
172 status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv);
173 if (status != ISC_R_SUCCESS)
174 return status;
175
176 switch (tv -> value -> type) {
178 len = sizeof (int);
179 break;
180
183 len = tv -> value -> u.buffer.len;
184 break;
185
187 len = sizeof (omapi_handle_t);
188 break;
189
190 default:
192 return ISC_R_UNEXPECTED;
193 }
194
195 status = omapi_data_string_new (result, len, MDL);
196 if (status != ISC_R_SUCCESS) {
198 return status;
199 }
200
201 switch (tv -> value -> type) {
203 ip = htonl (tv -> value -> u.integer);
204 memcpy ((*result) -> value, &ip, sizeof ip);
205 break;
206
209 memcpy ((*result) -> value,
210 tv -> value -> u.buffer.value,
211 tv -> value -> u.buffer.len);
212 break;
213
215 ip = htonl (tv -> value -> u.object -> handle);
216 memcpy ((*result) -> value, &ip, sizeof ip);
217 break;
218 }
219
221 return ISC_R_SUCCESS;
222}
223
224/* dhcpctl_get_boolean
225
226 like dhcpctl_get_value, but more convenient for boolean
227 values, since no data_string needs to be dealt with. */
228
230 dhcpctl_handle h, const char *value_name)
231{
232 isc_result_t status;
234 int rv;
235
236 status = dhcpctl_get_value (&data, h, value_name);
237 if (status != ISC_R_SUCCESS)
238 return status;
239 if (data -> len != sizeof rv) {
241 return ISC_R_UNEXPECTED;
242 }
243 memcpy (&rv, data -> value, sizeof rv);
244 *result = ntohl (rv);
246 return ISC_R_SUCCESS;
247}
248
249/* dhcpctl_set_value
250
251 Sets a value on an object referred to by a dhcpctl_handle.
252 The opposite of dhcpctl_get_value. Does not update the
253 server - just sets the value on the handle. */
254
256 const char *value_name)
257{
258 isc_result_t status;
261
262 status = omapi_data_string_new (&name, strlen (value_name), MDL);
263 if (status != ISC_R_SUCCESS)
264 return status;
265 memcpy (name -> value, value_name, strlen (value_name));
266
268 value -> len);
269 if (status != ISC_R_SUCCESS) {
271 return status;
272 }
273 memcpy (tv -> u.buffer.value, value -> value, value -> len);
274
275 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
278 return status;
279}
280
281/* dhcpctl_set_string_value
282
283 Sets a NUL-terminated ASCII value on an object referred to by
284 a dhcpctl_handle. like dhcpctl_set_value, but saves the
285 trouble of creating a data_string for a NUL-terminated string.
286 Does not update the server - just sets the value on the handle. */
287
289 const char *value_name)
290{
291 isc_result_t status;
294
295 status = omapi_data_string_new (&name, strlen (value_name), MDL);
296 if (status != ISC_R_SUCCESS)
297 return status;
298 memcpy (name -> value, value_name, strlen (value_name));
299
301 if (status != ISC_R_SUCCESS) {
303 return status;
304 }
305
306 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
309 return status;
310}
311
312/* dhcpctl_set_buffer_value
313
314 Sets a value on an object referred to by a dhcpctl_handle. like
315 dhcpctl_set_value, but saves the trouble of creating a data_string
316 for string for which we have a buffer and length. Does not update
317 the server - just sets the value on the handle. */
318
320 const char *value, unsigned len,
321 const char *value_name)
322{
323 isc_result_t status;
326 unsigned ll;
327
328 ll = strlen (value_name);
329 status = omapi_data_string_new (&name, ll, MDL);
330 if (status != ISC_R_SUCCESS)
331 return status;
332 memcpy (name -> value, value_name, ll);
333
334 status = omapi_typed_data_new (MDL, &tv,
336 if (status != ISC_R_SUCCESS) {
338 return status;
339 }
340 memcpy (tv -> u.buffer.value, value, len);
341
342 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
345 return status;
346}
347
348/* dhcpctl_set_null_value
349
350 Sets a null value on an object referred to by a dhcpctl_handle. */
351
353 const char *value_name)
354{
355 isc_result_t status;
357 unsigned ll;
358
359 ll = strlen (value_name);
360 status = omapi_data_string_new (&name, ll, MDL);
361 if (status != ISC_R_SUCCESS)
362 return status;
363 memcpy (name -> value, value_name, ll);
364
365 status = omapi_set_value (h, (omapi_object_t *)0, name,
366 (omapi_typed_data_t *)0);
368 return status;
369}
370
371/* dhcpctl_set_boolean_value
372
373 Sets a boolean value on an object - like dhcpctl_set_value,
374 only more convenient for booleans. */
375
377 const char *value_name)
378{
379 isc_result_t status;
382
383 status = omapi_data_string_new (&name, strlen (value_name), MDL);
384 if (status != ISC_R_SUCCESS)
385 return status;
386 memcpy (name -> value, value_name, strlen (value_name));
387
389 if (status != ISC_R_SUCCESS) {
391 return status;
392 }
393
394 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
397 return status;
398}
399
400/* dhcpctl_set_int_value
401
402 Sets a boolean value on an object - like dhcpctl_set_value,
403 only more convenient for booleans. */
404
406 const char *value_name)
407{
408 isc_result_t status;
411
412 status = omapi_data_string_new (&name, strlen (value_name), MDL);
413 if (status != ISC_R_SUCCESS)
414 return status;
415 memcpy (name -> value, value_name, strlen (value_name));
416
418 if (status != ISC_R_SUCCESS) {
420 return status;
421 }
422
423 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
426 return status;
427}
428
429/* dhcpctl_object_update
430
431 Queues an update on the object referenced by the handle (there
432 can't be any other work in progress on the handle). An
433 update means local parameters will be sent to the server. */
434
437{
438 isc_result_t status;
439 omapi_object_t *message = (omapi_object_t *)0;
441
442 if (h -> type != dhcpctl_remote_type)
443 return DHCP_R_INVALIDARG;
444 ro = (dhcpctl_remote_object_t *)h;
445
446 status = omapi_message_new (&message, MDL);
447 if (status != ISC_R_SUCCESS) {
448 omapi_object_dereference (&message, MDL);
449 return status;
450 }
451 status = omapi_set_int_value (message, (omapi_object_t *)0,
452 "op", OMAPI_OP_UPDATE);
453 if (status != ISC_R_SUCCESS) {
454 omapi_object_dereference (&message, MDL);
455 return status;
456 }
457
458 status = omapi_set_object_value (message, (omapi_object_t *)0,
459 "object", h);
460 if (status != ISC_R_SUCCESS) {
461 omapi_object_dereference (&message, MDL);
462 return status;
463 }
464
465 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
466 (int)(ro -> remote_handle));
467 if (status != ISC_R_SUCCESS) {
468 omapi_object_dereference (&message, MDL);
469 return status;
470 }
471
472 omapi_message_register (message);
473 status = omapi_protocol_send_message (connection -> outer,
474 (omapi_object_t *)0,
475 message, (omapi_object_t *)0);
476 omapi_object_dereference (&message, MDL);
477 return status;
478}
479
480/* Requests a refresh on the object referenced by the handle (there
481 can't be any other work in progress on the handle). A
482 refresh means local parameters are updated from the server. */
483
486{
487 isc_result_t status;
488 omapi_object_t *message = (omapi_object_t *)0;
490
491 if (h -> type != dhcpctl_remote_type)
492 return DHCP_R_INVALIDARG;
493 ro = (dhcpctl_remote_object_t *)h;
494
495 status = omapi_message_new (&message, MDL);
496 if (status != ISC_R_SUCCESS) {
497 omapi_object_dereference (&message, MDL);
498 return status;
499 }
500 status = omapi_set_int_value (message, (omapi_object_t *)0,
501 "op", OMAPI_OP_REFRESH);
502 if (status != ISC_R_SUCCESS) {
503 omapi_object_dereference (&message, MDL);
504 return status;
505 }
506 status = omapi_set_int_value (message, (omapi_object_t *)0,
507 "handle", (int)(ro -> remote_handle));
508 if (status != ISC_R_SUCCESS) {
509 omapi_object_dereference (&message, MDL);
510 return status;
511 }
512
513 omapi_message_register (message);
514 status = omapi_protocol_send_message (connection -> outer,
515 (omapi_object_t *)0,
516 message, (omapi_object_t *)0);
517
518 /* We don't want to send the contents of the object down the
519 wire, but we do need to reference it so that we know what
520 to do with the update. */
521 status = omapi_set_object_value (message, (omapi_object_t *)0,
522 "object", h);
523 if (status != ISC_R_SUCCESS) {
524 omapi_object_dereference (&message, MDL);
525 return status;
526 }
527
528 omapi_object_dereference (&message, MDL);
529 return status;
530}
531
532/* Requests the removal of the object referenced by the handle (there
533 can't be any other work in progress on the handle). A
534 removal means that all searchable references to the object on the
535 server are deleted. */
536
539{
540 isc_result_t status;
541 omapi_object_t *message = (omapi_object_t *)0;
543
544 if (h -> type != dhcpctl_remote_type)
545 return DHCP_R_INVALIDARG;
546 ro = (dhcpctl_remote_object_t *)h;
547
548 status = omapi_message_new (&message, MDL);
549 if (status != ISC_R_SUCCESS) {
550 omapi_object_dereference (&message, MDL);
551 return status;
552 }
553 status = omapi_set_int_value (message, (omapi_object_t *)0,
554 "op", OMAPI_OP_DELETE);
555 if (status != ISC_R_SUCCESS) {
556 omapi_object_dereference (&message, MDL);
557 return status;
558 }
559
560 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
561 (int)(ro -> remote_handle));
562 if (status != ISC_R_SUCCESS) {
563 omapi_object_dereference (&message, MDL);
564 return status;
565 }
566
567 status = omapi_set_object_value (message, (omapi_object_t *)0,
568 "notify-object", h);
569 if (status != ISC_R_SUCCESS) {
570 omapi_object_dereference (&message, MDL);
571 return status;
572 }
573
574 omapi_message_register (message);
575 status = omapi_protocol_send_message (connection -> outer,
576 (omapi_object_t *)0,
577 message, (omapi_object_t *)0);
578 omapi_object_dereference (&message, MDL);
579 return status;
580}
581
583 const char *file, int line)
584{
586}
#define RC_MISC
Definition: alloc.h:56
isc_result_t dhcpctl_callback_signal_handler(omapi_object_t *o, const char *name, va_list ap)
Definition: callback.c:103
isc_result_t dhcpctl_callback_get_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value)
Definition: callback.c:89
isc_result_t dhcpctl_callback_stuff_values(omapi_object_t *c, omapi_object_t *id, omapi_object_t *p)
Definition: callback.c:150
isc_result_t dhcpctl_callback_destroy(omapi_object_t *h, const char *file, int line)
Definition: callback.c:134
isc_result_t dhcpctl_callback_set_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_typed_data_t *value)
Definition: callback.c:75
dhcpctl_status dhcpctl_wait_for_completion(dhcpctl_handle h, dhcpctl_status *s)
Definition: dhcpctl.c:137
isc_result_t dhcpctl_data_string_dereference(dhcpctl_data_string *vp, const char *file, int line)
Definition: dhcpctl.c:582
dhcpctl_status dhcpctl_object_refresh(dhcpctl_handle connection, dhcpctl_handle h)
Definition: dhcpctl.c:484
dhcpctl_status dhcpctl_connect(dhcpctl_handle *connection, const char *server_name, int port, dhcpctl_handle authinfo)
Definition: dhcpctl.c:95
dhcpctl_status dhcpctl_object_update(dhcpctl_handle connection, dhcpctl_handle h)
Definition: dhcpctl.c:435
dhcpctl_status dhcpctl_set_int_value(dhcpctl_handle h, int value, const char *value_name)
Definition: dhcpctl.c:405
dhcpctl_status dhcpctl_object_remove(dhcpctl_handle connection, dhcpctl_handle h)
Definition: dhcpctl.c:537
dhcpctl_status dhcpctl_set_value(dhcpctl_handle h, dhcpctl_data_string value, const char *value_name)
Definition: dhcpctl.c:255
dhcpctl_status dhcpctl_set_null_value(dhcpctl_handle h, const char *value_name)
Definition: dhcpctl.c:352
dhcpctl_status dhcpctl_initialize()
Definition: dhcpctl.c:40
dhcpctl_status dhcpctl_set_string_value(dhcpctl_handle h, const char *value, const char *value_name)
Definition: dhcpctl.c:288
omapi_object_type_t * dhcpctl_remote_type
Definition: dhcpctl.c:34
dhcpctl_status dhcpctl_set_data_value(dhcpctl_handle h, const char *value, unsigned len, const char *value_name)
Definition: dhcpctl.c:319
dhcpctl_status dhcpctl_get_value(dhcpctl_data_string *result, dhcpctl_handle h, const char *value_name)
Definition: dhcpctl.c:164
omapi_object_type_t * dhcpctl_callback_type
Definition: dhcpctl.c:33
dhcpctl_status dhcpctl_set_boolean_value(dhcpctl_handle h, int value, const char *value_name)
Definition: dhcpctl.c:376
dhcpctl_status dhcpctl_get_boolean(int *result, dhcpctl_handle h, const char *value_name)
Definition: dhcpctl.c:229
isc_result_t dhcpctl_remote_stuff_values(omapi_object_t *, omapi_object_t *, omapi_object_t *)
Definition: remote.c:343
isc_result_t dhcpctl_remote_set_value(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *)
Definition: remote.c:251
omapi_data_string_t * dhcpctl_data_string
Definition: dhcpctl.h:36
isc_result_t dhcpctl_remote_destroy(omapi_object_t *, const char *, int)
Definition: remote.c:324
isc_result_t dhcpctl_remote_signal_handler(omapi_object_t *, const char *, va_list)
Definition: remote.c:291
isc_result_t dhcpctl_remote_get_value(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **)
Definition: remote.c:277
isc_result_t dhcpctl_status
Definition: dhcpctl.h:34
const char int line
Definition: dhcpd.h:3793
const char * file
Definition: dhcpd.h:3793
isc_result_t dhcp_context_create(int flags, struct in_addr *local4, struct in6_addr *local6)
Definition: isclib.c:167
#define DHCP_CONTEXT_PRE_DB
Definition: isclib.h:134
#define DHCP_CONTEXT_POST_DB
Definition: isclib.h:135
#define ISC_R_SUCCESS
isc_result_t omapi_value_dereference(omapi_value_t **, const char *, int)
Definition: alloc.c:1060
isc_result_t omapi_protocol_connect(omapi_object_t *, const char *, unsigned, omapi_object_t *)
#define MDL
Definition: omapip.h:567
isc_result_t omapi_protocol_send_message(omapi_object_t *, omapi_object_t *, omapi_object_t *, omapi_object_t *)
Definition: protocol.c:148
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
isc_result_t omapi_set_value(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *)
Definition: support.c:303
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
Definition: alloc.c:593
isc_result_t omapi_set_object_value(omapi_object_t *, omapi_object_t *, const char *, omapi_object_t *)
Definition: support.c:419
isc_result_t omapi_data_string_new(omapi_data_string_t **, unsigned, const char *, int)
Definition: alloc.c:950
const char int
Definition: omapip.h:442
isc_result_t omapi_message_register(omapi_object_t *)
Definition: message.c:267
isc_result_t omapi_init(void)
Definition: support.c:61
isc_result_t omapi_object_type_register(omapi_object_type_t **, const char *, isc_result_t(*)(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *), isc_result_t(*)(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **), isc_result_t(*)(omapi_object_t *, const char *, int), isc_result_t(*)(omapi_object_t *, const char *, va_list), isc_result_t(*)(omapi_object_t *, omapi_object_t *, omapi_object_t *), isc_result_t(*)(omapi_object_t **, omapi_object_t *, omapi_object_t *), isc_result_t(*)(omapi_object_t **, omapi_object_t *), isc_result_t(*)(omapi_object_t *, omapi_object_t *), isc_result_t(*)(omapi_object_t *, const char *, int), isc_result_t(*)(omapi_object_t **, const char *, int), isc_result_t(*)(size_t), size_t, isc_result_t(*)(omapi_object_t *, const char *, int), int)
Definition: support.c:193
@ omapi_datatype_string
Definition: omapip.h:43
@ omapi_datatype_object
Definition: omapip.h:45
@ omapi_datatype_int
Definition: omapip.h:42
@ omapi_datatype_data
Definition: omapip.h:44
isc_result_t omapi_typed_data_dereference(omapi_typed_data_t **, const char *, int)
Definition: alloc.c:901
isc_result_t omapi_wait_for_completion(omapi_object_t *, struct timeval *)
Definition: dispatch.c:420
isc_result_t omapi_data_string_dereference(omapi_data_string_t **, const char *, int)
Definition: alloc.c:988
unsigned int omapi_handle_t
Definition: omapip.h:36
isc_result_t omapi_typed_data_new(const char *, int, omapi_typed_data_t **, omapi_datatype_t,...)
Definition: alloc.c:803
isc_result_t omapi_get_value_str(omapi_object_t *, omapi_object_t *, const char *, omapi_value_t **)
Definition: support.c:482
isc_result_t omapi_message_new(omapi_object_t **, const char *, int)
isc_result_t omapi_set_int_value(omapi_object_t *, omapi_object_t *, const char *, int)
Definition: support.c:395
#define OMAPI_OP_UPDATE
Definition: omapip_p.h:90
#define OMAPI_OP_DELETE
Definition: omapip_p.h:93
#define OMAPI_OP_REFRESH
Definition: omapip_p.h:89
#define DHCP_R_INVALIDARG
Definition: result.h:49
#define DHCP_R_INCOMPLETE
Definition: result.h:58
Definition: data.h:289
Definition: ip.h:47
unsigned char value[1]
Definition: omapip.h:57
struct omapi_typed_data_t::@3::@4 buffer
Definition: data.h:205