ISC DHCP 4.4.3-P1
A reference DHCPv4 and DHCPv6 implementation
 
Loading...
Searching...
No Matches
generic.c
Go to the documentation of this file.
1/* generic.c
2
3 Subroutines that support the generic object. */
4
5/*
6 * Copyright (C) 2004-2022 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 * PO Box 360
23 * Newmarket, NH 03857 USA
24 * <info@isc.org>
25 * https://www.isc.org/
26 *
27 */
28
29#include "dhcpd.h"
30
31#include <omapip/omapip_p.h>
32
33OMAPI_OBJECT_ALLOC (omapi_generic,
35
36isc_result_t omapi_generic_new (omapi_object_t **gen,
37 const char *file, int line)
38{
39 /* Backwards compatibility. */
40 return omapi_generic_allocate ((omapi_generic_object_t **)gen,
41 file, line);
42}
43
48{
50 omapi_value_t *new;
51 omapi_value_t **va;
52 u_int8_t *ca;
53 int vm_new;
54 int i, vfree = -1;
55 isc_result_t status;
56
57 if (h -> type != omapi_type_generic)
58 return DHCP_R_INVALIDARG;
60
61 /* See if there's already a value with this name attached to
62 the generic object, and if so, replace the current value
63 with the new one. */
64 for (i = 0; i < g -> nvalues; i++) {
65 if (!g -> values[i])
66 continue;
67
68 if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
69 /* There's an inconsistency here: the standard
70 behaviour of a set_values method when
71 passed a matching name and a null value is
72 to delete the value associated with that
73 name (where possible). In the generic
74 object, we remember the name/null pair,
75 because generic objects are generally used
76 to pass messages around, and this is the
77 way that remote entities delete values from
78 local objects. If the get_value method of
79 a generic object is called for a name that
80 maps to a name/null pair, ISC_R_NOTFOUND is
81 returned. */
82 new = (omapi_value_t *)0;
83 status = (omapi_value_new (&new, MDL));
84 if (status != ISC_R_SUCCESS)
85 return status;
86 omapi_data_string_reference (&new -> name, name, MDL);
87 if (value)
89 value, MDL);
90
91 omapi_value_dereference (&(g -> values [i]), MDL);
92 status = (omapi_value_reference
93 (&(g -> values [i]), new, MDL));
95 g -> changed [i] = 1;
96 return status;
97 }
98 /* Notice a free slot if we pass one. */
99 else if (vfree == -1 && !g -> values [i])
100 vfree = i;
101 }
102
103 /* If the name isn't already attached to this object, see if an
104 inner object has it. */
105 if (h -> inner && h -> inner -> type -> set_value) {
106 status = ((*(h -> inner -> type -> set_value))
107 (h -> inner, id, name, value));
108 if (status != ISC_R_NOTFOUND)
109 return status;
110 }
111
112 /* Okay, so it's a value that no inner object knows about, and
113 (implicitly, since the outer object set_value method would
114 have called this object's set_value method) it's an object that
115 no outer object knows about, it's this object's responsibility
116 to remember it - that's what generic objects do. */
117
118 /* Arrange for there to be space for the pointer to the new
119 name/value pair if necessary: */
120 if (vfree == -1) {
121 vfree = g -> nvalues;
122 if (vfree == g -> va_max) {
123 if (g -> va_max)
124 vm_new = 2 * g -> va_max;
125 else
126 vm_new = 10;
127 va = dmalloc (vm_new * sizeof *va, MDL);
128 if (!va)
129 return ISC_R_NOMEMORY;
130 ca = dmalloc (vm_new * sizeof *ca, MDL);
131 if (!ca) {
132 dfree (va, MDL);
133 return ISC_R_NOMEMORY;
134 }
135 if (g -> va_max) {
136 memcpy (va, g -> values,
137 g -> va_max * sizeof *va);
138 memcpy (ca, g -> changed,
139 g -> va_max * sizeof *ca);
140 }
141 memset (va + g -> va_max, 0,
142 (vm_new - g -> va_max) * sizeof *va);
143 memset (ca + g -> va_max, 0,
144 (vm_new - g -> va_max) * sizeof *ca);
145 if (g -> values)
146 dfree (g -> values, MDL);
147 if (g -> changed)
148 dfree (g -> changed, MDL);
149 g -> values = va;
150 g -> changed = ca;
151 g -> va_max = vm_new;
152 }
153 }
154 status = omapi_value_new (&g -> values [vfree], MDL);
155 if (status != ISC_R_SUCCESS)
156 return status;
157 omapi_data_string_reference (&g -> values [vfree] -> name,
158 name, MDL);
159 if (value)
161 (&g -> values [vfree] -> value, value, MDL);
162 g -> changed [vfree] = 1;
163 if (vfree == g -> nvalues)
164 g -> nvalues++;
165 return ISC_R_SUCCESS;
166}
167
169 omapi_object_t *id,
172{
173 int i;
175
176 if (h -> type != omapi_type_generic)
177 return DHCP_R_INVALIDARG;
178 g = (omapi_generic_object_t *)h;
179
180 /* Look up the specified name in our list of objects. */
181 for (i = 0; i < g -> nvalues; i++) {
182 if (!g -> values[i])
183 continue;
184 if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
185 /* If this is a name/null value pair, this is the
186 same as if there were no value that matched
187 the specified name, so return ISC_R_NOTFOUND. */
188 if (!g -> values [i] -> value)
189 return ISC_R_NOTFOUND;
190 /* Otherwise, return the name/value pair. */
192 g -> values [i], MDL);
193 }
194 }
195
196 if (h -> inner && h -> inner -> type -> get_value)
197 return (*(h -> inner -> type -> get_value))
198 (h -> inner, id, name, value);
199 return ISC_R_NOTFOUND;
200}
201
203 const char *file, int line)
204{
206 int i;
207
208 if (h -> type != omapi_type_generic)
209 return ISC_R_UNEXPECTED;
210 g = (omapi_generic_object_t *)h;
211
212 if (g -> values) {
213 for (i = 0; i < g -> nvalues; i++) {
214 if (g -> values [i])
215 omapi_value_dereference (&g -> values [i],
216 file, line);
217 }
218 dfree (g -> values, file, line);
219 dfree (g -> changed, file, line);
220 g -> values = (omapi_value_t **)0;
221 g -> changed = (u_int8_t *)0;
222 g -> va_max = 0;
223 }
224
225 return ISC_R_SUCCESS;
226}
227
229 const char *name, va_list ap)
230{
231 if (h -> type != omapi_type_generic)
232 return DHCP_R_INVALIDARG;
233
234 if (h -> inner && h -> inner -> type -> signal_handler)
235 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
236 name, ap);
237 return ISC_R_NOTFOUND;
238}
239
240/* Write all the published values associated with the object through the
241 specified connection. */
242
244 omapi_object_t *id,
246{
248 int i;
249 isc_result_t status;
250
251 if (g -> type != omapi_type_generic)
252 return DHCP_R_INVALIDARG;
253 src = (omapi_generic_object_t *)g;
254
255 for (i = 0; i < src -> nvalues; i++) {
256 if (src -> values [i] && src -> values [i] -> name -> len &&
257 src -> changed [i]) {
259 (c, src -> values [i] -> name -> len));
260 if (status != ISC_R_SUCCESS)
261 return status;
263 (c, src -> values [i] -> name -> value,
264 src -> values [i] -> name -> len));
265 if (status != ISC_R_SUCCESS)
266 return status;
267
269 (c, src -> values [i] -> value));
270 if (status != ISC_R_SUCCESS)
271 return status;
272 }
273 }
274
275 if (g -> inner && g -> inner -> type -> stuff_values)
276 return (*(g -> inner -> type -> stuff_values)) (c, id,
277 g -> inner);
278 return ISC_R_SUCCESS;
279}
280
281/* Clear the changed flags on the object. This has the effect that if
282 generic_stuff is called, any attributes that still have a cleared changed
283 flag aren't sent to the peer. This also deletes any values that are
284 null, presuming that these have now been properly handled. */
285
287{
288 int i;
290
291 if (o -> type != omapi_type_generic)
292 return DHCP_R_INVALIDARG;
293 g = (omapi_generic_object_t *)o;
294
295 for (i = 0; i < g -> nvalues; i++) {
296 g -> changed [i] = 0;
297 if (g -> values [i] &&
298 !g -> values [i] -> value)
299 omapi_value_dereference (&g -> values [i], MDL);
300 }
301 return ISC_R_SUCCESS;
302}
isc_result_t omapi_connection_put_uint16(omapi_object_t *, u_int32_t)
Definition buffer.c:621
isc_result_t omapi_connection_copyin(omapi_object_t *, const unsigned char *, unsigned)
Definition buffer.c:265
const char int line
Definition dhcpd.h:3802
const char * file
Definition dhcpd.h:3802
isc_result_t omapi_generic_clear_flags(omapi_object_t *o)
Definition generic.c:286
isc_result_t omapi_generic_stuff_values(omapi_object_t *c, omapi_object_t *id, omapi_object_t *g)
Definition generic.c:243
isc_result_t omapi_generic_signal_handler(omapi_object_t *h, const char *name, va_list ap)
Definition generic.c:228
isc_result_t omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value)
Definition generic.c:168
isc_result_t omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_typed_data_t *value)
Definition generic.c:44
isc_result_t omapi_generic_destroy(omapi_object_t *h, const char *file, int line)
Definition generic.c:202
#define ISC_R_SUCCESS
isc_result_t omapi_value_dereference(omapi_value_t **, const char *, int)
Definition alloc.c:1060
#define MDL
Definition omapip.h:567
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
int omapi_data_string_cmp(omapi_data_string_t *, omapi_data_string_t *)
Definition support.c:562
isc_result_t omapi_typed_data_reference(omapi_typed_data_t **, omapi_typed_data_t *, const char *, int)
Definition alloc.c:880
#define OMAPI_OBJECT_ALLOC(name, stype, type)
Definition omapip.h:160
isc_result_t omapi_value_reference(omapi_value_t **, omapi_value_t *, const char *, int)
Definition alloc.c:1038
struct __omapi_object omapi_object_t
Definition omapip.h:39
omapi_object_type_t * omapi_type_generic
Definition support.c:37
isc_result_t omapi_connection_write_typed_data(omapi_object_t *, omapi_typed_data_t *)
Definition buffer.c:632
void * dmalloc(size_t, const char *, int)
Definition alloc.c:57
isc_result_t omapi_data_string_reference(omapi_data_string_t **, omapi_data_string_t *, const char *, int)
Definition alloc.c:967
void dfree(void *, const char *, int)
Definition alloc.c:145
isc_result_t omapi_value_new(omapi_value_t **, const char *, int)
Definition alloc.c:1026
struct __omapi_generic_object omapi_generic_object_t
#define DHCP_R_INVALIDARG
Definition result.h:49
Definition data.h:205