]> git.ipfire.org Git - thirdparty/dhcp.git/blame - dhcpctl/dhcpctl.c
Go back to the BSD license.
[thirdparty/dhcp.git] / dhcpctl / dhcpctl.c
CommitLineData
1d6fed18
TL
1/* dhcpctl.c
2
3 Subroutines providing general support for objects. */
4
5/*
49733f31
TL
6 * Copyright (c) 1999-2000 Internet Software Consortium.
7 * All rights reserved.
1d6fed18 8 *
49733f31
TL
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
1d6fed18 12 *
49733f31
TL
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.
1d6fed18 21 *
49733f31
TL
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
34 * SUCH DAMAGE.
35 *
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''.
1d6fed18
TL
42 */
43
6a4c4be8 44#include <omapip/omapip_p.h>
1d6fed18
TL
45#include "dhcpctl.h"
46
47omapi_object_type_t *dhcpctl_callback_type;
b94dc677 48omapi_object_type_t *dhcpctl_remote_type;
1d6fed18
TL
49
50/* dhcpctl_initialize ()
51
52 Must be called before any other dhcpctl function. */
53
54dhcpctl_status dhcpctl_initialize ()
55{
56 omapi_init();
57 omapi_object_type_register (&dhcpctl_callback_type,
58 "dhcpctl-callback",
59 dhcpctl_callback_set_value,
60 dhcpctl_callback_get_value,
61 dhcpctl_callback_destroy,
62 dhcpctl_callback_signal_handler,
52f59a91 63 dhcpctl_callback_stuff_values, 0, 0, 0);
b94dc677
TL
64 omapi_object_type_register (&dhcpctl_remote_type,
65 "dhcpctl-remote",
66 dhcpctl_remote_set_value,
67 dhcpctl_remote_get_value,
68 dhcpctl_remote_destroy,
69 dhcpctl_remote_signal_handler,
52f59a91 70 dhcpctl_remote_stuff_values, 0, 0, 0);
1d6fed18
TL
71 return ISC_R_SUCCESS;
72}
73
74/* dhcpctl_connect
75
76 synchronous
77 returns nonzero status code if it didn't connect, zero otherwise
78 stores connection handle through connection, which can be used
79 for subsequent access to the specified server.
80 server_name is the name of the server, and port is the TCP
81 port on which it is listening.
82 authinfo is the handle to an object containing authentication
83 information. */
84
85dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
b1b7b521 86 const char *server_name, int port,
1d6fed18
TL
87 dhcpctl_handle authinfo)
88{
89 isc_result_t status;
90
4bd8800e 91 status = omapi_generic_new (connection, MDL);
1d6fed18
TL
92 if (status != ISC_R_SUCCESS) {
93 return status;
94 }
95
96 status = omapi_protocol_connect (*connection, server_name,
871f37bf 97 (unsigned)port, authinfo);
1d6fed18 98 if (status != ISC_R_SUCCESS) {
4bd8800e 99 omapi_object_dereference (connection, MDL);
1d6fed18
TL
100 return status;
101 }
102
103 status = omapi_wait_for_completion (*connection, 0);
104 if (status != ISC_R_SUCCESS) {
4bd8800e 105 omapi_object_dereference (connection, MDL);
1d6fed18
TL
106 return status;
107 }
108
109 return status;
110}
111
1d6fed18
TL
112/* dhcpctl_wait_for_completion
113
114 synchronous
115 returns zero if the callback completes, a nonzero status if
116 there was some problem relating to the wait operation. The
117 status of the queued request will be stored through s, and
118 will also be either zero for success or nonzero for some kind
119 of failure. Never returns until completion or until the
120 connection to the server is lost. This performs the same
121 function as dhcpctl_set_callback and the subsequent callback,
122 for programs that want to do inline execution instead of using
123 callbacks. */
124
125dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
126 dhcpctl_status *s)
127{
b94dc677
TL
128 isc_result_t status;
129 status = omapi_wait_for_completion (h, 0);
130 if (status != ISC_R_SUCCESS)
131 return status;
132 if (h -> type == dhcpctl_remote_type)
133 *s = ((dhcpctl_remote_object_t *)h) -> waitstatus;
134 return ISC_R_SUCCESS;
1d6fed18
TL
135}
136
137/* dhcpctl_get_value
138
139 synchronous
140 returns zero if the call succeeded, a nonzero status code if
141 it didn't.
142 result is the address of an empty data string (initialized
143 with bzero or cleared with data_string_forget). On
144 successful completion, the addressed data string will contain
145 the value that was fetched.
146 dhcpctl_handle refers to some dhcpctl item
147 value_name refers to some value related to that item - e.g.,
148 for a handle associated with a completed host lookup, value
149 could be one of "hardware-address", "dhcp-client-identifier",
150 "known" or "client-hostname". */
151
152dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result,
b1b7b521 153 dhcpctl_handle h, const char *value_name)
1d6fed18
TL
154{
155 isc_result_t status;
156 omapi_value_t *tv = (omapi_value_t *)0;
1d6fed18 157 omapi_data_string_t *value = (omapi_data_string_t *)0;
b1b7b521 158 unsigned len;
1d6fed18
TL
159 int ip;
160
d2513ce0 161 status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv);
1d6fed18
TL
162 if (status != ISC_R_SUCCESS)
163 return status;
1d6fed18
TL
164
165 switch (tv -> value -> type) {
166 case omapi_datatype_int:
167 len = sizeof (int);
168 break;
169
170 case omapi_datatype_string:
171 case omapi_datatype_data:
172 len = tv -> value -> u.buffer.len;
173 break;
174
175 case omapi_datatype_object:
176 len = sizeof (omapi_handle_t);
177 break;
178
179 default:
4bd8800e 180 omapi_typed_data_dereference (&tv -> value, MDL);
1d6fed18
TL
181 return ISC_R_UNEXPECTED;
182 }
183
4bd8800e 184 status = omapi_data_string_new (result, len, MDL);
1d6fed18 185 if (status != ISC_R_SUCCESS) {
4bd8800e 186 omapi_typed_data_dereference (&tv -> value, MDL);
1d6fed18
TL
187 return status;
188 }
189
190 switch (tv -> value -> type) {
191 case omapi_datatype_int:
192 ip = htonl (tv -> value -> u.integer);
193 memcpy ((*result) -> value, &ip, sizeof ip);
194 break;
195
196 case omapi_datatype_string:
197 case omapi_datatype_data:
198 memcpy ((*result) -> value,
199 tv -> value -> u.buffer.value,
200 tv -> value -> u.buffer.len);
201 break;
202
203 case omapi_datatype_object:
204 ip = htonl (tv -> value -> u.object -> handle);
205 memcpy ((*result) -> value, &ip, sizeof ip);
206 break;
207 }
208
4bd8800e 209 omapi_value_dereference (&tv, MDL);
1d6fed18
TL
210 return ISC_R_SUCCESS;
211}
212
213/* dhcpctl_get_boolean
214
215 like dhcpctl_get_value, but more convenient for boolean
216 values, since no data_string needs to be dealt with. */
217
218dhcpctl_status dhcpctl_get_boolean (int *result,
b1b7b521 219 dhcpctl_handle h, const char *value_name)
1d6fed18
TL
220{
221 isc_result_t status;
222 dhcpctl_data_string data = (dhcpctl_data_string)0;
223 int rv;
224
225 status = dhcpctl_get_value (&data, h, value_name);
226 if (status != ISC_R_SUCCESS)
227 return status;
228 if (data -> len != sizeof rv) {
4bd8800e 229 omapi_data_string_dereference (&data, MDL);
1d6fed18
TL
230 return ISC_R_UNEXPECTED;
231 }
232 memcpy (&rv, data -> value, sizeof rv);
233 *result = ntohl (rv);
234 return ISC_R_SUCCESS;
235}
236
237/* dhcpctl_set_value
238
239 Sets a value on an object referred to by a dhcpctl_handle.
240 The opposite of dhcpctl_get_value. Does not update the
241 server - just sets the value on the handle. */
242
243dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value,
b1b7b521 244 const char *value_name)
1d6fed18
TL
245{
246 isc_result_t status;
247 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
248 omapi_data_string_t *name = (omapi_data_string_t *)0;
249 int len;
250 int ip;
251
4bd8800e 252 status = omapi_data_string_new (&name, strlen (value_name), MDL);
1d6fed18
TL
253 if (status != ISC_R_SUCCESS)
254 return status;
d2513ce0 255 memcpy (name -> value, value_name, strlen (value_name));
1d6fed18 256
4bd8800e 257 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_data,
1d6fed18
TL
258 value -> len);
259 if (status != ISC_R_SUCCESS) {
4bd8800e 260 omapi_data_string_dereference (&name, MDL);
1d6fed18
TL
261 return status;
262 }
263 memcpy (tv -> u.buffer.value, value -> value, value -> len);
264
265 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
4bd8800e
TL
266 omapi_data_string_dereference (&name, MDL);
267 omapi_typed_data_dereference (&tv, MDL);
1d6fed18
TL
268 return status;
269}
270
271/* dhcpctl_set_string_value
272
273 Sets a NUL-terminated ASCII value on an object referred to by
274 a dhcpctl_handle. like dhcpctl_set_value, but saves the
275 trouble of creating a data_string for a NUL-terminated string.
276 Does not update the server - just sets the value on the handle. */
277
7528da64
TL
278dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
279 const char *value_name)
1d6fed18
TL
280{
281 isc_result_t status;
282 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
283 omapi_data_string_t *name = (omapi_data_string_t *)0;
284 int len;
285 int ip;
286
4bd8800e 287 status = omapi_data_string_new (&name, strlen (value_name), MDL);
1d6fed18
TL
288 if (status != ISC_R_SUCCESS)
289 return status;
d2513ce0 290 memcpy (name -> value, value_name, strlen (value_name));
1d6fed18 291
4bd8800e 292 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
1d6fed18 293 if (status != ISC_R_SUCCESS) {
4bd8800e 294 omapi_data_string_dereference (&name, MDL);
1d6fed18
TL
295 return status;
296 }
297
298 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
4bd8800e
TL
299 omapi_data_string_dereference (&name, MDL);
300 omapi_typed_data_dereference (&tv, MDL);
1d6fed18
TL
301 return status;
302}
303
d2513ce0
TL
304/* dhcpctl_set_boolean_value
305
306 Sets a boolean value on an object - like dhcpctl_set_value,
307 only more convenient for booleans. */
308
309dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value,
b1b7b521 310 const char *value_name)
d2513ce0
TL
311{
312 isc_result_t status;
313 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
314 omapi_data_string_t *name = (omapi_data_string_t *)0;
315 int len;
316 int ip;
317
4bd8800e 318 status = omapi_data_string_new (&name, strlen (value_name), MDL);
d2513ce0
TL
319 if (status != ISC_R_SUCCESS)
320 return status;
321 memcpy (name -> value, value_name, strlen (value_name));
322
4bd8800e 323 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
d2513ce0 324 if (status != ISC_R_SUCCESS) {
4bd8800e 325 omapi_data_string_dereference (&name, MDL);
d2513ce0
TL
326 return status;
327 }
328
329 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
4bd8800e
TL
330 omapi_data_string_dereference (&name, MDL);
331 omapi_typed_data_dereference (&tv, MDL);
d2513ce0
TL
332 return status;
333}
334
335/* dhcpctl_set_int_value
1d6fed18
TL
336
337 Sets a boolean value on an object - like dhcpctl_set_value,
338 only more convenient for booleans. */
339
d2513ce0 340dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
b1b7b521 341 const char *value_name)
1d6fed18
TL
342{
343 isc_result_t status;
344 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
345 omapi_data_string_t *name = (omapi_data_string_t *)0;
346 int len;
347 int ip;
348
4bd8800e 349 status = omapi_data_string_new (&name, strlen (value_name), MDL);
1d6fed18
TL
350 if (status != ISC_R_SUCCESS)
351 return status;
d2513ce0 352 memcpy (name -> value, value_name, strlen (value_name));
1d6fed18 353
4bd8800e 354 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
1d6fed18 355 if (status != ISC_R_SUCCESS) {
4bd8800e 356 omapi_data_string_dereference (&name, MDL);
1d6fed18
TL
357 return status;
358 }
359
360 status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
4bd8800e
TL
361 omapi_data_string_dereference (&name, MDL);
362 omapi_typed_data_dereference (&tv, MDL);
1d6fed18
TL
363 return status;
364}
365
366/* dhcpctl_object_update
367
368 Queues an update on the object referenced by the handle (there
369 can't be any other work in progress on the handle). An
370 update means local parameters will be sent to the server. */
371
372dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection,
373 dhcpctl_handle h)
374{
375 isc_result_t status;
376 omapi_object_t *message = (omapi_object_t *)0;
377
4bd8800e 378 status = omapi_message_new (&message, MDL);
1d6fed18 379 if (status != ISC_R_SUCCESS) {
4bd8800e 380 omapi_object_dereference (&message, MDL);
1d6fed18
TL
381 return status;
382 }
d2513ce0
TL
383 status = omapi_set_int_value (message, (omapi_object_t *)0,
384 "op", OMAPI_OP_UPDATE);
1d6fed18 385 if (status != ISC_R_SUCCESS) {
4bd8800e 386 omapi_object_dereference (&message, MDL);
1d6fed18
TL
387 return status;
388 }
d2513ce0
TL
389 status = omapi_set_object_value (message, (omapi_object_t *)0,
390 "object", h);
1d6fed18 391 if (status != ISC_R_SUCCESS) {
4bd8800e 392 omapi_object_dereference (&message, MDL);
1d6fed18
TL
393 return status;
394 }
395
396 omapi_message_register (message);
397 status = omapi_protocol_send_message (connection -> outer,
398 (omapi_object_t *)0,
399 message, (omapi_object_t *)0);
4bd8800e 400 omapi_object_dereference (&message, MDL);
1d6fed18
TL
401 return status;
402}
403
404/* Requests a refresh on the object referenced by the handle (there
405 can't be any other work in progress on the handle). A
406 refresh means local parameters are updated from the server. */
407
408dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection,
409 dhcpctl_handle h)
410{
411 isc_result_t status;
412 omapi_object_t *message = (omapi_object_t *)0;
413
4bd8800e 414 status = omapi_message_new (&message, MDL);
1d6fed18 415 if (status != ISC_R_SUCCESS) {
4bd8800e 416 omapi_object_dereference (&message, MDL);
1d6fed18
TL
417 return status;
418 }
d2513ce0
TL
419 status = omapi_set_int_value (message, (omapi_object_t *)0,
420 "op", OMAPI_OP_REFRESH);
1d6fed18 421 if (status != ISC_R_SUCCESS) {
4bd8800e 422 omapi_object_dereference (&message, MDL);
1d6fed18
TL
423 return status;
424 }
d2513ce0 425 status = omapi_set_int_value (message, (omapi_object_t *)0,
b1b7b521 426 "handle", (int)(h -> handle));
1d6fed18 427 if (status != ISC_R_SUCCESS) {
4bd8800e 428 omapi_object_dereference (&message, MDL);
52f59a91
TL
429 return status;
430 }
431
432 omapi_message_register (message);
433 status = omapi_protocol_send_message (connection -> outer,
434 (omapi_object_t *)0,
435 message, (omapi_object_t *)0);
4bd8800e 436 omapi_object_dereference (&message, MDL);
52f59a91
TL
437 return status;
438}
439
83b89e97 440/* Requests the removal of the object referenced by the handle (there
52f59a91 441 can't be any other work in progress on the handle). A
83b89e97
TL
442 removal means that all searchable references to the object on the
443 server are deleted. */
52f59a91 444
83b89e97 445dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection,
52f59a91
TL
446 dhcpctl_handle h)
447{
448 isc_result_t status;
449 omapi_object_t *message = (omapi_object_t *)0;
450 dhcpctl_remote_object_t *ro;
451
452 if (h -> type != dhcpctl_remote_type)
453 return ISC_R_INVALIDARG;
454 ro = (dhcpctl_remote_object_t *)h;
455
4bd8800e 456 status = omapi_message_new (&message, MDL);
52f59a91 457 if (status != ISC_R_SUCCESS) {
4bd8800e 458 omapi_object_dereference (&message, MDL);
52f59a91
TL
459 return status;
460 }
461 status = omapi_set_int_value (message, (omapi_object_t *)0,
462 "op", OMAPI_OP_DELETE);
463 if (status != ISC_R_SUCCESS) {
4bd8800e 464 omapi_object_dereference (&message, MDL);
52f59a91
TL
465 return status;
466 }
467
468 status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
b1b7b521 469 (int)(ro -> remote_handle));
52f59a91 470 if (status != ISC_R_SUCCESS) {
4bd8800e 471 omapi_object_dereference (&message, MDL);
52f59a91
TL
472 return status;
473 }
474
475 status = omapi_set_object_value (message, (omapi_object_t *)0,
476 "notify-object", h);
477 if (status != ISC_R_SUCCESS) {
4bd8800e 478 omapi_object_dereference (&message, MDL);
1d6fed18
TL
479 return status;
480 }
481
482 omapi_message_register (message);
483 status = omapi_protocol_send_message (connection -> outer,
484 (omapi_object_t *)0,
485 message, (omapi_object_t *)0);
4bd8800e 486 omapi_object_dereference (&message, MDL);
1d6fed18
TL
487 return status;
488}
489
29dd6d57 490isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *vp,
4bd8800e 491 const char *file, int line)
29dd6d57 492{
4bd8800e 493 return omapi_data_string_dereference (vp, file, line);
29dd6d57 494}