File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / dhcpctl / dhcpctl.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:54 2012 UTC (12 years ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

    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>