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 return (nwam_errno_to_nwam_error(nverr));
529 }
530
531 switch (nvpair_type(prop)) {
532 case DATA_TYPE_BOOLEAN_ARRAY:
533 if ((nverr = nvpair_value_boolean_array(prop,
534 &valbool, &numvalues)) != 0)
535 return (nwam_errno_to_nwam_error(nverr));
536 if ((err = nwam_value_create_boolean_array(valbool, numvalues,
537 valuep)) != NWAM_SUCCESS)
538 return (err);
539 break;
540 case DATA_TYPE_INT64_ARRAY:
541 if ((nverr = nvpair_value_int64_array(prop,
542 &valint64, &numvalues)) != 0)
543 return (nwam_errno_to_nwam_error(nverr));
544 if ((err = nwam_value_create_int64_array(valint64, numvalues,
545 valuep)) != NWAM_SUCCESS)
546 return (err);
547 break;
548 case DATA_TYPE_UINT64_ARRAY:
549 if ((nverr = nvpair_value_uint64_array(prop,
550 &valuint64, &numvalues)) != 0)
551 return (nwam_errno_to_nwam_error(nverr));
552 if ((err = nwam_value_create_uint64_array(valuint64, numvalues,
553 valuep)) != NWAM_SUCCESS)
554 return (err);
555 break;
556 case DATA_TYPE_STRING_ARRAY:
557 if ((nverr = nvpair_value_string_array(prop,
558 &valstr, &numvalues)) != 0)
559 return (nwam_errno_to_nwam_error(nverr));
560 if ((err = nwam_value_create_string_array(valstr, numvalues,
561 valuep)) != NWAM_SUCCESS)
562 return (err);
563 break;
564 default:
565 /* Should not happen */
566 return (NWAM_ERROR_INTERNAL);
567 }
568 return (NWAM_SUCCESS);
569 }
570
571 nwam_error_t
nwam_delete_prop(void * list,const char * name)572 nwam_delete_prop(void *list, const char *name)
573 {
574 int nverr;
575
576 if ((nverr = nvlist_remove_all(list, name)) != 0)
577 return (nwam_errno_to_nwam_error(nverr));
578 return (NWAM_SUCCESS);
579 }
580
581 nwam_error_t
nwam_set_prop_value(void * list,const char * propname,nwam_value_t value)582 nwam_set_prop_value(void *list, const char *propname, nwam_value_t value)
583 {
584 int nverr;
585 nwam_error_t err;
586 nwam_value_type_t type;
587 uint_t numvalues;
588 boolean_t *valbool;
589 int64_t *valint64;
590 uint64_t *valuint64;
591 char **valstr;
592
593 assert(list != NULL && value != NULL);
594
595 if ((err = nwam_value_get_type(value, &type)) != NWAM_SUCCESS)
596 return (err);
597
598 switch (type) {
599 case NWAM_VALUE_TYPE_BOOLEAN:
600 if ((err = nwam_value_get_boolean_array(value, &valbool,
601 &numvalues)) != NWAM_SUCCESS)
602 return (err);
603 if ((nverr = nvlist_add_boolean_array(list, propname,
604 valbool, numvalues)) != 0)
605 return (nwam_errno_to_nwam_error(nverr));
606 break;
607 case NWAM_VALUE_TYPE_INT64:
608 if ((err = nwam_value_get_int64_array(value, &valint64,
609 &numvalues)) != NWAM_SUCCESS)
610 return (err);
611 if ((nverr = nvlist_add_int64_array(list, propname,
612 valint64, numvalues)) != 0)
613 return (nwam_errno_to_nwam_error(nverr));
614 break;
615 case NWAM_VALUE_TYPE_UINT64:
616 if ((err = nwam_value_get_uint64_array(value, &valuint64,
617 &numvalues)) != NWAM_SUCCESS)
618 return (err);
619 if ((nverr = nvlist_add_uint64_array(list, propname,
620 valuint64, numvalues)) != 0)
621 return (nwam_errno_to_nwam_error(nverr));
622 break;
623 case NWAM_VALUE_TYPE_STRING:
624 if ((err = nwam_value_get_string_array(value, &valstr,
625 &numvalues)) != NWAM_SUCCESS)
626 return (err);
627 if ((nverr = nvlist_add_string_array(list, propname,
628 valstr, numvalues)) != 0)
629 return (nwam_errno_to_nwam_error(nverr));
630 break;
631 default:
632 return (NWAM_INVALID_ARG);
633 }
634
635 return (NWAM_SUCCESS);
636 }
637
638 /* Map uint64 values to their string counterparts */
639
640 struct nwam_value_entry {
641 const char *value_string;
642 uint64_t value;
643 };
644
645 struct nwam_value_entry prop_activation_mode_value_entries[] =
646 {
647 { NWAM_ACTIVATION_MODE_MANUAL_STRING, NWAM_ACTIVATION_MODE_MANUAL },
648 { NWAM_ACTIVATION_MODE_SYSTEM_STRING, NWAM_ACTIVATION_MODE_SYSTEM },
649 { NWAM_ACTIVATION_MODE_CONDITIONAL_ANY_STRING,
650 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY },
651 { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL_STRING,
652 NWAM_ACTIVATION_MODE_CONDITIONAL_ALL },
653 { NWAM_ACTIVATION_MODE_PRIORITIZED_STRING,
654 NWAM_ACTIVATION_MODE_PRIORITIZED },
655 { NULL, 0 }
656 };
657
658 struct nwam_value_entry ncu_prop_type_entries[] =
659 {
660 { NWAM_NCU_TYPE_LINK_STRING, NWAM_NCU_TYPE_LINK },
661 { NWAM_NCU_TYPE_INTERFACE_STRING, NWAM_NCU_TYPE_INTERFACE },
662 { NULL, 0 }
663 };
664
665 struct nwam_value_entry ncu_prop_class_entries[] =
666 {
667 { NWAM_NCU_CLASS_PHYS_STRING, NWAM_NCU_CLASS_PHYS },
668 { NWAM_NCU_CLASS_IP_STRING, NWAM_NCU_CLASS_IP },
669 { NULL, 0 }
670 };
671
672 struct nwam_value_entry ncu_prop_ip_version_entries[] =
673 {
674 { NWAM_IP_VERSION_IPV4_STRING, IPV4_VERSION },
675 { NWAM_IP_VERSION_IPV6_STRING, IPV6_VERSION },
676 { NULL, 0 }
677 };
678
679 struct nwam_value_entry ncu_prop_ipv4_addrsrc_entries[] =
680 {
681 { NWAM_ADDRSRC_DHCP_STRING, NWAM_ADDRSRC_DHCP },
682 { NWAM_ADDRSRC_STATIC_STRING, NWAM_ADDRSRC_STATIC },
683 { NULL, 0 }
684 };
685
686 struct nwam_value_entry ncu_prop_ipv6_addrsrc_entries[] =
687 {
688 { NWAM_ADDRSRC_DHCP_STRING, NWAM_ADDRSRC_DHCP },
689 { NWAM_ADDRSRC_STATIC_STRING, NWAM_ADDRSRC_STATIC },
690 { NWAM_ADDRSRC_AUTOCONF_STRING, NWAM_ADDRSRC_AUTOCONF },
691 { NULL, 0 }
692 };
693
694 struct nwam_value_entry ncu_prop_priority_mode_entries[] =
695 {
696 { NWAM_PRIORITY_MODE_EXCLUSIVE_STRING, NWAM_PRIORITY_MODE_EXCLUSIVE },
697 { NWAM_PRIORITY_MODE_SHARED_STRING, NWAM_PRIORITY_MODE_SHARED },
698 { NWAM_PRIORITY_MODE_ALL_STRING, NWAM_PRIORITY_MODE_ALL },
699 { NULL, 0 }
700 };
701
702 struct nwam_value_entry loc_prop_nameservices_entries[] =
703 {
704 { NWAM_NAMESERVICES_DNS_STRING, NWAM_NAMESERVICES_DNS },
705 { NWAM_NAMESERVICES_FILES_STRING, NWAM_NAMESERVICES_FILES },
706 { NWAM_NAMESERVICES_NIS_STRING, NWAM_NAMESERVICES_NIS },
707 { NWAM_NAMESERVICES_LDAP_STRING, NWAM_NAMESERVICES_LDAP },
708 { NULL, 0 }
709 };
710
711 struct nwam_value_entry loc_prop_nameservice_configsrc_entries[] =
712 {
713 { NWAM_CONFIGSRC_MANUAL_STRING, NWAM_CONFIGSRC_MANUAL },
714 { NWAM_CONFIGSRC_DHCP_STRING, NWAM_CONFIGSRC_DHCP },
715 { NULL, 0 }
716 };
717
718 struct nwam_value_entry known_wlan_prop_security_mode_entries[] =
719 {
720 { "none", DLADM_WLAN_SECMODE_NONE },
721 { "wep", DLADM_WLAN_SECMODE_WEP },
722 { "wpa", DLADM_WLAN_SECMODE_WPA },
723 { NULL, 0 }
724 };
725
726 struct nwam_prop_value_entry {
727 const char *prop_name;
728 struct nwam_value_entry *value_entries;
729 } prop_value_entry_table[] =
730 {
731 { NWAM_NCU_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
732 { NWAM_NCU_PROP_TYPE, ncu_prop_type_entries },
733 { NWAM_NCU_PROP_CLASS, ncu_prop_class_entries },
734 { NWAM_NCU_PROP_IP_VERSION, ncu_prop_ip_version_entries },
735 { NWAM_NCU_PROP_IPV4_ADDRSRC, ncu_prop_ipv4_addrsrc_entries },
736 { NWAM_NCU_PROP_IPV6_ADDRSRC, ncu_prop_ipv6_addrsrc_entries },
737 { NWAM_NCU_PROP_PRIORITY_MODE, ncu_prop_priority_mode_entries },
738 { NWAM_ENM_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
739 { NWAM_LOC_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
740 { NWAM_LOC_PROP_NAMESERVICES, loc_prop_nameservices_entries },
741 { NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
742 loc_prop_nameservice_configsrc_entries },
743 { NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
744 loc_prop_nameservice_configsrc_entries },
745 { NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
746 loc_prop_nameservice_configsrc_entries },
747 { NWAM_KNOWN_WLAN_PROP_SECURITY_MODE,
748 known_wlan_prop_security_mode_entries },
749 { NULL, NULL }
750 };
751
752 /*
753 * Convert uint64 values for property propname into a string representing
754 * that value. Used by enum values.
755 */
756 nwam_error_t
nwam_uint64_get_value_string(const char * propname,uint64_t val,const char ** valstrp)757 nwam_uint64_get_value_string(const char *propname, uint64_t val,
758 const char **valstrp)
759 {
760 int i, j;
761 int max = 0; /* largest enum value seen so far */
762 struct nwam_value_entry *value_entries;
763
764 assert(propname != NULL && valstrp != NULL);
765
766 for (i = 0; prop_value_entry_table[i].prop_name != NULL; i++) {
767 if (strcmp(prop_value_entry_table[i].prop_name, propname) != 0)
768 continue;
769
770 value_entries = prop_value_entry_table[i].value_entries;
771
772 for (j = 0; value_entries[j].value_string != NULL; j++) {
773 if (value_entries[j].value == val) {
774 *valstrp = value_entries[j].value_string;
775 return (NWAM_SUCCESS);
776 }
777 max = value_entries[j].value > max ?
778 value_entries[j].value : max;
779 }
780 /*
781 * If trying to get the string for an enum value that doesn't
782 * exist, return NWAM_LIST_END. Otherwise, the input enum
783 * value doesn't exist for the given property.
784 */
785 if (val > max)
786 return (NWAM_LIST_END);
787 else
788 return (NWAM_ENTITY_INVALID_VALUE);
789 }
790 return (NWAM_INVALID_ARG);
791 }
792
793 /*
794 * Convert string to appropriate uint64 value.
795 */
796 nwam_error_t
nwam_value_string_get_uint64(const char * propname,const char * valstr,uint64_t * valp)797 nwam_value_string_get_uint64(const char *propname, const char *valstr,
798 uint64_t *valp)
799 {
800 int i, j;
801 struct nwam_value_entry *value_entries;
802
803 assert(propname != NULL && valstr != NULL && valp != NULL);
804
805 for (i = 0; prop_value_entry_table[i].prop_name != NULL; i++) {
806 if (strcmp(prop_value_entry_table[i].prop_name, propname) != 0)
807 continue;
808
809 value_entries = prop_value_entry_table[i].value_entries;
810
811 for (j = 0; value_entries[j].value_string != NULL; j++) {
812 if (strcasecmp(value_entries[j].value_string, valstr)
813 == 0) {
814 *valp = value_entries[j].value;
815 return (NWAM_SUCCESS);
816 }
817 }
818 return (NWAM_ENTITY_INVALID_VALUE);
819 }
820 return (NWAM_INVALID_ARG);
821 }
822
823 /* Conditional activation functions */
824
825 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)826 nwam_condition_to_condition_string(nwam_condition_object_type_t object_type,
827 nwam_condition_t condition, const char *object_name, char **stringp)
828 {
829 char *object_type_string, *condition_string;
830 char *string;
831
832 assert(stringp != NULL);
833
834 *stringp = NULL;
835
836 switch (object_type) {
837 case NWAM_CONDITION_OBJECT_TYPE_NCP:
838 object_type_string = NWAM_CONDITION_OBJECT_TYPE_NCP_STRING;
839 break;
840 case NWAM_CONDITION_OBJECT_TYPE_NCU:
841 object_type_string = NWAM_CONDITION_OBJECT_TYPE_NCU_STRING;
842 break;
843 case NWAM_CONDITION_OBJECT_TYPE_ENM:
844 object_type_string = NWAM_CONDITION_OBJECT_TYPE_ENM_STRING;
845 break;
846 case NWAM_CONDITION_OBJECT_TYPE_LOC:
847 object_type_string = NWAM_CONDITION_OBJECT_TYPE_LOC_STRING;
848 break;
849 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
850 object_type_string =
851 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS_STRING;
852 break;
853 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
854 object_type_string =
855 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN_STRING;
856 break;
857 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
858 object_type_string =
859 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN_STRING;
860 break;
861 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
862 object_type_string = NWAM_CONDITION_OBJECT_TYPE_ESSID_STRING;
863 break;
864 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
865 object_type_string = NWAM_CONDITION_OBJECT_TYPE_BSSID_STRING;
866 break;
867 default:
868 return (NWAM_INVALID_ARG);
869
870 }
871 switch (condition) {
872 case NWAM_CONDITION_IS:
873 condition_string = NWAM_CONDITION_IS_STRING;
874 break;
875 case NWAM_CONDITION_IS_NOT:
876 condition_string = NWAM_CONDITION_IS_NOT_STRING;
877 break;
878 case NWAM_CONDITION_CONTAINS:
879 if (object_type != NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
880 object_type != NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
881 object_type != NWAM_CONDITION_OBJECT_TYPE_ESSID)
882 return (NWAM_INVALID_ARG);
883 condition_string = NWAM_CONDITION_CONTAINS_STRING;
884 break;
885 case NWAM_CONDITION_DOES_NOT_CONTAIN:
886 if (object_type != NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
887 object_type != NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
888 object_type != NWAM_CONDITION_OBJECT_TYPE_ESSID)
889 return (NWAM_INVALID_ARG);
890
891 condition_string = NWAM_CONDITION_DOES_NOT_CONTAIN_STRING;
892 break;
893 case NWAM_CONDITION_IS_IN_RANGE:
894 if (object_type != NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS)
895 return (NWAM_INVALID_ARG);
896 condition_string = NWAM_CONDITION_IS_IN_RANGE_STRING;
897 break;
898 case NWAM_CONDITION_IS_NOT_IN_RANGE:
899 if (object_type != NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS)
900 return (NWAM_INVALID_ARG);
901 condition_string = NWAM_CONDITION_IS_NOT_IN_RANGE_STRING;
902 break;
903 default:
904 return (NWAM_INVALID_ARG);
905 }
906 if ((string = malloc(NWAM_MAX_VALUE_LEN)) == NULL)
907 return (NWAM_NO_MEMORY);
908 switch (object_type) {
909 case NWAM_CONDITION_OBJECT_TYPE_NCP:
910 case NWAM_CONDITION_OBJECT_TYPE_NCU:
911 case NWAM_CONDITION_OBJECT_TYPE_ENM:
912 case NWAM_CONDITION_OBJECT_TYPE_LOC:
913 (void) snprintf(string, NWAM_MAX_VALUE_LEN,
914 "%s %s %s active", object_type_string,
915 object_name, condition_string);
916 *stringp = string;
917 break;
918
919 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
920 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
921 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
922 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
923 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
924 (void) snprintf(string, NWAM_MAX_VALUE_LEN,
925 "%s %s %s", object_type_string,
926 condition_string, object_name);
927 *stringp = string;
928 break;
929
930 default:
931 free(string);
932 return (NWAM_INVALID_ARG);
933
934 }
935 return (NWAM_SUCCESS);
936 }
937
938 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)939 nwam_condition_string_to_condition(const char *string,
940 nwam_condition_object_type_t *object_typep,
941 nwam_condition_t *conditionp, char **object_namep)
942 {
943 char *copy, *lasts;
944 char *object_type_string, *object_name;
945 char *condition_string, *active_string;
946
947 assert(string != NULL && object_typep != NULL && conditionp != NULL &&
948 object_namep != NULL);
949
950 if ((copy = strdup(string)) == NULL)
951 return (NWAM_NO_MEMORY);
952
953 if ((object_type_string = strtok_r(copy, " \t", &lasts)) == NULL) {
954 free(copy);
955 return (NWAM_INVALID_ARG);
956 }
957
958 if (strcmp(object_type_string, NWAM_CONDITION_OBJECT_TYPE_NCP_STRING)
959 == 0)
960 *object_typep = NWAM_CONDITION_OBJECT_TYPE_NCP;
961 else if (strcmp(object_type_string,
962 NWAM_CONDITION_OBJECT_TYPE_NCU_STRING) == 0)
963 *object_typep = NWAM_CONDITION_OBJECT_TYPE_NCU;
964 else if (strcmp(object_type_string,
965 NWAM_CONDITION_OBJECT_TYPE_ENM_STRING) == 0)
966 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ENM;
967 else if (strcmp(object_type_string,
968 NWAM_CONDITION_OBJECT_TYPE_LOC_STRING) == 0)
969 *object_typep = NWAM_CONDITION_OBJECT_TYPE_LOC;
970 else if (strcmp(object_type_string,
971 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS_STRING) == 0)
972 *object_typep = NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS;
973 else if (strcmp(object_type_string,
974 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN_STRING) == 0)
975 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN;
976 else if (strcmp(object_type_string,
977 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN_STRING) == 0)
978 *object_typep = NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN;
979 else if (strcmp(object_type_string,
980 NWAM_CONDITION_OBJECT_TYPE_ESSID_STRING) == 0)
981 *object_typep = NWAM_CONDITION_OBJECT_TYPE_ESSID;
982 else if (strcmp(object_type_string,
983 NWAM_CONDITION_OBJECT_TYPE_BSSID_STRING) == 0)
984 *object_typep = NWAM_CONDITION_OBJECT_TYPE_BSSID;
985 else {
986 free(copy);
987 return (NWAM_INVALID_ARG);
988 }
989
990 if (*object_typep == NWAM_CONDITION_OBJECT_TYPE_NCP ||
991 *object_typep == NWAM_CONDITION_OBJECT_TYPE_NCU ||
992 *object_typep == NWAM_CONDITION_OBJECT_TYPE_ENM ||
993 *object_typep == NWAM_CONDITION_OBJECT_TYPE_LOC) {
994 if ((object_name = strtok_r(NULL, " \t", &lasts)) == NULL) {
995 free(copy);
996 return (NWAM_INVALID_ARG);
997 }
998 if ((*object_namep = strdup(object_name)) == NULL) {
999 free(copy);
1000 return (NWAM_NO_MEMORY);
1001 }
1002
1003 }
1004
1005 if ((condition_string = strtok_r(NULL, " \t", &lasts)) == NULL) {
1006 free(copy);
1007 if (*object_namep != NULL)
1008 free(*object_namep);
1009 return (NWAM_INVALID_ARG);
1010 }
1011 if (strcmp(condition_string, NWAM_CONDITION_IS_STRING) == 0)
1012 *conditionp = NWAM_CONDITION_IS;
1013 else if (strcmp(condition_string, NWAM_CONDITION_IS_NOT_STRING) == 0)
1014 *conditionp = NWAM_CONDITION_IS_NOT;
1015 else if (strcmp(condition_string, NWAM_CONDITION_CONTAINS_STRING) == 0)
1016 *conditionp = NWAM_CONDITION_CONTAINS;
1017 else if (strcmp(condition_string,
1018 NWAM_CONDITION_DOES_NOT_CONTAIN_STRING) == 0)
1019 *conditionp = NWAM_CONDITION_DOES_NOT_CONTAIN;
1020 else if (strcmp(condition_string,
1021 NWAM_CONDITION_IS_IN_RANGE_STRING) == 0)
1022 *conditionp = NWAM_CONDITION_IS_IN_RANGE;
1023 else if (strcmp(condition_string,
1024 NWAM_CONDITION_IS_NOT_IN_RANGE_STRING) == 0)
1025 *conditionp = NWAM_CONDITION_IS_NOT_IN_RANGE;
1026 else {
1027 free(copy);
1028 if (*object_namep != NULL)
1029 free(*object_namep);
1030 return (NWAM_INVALID_ARG);
1031 }
1032
1033 if (*object_typep == NWAM_CONDITION_OBJECT_TYPE_NCP ||
1034 *object_typep == NWAM_CONDITION_OBJECT_TYPE_NCU ||
1035 *object_typep == NWAM_CONDITION_OBJECT_TYPE_ENM ||
1036 *object_typep == NWAM_CONDITION_OBJECT_TYPE_LOC) {
1037 if ((*conditionp != NWAM_CONDITION_IS &&
1038 *conditionp != NWAM_CONDITION_IS_NOT) ||
1039 (active_string = strtok_r(NULL, " \t", &lasts)) == NULL ||
1040 strcmp(active_string, NWAM_CONDITION_ACTIVE_STRING) != 0) {
1041 free(copy);
1042 free(*object_namep);
1043 return (NWAM_INVALID_ARG);
1044 }
1045 } else {
1046 switch (*conditionp) {
1047 case NWAM_CONDITION_CONTAINS:
1048 case NWAM_CONDITION_DOES_NOT_CONTAIN:
1049 if (*object_typep !=
1050 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
1051 *object_typep !=
1052 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
1053 *object_typep != NWAM_CONDITION_OBJECT_TYPE_ESSID) {
1054 free(copy);
1055 free(*object_namep);
1056 return (NWAM_INVALID_ARG);
1057 }
1058 break;
1059 case NWAM_CONDITION_IS_IN_RANGE:
1060 case NWAM_CONDITION_IS_NOT_IN_RANGE:
1061 if (*object_typep !=
1062 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS) {
1063 free(copy);
1064 free(*object_namep);
1065 return (NWAM_INVALID_ARG);
1066 }
1067 break;
1068 }
1069
1070 if ((object_name = strtok_r(NULL, " \t", &lasts)) == NULL) {
1071 free(copy);
1072 free(*object_namep);
1073 return (NWAM_INVALID_ARG);
1074 }
1075 if ((*object_namep = strdup(object_name)) == NULL) {
1076 free(copy);
1077 free(*object_namep);
1078 return (NWAM_NO_MEMORY);
1079 }
1080 }
1081
1082 free(copy);
1083 return (NWAM_SUCCESS);
1084 }
1085
1086 nwam_error_t
nwam_condition_rate(nwam_condition_object_type_t object_type,nwam_condition_t condition,uint64_t * ratep)1087 nwam_condition_rate(nwam_condition_object_type_t object_type,
1088 nwam_condition_t condition, uint64_t *ratep)
1089 {
1090 assert(ratep != NULL);
1091
1092 *ratep = 0;
1093
1094 switch (object_type) {
1095 case NWAM_CONDITION_OBJECT_TYPE_NCP:
1096 case NWAM_CONDITION_OBJECT_TYPE_NCU:
1097 case NWAM_CONDITION_OBJECT_TYPE_ENM:
1098 case NWAM_CONDITION_OBJECT_TYPE_LOC:
1099 (*ratep)++;
1100 /* FALLTHRU */
1101 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
1102 (*ratep)++;
1103 /* FALLTHRU */
1104 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
1105 (*ratep)++;
1106 /* FALLTHRU */
1107 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
1108 (*ratep)++;
1109 /* FALLTHRU */
1110 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
1111 (*ratep)++;
1112 /* FALLTHRU */
1113 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
1114 (*ratep)++;
1115 break;
1116 default:
1117 return (NWAM_INVALID_ARG);
1118 }
1119
1120 switch (condition) {
1121 case NWAM_CONDITION_IS:
1122 (*ratep)++;
1123 /* FALLTHRU */
1124 case NWAM_CONDITION_CONTAINS:
1125 case NWAM_CONDITION_IS_IN_RANGE:
1126 (*ratep)++;
1127 /* FALLTHRU */
1128 case NWAM_CONDITION_DOES_NOT_CONTAIN:
1129 case NWAM_CONDITION_IS_NOT_IN_RANGE:
1130 (*ratep)++;
1131 /* FALLTHRU */
1132 case NWAM_CONDITION_IS_NOT:
1133 (*ratep)++;
1134 break;
1135 default:
1136 return (NWAM_INVALID_ARG);
1137 }
1138 return (NWAM_SUCCESS);
1139 }
1140