Annotation of embedaddon/dhcp/dhcpctl/dhcpctl.c, revision 1.1
1.1 ! misho 1: /* dhcpctl.c
! 2:
! 3: Subroutines providing general support for objects. */
! 4:
! 5: /*
! 6: * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
! 7: * Copyright (c) 1999-2003 by Internet Software Consortium
! 8: *
! 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.
! 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: * 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: * ``https://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''.
! 33: */
! 34:
! 35: #include "dhcpd.h"
! 36: #include <omapip/omapip_p.h>
! 37: #include "dhcpctl.h"
! 38:
! 39: omapi_object_type_t *dhcpctl_callback_type;
! 40: omapi_object_type_t *dhcpctl_remote_type;
! 41:
! 42: /* dhcpctl_initialize ()
! 43:
! 44: Must be called before any other dhcpctl function. */
! 45:
! 46: dhcpctl_status dhcpctl_initialize ()
! 47: {
! 48: isc_result_t status;
! 49:
! 50: status = omapi_init();
! 51: if (status != ISC_R_SUCCESS)
! 52: return status;
! 53:
! 54: status = omapi_object_type_register (&dhcpctl_callback_type,
! 55: "dhcpctl-callback",
! 56: dhcpctl_callback_set_value,
! 57: dhcpctl_callback_get_value,
! 58: dhcpctl_callback_destroy,
! 59: dhcpctl_callback_signal_handler,
! 60: dhcpctl_callback_stuff_values,
! 61: 0, 0, 0, 0, 0, 0,
! 62: sizeof
! 63: (dhcpctl_callback_object_t), 0,
! 64: RC_MISC);
! 65: if (status != ISC_R_SUCCESS)
! 66: return status;
! 67:
! 68: status = omapi_object_type_register (&dhcpctl_remote_type,
! 69: "dhcpctl-remote",
! 70: dhcpctl_remote_set_value,
! 71: dhcpctl_remote_get_value,
! 72: dhcpctl_remote_destroy,
! 73: dhcpctl_remote_signal_handler,
! 74: dhcpctl_remote_stuff_values,
! 75: 0, 0, 0, 0, 0, 0,
! 76: sizeof (dhcpctl_remote_object_t),
! 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:
! 95: dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
! 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 != ISC_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:
! 137: dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
! 138: dhcpctl_status *s)
! 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:
! 164: dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result,
! 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) {
! 177: case omapi_datatype_int:
! 178: len = sizeof (int);
! 179: break;
! 180:
! 181: case omapi_datatype_string:
! 182: case omapi_datatype_data:
! 183: len = tv -> value -> u.buffer.len;
! 184: break;
! 185:
! 186: case omapi_datatype_object:
! 187: len = sizeof (omapi_handle_t);
! 188: break;
! 189:
! 190: default:
! 191: omapi_typed_data_dereference (&tv -> value, MDL);
! 192: return ISC_R_UNEXPECTED;
! 193: }
! 194:
! 195: status = omapi_data_string_new (result, len, MDL);
! 196: if (status != ISC_R_SUCCESS) {
! 197: omapi_typed_data_dereference (&tv -> value, MDL);
! 198: return status;
! 199: }
! 200:
! 201: switch (tv -> value -> type) {
! 202: case omapi_datatype_int:
! 203: ip = htonl (tv -> value -> u.integer);
! 204: memcpy ((*result) -> value, &ip, sizeof ip);
! 205: break;
! 206:
! 207: case omapi_datatype_string:
! 208: case omapi_datatype_data:
! 209: memcpy ((*result) -> value,
! 210: tv -> value -> u.buffer.value,
! 211: tv -> value -> u.buffer.len);
! 212: break;
! 213:
! 214: case omapi_datatype_object:
! 215: ip = htonl (tv -> value -> u.object -> handle);
! 216: memcpy ((*result) -> value, &ip, sizeof ip);
! 217: break;
! 218: }
! 219:
! 220: omapi_value_dereference (&tv, MDL);
! 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:
! 229: dhcpctl_status dhcpctl_get_boolean (int *result,
! 230: dhcpctl_handle h, const char *value_name)
! 231: {
! 232: isc_result_t status;
! 233: dhcpctl_data_string data = (dhcpctl_data_string)0;
! 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) {
! 240: omapi_data_string_dereference (&data, MDL);
! 241: return ISC_R_UNEXPECTED;
! 242: }
! 243: memcpy (&rv, data -> value, sizeof rv);
! 244: *result = ntohl (rv);
! 245: return ISC_R_SUCCESS;
! 246: }
! 247:
! 248: /* dhcpctl_set_value
! 249:
! 250: Sets a value on an object referred to by a dhcpctl_handle.
! 251: The opposite of dhcpctl_get_value. Does not update the
! 252: server - just sets the value on the handle. */
! 253:
! 254: dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value,
! 255: const char *value_name)
! 256: {
! 257: isc_result_t status;
! 258: omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
! 259: omapi_data_string_t *name = (omapi_data_string_t *)0;
! 260:
! 261: status = omapi_data_string_new (&name, strlen (value_name), MDL);
! 262: if (status != ISC_R_SUCCESS)
! 263: return status;
! 264: memcpy (name -> value, value_name, strlen (value_name));
! 265:
! 266: status = omapi_typed_data_new (MDL, &tv, omapi_datatype_data,
! 267: value -> len);
! 268: if (status != ISC_R_SUCCESS) {
! 269: omapi_data_string_dereference (&name, MDL);
! 270: return status;
! 271: }
! 272: memcpy (tv -> u.buffer.value, value -> value, value -> len);
! 273:
! 274: status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
! 275: omapi_data_string_dereference (&name, MDL);
! 276: omapi_typed_data_dereference (&tv, MDL);
! 277: return status;
! 278: }
! 279:
! 280: /* dhcpctl_set_string_value
! 281:
! 282: Sets a NUL-terminated ASCII value on an object referred to by
! 283: a dhcpctl_handle. like dhcpctl_set_value, but saves the
! 284: trouble of creating a data_string for a NUL-terminated string.
! 285: Does not update the server - just sets the value on the handle. */
! 286:
! 287: dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
! 288: const char *value_name)
! 289: {
! 290: isc_result_t status;
! 291: omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
! 292: omapi_data_string_t *name = (omapi_data_string_t *)0;
! 293:
! 294: status = omapi_data_string_new (&name, strlen (value_name), MDL);
! 295: if (status != ISC_R_SUCCESS)
! 296: return status;
! 297: memcpy (name -> value, value_name, strlen (value_name));
! 298:
! 299: status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
! 300: if (status != ISC_R_SUCCESS) {
! 301: omapi_data_string_dereference (&name, MDL);
! 302: return status;
! 303: }
! 304:
! 305: status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
! 306: omapi_data_string_dereference (&name, MDL);
! 307: omapi_typed_data_dereference (&tv, MDL);
! 308: return status;
! 309: }
! 310:
! 311: /* dhcpctl_set_buffer_value
! 312:
! 313: Sets a value on an object referred to by a dhcpctl_handle. like
! 314: dhcpctl_set_value, but saves the trouble of creating a data_string
! 315: for string for which we have a buffer and length. Does not update
! 316: the server - just sets the value on the handle. */
! 317:
! 318: dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
! 319: const char *value, unsigned len,
! 320: const char *value_name)
! 321: {
! 322: isc_result_t status;
! 323: omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
! 324: omapi_data_string_t *name = (omapi_data_string_t *)0;
! 325: unsigned ll;
! 326:
! 327: ll = strlen (value_name);
! 328: status = omapi_data_string_new (&name, ll, MDL);
! 329: if (status != ISC_R_SUCCESS)
! 330: return status;
! 331: memcpy (name -> value, value_name, ll);
! 332:
! 333: status = omapi_typed_data_new (MDL, &tv,
! 334: omapi_datatype_data, len, value);
! 335: if (status != ISC_R_SUCCESS) {
! 336: omapi_data_string_dereference (&name, MDL);
! 337: return status;
! 338: }
! 339: memcpy (tv -> u.buffer.value, value, len);
! 340:
! 341: status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
! 342: omapi_data_string_dereference (&name, MDL);
! 343: omapi_typed_data_dereference (&tv, MDL);
! 344: return status;
! 345: }
! 346:
! 347: /* dhcpctl_set_null_value
! 348:
! 349: Sets a null value on an object referred to by a dhcpctl_handle. */
! 350:
! 351: dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h,
! 352: const char *value_name)
! 353: {
! 354: isc_result_t status;
! 355: omapi_data_string_t *name = (omapi_data_string_t *)0;
! 356: unsigned ll;
! 357:
! 358: ll = strlen (value_name);
! 359: status = omapi_data_string_new (&name, ll, MDL);
! 360: if (status != ISC_R_SUCCESS)
! 361: return status;
! 362: memcpy (name -> value, value_name, ll);
! 363:
! 364: status = omapi_set_value (h, (omapi_object_t *)0, name,
! 365: (omapi_typed_data_t *)0);
! 366: omapi_data_string_dereference (&name, MDL);
! 367: return status;
! 368: }
! 369:
! 370: /* dhcpctl_set_boolean_value
! 371:
! 372: Sets a boolean value on an object - like dhcpctl_set_value,
! 373: only more convenient for booleans. */
! 374:
! 375: dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value,
! 376: const char *value_name)
! 377: {
! 378: isc_result_t status;
! 379: omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
! 380: omapi_data_string_t *name = (omapi_data_string_t *)0;
! 381:
! 382: status = omapi_data_string_new (&name, strlen (value_name), MDL);
! 383: if (status != ISC_R_SUCCESS)
! 384: return status;
! 385: memcpy (name -> value, value_name, strlen (value_name));
! 386:
! 387: status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
! 388: if (status != ISC_R_SUCCESS) {
! 389: omapi_data_string_dereference (&name, MDL);
! 390: return status;
! 391: }
! 392:
! 393: status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
! 394: omapi_data_string_dereference (&name, MDL);
! 395: omapi_typed_data_dereference (&tv, MDL);
! 396: return status;
! 397: }
! 398:
! 399: /* dhcpctl_set_int_value
! 400:
! 401: Sets a boolean value on an object - like dhcpctl_set_value,
! 402: only more convenient for booleans. */
! 403:
! 404: dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
! 405: const char *value_name)
! 406: {
! 407: isc_result_t status;
! 408: omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
! 409: omapi_data_string_t *name = (omapi_data_string_t *)0;
! 410:
! 411: status = omapi_data_string_new (&name, strlen (value_name), MDL);
! 412: if (status != ISC_R_SUCCESS)
! 413: return status;
! 414: memcpy (name -> value, value_name, strlen (value_name));
! 415:
! 416: status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
! 417: if (status != ISC_R_SUCCESS) {
! 418: omapi_data_string_dereference (&name, MDL);
! 419: return status;
! 420: }
! 421:
! 422: status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
! 423: omapi_data_string_dereference (&name, MDL);
! 424: omapi_typed_data_dereference (&tv, MDL);
! 425: return status;
! 426: }
! 427:
! 428: /* dhcpctl_object_update
! 429:
! 430: Queues an update on the object referenced by the handle (there
! 431: can't be any other work in progress on the handle). An
! 432: update means local parameters will be sent to the server. */
! 433:
! 434: dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection,
! 435: dhcpctl_handle h)
! 436: {
! 437: isc_result_t status;
! 438: omapi_object_t *message = (omapi_object_t *)0;
! 439: dhcpctl_remote_object_t *ro;
! 440:
! 441: if (h -> type != dhcpctl_remote_type)
! 442: return ISC_R_INVALIDARG;
! 443: ro = (dhcpctl_remote_object_t *)h;
! 444:
! 445: status = omapi_message_new (&message, MDL);
! 446: if (status != ISC_R_SUCCESS) {
! 447: omapi_object_dereference (&message, MDL);
! 448: return status;
! 449: }
! 450: status = omapi_set_int_value (message, (omapi_object_t *)0,
! 451: "op", OMAPI_OP_UPDATE);
! 452: if (status != ISC_R_SUCCESS) {
! 453: omapi_object_dereference (&message, MDL);
! 454: return status;
! 455: }
! 456:
! 457: status = omapi_set_object_value (message, (omapi_object_t *)0,
! 458: "object", h);
! 459: if (status != ISC_R_SUCCESS) {
! 460: omapi_object_dereference (&message, MDL);
! 461: return status;
! 462: }
! 463:
! 464: status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
! 465: (int)(ro -> remote_handle));
! 466: if (status != ISC_R_SUCCESS) {
! 467: omapi_object_dereference (&message, MDL);
! 468: return status;
! 469: }
! 470:
! 471: omapi_message_register (message);
! 472: status = omapi_protocol_send_message (connection -> outer,
! 473: (omapi_object_t *)0,
! 474: message, (omapi_object_t *)0);
! 475: omapi_object_dereference (&message, MDL);
! 476: return status;
! 477: }
! 478:
! 479: /* Requests a refresh on the object referenced by the handle (there
! 480: can't be any other work in progress on the handle). A
! 481: refresh means local parameters are updated from the server. */
! 482:
! 483: dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection,
! 484: dhcpctl_handle h)
! 485: {
! 486: isc_result_t status;
! 487: omapi_object_t *message = (omapi_object_t *)0;
! 488: dhcpctl_remote_object_t *ro;
! 489:
! 490: if (h -> type != dhcpctl_remote_type)
! 491: return ISC_R_INVALIDARG;
! 492: ro = (dhcpctl_remote_object_t *)h;
! 493:
! 494: status = omapi_message_new (&message, MDL);
! 495: if (status != ISC_R_SUCCESS) {
! 496: omapi_object_dereference (&message, MDL);
! 497: return status;
! 498: }
! 499: status = omapi_set_int_value (message, (omapi_object_t *)0,
! 500: "op", OMAPI_OP_REFRESH);
! 501: if (status != ISC_R_SUCCESS) {
! 502: omapi_object_dereference (&message, MDL);
! 503: return status;
! 504: }
! 505: status = omapi_set_int_value (message, (omapi_object_t *)0,
! 506: "handle", (int)(ro -> remote_handle));
! 507: if (status != ISC_R_SUCCESS) {
! 508: omapi_object_dereference (&message, MDL);
! 509: return status;
! 510: }
! 511:
! 512: omapi_message_register (message);
! 513: status = omapi_protocol_send_message (connection -> outer,
! 514: (omapi_object_t *)0,
! 515: message, (omapi_object_t *)0);
! 516:
! 517: /* We don't want to send the contents of the object down the
! 518: wire, but we do need to reference it so that we know what
! 519: to do with the update. */
! 520: status = omapi_set_object_value (message, (omapi_object_t *)0,
! 521: "object", h);
! 522: if (status != ISC_R_SUCCESS) {
! 523: omapi_object_dereference (&message, MDL);
! 524: return status;
! 525: }
! 526:
! 527: omapi_object_dereference (&message, MDL);
! 528: return status;
! 529: }
! 530:
! 531: /* Requests the removal of the object referenced by the handle (there
! 532: can't be any other work in progress on the handle). A
! 533: removal means that all searchable references to the object on the
! 534: server are deleted. */
! 535:
! 536: dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection,
! 537: dhcpctl_handle h)
! 538: {
! 539: isc_result_t status;
! 540: omapi_object_t *message = (omapi_object_t *)0;
! 541: dhcpctl_remote_object_t *ro;
! 542:
! 543: if (h -> type != dhcpctl_remote_type)
! 544: return ISC_R_INVALIDARG;
! 545: ro = (dhcpctl_remote_object_t *)h;
! 546:
! 547: status = omapi_message_new (&message, MDL);
! 548: if (status != ISC_R_SUCCESS) {
! 549: omapi_object_dereference (&message, MDL);
! 550: return status;
! 551: }
! 552: status = omapi_set_int_value (message, (omapi_object_t *)0,
! 553: "op", OMAPI_OP_DELETE);
! 554: if (status != ISC_R_SUCCESS) {
! 555: omapi_object_dereference (&message, MDL);
! 556: return status;
! 557: }
! 558:
! 559: status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
! 560: (int)(ro -> remote_handle));
! 561: if (status != ISC_R_SUCCESS) {
! 562: omapi_object_dereference (&message, MDL);
! 563: return status;
! 564: }
! 565:
! 566: status = omapi_set_object_value (message, (omapi_object_t *)0,
! 567: "notify-object", h);
! 568: if (status != ISC_R_SUCCESS) {
! 569: omapi_object_dereference (&message, MDL);
! 570: return status;
! 571: }
! 572:
! 573: omapi_message_register (message);
! 574: status = omapi_protocol_send_message (connection -> outer,
! 575: (omapi_object_t *)0,
! 576: message, (omapi_object_t *)0);
! 577: omapi_object_dereference (&message, MDL);
! 578: return status;
! 579: }
! 580:
! 581: isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *vp,
! 582: const char *file, int line)
! 583: {
! 584: return omapi_data_string_dereference (vp, file, line);
! 585: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>