xref: /minix/external/bsd/dhcp/dist/omapip/generic.c (revision 83ee113e)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: generic.c,v 1.1.1.2 2014/07/12 11:57:59 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* generic.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    Subroutines that support the generic object. */
5*83ee113eSDavid van Moolenbroek 
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004-2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 1999-2003 by Internet Software Consortium
9*83ee113eSDavid van Moolenbroek  *
10*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek  *
14*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21*83ee113eSDavid van Moolenbroek  *
22*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
23*83ee113eSDavid van Moolenbroek  *   950 Charter Street
24*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
25*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
26*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
27*83ee113eSDavid van Moolenbroek  *
28*83ee113eSDavid van Moolenbroek  */
29*83ee113eSDavid van Moolenbroek 
30*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
31*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: generic.c,v 1.1.1.2 2014/07/12 11:57:59 spz Exp $");
32*83ee113eSDavid van Moolenbroek 
33*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
34*83ee113eSDavid van Moolenbroek 
35*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
36*83ee113eSDavid van Moolenbroek 
OMAPI_OBJECT_ALLOC(omapi_generic,omapi_generic_object_t,omapi_type_generic)37*83ee113eSDavid van Moolenbroek OMAPI_OBJECT_ALLOC (omapi_generic,
38*83ee113eSDavid van Moolenbroek 		    omapi_generic_object_t, omapi_type_generic)
39*83ee113eSDavid van Moolenbroek 
40*83ee113eSDavid van Moolenbroek isc_result_t omapi_generic_new (omapi_object_t **gen,
41*83ee113eSDavid van Moolenbroek 				const char *file, int line)
42*83ee113eSDavid van Moolenbroek {
43*83ee113eSDavid van Moolenbroek 	/* Backwards compatibility. */
44*83ee113eSDavid van Moolenbroek 	return omapi_generic_allocate ((omapi_generic_object_t **)gen,
45*83ee113eSDavid van Moolenbroek 				       file, line);
46*83ee113eSDavid van Moolenbroek }
47*83ee113eSDavid van Moolenbroek 
omapi_generic_set_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_typed_data_t * value)48*83ee113eSDavid van Moolenbroek isc_result_t omapi_generic_set_value (omapi_object_t *h,
49*83ee113eSDavid van Moolenbroek 				      omapi_object_t *id,
50*83ee113eSDavid van Moolenbroek 				      omapi_data_string_t *name,
51*83ee113eSDavid van Moolenbroek 				      omapi_typed_data_t *value)
52*83ee113eSDavid van Moolenbroek {
53*83ee113eSDavid van Moolenbroek 	omapi_generic_object_t *g;
54*83ee113eSDavid van Moolenbroek 	omapi_value_t *new;
55*83ee113eSDavid van Moolenbroek 	omapi_value_t **va;
56*83ee113eSDavid van Moolenbroek 	u_int8_t *ca;
57*83ee113eSDavid van Moolenbroek 	int vm_new;
58*83ee113eSDavid van Moolenbroek 	int i, vfree = -1;
59*83ee113eSDavid van Moolenbroek 	isc_result_t status;
60*83ee113eSDavid van Moolenbroek 
61*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_generic)
62*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
63*83ee113eSDavid van Moolenbroek 	g = (omapi_generic_object_t *)h;
64*83ee113eSDavid van Moolenbroek 
65*83ee113eSDavid van Moolenbroek 	/* See if there's already a value with this name attached to
66*83ee113eSDavid van Moolenbroek 	   the generic object, and if so, replace the current value
67*83ee113eSDavid van Moolenbroek 	   with the new one. */
68*83ee113eSDavid van Moolenbroek 	for (i = 0; i < g -> nvalues; i++) {
69*83ee113eSDavid van Moolenbroek 		if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
70*83ee113eSDavid van Moolenbroek 			/* There's an inconsistency here: the standard
71*83ee113eSDavid van Moolenbroek 			   behaviour of a set_values method when
72*83ee113eSDavid van Moolenbroek 			   passed a matching name and a null value is
73*83ee113eSDavid van Moolenbroek 			   to delete the value associated with that
74*83ee113eSDavid van Moolenbroek 			   name (where possible).  In the generic
75*83ee113eSDavid van Moolenbroek 			   object, we remember the name/null pair,
76*83ee113eSDavid van Moolenbroek 			   because generic objects are generally used
77*83ee113eSDavid van Moolenbroek 			   to pass messages around, and this is the
78*83ee113eSDavid van Moolenbroek 			   way that remote entities delete values from
79*83ee113eSDavid van Moolenbroek 			   local objects.  If the get_value method of
80*83ee113eSDavid van Moolenbroek 			   a generic object is called for a name that
81*83ee113eSDavid van Moolenbroek 			   maps to a name/null pair, ISC_R_NOTFOUND is
82*83ee113eSDavid van Moolenbroek 			   returned. */
83*83ee113eSDavid van Moolenbroek 			new = (omapi_value_t *)0;
84*83ee113eSDavid van Moolenbroek 			status = (omapi_value_new (&new, MDL));
85*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS)
86*83ee113eSDavid van Moolenbroek 				return status;
87*83ee113eSDavid van Moolenbroek 			omapi_data_string_reference (&new -> name, name, MDL);
88*83ee113eSDavid van Moolenbroek 			if (value)
89*83ee113eSDavid van Moolenbroek 				omapi_typed_data_reference (&new -> value,
90*83ee113eSDavid van Moolenbroek 							    value, MDL);
91*83ee113eSDavid van Moolenbroek 
92*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&(g -> values [i]), MDL);
93*83ee113eSDavid van Moolenbroek 			status = (omapi_value_reference
94*83ee113eSDavid van Moolenbroek 				  (&(g -> values [i]), new, MDL));
95*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&new, MDL);
96*83ee113eSDavid van Moolenbroek 			g -> changed [i] = 1;
97*83ee113eSDavid van Moolenbroek 			return status;
98*83ee113eSDavid van Moolenbroek 		}
99*83ee113eSDavid van Moolenbroek 		/* Notice a free slot if we pass one. */
100*83ee113eSDavid van Moolenbroek 		else if (vfree == -1 && !g -> values [i])
101*83ee113eSDavid van Moolenbroek 			vfree = i;
102*83ee113eSDavid van Moolenbroek 	}
103*83ee113eSDavid van Moolenbroek 
104*83ee113eSDavid van Moolenbroek 	/* If the name isn't already attached to this object, see if an
105*83ee113eSDavid van Moolenbroek 	   inner object has it. */
106*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> set_value) {
107*83ee113eSDavid van Moolenbroek 		status = ((*(h -> inner -> type -> set_value))
108*83ee113eSDavid van Moolenbroek 			  (h -> inner, id, name, value));
109*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_NOTFOUND)
110*83ee113eSDavid van Moolenbroek 			return status;
111*83ee113eSDavid van Moolenbroek 	}
112*83ee113eSDavid van Moolenbroek 
113*83ee113eSDavid van Moolenbroek 	/* Okay, so it's a value that no inner object knows about, and
114*83ee113eSDavid van Moolenbroek 	   (implicitly, since the outer object set_value method would
115*83ee113eSDavid van Moolenbroek 	   have called this object's set_value method) it's an object that
116*83ee113eSDavid van Moolenbroek 	   no outer object knows about, it's this object's responsibility
117*83ee113eSDavid van Moolenbroek 	   to remember it - that's what generic objects do. */
118*83ee113eSDavid van Moolenbroek 
119*83ee113eSDavid van Moolenbroek 	/* Arrange for there to be space for the pointer to the new
120*83ee113eSDavid van Moolenbroek            name/value pair if necessary: */
121*83ee113eSDavid van Moolenbroek 	if (vfree == -1) {
122*83ee113eSDavid van Moolenbroek 		vfree = g -> nvalues;
123*83ee113eSDavid van Moolenbroek 		if (vfree == g -> va_max) {
124*83ee113eSDavid van Moolenbroek 			if (g -> va_max)
125*83ee113eSDavid van Moolenbroek 				vm_new = 2 * g -> va_max;
126*83ee113eSDavid van Moolenbroek 			else
127*83ee113eSDavid van Moolenbroek 				vm_new = 10;
128*83ee113eSDavid van Moolenbroek 			va = dmalloc (vm_new * sizeof *va, MDL);
129*83ee113eSDavid van Moolenbroek 			if (!va)
130*83ee113eSDavid van Moolenbroek 				return ISC_R_NOMEMORY;
131*83ee113eSDavid van Moolenbroek 			ca = dmalloc (vm_new * sizeof *ca, MDL);
132*83ee113eSDavid van Moolenbroek 			if (!ca) {
133*83ee113eSDavid van Moolenbroek 				dfree (va, MDL);
134*83ee113eSDavid van Moolenbroek 				return ISC_R_NOMEMORY;
135*83ee113eSDavid van Moolenbroek 			}
136*83ee113eSDavid van Moolenbroek 			if (g -> va_max) {
137*83ee113eSDavid van Moolenbroek 				memcpy (va, g -> values,
138*83ee113eSDavid van Moolenbroek 					g -> va_max * sizeof *va);
139*83ee113eSDavid van Moolenbroek 				memcpy (ca, g -> changed,
140*83ee113eSDavid van Moolenbroek 					g -> va_max * sizeof *ca);
141*83ee113eSDavid van Moolenbroek 			}
142*83ee113eSDavid van Moolenbroek 			memset (va + g -> va_max, 0,
143*83ee113eSDavid van Moolenbroek 				(vm_new - g -> va_max) * sizeof *va);
144*83ee113eSDavid van Moolenbroek 			memset (ca + g -> va_max, 0,
145*83ee113eSDavid van Moolenbroek 				(vm_new - g -> va_max) * sizeof *ca);
146*83ee113eSDavid van Moolenbroek 			if (g -> values)
147*83ee113eSDavid van Moolenbroek 				dfree (g -> values, MDL);
148*83ee113eSDavid van Moolenbroek 			if (g -> changed)
149*83ee113eSDavid van Moolenbroek 				dfree (g -> changed, MDL);
150*83ee113eSDavid van Moolenbroek 			g -> values = va;
151*83ee113eSDavid van Moolenbroek 			g -> changed = ca;
152*83ee113eSDavid van Moolenbroek 			g -> va_max = vm_new;
153*83ee113eSDavid van Moolenbroek 		}
154*83ee113eSDavid van Moolenbroek 	}
155*83ee113eSDavid van Moolenbroek 	status = omapi_value_new (&g -> values [vfree], MDL);
156*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
157*83ee113eSDavid van Moolenbroek 		return status;
158*83ee113eSDavid van Moolenbroek 	omapi_data_string_reference (&g -> values [vfree] -> name,
159*83ee113eSDavid van Moolenbroek 				     name, MDL);
160*83ee113eSDavid van Moolenbroek 	if (value)
161*83ee113eSDavid van Moolenbroek 		omapi_typed_data_reference
162*83ee113eSDavid van Moolenbroek 			(&g -> values [vfree] -> value, value, MDL);
163*83ee113eSDavid van Moolenbroek 	g -> changed [vfree] = 1;
164*83ee113eSDavid van Moolenbroek 	if (vfree == g -> nvalues)
165*83ee113eSDavid van Moolenbroek 		g -> nvalues++;
166*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
167*83ee113eSDavid van Moolenbroek }
168*83ee113eSDavid van Moolenbroek 
omapi_generic_get_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_value_t ** value)169*83ee113eSDavid van Moolenbroek isc_result_t omapi_generic_get_value (omapi_object_t *h,
170*83ee113eSDavid van Moolenbroek 				      omapi_object_t *id,
171*83ee113eSDavid van Moolenbroek 				      omapi_data_string_t *name,
172*83ee113eSDavid van Moolenbroek 				      omapi_value_t **value)
173*83ee113eSDavid van Moolenbroek {
174*83ee113eSDavid van Moolenbroek 	int i;
175*83ee113eSDavid van Moolenbroek 	omapi_generic_object_t *g;
176*83ee113eSDavid van Moolenbroek 
177*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_generic)
178*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
179*83ee113eSDavid van Moolenbroek 	g = (omapi_generic_object_t *)h;
180*83ee113eSDavid van Moolenbroek 
181*83ee113eSDavid van Moolenbroek 	/* Look up the specified name in our list of objects. */
182*83ee113eSDavid van Moolenbroek 	for (i = 0; i < g -> nvalues; i++) {
183*83ee113eSDavid van Moolenbroek 		if (!g -> values[i])
184*83ee113eSDavid van Moolenbroek 			continue;
185*83ee113eSDavid van Moolenbroek 		if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
186*83ee113eSDavid van Moolenbroek 			/* If this is a name/null value pair, this is the
187*83ee113eSDavid van Moolenbroek 			   same as if there were no value that matched
188*83ee113eSDavid van Moolenbroek 			   the specified name, so return ISC_R_NOTFOUND. */
189*83ee113eSDavid van Moolenbroek 			if (!g -> values [i] -> value)
190*83ee113eSDavid van Moolenbroek 				return ISC_R_NOTFOUND;
191*83ee113eSDavid van Moolenbroek 			/* Otherwise, return the name/value pair. */
192*83ee113eSDavid van Moolenbroek 			return omapi_value_reference (value,
193*83ee113eSDavid van Moolenbroek 						      g -> values [i], MDL);
194*83ee113eSDavid van Moolenbroek 		}
195*83ee113eSDavid van Moolenbroek 	}
196*83ee113eSDavid van Moolenbroek 
197*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> get_value)
198*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> get_value))
199*83ee113eSDavid van Moolenbroek 			(h -> inner, id, name, value);
200*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
201*83ee113eSDavid van Moolenbroek }
202*83ee113eSDavid van Moolenbroek 
omapi_generic_destroy(omapi_object_t * h,const char * file,int line)203*83ee113eSDavid van Moolenbroek isc_result_t omapi_generic_destroy (omapi_object_t *h,
204*83ee113eSDavid van Moolenbroek 				    const char *file, int line)
205*83ee113eSDavid van Moolenbroek {
206*83ee113eSDavid van Moolenbroek 	omapi_generic_object_t *g;
207*83ee113eSDavid van Moolenbroek 	int i;
208*83ee113eSDavid van Moolenbroek 
209*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_generic)
210*83ee113eSDavid van Moolenbroek 		return ISC_R_UNEXPECTED;
211*83ee113eSDavid van Moolenbroek 	g = (omapi_generic_object_t *)h;
212*83ee113eSDavid van Moolenbroek 
213*83ee113eSDavid van Moolenbroek 	if (g -> values) {
214*83ee113eSDavid van Moolenbroek 		for (i = 0; i < g -> nvalues; i++) {
215*83ee113eSDavid van Moolenbroek 			if (g -> values [i])
216*83ee113eSDavid van Moolenbroek 				omapi_value_dereference (&g -> values [i],
217*83ee113eSDavid van Moolenbroek 							 file, line);
218*83ee113eSDavid van Moolenbroek 		}
219*83ee113eSDavid van Moolenbroek 		dfree (g -> values, file, line);
220*83ee113eSDavid van Moolenbroek 		dfree (g -> changed, file, line);
221*83ee113eSDavid van Moolenbroek 		g -> values = (omapi_value_t **)0;
222*83ee113eSDavid van Moolenbroek 		g -> changed = (u_int8_t *)0;
223*83ee113eSDavid van Moolenbroek 		g -> va_max = 0;
224*83ee113eSDavid van Moolenbroek 	}
225*83ee113eSDavid van Moolenbroek 
226*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
227*83ee113eSDavid van Moolenbroek }
228*83ee113eSDavid van Moolenbroek 
omapi_generic_signal_handler(omapi_object_t * h,const char * name,va_list ap)229*83ee113eSDavid van Moolenbroek isc_result_t omapi_generic_signal_handler (omapi_object_t *h,
230*83ee113eSDavid van Moolenbroek 					   const char *name, va_list ap)
231*83ee113eSDavid van Moolenbroek {
232*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_generic)
233*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
234*83ee113eSDavid van Moolenbroek 
235*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> signal_handler)
236*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> signal_handler)) (h -> inner,
237*83ee113eSDavid van Moolenbroek 								  name, ap);
238*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
239*83ee113eSDavid van Moolenbroek }
240*83ee113eSDavid van Moolenbroek 
241*83ee113eSDavid van Moolenbroek /* Write all the published values associated with the object through the
242*83ee113eSDavid van Moolenbroek    specified connection. */
243*83ee113eSDavid van Moolenbroek 
omapi_generic_stuff_values(omapi_object_t * c,omapi_object_t * id,omapi_object_t * g)244*83ee113eSDavid van Moolenbroek isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
245*83ee113eSDavid van Moolenbroek 					 omapi_object_t *id,
246*83ee113eSDavid van Moolenbroek 					 omapi_object_t *g)
247*83ee113eSDavid van Moolenbroek {
248*83ee113eSDavid van Moolenbroek 	omapi_generic_object_t *src;
249*83ee113eSDavid van Moolenbroek 	int i;
250*83ee113eSDavid van Moolenbroek 	isc_result_t status;
251*83ee113eSDavid van Moolenbroek 
252*83ee113eSDavid van Moolenbroek 	if (g -> type != omapi_type_generic)
253*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
254*83ee113eSDavid van Moolenbroek 	src = (omapi_generic_object_t *)g;
255*83ee113eSDavid van Moolenbroek 
256*83ee113eSDavid van Moolenbroek 	for (i = 0; i < src -> nvalues; i++) {
257*83ee113eSDavid van Moolenbroek 		if (src -> values [i] && src -> values [i] -> name -> len &&
258*83ee113eSDavid van Moolenbroek 		    src -> changed [i]) {
259*83ee113eSDavid van Moolenbroek 			status = (omapi_connection_put_uint16
260*83ee113eSDavid van Moolenbroek 				  (c, src -> values [i] -> name -> len));
261*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS)
262*83ee113eSDavid van Moolenbroek 				return status;
263*83ee113eSDavid van Moolenbroek 			status = (omapi_connection_copyin
264*83ee113eSDavid van Moolenbroek 				  (c, src -> values [i] -> name -> value,
265*83ee113eSDavid van Moolenbroek 				   src -> values [i] -> name -> len));
266*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS)
267*83ee113eSDavid van Moolenbroek 				return status;
268*83ee113eSDavid van Moolenbroek 
269*83ee113eSDavid van Moolenbroek 			status = (omapi_connection_write_typed_data
270*83ee113eSDavid van Moolenbroek 				  (c, src -> values [i] -> value));
271*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS)
272*83ee113eSDavid van Moolenbroek 				return status;
273*83ee113eSDavid van Moolenbroek 		}
274*83ee113eSDavid van Moolenbroek 	}
275*83ee113eSDavid van Moolenbroek 
276*83ee113eSDavid van Moolenbroek 	if (g -> inner && g -> inner -> type -> stuff_values)
277*83ee113eSDavid van Moolenbroek 		return (*(g -> inner -> type -> stuff_values)) (c, id,
278*83ee113eSDavid van Moolenbroek 								g -> inner);
279*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
280*83ee113eSDavid van Moolenbroek }
281*83ee113eSDavid van Moolenbroek 
282*83ee113eSDavid van Moolenbroek /* Clear the changed flags on the object.   This has the effect that if
283*83ee113eSDavid van Moolenbroek    generic_stuff is called, any attributes that still have a cleared changed
284*83ee113eSDavid van Moolenbroek    flag aren't sent to the peer.   This also deletes any values that are
285*83ee113eSDavid van Moolenbroek    null, presuming that these have now been properly handled. */
286*83ee113eSDavid van Moolenbroek 
omapi_generic_clear_flags(omapi_object_t * o)287*83ee113eSDavid van Moolenbroek isc_result_t omapi_generic_clear_flags (omapi_object_t *o)
288*83ee113eSDavid van Moolenbroek {
289*83ee113eSDavid van Moolenbroek 	int i;
290*83ee113eSDavid van Moolenbroek 	omapi_generic_object_t *g;
291*83ee113eSDavid van Moolenbroek 
292*83ee113eSDavid van Moolenbroek 	if (o -> type != omapi_type_generic)
293*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
294*83ee113eSDavid van Moolenbroek 	g = (omapi_generic_object_t *)o;
295*83ee113eSDavid van Moolenbroek 
296*83ee113eSDavid van Moolenbroek 	for (i = 0; i < g -> nvalues; i++) {
297*83ee113eSDavid van Moolenbroek 		g -> changed [i] = 0;
298*83ee113eSDavid van Moolenbroek 		if (g -> values [i] &&
299*83ee113eSDavid van Moolenbroek 		    !g -> values [i] -> value)
300*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&g -> values [i], MDL);
301*83ee113eSDavid van Moolenbroek 	}
302*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
303*83ee113eSDavid van Moolenbroek }
304