1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27 #include <assert.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <libdlwlan.h>
33 #include <libnvpair.h>
34
35 #include "libnwam_impl.h"
36 #include <libnwam_priv.h>
37 #include <libnwam.h>
38
39 /*
40 * Internal implementation of libnwam in-memory objects and values. Objects
41 * are nvlists.
42 */
43
44 void
nwam_value_free(nwam_value_t value)45 nwam_value_free(nwam_value_t value)
46 {
47 uint_t i;
48
49 if (value == NULL)
50 return;
51
52 switch (value->nwv_value_type) {
53 case NWAM_VALUE_TYPE_BOOLEAN:
54 free(value->nwv_values.nwv_boolean);
55 break;
56 case NWAM_VALUE_TYPE_INT64:
57 free(value->nwv_values.nwv_int64);
58 break;
59 case NWAM_VALUE_TYPE_UINT64:
60 free(value->nwv_values.nwv_uint64);
61 break;
62 case NWAM_VALUE_TYPE_STRING:
63 for (i = 0; i < value->nwv_value_numvalues; i++)
64 free(value->nwv_values.nwv_string[i]);
65 free(value->nwv_values.nwv_string);
66 break;
67 }
68 free(value);
69 }
70
71 nwam_error_t
nwam_value_create(nwam_value_type_t value_type,void * values,uint_t numvalues,nwam_value_t * valuep)72 nwam_value_create(nwam_value_type_t value_type, void *values, uint_t numvalues,
73 nwam_value_t *valuep)
74 {
75 nwam_value_t newvalue;
76 boolean_t *values_boolean;
77 int64_t *values_int64;
78 uint64_t *values_uint64;
79 char **values_string;
80 int i, j;
81 nwam_error_t err = NWAM_SUCCESS;
82
83 *valuep = NULL;
84
85 if ((newvalue = calloc(1, sizeof (struct nwam_value))) == NULL)
86 return (NWAM_NO_MEMORY);
87
88 newvalue->nwv_value_type = value_type;
89 newvalue->nwv_value_numvalues = numvalues;
90
91 switch (value_type) {
92 case NWAM_VALUE_TYPE_BOOLEAN:
93 values_boolean = values;
94 if ((newvalue->nwv_values.nwv_boolean =
95 calloc(numvalues, sizeof (boolean_t))) == NULL) {
96 free(newvalue);
97 return (NWAM_NO_MEMORY);
98 }
99 for (i = 0; i < numvalues; i++)
100 newvalue->nwv_values.nwv_boolean[i] = values_boolean[i];
101 break;
102 case NWAM_VALUE_TYPE_INT64:
103 values_int64 = values;
104 if ((newvalue->nwv_values.nwv_int64 =
105 calloc(numvalues, sizeof (int64_t))) == NULL) {
106 free(newvalue);
107 return (NWAM_NO_MEMORY);
108 }
109 for (i = 0; i < numvalues; i++)
110 newvalue->nwv_values.nwv_int64[i] = values_int64[i];
111 break;
112 case NWAM_VALUE_TYPE_UINT64:
113 values_uint64 = values;
114 if ((newvalue->nwv_values.nwv_uint64 =
115 calloc(numvalues, sizeof (uint64_t))) == NULL) {
116 free(newvalue);
117 return (NWAM_NO_MEMORY);
118 }
119 for (i = 0; i < numvalues; i++)
120 newvalue->nwv_values.nwv_uint64[i] = values_uint64[i];
121 break;
122 case NWAM_VALUE_TYPE_STRING:
123 values_string = values;
124 if ((newvalue->nwv_values.nwv_string =
125 calloc(numvalues, sizeof (char *))) == NULL) {
126 free(newvalue);
127 return (NWAM_NO_MEMORY);
128 }
129 for (i = 0; i < numvalues; i++) {
130 if (strnlen(values_string[i], NWAM_MAX_VALUE_LEN) ==
131 NWAM_MAX_VALUE_LEN) {
132 err = NWAM_ENTITY_INVALID_VALUE;
133 } else if ((newvalue->nwv_values.nwv_string[i] =
134 strdup(values_string[i])) == NULL) {
135 err = NWAM_NO_MEMORY;
136 }
137 if (err != NWAM_SUCCESS) {
138 for (j = 0; j < i; j++)
139 free(
140 newvalue->nwv_values.nwv_string[i]);
141 free(newvalue->nwv_values.nwv_string);
142 free(newvalue);
143 return (err);
144 }
145 }
146 break;
147 default:
148 break;
149 }
150
151 *valuep = newvalue;
152 return (NWAM_SUCCESS);
153 }
154
155 nwam_error_t
nwam_value_copy(nwam_value_t old,nwam_value_t * newp)156 nwam_value_copy(nwam_value_t old, nwam_value_t *newp)
157 {
158 void *values;
159
160 assert(old != NULL && newp != NULL);
161
162 switch (old->nwv_value_type) {
163 case NWAM_VALUE_TYPE_BOOLEAN:
164 values = old->nwv_values.nwv_boolean;
165 break;
166 case NWAM_VALUE_TYPE_INT64:
167 values = old->nwv_values.nwv_int64;
168 break;
169 case NWAM_VALUE_TYPE_UINT64:
170 values = old->nwv_values.nwv_uint64;
171 break;
172 case NWAM_VALUE_TYPE_STRING:
173 values = old->nwv_values.nwv_string;
174 break;
175 default:
176 return (NWAM_INVALID_ARG);
177 }
178 return (nwam_value_create(old->nwv_value_type, values,
179 old->nwv_value_numvalues, newp));
180 }
181 nwam_error_t
nwam_value_create_boolean_array(boolean_t * values,uint_t numvalues,nwam_value_t * valuep)182 nwam_value_create_boolean_array(boolean_t *values, uint_t numvalues,
183 nwam_value_t *valuep)
184 {
185 return (nwam_value_create(NWAM_VALUE_TYPE_BOOLEAN, values, numvalues,
186 valuep));
187 }
188
189 nwam_error_t
nwam_value_create_boolean(boolean_t value,nwam_value_t * valuep)190 nwam_value_create_boolean(boolean_t value, nwam_value_t *valuep)
191 {
192 return (nwam_value_create_boolean_array(&value, 1, valuep));
193 }
194
195 nwam_error_t
nwam_value_create_int64_array(int64_t * values,uint_t numvalues,nwam_value_t * valuep)196 nwam_value_create_int64_array(int64_t *values, uint_t numvalues,
197 nwam_value_t *valuep)
198 {
199 return (nwam_value_create(NWAM_VALUE_TYPE_INT64, values, numvalues,
200 valuep));
201 }
202
203 nwam_error_t
nwam_value_create_int64(int64_t value,nwam_value_t * valuep)204 nwam_value_create_int64(int64_t value, nwam_value_t *valuep)
205 {
206 return (nwam_value_create_int64_array(&value, 1, valuep));
207 }
208
209 nwam_error_t
nwam_value_create_uint64_array(uint64_t * values,uint_t numvalues,nwam_value_t * valuep)210 nwam_value_create_uint64_array(uint64_t *values, uint_t numvalues,
211 nwam_value_t *valuep)
212 {
213 return (nwam_value_create(NWAM_VALUE_TYPE_UINT64, values, numvalues,
214 valuep));
215 }
216
217 nwam_error_t
nwam_value_create_uint64(uint64_t value,nwam_value_t * valuep)218 nwam_value_create_uint64(uint64_t value, nwam_value_t *valuep)
219 {
220 return (nwam_value_create_uint64_array(&value, 1, valuep));
221 }
222
223 nwam_error_t
nwam_value_create_string_array(char ** values,uint_t numvalues,nwam_value_t * valuep)224 nwam_value_create_string_array(char **values, uint_t numvalues,
225 nwam_value_t *valuep)
226 {
227 return (nwam_value_create(NWAM_VALUE_TYPE_STRING, values, numvalues,
228 valuep));
229 }
230
231 nwam_error_t
nwam_value_create_string(char * value,nwam_value_t * valuep)232 nwam_value_create_string(char *value, nwam_value_t *valuep)
233 {
234 return (nwam_value_create_string_array(&value, 1, valuep));
235 }
236
237 nwam_error_t
nwam_value_get_boolean_array(nwam_value_t value,boolean_t ** valuesp,uint_t * numvaluesp)238 nwam_value_get_boolean_array(nwam_value_t value, boolean_t **valuesp,
239 uint_t *numvaluesp)
240 {
241 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
242
243 *numvaluesp = value->nwv_value_numvalues;
244 *valuesp = value->nwv_values.nwv_boolean;
245 return (NWAM_SUCCESS);
246 }
247
248 nwam_error_t
nwam_value_get_boolean(nwam_value_t value,boolean_t * valuep)249 nwam_value_get_boolean(nwam_value_t value, boolean_t *valuep)
250 {
251 uint_t numvalues;
252 boolean_t *myvaluesp;
253 nwam_error_t err;
254
255 err = nwam_value_get_boolean_array(value, &myvaluesp, &numvalues);
256 if (err != NWAM_SUCCESS)
257 return (err);
258 if (numvalues != 1)
259 return (NWAM_ENTITY_MULTIPLE_VALUES);
260
261 *valuep = myvaluesp[0];
262 return (NWAM_SUCCESS);
263 }
264
265 nwam_error_t
nwam_value_get_int64_array(nwam_value_t value,int64_t ** valuesp,uint_t * numvaluesp)266 nwam_value_get_int64_array(nwam_value_t value, int64_t **valuesp,
267 uint_t *numvaluesp)
268 {
269 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
270
271 *numvaluesp = value->nwv_value_numvalues;
272 *valuesp = value->nwv_values.nwv_int64;
273 return (NWAM_SUCCESS);
274 }
275
276 nwam_error_t
nwam_value_get_int64(nwam_value_t value,int64_t * valuep)277 nwam_value_get_int64(nwam_value_t value, int64_t *valuep)
278 {
279 uint_t numvalues;
280 int64_t *myvaluesp;
281 nwam_error_t err;
282
283 err = nwam_value_get_int64_array(value, &myvaluesp, &numvalues);
284 if (err != NWAM_SUCCESS)
285 return (err);
286 if (numvalues != 1)
287 return (NWAM_ENTITY_MULTIPLE_VALUES);
288
289 *valuep = myvaluesp[0];
290 return (NWAM_SUCCESS);
291 }
292
293 nwam_error_t
nwam_value_get_uint64_array(nwam_value_t value,uint64_t ** valuesp,uint_t * numvaluesp)294 nwam_value_get_uint64_array(nwam_value_t value, uint64_t **valuesp,
295 uint_t *numvaluesp)
296 {
297 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
298
299 *numvaluesp = value->nwv_value_numvalues;
300 *valuesp = value->nwv_values.nwv_uint64;
301 return (NWAM_SUCCESS);
302 }
303
304 nwam_error_t
nwam_value_get_uint64(nwam_value_t value,uint64_t * valuep)305 nwam_value_get_uint64(nwam_value_t value, uint64_t *valuep)
306 {
307 uint_t numvalues;
308 uint64_t *myvaluesp;
309 nwam_error_t err;
310
311 err = nwam_value_get_uint64_array(value, &myvaluesp, &numvalues);
312 if (err != NWAM_SUCCESS)
313 return (err);
314 if (numvalues != 1)
315 return (NWAM_ENTITY_MULTIPLE_VALUES);
316
317 *valuep = myvaluesp[0];
318 return (NWAM_SUCCESS);
319 }
320
321 nwam_error_t
nwam_value_get_string_array(nwam_value_t value,char *** valuesp,uint_t * numvaluesp)322 nwam_value_get_string_array(nwam_value_t value, char ***valuesp,
323 uint_t *numvaluesp)
324 {
325 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
326
327 *numvaluesp = value->nwv_value_numvalues;
328 *valuesp = value->nwv_values.nwv_string;
329 return (NWAM_SUCCESS);
330 }
331
332 nwam_error_t
nwam_value_get_string(nwam_value_t value,char ** valuep)333 nwam_value_get_string(nwam_value_t value, char **valuep)
334 {
335 uint_t numvalues;
336 char **myvaluesp;
337 nwam_error_t err;
338
339 err = nwam_value_get_string_array(value, &myvaluesp, &numvalues);
340 if (err != NWAM_SUCCESS)
341 return (err);
342 if (numvalues != 1)
343 return (NWAM_ENTITY_MULTIPLE_VALUES);
344
345 *valuep = myvaluesp[0];
346 return (NWAM_SUCCESS);
347 }
348
349 nwam_error_t
nwam_value_get_type(nwam_value_t value,nwam_value_type_t * typep)350 nwam_value_get_type(nwam_value_t value, nwam_value_type_t *typep)
351 {
352 *typep = value->nwv_value_type;
353 return (NWAM_SUCCESS);
354 }
355
356 nwam_error_t
nwam_value_get_numvalues(nwam_value_t value,uint_t * numvaluesp)357 nwam_value_get_numvalues(nwam_value_t value, uint_t *numvaluesp)
358 {
359 *numvaluesp = value->nwv_value_numvalues;
360 return (NWAM_SUCCESS);
361 }
362
363 /*
364 * Generic object data functions. We hide nvlist implementation
365 * from NCP, ENM and location implementations.
366 */
367 nwam_error_t
nwam_alloc_object_list(void * list)368 nwam_alloc_object_list(void *list)
369 {
370 int nverr;
371
372 assert(list != NULL);
373
374 if ((nverr = nvlist_alloc((nvlist_t **)list, NV_UNIQUE_NAME, 0)) != 0)
375 return (nwam_errno_to_nwam_error(nverr));
376
377 return (NWAM_SUCCESS);
378 }
379
380 void
nwam_free_object_list(void * list)381 nwam_free_object_list(void *list)
382 {
383 nvlist_free(list);
384 }
385
386 nwam_error_t
nwam_dup_object_list(void * oldlist,void * newlist)387 nwam_dup_object_list(void *oldlist, void *newlist)
388 {
389 int nverr;
390
391 assert(oldlist != NULL && newlist != NULL);
392
393 if ((nverr = nvlist_dup(oldlist, newlist, 0)) != 0)
394 return (nwam_errno_to_nwam_error(nverr));
395
396 return (NWAM_SUCCESS);
397 }
398
399 /* Add child object list to parent object list using property name childname */
400 nwam_error_t
nwam_object_list_add_object_list(void * parentlist,char * childname,void * childlist)401 nwam_object_list_add_object_list(void *parentlist, char *childname,
402 void *childlist)
403 {
404 return (nwam_errno_to_nwam_error(nvlist_add_nvlist(parentlist,
405 childname, childlist)));
406 }
407
408 /* Remove object list from parent object list */
409 nwam_error_t
nwam_object_list_remove_object_list(void * parentlist,char * childname)410 nwam_object_list_remove_object_list(void *parentlist, char *childname)
411 {
412 return (nwam_errno_to_nwam_error(nvlist_remove_all(parentlist,
413 childname)));
414 }
415
416 /*
417 * Get next object list (nvlist) after lastname. Used to walk NCUs, ENMs and
418 * locations, each of which is internally represented as an nvlist.
419 */
420 nwam_error_t
nwam_next_object_list(void * parentlist,char * lastname,char ** childnamep,void * childlistp)421 nwam_next_object_list(void *parentlist, char *lastname, char **childnamep,
422 void *childlistp)
423 {
424 nvpair_t *last = NULL, *next;
425 int nverr;
426
427 if (lastname != NULL) {
428 if ((nverr = nvlist_lookup_nvpair(parentlist, lastname, &last))
429 != 0)
430 return (nwam_errno_to_nwam_error(nverr));
431 }
432 if ((next = nvlist_next_nvpair(parentlist, last)) == NULL)
433 return (NWAM_LIST_END);
434
435 *childnamep = nvpair_name(next);
436
437 if (nvpair_type(next) != DATA_TYPE_NVLIST)
438 return (NWAM_ERROR_INTERNAL);
439
440 if ((nverr = nvpair_value_nvlist(next, childlistp)) != NWAM_SUCCESS)
441 return (nwam_errno_to_nwam_error(nverr));
442
443 return (NWAM_SUCCESS);
444 }
445
446 /*
447 * Pack nvlist into contiguous memory. If packed_listp is NULL, we just
448 * return the size of the memory needed to do so.
449 */
450 nwam_error_t
nwam_pack_object_list(void * list,char ** packed_listp,size_t * packed_sizep)451 nwam_pack_object_list(void *list, char **packed_listp, size_t *packed_sizep)
452 {
453 int nverr;
454
455 assert(list != NULL && packed_sizep != NULL);
456
457 if (packed_listp == NULL) {
458 nverr = nvlist_size(list, packed_sizep, NV_ENCODE_XDR);
459 } else {
460 nverr = nvlist_pack(list, packed_listp, packed_sizep,
461 NV_ENCODE_XDR, 0);
462 }
463
464 if (nverr != 0)
465 return (nwam_errno_to_nwam_error(nverr));
466
467 return (NWAM_SUCCESS);
468 }
469
470 nwam_error_t
nwam_unpack_object_list(char * packed_list,size_t packed_size,void * list)471 nwam_unpack_object_list(char *packed_list, size_t packed_size,
472 void *list)
473 {
474 int nverr;
475
476 assert(packed_list != NULL && list != NULL);
477
478 *((nvlist_t **)list) = NULL;
479
480 nverr = nvlist_unpack(packed_list, packed_size, (nvlist_t **)list, 0);
481
482 if (nverr != 0)
483 return (nwam_errno_to_nwam_error(nverr));
484
485 return (NWAM_SUCCESS);
486 }
487
488 /*
489 * Functions to walk, set and get properties in nvlist, translating
490 * between nwam_value_t and nvlist/nvpair representations.
491 */
492 nwam_error_t
nwam_next_object_prop(void * list,char * lastname,char ** namep,nwam_value_t * valuep)493 nwam_next_object_prop(void *list, char *lastname, char **namep,
494 nwam_value_t *valuep)
495 {
496 nvpair_t *last = NULL, *next;
497 int nverr;
498
499 if (lastname != NULL) {
500 if ((nverr = nvlist_lookup_nvpair(list, lastname, &last)) != 0)
501 return (nwam_errno_to_nwam_error(nverr));
502 }
503 if ((next = nvlist_next_nvpair(list, last)) == NULL)
504 return (NWAM_LIST_END);
505
506 *namep = nvpair_name(next);
507
508 return (nwam_get_prop_value(list, (const char *)*namep, valuep));
509 }
510
511 nwam_error_t
nwam_get_prop_value(void * list,const char * name,nwam_value_t * valuep)512 nwam_get_prop_value(void *list, const char *name, nwam_value_t *valuep)
513 {
514 nvpair_t *prop;
515 nwam_error_t err;
516 int nverr;
517 boolean_t *valbool;
518 int64_t *valint64;
519 uint64_t *valuint64;
520 char **valstr;
521 uint_t numvalues;
522
523 assert(valuep != NULL);
524
525 *valuep = NULL;
526
527 if ((nverr = nvlist_lookup_nvpair(list, name, &prop)) != 0) {
528 /* convert EINVAL to NOT_FOUND */
529 if (nverr == EINVAL)
530 return (NWAM_ENTITY_NOT_FOUND);
531 return (nwam_errno_to_nwam_error(nverr));
532 }
533
534 switch (nvpair_type(prop)) {
535 case DATA_TYPE_BOOLEAN_ARRAY:
536 if ((nverr = nvpair_value_boolean_array(prop,
537 &valbool, &numvalues)) != 0)
538 return (nwam_errno_to_nwam_error(nverr));
539 if ((err = nwam_value_create_boolean_array(valbool, numvalues,
540 valuep)) != NWAM_SUCCESS)
541 return (err);
542 break;
543 case DATA_TYPE_INT64_ARRAY:
544 if ((nverr = nvpair_value_int64_array(prop,
545 &valint64, &numvalues)) != 0)
546 return (nwam_errno_to_nwam_error(nverr));
547 if ((err = nwam_value_create_int64_array(valint64, numvalues,
548 valuep)) != NWAM_SUCCESS)
549 return (err);
550 break;
551 case DATA_TYPE_UINT64_ARRAY:
552 if ((nverr = nvpair_value_uint64_array(prop,
553 &valuint64, &numvalues)) != 0)
554 return (nwam_errno_to_nwam_error(nverr));
555 if ((err = nwam_value_create_uint64_array(valuint64, numvalues,
556 valuep)) != NWAM_SUCCESS)
557 return (err);
558 break;
559 case DATA_TYPE_STRING_ARRAY:
560 if ((nverr = nvpair_value_string_array(prop,
561 &valstr, &numvalues)) != 0)
562 return (nwam_errno_to_nwam_error(nverr));
563 if ((err = nwam_value_create_string_array(valstr, numvalues,
564 valuep)) != NWAM_SUCCESS)
565 return (err);
566 break;
567 default:
568 /* Should not happen */
569 return (NWAM_ERROR_INTERNAL);
570 }
571 return (NWAM_SUCCESS);
572 }
573
574 nwam_error_t
nwam_delete_prop(void * list,const char * name)575 nwam_delete_prop(void *list, const char *name)
576 {
577 int nverr;
578
579 if ((nverr = nvlist_remove_all(list, name)) != 0)
580 return (nwam_errno_to_nwam_error(nverr));
581 return (NWAM_SUCCESS);
582 }
583
584 nwam_error_t
nwam_set_prop_value(void * list,const char * propname,nwam_value_t value)585 nwam_set_prop_value(void *list, const char *propname, nwam_value_t value)
586 {
587 int nverr;
588 nwam_error_t err;
589 nwam_value_type_t type;
590 uint_t numvalues;
591 boolean_t *valbool;
592 int64_t *valint64;
593 uint64_t *valuint64;
594 char **valstr;
595
596 assert(list != NULL && value != NULL);
597
598 if ((err = nwam_value_get_type(value, &type)) != NWAM_SUCCESS)
599 return (err);
600
601 switch (type) {
602 case NWAM_VALUE_TYPE_BOOLEAN:
603 if ((err = nwam_value_get_boolean_array(value, &valbool,
604 &numvalues)) != NWAM_SUCCESS)
605 return (err);
606 if ((nverr = nvlist_add_boolean_array(list, propname,
607 valbool, numvalues)) != 0)
608 return (nwam_errno_to_nwam_error(nverr));
609 break;
610 case NWAM_VALUE_TYPE_INT64:
611 if ((err = nwam_value_get_int64_array(value, &valint64,
612 &numvalues)) != NWAM_SUCCESS)
613 return (err);
614 if ((nverr = nvlist_add_int64_array(list, propname,
615 valint64, numvalues)) != 0)
616 return (nwam_errno_to_nwam_error(nverr));
617 break;
618 case NWAM_VALUE_TYPE_UINT64:
619 if ((err = nwam_value_get_uint64_array(value, &valuint64,
620 &numvalues)) != NWAM_SUCCESS)
621 return (err);
622 if ((nverr = nvlist_add_uint64_array(list, propname,
623 valuint64, numvalues)) != 0)
624 return (nwam_errno_to_nwam_error(nverr));
625 break;
626 case NWAM_VALUE_TYPE_STRING:
627 if ((err = nwam_value_get_string_array(value, &valstr,
628 &numvalues)) != NWAM_SUCCESS)
629 return (err);
630 if ((nverr = nvlist_add_string_array(list, propname,
631 valstr, numvalues)) != 0)
632 return (nwam_errno_to_nwam_error(nverr));
633 break;
634 default:
635 return (NWAM_INVALID_ARG);
636 }
637
638 return (NWAM_SUCCESS);
639 }
640
641 /* Map uint64 values to their string counterparts */
642
643 struct nwam_value_entry {
644 const char *value_string;
645 uint64_t value;
646 };
647
648 struct nwam_value_entry prop_activation_mode_value_entries[] =
649 {
650 { NWAM_ACTIVATION_MODE_MANUAL_STRING, NWAM_ACTIVATION_MODE_MANUAL },
651 { NWAM_ACTIVATION_MODE_SYSTEM_STRING, NWAM_ACTIVATION_MODE_SYSTEM },
652 { NWAM_ACTIVATION_MODE_CONDITIONAL_ANY_STRING,
653 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY },
654 { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL_STRING,
655 NWAM_ACTIVATION_MODE_CONDITIONAL_ALL },
656 { NWAM_ACTIVATION_MODE_PRIORITIZED_STRING,
657 NWAM_ACTIVATION_MODE_PRIORITIZED },
658 { NULL, 0 }
659 };
660
661 struct nwam_value_entry ncu_prop_type_entries[] =
662 {
663 { NWAM_NCU_TYPE_LINK_STRING, NWAM_NCU_TYPE_LINK },
664 { NWAM_NCU_TYPE_INTERFACE_STRING, NWAM_NCU_TYPE_INTERFACE },
665 { NULL, 0 }
666 };
667
668 struct nwam_value_entry ncu_prop_class_entries[] =
669 {
670 { NWAM_NCU_CLASS_PHYS_STRING, NWAM_NCU_CLASS_PHYS },
671 { NWAM_NCU_CLASS_IP_STRING, NWAM_NCU_CLASS_IP },
672 { NULL, 0 }
673 };
674
675 struct nwam_value_entry ncu_prop_ip_version_entries[] =
676 {
677 { NWAM_IP_VERSION_IPV4_STRING, IPV4_VERSION },
678 { NWAM_IP_VERSION_IPV6_STRING, IPV6_VERSION },
679 { NULL, 0 }
680 };
681
682 struct nwam_value_entry ncu_prop_ipv4_addrsrc_entries[] =
683 {
684 { NWAM_ADDRSRC_DHCP_STRING, NWAM_ADDRSRC_DHCP },
685 { NWAM_ADDRSRC_STATIC_STRING, NWAM_ADDRSRC_STATIC },
686 { NULL, 0 }
687 };
688
689 struct nwam_value_entry ncu_prop_ipv6_addrsrc_entries[] =
690 {
691 { NWAM_ADDRSRC_DHCP_STRING, NWAM_ADDRSRC_DHCP },
692 { NWAM_ADDRSRC_STATIC_STRING, NWAM_ADDRSRC_STATIC },
693 { NWAM_ADDRSRC_AUTOCONF_STRING, NWAM_ADDRSRC_AUTOCONF },
694 { NULL, 0 }
695 };
696
697 struct nwam_value_entry ncu_prop_priority_mode_entries[] =
698 {
699 { NWAM_PRIORITY_MODE_EXCLUSIVE_STRING, NWAM_PRIORITY_MODE_EXCLUSIVE },
700 { NWAM_PRIORITY_MODE_SHARED_STRING, NWAM_PRIORITY_MODE_SHARED },
701 { NWAM_PRIORITY_MODE_ALL_STRING, NWAM_PRIORITY_MODE_ALL },
702 { NULL, 0 }
703 };
704
705 struct nwam_value_entry loc_prop_nameservices_entries[] =
706 {
707 { NWAM_NAMESERVICES_DNS_STRING, NWAM_NAMESERVICES_DNS },
708 { NWAM_NAMESERVICES_FILES_STRING, NWAM_NAMESERVICES_FILES },
709 { NWAM_NAMESERVICES_NIS_STRING, NWAM_NAMESERVICES_NIS },
710 { NWAM_NAMESERVICES_LDAP_STRING, NWAM_NAMESERVICES_LDAP },
711 { NULL, 0 }
712 };
713
714 struct nwam_value_entry loc_prop_nameservice_configsrc_entries[] =
715 {
716 { NWAM_CONFIGSRC_MANUAL_STRING, NWAM_CONFIGSRC_MANUAL },
717 { NWAM_CONFIGSRC_DHCP_STRING, NWAM_CONFIGSRC_DHCP },
718 { NULL, 0 }
719 };
720
721 struct nwam_value_entry known_wlan_prop_security_mode_entries[] =
722 {
723 { "none", DLADM_WLAN_SECMODE_NONE },
724 { "wep", DLADM_WLAN_SECMODE_WEP },
725 { "wpa", DLADM_WLAN_SECMODE_WPA },
726 { NULL, 0 }
727 };
728
729 struct nwam_prop_value_entry {
730 const char *prop_name;
731 struct nwam_value_entry *value_entries;
732 } prop_value_entry_table[] =
733 {
734 { NWAM_NCU_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
735 { NWAM_NCU_PROP_TYPE, ncu_prop_type_entries },
736 { NWAM_NCU_PROP_CLASS, ncu_prop_class_entries },
737 { NWAM_NCU_PROP_IP_VERSION, ncu_prop_ip_version_entries },
738 { NWAM_NCU_PROP_IPV4_ADDRSRC, ncu_prop_ipv4_addrsrc_entries },
739 { NWAM_NCU_PROP_IPV6_ADDRSRC, ncu_prop_ipv6_addrsrc_entries },
740 { NWAM_NCU_PROP_PRIORITY_MODE, ncu_prop_priority_mode_entries },
741 { NWAM_ENM_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
742 { NWAM_LOC_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
743 { NWAM_LOC_PROP_NAMESERVICES, loc_prop_nameservices_entries },
744 { NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
745 loc_prop_nameservice_configsrc_entries },
746 { NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
747 loc_prop_nameservice_configsrc_entries },
748 { NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
749 loc_prop_nameservice_configsrc_entries },
750 { NWAM_KNOWN_WLAN_PROP_SECURITY_MODE,
751 known_wlan_prop_security_mode_entries },
752 { NULL, NULL }
753 };
754
755 /*
756 * Convert uint64 values for property propname into a string representing
757 * that value. Used by enum values.
758 */
759 nwam_error_t
nwam_uint64_get_value_string(const char * propname,uint64_t val,const char ** valstrp)760 nwam_uint64_get_value_string(const char *propname, uint64_t val,
761 const char **valstrp)
762 {
763 int i, j;
764 int max = 0; /* largest enum value seen so far */
765 struct nwam_value_entry *value_entries;
766
767 assert(propname != NULL && valstrp != NULL);
768
769 for (i = 0; prop_value_entry_table[i].prop_name != NULL; i++) {
770 if (strcmp(prop_value_entry_table[i].prop_name, propname) != 0)
771 continue;
772
773 value_entries = prop_value_entry_table[i].value_entries;
774
775 for (j = 0; value_entries[j].value_string != NULL; j++) {
776 if (value_entries[j].value == val) {
777 *valstrp = value_entries[j].value_string;
778 return (NWAM_SUCCESS);
779 }
780 max = value_entries[j].value > max ?
781 value_entries[j].value : max;
782 }
783 /*
784 * If trying to get the string for an enum value that doesn't
785 * exist, return NWAM_LIST_END. Otherwise, the input enum
786 * value doesn't exist for the given property.
787 */
788 if (val > max)
789 return (NWAM_LIST_END);
790 else
791 return (NWAM_ENTITY_INVALID_VALUE);
792 }
793 return (NWAM_INVALID_ARG);
794 }
795
796 /*
797 * Convert string to appropriate uint64 value.
798 */
799 nwam_error_t
nwam_value_string_get_uint64(const char * propname,const char * valstr,uint64_t * valp)800 nwam_value_string_get_uint64(const char *propname, const char *valstr,
801 uint64_t *valp)
802 {
803 int i, j;
804 struct nwam_value_entry *value_entries;
805
806 assert(propname != NULL && valstr != NULL && valp != NULL);
807
808 for (i = 0; prop_value_entry_table[i].prop_name != NULL; i++) {
809 if (strcmp(prop_value_entry_table[i].prop_name, propname) != 0)
810 continue;
811
812 value_entries = prop_value_entry_table[i].value_entries;
813
814 for (j = 0; value_entries[j].value_string != NULL; j++) {
815 if (strcasecmp(value_entries[j].value_string, valstr)
816 == 0) {
817 *valp = value_entries[j].value;
818 return (NWAM_SUCCESS);
819 }
820 }
821 return (NWAM_ENTITY_INVALID_VALUE);
822 }
823 return (NWAM_INVALID_ARG);
824 }
825
826 /* Conditional activation functions */
827
828 nwam_error_t
nwam_condition_to_condition_string(nwam_condition_object_type_t object_type,nwam_condition_t condition,const char * object_name,char ** stringp)829 nwam_condition_to_condition_string(nwam_condition_object_type_t object_type,
830 nwam_condition_t condition, const char *object_name, char **stringp)
831 {
832 char *object_type_string, *condition_string;
833 char *string;
834
835 assert(stringp != NULL);
836
837 *stringp = NULL;
838
839 switch (object_type) {
840 case NWAM_CONDITION_OBJECT_TYPE_NCP:
841 object_type_string = NWAM_CONDITION_OBJECT_TYPE_NCP_STRING;
842 break;
843 case NWAM_CONDITION_OBJECT_TYPE_NCU:
844 object_type_string = NWAM_CONDITION_OBJECT_TYPE_NCU_STRING;
845 break;
846 case NWAM_CONDITION_OBJECT_TYPE_ENM:
847 object_type_string = NWAM_CONDITION_OBJECT_TYPE_ENM_STRING;
848 break;
849 case NWAM_CONDITION_OBJECT_TYPE_LOC:
850 object_type_string = NWAM_CONDITION_OBJECT_TYPE_LOC_STRING;
851 break;
852 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
853 object_type_string =
854 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS_STRING;
855 break;
856 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
857 object_type_string =
858 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN_STRING;
859 break;
860 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
861 object_type_string =
862 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN_STRING;
863 break;
864 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
865 object_type_string = NWAM_CONDITION_OBJECT_TYPE_ESSID_STRING;
866 break;
867 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
868 object_type_string = NWAM_CONDITION_OBJECT_TYPE_BSSID_STRING;
869 break;
870 default:
871 return (NWAM_INVALID_ARG);
872
873 }
874 switch (condition) {
875 case NWAM_CONDITION_IS:
876 condition_string = NWAM_CONDITION_IS_STRING;
877 break;
878 case NWAM_CONDITION_IS_NOT:
879 condition_string = NWAM_CONDITION_IS_NOT_STRING;
880 break;
881 case NWAM_CONDITION_CONTAINS:
882 if (object_type != NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
883 object_type != NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
884 object_type != NWAM_CONDITION_OBJECT_TYPE_ESSID)
885 return (NWAM_INVALID_ARG);
886 condition_string = NWAM_CONDITION_CONTAINS_STRING;
887 break;
888 case NWAM_CONDITION_DOES_NOT_CONTAIN:
889 if (object_type != NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
890 object_type != NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
891 object_type != NWAM_CONDITION_OBJECT_TYPE_ESSID)
892 return (NWAM_INVALID_ARG);
893
894 condition_string = NWAM_CONDITION_DOES_NOT_CONTAIN_STRING;
895 break;
896 case NWAM_CONDITION_IS_IN_RANGE:
897 if (object_type != NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS)
898 return (NWAM_INVALID_ARG);
899 condition_string = NWAM_CONDITION_IS_IN_RANGE_STRING;
900 break;
901 case NWAM_CONDITION_IS_NOT_IN_RANGE:
902 if (object_type != NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS)
903 return (NWAM_INVALID_ARG);
904 condition_string = NWAM_CONDITION_IS_NOT_IN_RANGE_STRING;
905 break;
906 default:
907 return (NWAM_INVALID_ARG);
908 }
909 if ((string = malloc(NWAM_MAX_VALUE_LEN)) == NULL)
910 return (NWAM_NO_MEMORY);
911 switch (object_type) {
912 case NWAM_CONDITION_OBJECT_TYPE_NCP:
913 case NWAM_CONDITION_OBJECT_TYPE_NCU:
914 case NWAM_CONDITION_OBJECT_TYPE_ENM:
915 case NWAM_CONDITION_OBJECT_TYPE_LOC:
916 (void) snprintf(string, NWAM_MAX_VALUE_LEN,
917 "%s %s %s active", object_type_string,
918 object_name, condition_string);
919 *stringp = string;
920 break;
921
922 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
923 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
924 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
925 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
926 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
927 (void) snprintf(string, NWAM_MAX_VALUE_LEN,
928 "%s %s %s", object_type_string,
929 condition_string, object_name);
930 *stringp = string;
931 break;
932
933 default:
934 free(string);
935 return (NWAM_INVALID_ARG);
936
937 }
938 return (NWAM_SUCCESS);
939 }
940
941 nwam_error_t
nwam_condition_string_to_condition(const char * string,nwam_condition_object_type_t * object_typep,nwam_condition_t * conditionp,char ** object_namep)942 nwam_condition_string_to_condition(const char *string,
943 nwam_condition_object_type_t *object_typep,
944 nwam_condition_t *conditionp, char **object_namep)
945 {
946 char *copy, *lasts;
947 char *object_type_string, *object_name;
948 char *condition_string, *active_string;
949
950 assert(string != NULL && object_typep != NULL && conditionp != NULL &&
951 object_namep != NULL);
952
953 if ((copy = strdup(string)) == NULL)
954 return (NWAM_NO_MEMORY);
955
956 if ((object_type_string = strtok_r(copy, " \t", &lasts)) == NULL) {
957 free(copy);
958 return (NWAM_INVALID_ARG);
959 }
960
961 if (strcmp(object_type_string, NWAM_CONDITION_OBJECT_TYPE_NCP_STRING)
962 == 0)
963 *object_typep = NWAM_CONDITION_OBJECT_TYPE_NCP;
964 else if (strcmp(object_type_string,
965 NWAM_CONDITION_OBJECT_TYPE_NCU_STRING) == 0)
966 *object_typep = NWAM_CONDITION_OBJECT_TYPE_NCU;
967 else if (strcmp(object_type_string,
968 NWAM_CONDITION_OBJECT_TYPE_ENM_STRING) == 0)
969 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ENM;
970 else if (strcmp(object_type_string,
971 NWAM_CONDITION_OBJECT_TYPE_LOC_STRING) == 0)
972 *object_typep = NWAM_CONDITION_OBJECT_TYPE_LOC;
973 else if (strcmp(object_type_string,
974 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS_STRING) == 0)
975 *object_typep = NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS;
976 else if (strcmp(object_type_string,
977 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN_STRING) == 0)
978 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN;
979 else if (strcmp(object_type_string,
980 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN_STRING) == 0)
981 *object_typep = NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN;
982 else if (strcmp(object_type_string,
983 NWAM_CONDITION_OBJECT_TYPE_ESSID_STRING) == 0)
984 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ESSID;
985 else if (strcmp(object_type_string,
986 NWAM_CONDITION_OBJECT_TYPE_BSSID_STRING) == 0)
987 *object_typep = NWAM_CONDITION_OBJECT_TYPE_BSSID;
988 else {
989 free(copy);
990 return (NWAM_INVALID_ARG);
991 }
992
993 if (*object_typep == NWAM_CONDITION_OBJECT_TYPE_NCP ||
994 *object_typep == NWAM_CONDITION_OBJECT_TYPE_NCU ||
995 *object_typep == NWAM_CONDITION_OBJECT_TYPE_ENM ||
996 *object_typep == NWAM_CONDITION_OBJECT_TYPE_LOC) {
997 if ((object_name = strtok_r(NULL, " \t", &lasts)) == NULL) {
998 free(copy);
999 return (NWAM_INVALID_ARG);
1000 }
1001 if ((*object_namep = strdup(object_name)) == NULL) {
1002 free(copy);
1003 return (NWAM_NO_MEMORY);
1004 }
1005
1006 }
1007
1008 if ((condition_string = strtok_r(NULL, " \t", &lasts)) == NULL) {
1009 free(copy);
1010 if (*object_namep != NULL)
1011 free(*object_namep);
1012 return (NWAM_INVALID_ARG);
1013 }
1014 if (strcmp(condition_string, NWAM_CONDITION_IS_STRING) == 0)
1015 *conditionp = NWAM_CONDITION_IS;
1016 else if (strcmp(condition_string, NWAM_CONDITION_IS_NOT_STRING) == 0)
1017 *conditionp = NWAM_CONDITION_IS_NOT;
1018 else if (strcmp(condition_string, NWAM_CONDITION_CONTAINS_STRING) == 0)
1019 *conditionp = NWAM_CONDITION_CONTAINS;
1020 else if (strcmp(condition_string,
1021 NWAM_CONDITION_DOES_NOT_CONTAIN_STRING) == 0)
1022 *conditionp = NWAM_CONDITION_DOES_NOT_CONTAIN;
1023 else if (strcmp(condition_string,
1024 NWAM_CONDITION_IS_IN_RANGE_STRING) == 0)
1025 *conditionp = NWAM_CONDITION_IS_IN_RANGE;
1026 else if (strcmp(condition_string,
1027 NWAM_CONDITION_IS_NOT_IN_RANGE_STRING) == 0)
1028 *conditionp = NWAM_CONDITION_IS_NOT_IN_RANGE;
1029 else {
1030 free(copy);
1031 if (*object_namep != NULL)
1032 free(*object_namep);
1033 return (NWAM_INVALID_ARG);
1034 }
1035
1036 if (*object_typep == NWAM_CONDITION_OBJECT_TYPE_NCP ||
1037 *object_typep == NWAM_CONDITION_OBJECT_TYPE_NCU ||
1038 *object_typep == NWAM_CONDITION_OBJECT_TYPE_ENM ||
1039 *object_typep == NWAM_CONDITION_OBJECT_TYPE_LOC) {
1040 if ((*conditionp != NWAM_CONDITION_IS &&
1041 *conditionp != NWAM_CONDITION_IS_NOT) ||
1042 (active_string = strtok_r(NULL, " \t", &lasts)) == NULL ||
1043 strcmp(active_string, NWAM_CONDITION_ACTIVE_STRING) != 0) {
1044 free(copy);
1045 free(*object_namep);
1046 return (NWAM_INVALID_ARG);
1047 }
1048 } else {
1049 switch (*conditionp) {
1050 case NWAM_CONDITION_CONTAINS:
1051 case NWAM_CONDITION_DOES_NOT_CONTAIN:
1052 if (*object_typep !=
1053 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
1054 *object_typep !=
1055 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
1056 *object_typep != NWAM_CONDITION_OBJECT_TYPE_ESSID) {
1057 free(copy);
1058 free(*object_namep);
1059 return (NWAM_INVALID_ARG);
1060 }
1061 break;
1062 case NWAM_CONDITION_IS_IN_RANGE:
1063 case NWAM_CONDITION_IS_NOT_IN_RANGE:
1064 if (*object_typep !=
1065 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS) {
1066 free(copy);
1067 free(*object_namep);
1068 return (NWAM_INVALID_ARG);
1069 }
1070 break;
1071 }
1072
1073 if ((object_name = strtok_r(NULL, " \t", &lasts)) == NULL) {
1074 free(copy);
1075 free(*object_namep);
1076 return (NWAM_INVALID_ARG);
1077 }
1078 if ((*object_namep = strdup(object_name)) == NULL) {
1079 free(copy);
1080 free(*object_namep);
1081 return (NWAM_NO_MEMORY);
1082 }
1083 }
1084
1085 free(copy);
1086 return (NWAM_SUCCESS);
1087 }
1088
1089 nwam_error_t
nwam_condition_rate(nwam_condition_object_type_t object_type,nwam_condition_t condition,uint64_t * ratep)1090 nwam_condition_rate(nwam_condition_object_type_t object_type,
1091 nwam_condition_t condition, uint64_t *ratep)
1092 {
1093 assert(ratep != NULL);
1094
1095 *ratep = 0;
1096
1097 switch (object_type) {
1098 case NWAM_CONDITION_OBJECT_TYPE_NCP:
1099 case NWAM_CONDITION_OBJECT_TYPE_NCU:
1100 case NWAM_CONDITION_OBJECT_TYPE_ENM:
1101 case NWAM_CONDITION_OBJECT_TYPE_LOC:
1102 (*ratep)++;
1103 /* FALLTHRU */
1104 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
1105 (*ratep)++;
1106 /* FALLTHRU */
1107 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
1108 (*ratep)++;
1109 /* FALLTHRU */
1110 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
1111 (*ratep)++;
1112 /* FALLTHRU */
1113 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
1114 (*ratep)++;
1115 /* FALLTHRU */
1116 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
1117 (*ratep)++;
1118 break;
1119 default:
1120 return (NWAM_INVALID_ARG);
1121 }
1122
1123 switch (condition) {
1124 case NWAM_CONDITION_IS:
1125 (*ratep)++;
1126 /* FALLTHRU */
1127 case NWAM_CONDITION_CONTAINS:
1128 case NWAM_CONDITION_IS_IN_RANGE:
1129 (*ratep)++;
1130 /* FALLTHRU */
1131 case NWAM_CONDITION_DOES_NOT_CONTAIN:
1132 case NWAM_CONDITION_IS_NOT_IN_RANGE:
1133 (*ratep)++;
1134 /* FALLTHRU */
1135 case NWAM_CONDITION_IS_NOT:
1136 (*ratep)++;
1137 break;
1138 default:
1139 return (NWAM_INVALID_ARG);
1140 }
1141 return (NWAM_SUCCESS);
1142 }
1143