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 */
25
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <libdlwlan.h>
32 #include <libnvpair.h>
33
34 #include "libnwam_impl.h"
35 #include <libnwam_priv.h>
36 #include <libnwam.h>
37
38 /*
39 * Internal implementation of libnwam in-memory objects and values. Objects
40 * are nvlists.
41 */
42
43 void
nwam_value_free(nwam_value_t value)44 nwam_value_free(nwam_value_t value)
45 {
46 uint_t i;
47
48 if (value == NULL)
49 return;
50
51 switch (value->nwv_value_type) {
52 case NWAM_VALUE_TYPE_BOOLEAN:
53 free(value->nwv_values.nwv_boolean);
54 break;
55 case NWAM_VALUE_TYPE_INT64:
56 free(value->nwv_values.nwv_int64);
57 break;
58 case NWAM_VALUE_TYPE_UINT64:
59 free(value->nwv_values.nwv_uint64);
60 break;
61 case NWAM_VALUE_TYPE_STRING:
62 for (i = 0; i < value->nwv_value_numvalues; i++)
63 free(value->nwv_values.nwv_string[i]);
64 free(value->nwv_values.nwv_string);
65 break;
66 }
67 free(value);
68 }
69
70 nwam_error_t
nwam_value_create(nwam_value_type_t value_type,void * values,uint_t numvalues,nwam_value_t * valuep)71 nwam_value_create(nwam_value_type_t value_type, void *values, uint_t numvalues,
72 nwam_value_t *valuep)
73 {
74 nwam_value_t newvalue;
75 boolean_t *values_boolean;
76 int64_t *values_int64;
77 uint64_t *values_uint64;
78 char **values_string;
79 int i, j;
80 nwam_error_t err = NWAM_SUCCESS;
81
82 *valuep = NULL;
83
84 if ((newvalue = calloc(1, sizeof (struct nwam_value))) == NULL)
85 return (NWAM_NO_MEMORY);
86
87 newvalue->nwv_value_type = value_type;
88 newvalue->nwv_value_numvalues = numvalues;
89
90 switch (value_type) {
91 case NWAM_VALUE_TYPE_BOOLEAN:
92 values_boolean = values;
93 if ((newvalue->nwv_values.nwv_boolean =
94 calloc(numvalues, sizeof (boolean_t))) == NULL) {
95 free(newvalue);
96 return (NWAM_NO_MEMORY);
97 }
98 for (i = 0; i < numvalues; i++)
99 newvalue->nwv_values.nwv_boolean[i] = values_boolean[i];
100 break;
101 case NWAM_VALUE_TYPE_INT64:
102 values_int64 = values;
103 if ((newvalue->nwv_values.nwv_int64 =
104 calloc(numvalues, sizeof (int64_t))) == NULL) {
105 free(newvalue);
106 return (NWAM_NO_MEMORY);
107 }
108 for (i = 0; i < numvalues; i++)
109 newvalue->nwv_values.nwv_int64[i] = values_int64[i];
110 break;
111 case NWAM_VALUE_TYPE_UINT64:
112 values_uint64 = values;
113 if ((newvalue->nwv_values.nwv_uint64 =
114 calloc(numvalues, sizeof (uint64_t))) == NULL) {
115 free(newvalue);
116 return (NWAM_NO_MEMORY);
117 }
118 for (i = 0; i < numvalues; i++)
119 newvalue->nwv_values.nwv_uint64[i] = values_uint64[i];
120 break;
121 case NWAM_VALUE_TYPE_STRING:
122 values_string = values;
123 if ((newvalue->nwv_values.nwv_string =
124 calloc(numvalues, sizeof (char *))) == NULL) {
125 free(newvalue);
126 return (NWAM_NO_MEMORY);
127 }
128 for (i = 0; i < numvalues; i++) {
129 if (strnlen(values_string[i], NWAM_MAX_VALUE_LEN) ==
130 NWAM_MAX_VALUE_LEN) {
131 err = NWAM_ENTITY_INVALID_VALUE;
132 } else if ((newvalue->nwv_values.nwv_string[i] =
133 strdup(values_string[i])) == NULL) {
134 err = NWAM_NO_MEMORY;
135 }
136 if (err != NWAM_SUCCESS) {
137 for (j = 0; j < i; j++)
138 free(
139 newvalue->nwv_values.nwv_string[i]);
140 free(newvalue->nwv_values.nwv_string);
141 free(newvalue);
142 return (err);
143 }
144 }
145 break;
146 default:
147 break;
148 }
149
150 *valuep = newvalue;
151 return (NWAM_SUCCESS);
152 }
153
154 nwam_error_t
nwam_value_copy(nwam_value_t old,nwam_value_t * newp)155 nwam_value_copy(nwam_value_t old, nwam_value_t *newp)
156 {
157 void *values;
158
159 assert(old != NULL && newp != NULL);
160
161 switch (old->nwv_value_type) {
162 case NWAM_VALUE_TYPE_BOOLEAN:
163 values = old->nwv_values.nwv_boolean;
164 break;
165 case NWAM_VALUE_TYPE_INT64:
166 values = old->nwv_values.nwv_int64;
167 break;
168 case NWAM_VALUE_TYPE_UINT64:
169 values = old->nwv_values.nwv_uint64;
170 break;
171 case NWAM_VALUE_TYPE_STRING:
172 values = old->nwv_values.nwv_string;
173 break;
174 default:
175 return (NWAM_INVALID_ARG);
176 }
177 return (nwam_value_create(old->nwv_value_type, values,
178 old->nwv_value_numvalues, newp));
179 }
180 nwam_error_t
nwam_value_create_boolean_array(boolean_t * values,uint_t numvalues,nwam_value_t * valuep)181 nwam_value_create_boolean_array(boolean_t *values, uint_t numvalues,
182 nwam_value_t *valuep)
183 {
184 return (nwam_value_create(NWAM_VALUE_TYPE_BOOLEAN, values, numvalues,
185 valuep));
186 }
187
188 nwam_error_t
nwam_value_create_boolean(boolean_t value,nwam_value_t * valuep)189 nwam_value_create_boolean(boolean_t value, nwam_value_t *valuep)
190 {
191 return (nwam_value_create_boolean_array(&value, 1, valuep));
192 }
193
194 nwam_error_t
nwam_value_create_int64_array(int64_t * values,uint_t numvalues,nwam_value_t * valuep)195 nwam_value_create_int64_array(int64_t *values, uint_t numvalues,
196 nwam_value_t *valuep)
197 {
198 return (nwam_value_create(NWAM_VALUE_TYPE_INT64, values, numvalues,
199 valuep));
200 }
201
202 nwam_error_t
nwam_value_create_int64(int64_t value,nwam_value_t * valuep)203 nwam_value_create_int64(int64_t value, nwam_value_t *valuep)
204 {
205 return (nwam_value_create_int64_array(&value, 1, valuep));
206 }
207
208 nwam_error_t
nwam_value_create_uint64_array(uint64_t * values,uint_t numvalues,nwam_value_t * valuep)209 nwam_value_create_uint64_array(uint64_t *values, uint_t numvalues,
210 nwam_value_t *valuep)
211 {
212 return (nwam_value_create(NWAM_VALUE_TYPE_UINT64, values, numvalues,
213 valuep));
214 }
215
216 nwam_error_t
nwam_value_create_uint64(uint64_t value,nwam_value_t * valuep)217 nwam_value_create_uint64(uint64_t value, nwam_value_t *valuep)
218 {
219 return (nwam_value_create_uint64_array(&value, 1, valuep));
220 }
221
222 nwam_error_t
nwam_value_create_string_array(char ** values,uint_t numvalues,nwam_value_t * valuep)223 nwam_value_create_string_array(char **values, uint_t numvalues,
224 nwam_value_t *valuep)
225 {
226 return (nwam_value_create(NWAM_VALUE_TYPE_STRING, values, numvalues,
227 valuep));
228 }
229
230 nwam_error_t
nwam_value_create_string(char * value,nwam_value_t * valuep)231 nwam_value_create_string(char *value, nwam_value_t *valuep)
232 {
233 return (nwam_value_create_string_array(&value, 1, valuep));
234 }
235
236 nwam_error_t
nwam_value_get_boolean_array(nwam_value_t value,boolean_t ** valuesp,uint_t * numvaluesp)237 nwam_value_get_boolean_array(nwam_value_t value, boolean_t **valuesp,
238 uint_t *numvaluesp)
239 {
240 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
241
242 *numvaluesp = value->nwv_value_numvalues;
243 *valuesp = value->nwv_values.nwv_boolean;
244 return (NWAM_SUCCESS);
245 }
246
247 nwam_error_t
nwam_value_get_boolean(nwam_value_t value,boolean_t * valuep)248 nwam_value_get_boolean(nwam_value_t value, boolean_t *valuep)
249 {
250 uint_t numvalues;
251 boolean_t *myvaluesp;
252 nwam_error_t err;
253
254 err = nwam_value_get_boolean_array(value, &myvaluesp, &numvalues);
255 if (err != NWAM_SUCCESS)
256 return (err);
257 if (numvalues != 1)
258 return (NWAM_ENTITY_MULTIPLE_VALUES);
259
260 *valuep = myvaluesp[0];
261 return (NWAM_SUCCESS);
262 }
263
264 nwam_error_t
nwam_value_get_int64_array(nwam_value_t value,int64_t ** valuesp,uint_t * numvaluesp)265 nwam_value_get_int64_array(nwam_value_t value, int64_t **valuesp,
266 uint_t *numvaluesp)
267 {
268 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
269
270 *numvaluesp = value->nwv_value_numvalues;
271 *valuesp = value->nwv_values.nwv_int64;
272 return (NWAM_SUCCESS);
273 }
274
275 nwam_error_t
nwam_value_get_int64(nwam_value_t value,int64_t * valuep)276 nwam_value_get_int64(nwam_value_t value, int64_t *valuep)
277 {
278 uint_t numvalues;
279 int64_t *myvaluesp;
280 nwam_error_t err;
281
282 err = nwam_value_get_int64_array(value, &myvaluesp, &numvalues);
283 if (err != NWAM_SUCCESS)
284 return (err);
285 if (numvalues != 1)
286 return (NWAM_ENTITY_MULTIPLE_VALUES);
287
288 *valuep = myvaluesp[0];
289 return (NWAM_SUCCESS);
290 }
291
292 nwam_error_t
nwam_value_get_uint64_array(nwam_value_t value,uint64_t ** valuesp,uint_t * numvaluesp)293 nwam_value_get_uint64_array(nwam_value_t value, uint64_t **valuesp,
294 uint_t *numvaluesp)
295 {
296 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
297
298 *numvaluesp = value->nwv_value_numvalues;
299 *valuesp = value->nwv_values.nwv_uint64;
300 return (NWAM_SUCCESS);
301 }
302
303 nwam_error_t
nwam_value_get_uint64(nwam_value_t value,uint64_t * valuep)304 nwam_value_get_uint64(nwam_value_t value, uint64_t *valuep)
305 {
306 uint_t numvalues;
307 uint64_t *myvaluesp;
308 nwam_error_t err;
309
310 err = nwam_value_get_uint64_array(value, &myvaluesp, &numvalues);
311 if (err != NWAM_SUCCESS)
312 return (err);
313 if (numvalues != 1)
314 return (NWAM_ENTITY_MULTIPLE_VALUES);
315
316 *valuep = myvaluesp[0];
317 return (NWAM_SUCCESS);
318 }
319
320 nwam_error_t
nwam_value_get_string_array(nwam_value_t value,char *** valuesp,uint_t * numvaluesp)321 nwam_value_get_string_array(nwam_value_t value, char ***valuesp,
322 uint_t *numvaluesp)
323 {
324 assert(value != NULL && numvaluesp != NULL && valuesp != NULL);
325
326 *numvaluesp = value->nwv_value_numvalues;
327 *valuesp = value->nwv_values.nwv_string;
328 return (NWAM_SUCCESS);
329 }
330
331 nwam_error_t
nwam_value_get_string(nwam_value_t value,char ** valuep)332 nwam_value_get_string(nwam_value_t value, char **valuep)
333 {
334 uint_t numvalues;
335 char **myvaluesp;
336 nwam_error_t err;
337
338 err = nwam_value_get_string_array(value, &myvaluesp, &numvalues);
339 if (err != NWAM_SUCCESS)
340 return (err);
341 if (numvalues != 1)
342 return (NWAM_ENTITY_MULTIPLE_VALUES);
343
344 *valuep = myvaluesp[0];
345 return (NWAM_SUCCESS);
346 }
347
348 nwam_error_t
nwam_value_get_type(nwam_value_t value,nwam_value_type_t * typep)349 nwam_value_get_type(nwam_value_t value, nwam_value_type_t *typep)
350 {
351 *typep = value->nwv_value_type;
352 return (NWAM_SUCCESS);
353 }
354
355 nwam_error_t
nwam_value_get_numvalues(nwam_value_t value,uint_t * numvaluesp)356 nwam_value_get_numvalues(nwam_value_t value, uint_t *numvaluesp)
357 {
358 *numvaluesp = value->nwv_value_numvalues;
359 return (NWAM_SUCCESS);
360 }
361
362 /*
363 * Generic object data functions. We hide nvlist implementation
364 * from NCP, ENM and location implementations.
365 */
366 nwam_error_t
nwam_alloc_object_list(void * list)367 nwam_alloc_object_list(void *list)
368 {
369 int nverr;
370
371 assert(list != NULL);
372
373 if ((nverr = nvlist_alloc((nvlist_t **)list, NV_UNIQUE_NAME, 0)) != 0)
374 return (nwam_errno_to_nwam_error(nverr));
375
376 return (NWAM_SUCCESS);
377 }
378
379 void
nwam_free_object_list(void * list)380 nwam_free_object_list(void *list)
381 {
382 if (list != NULL)
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 break;
909 }
910 if ((string = malloc(NWAM_MAX_VALUE_LEN)) == NULL)
911 return (NWAM_NO_MEMORY);
912 switch (object_type) {
913 case NWAM_CONDITION_OBJECT_TYPE_NCP:
914 case NWAM_CONDITION_OBJECT_TYPE_NCU:
915 case NWAM_CONDITION_OBJECT_TYPE_ENM:
916 case NWAM_CONDITION_OBJECT_TYPE_LOC:
917 (void) snprintf(string, NWAM_MAX_VALUE_LEN,
918 "%s %s %s active", object_type_string,
919 object_name, condition_string);
920 *stringp = string;
921 break;
922
923 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
924 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
925 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
926 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
927 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
928 (void) snprintf(string, NWAM_MAX_VALUE_LEN,
929 "%s %s %s", object_type_string,
930 condition_string, object_name);
931 *stringp = string;
932 break;
933
934 default:
935 free(string);
936 return (NWAM_INVALID_ARG);
937
938 }
939 return (NWAM_SUCCESS);
940 }
941
942 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)943 nwam_condition_string_to_condition(const char *string,
944 nwam_condition_object_type_t *object_typep,
945 nwam_condition_t *conditionp, char **object_namep)
946 {
947 char *copy, *lasts;
948 char *object_type_string, *object_name;
949 char *condition_string, *active_string;
950
951 assert(string != NULL && object_typep != NULL && conditionp != NULL &&
952 object_namep != NULL);
953
954 if ((copy = strdup(string)) == NULL)
955 return (NWAM_NO_MEMORY);
956
957 if ((object_type_string = strtok_r(copy, " \t", &lasts)) == NULL) {
958 free(copy);
959 return (NWAM_INVALID_ARG);
960 }
961
962 if (strcmp(object_type_string, NWAM_CONDITION_OBJECT_TYPE_NCP_STRING)
963 == 0)
964 *object_typep = NWAM_CONDITION_OBJECT_TYPE_NCP;
965 else if (strcmp(object_type_string,
966 NWAM_CONDITION_OBJECT_TYPE_NCU_STRING) == 0)
967 *object_typep = NWAM_CONDITION_OBJECT_TYPE_NCU;
968 else if (strcmp(object_type_string,
969 NWAM_CONDITION_OBJECT_TYPE_ENM_STRING) == 0)
970 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ENM;
971 else if (strcmp(object_type_string,
972 NWAM_CONDITION_OBJECT_TYPE_LOC_STRING) == 0)
973 *object_typep = NWAM_CONDITION_OBJECT_TYPE_LOC;
974 else if (strcmp(object_type_string,
975 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS_STRING) == 0)
976 *object_typep = NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS;
977 else if (strcmp(object_type_string,
978 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN_STRING) == 0)
979 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN;
980 else if (strcmp(object_type_string,
981 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN_STRING) == 0)
982 *object_typep = NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN;
983 else if (strcmp(object_type_string,
984 NWAM_CONDITION_OBJECT_TYPE_ESSID_STRING) == 0)
985 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ESSID;
986 else if (strcmp(object_type_string,
987 NWAM_CONDITION_OBJECT_TYPE_BSSID_STRING) == 0)
988 *object_typep = NWAM_CONDITION_OBJECT_TYPE_BSSID;
989 else {
990 free(copy);
991 return (NWAM_INVALID_ARG);
992 }
993
994 if (*object_typep == NWAM_CONDITION_OBJECT_TYPE_NCP ||
995 *object_typep == NWAM_CONDITION_OBJECT_TYPE_NCU ||
996 *object_typep == NWAM_CONDITION_OBJECT_TYPE_ENM ||
997 *object_typep == NWAM_CONDITION_OBJECT_TYPE_LOC) {
998 if ((object_name = strtok_r(NULL, " \t", &lasts)) == NULL) {
999 free(copy);
1000 return (NWAM_INVALID_ARG);
1001 }
1002 if ((*object_namep = strdup(object_name)) == NULL) {
1003 free(copy);
1004 return (NWAM_NO_MEMORY);
1005 }
1006
1007 }
1008
1009 if ((condition_string = strtok_r(NULL, " \t", &lasts)) == NULL) {
1010 free(copy);
1011 if (*object_namep != NULL)
1012 free(*object_namep);
1013 return (NWAM_INVALID_ARG);
1014 }
1015 if (strcmp(condition_string, NWAM_CONDITION_IS_STRING) == 0)
1016 *conditionp = NWAM_CONDITION_IS;
1017 else if (strcmp(condition_string, NWAM_CONDITION_IS_NOT_STRING) == 0)
1018 *conditionp = NWAM_CONDITION_IS_NOT;
1019 else if (strcmp(condition_string, NWAM_CONDITION_CONTAINS_STRING) == 0)
1020 *conditionp = NWAM_CONDITION_CONTAINS;
1021 else if (strcmp(condition_string,
1022 NWAM_CONDITION_DOES_NOT_CONTAIN_STRING) == 0)
1023 *conditionp = NWAM_CONDITION_DOES_NOT_CONTAIN;
1024 else if (strcmp(condition_string,
1025 NWAM_CONDITION_IS_IN_RANGE_STRING) == 0)
1026 *conditionp = NWAM_CONDITION_IS_IN_RANGE;
1027 else if (strcmp(condition_string,
1028 NWAM_CONDITION_IS_NOT_IN_RANGE_STRING) == 0)
1029 *conditionp = NWAM_CONDITION_IS_NOT_IN_RANGE;
1030 else {
1031 free(copy);
1032 if (*object_namep != NULL)
1033 free(*object_namep);
1034 return (NWAM_INVALID_ARG);
1035 }
1036
1037 if (*object_typep == NWAM_CONDITION_OBJECT_TYPE_NCP ||
1038 *object_typep == NWAM_CONDITION_OBJECT_TYPE_NCU ||
1039 *object_typep == NWAM_CONDITION_OBJECT_TYPE_ENM ||
1040 *object_typep == NWAM_CONDITION_OBJECT_TYPE_LOC) {
1041 if ((*conditionp != NWAM_CONDITION_IS &&
1042 *conditionp != NWAM_CONDITION_IS_NOT) ||
1043 (active_string = strtok_r(NULL, " \t", &lasts)) == NULL ||
1044 strcmp(active_string, NWAM_CONDITION_ACTIVE_STRING) != 0) {
1045 free(copy);
1046 free(*object_namep);
1047 return (NWAM_INVALID_ARG);
1048 }
1049 } else {
1050 switch (*conditionp) {
1051 case NWAM_CONDITION_CONTAINS:
1052 case NWAM_CONDITION_DOES_NOT_CONTAIN:
1053 if (*object_typep !=
1054 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
1055 *object_typep !=
1056 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
1057 *object_typep != NWAM_CONDITION_OBJECT_TYPE_ESSID) {
1058 free(copy);
1059 free(*object_namep);
1060 return (NWAM_INVALID_ARG);
1061 }
1062 break;
1063 case NWAM_CONDITION_IS_IN_RANGE:
1064 case NWAM_CONDITION_IS_NOT_IN_RANGE:
1065 if (*object_typep !=
1066 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS) {
1067 free(copy);
1068 free(*object_namep);
1069 return (NWAM_INVALID_ARG);
1070 }
1071 break;
1072 }
1073
1074 if ((object_name = strtok_r(NULL, " \t", &lasts)) == NULL) {
1075 free(copy);
1076 free(*object_namep);
1077 return (NWAM_INVALID_ARG);
1078 }
1079 if ((*object_namep = strdup(object_name)) == NULL) {
1080 free(copy);
1081 free(*object_namep);
1082 return (NWAM_NO_MEMORY);
1083 }
1084 }
1085
1086 free(copy);
1087 return (NWAM_SUCCESS);
1088 }
1089
1090 nwam_error_t
nwam_condition_rate(nwam_condition_object_type_t object_type,nwam_condition_t condition,uint64_t * ratep)1091 nwam_condition_rate(nwam_condition_object_type_t object_type,
1092 nwam_condition_t condition, uint64_t *ratep)
1093 {
1094 assert(ratep != NULL);
1095
1096 *ratep = 0;
1097
1098 switch (object_type) {
1099 case NWAM_CONDITION_OBJECT_TYPE_NCP:
1100 case NWAM_CONDITION_OBJECT_TYPE_NCU:
1101 case NWAM_CONDITION_OBJECT_TYPE_ENM:
1102 case NWAM_CONDITION_OBJECT_TYPE_LOC:
1103 (*ratep)++;
1104 /* FALLTHRU */
1105 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
1106 (*ratep)++;
1107 /* FALLTHRU */
1108 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
1109 (*ratep)++;
1110 /* FALLTHRU */
1111 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
1112 (*ratep)++;
1113 /* FALLTHRU */
1114 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
1115 (*ratep)++;
1116 /* FALLTHRU */
1117 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
1118 (*ratep)++;
1119 break;
1120 default:
1121 return (NWAM_INVALID_ARG);
1122 }
1123
1124 switch (condition) {
1125 case NWAM_CONDITION_IS:
1126 (*ratep)++;
1127 /* FALLTHRU */
1128 case NWAM_CONDITION_CONTAINS:
1129 case NWAM_CONDITION_IS_IN_RANGE:
1130 (*ratep)++;
1131 /* FALLTHRU */
1132 case NWAM_CONDITION_DOES_NOT_CONTAIN:
1133 case NWAM_CONDITION_IS_NOT_IN_RANGE:
1134 (*ratep)++;
1135 /* FALLTHRU */
1136 case NWAM_CONDITION_IS_NOT:
1137 (*ratep)++;
1138 break;
1139 default:
1140 return (NWAM_INVALID_ARG);
1141 }
1142 return (NWAM_SUCCESS);
1143 }
1144