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 if (list != NULL)
384 nvlist_free(list);
385 }
386
387 nwam_error_t
nwam_dup_object_list(void * oldlist,void * newlist)388 nwam_dup_object_list(void *oldlist, void *newlist)
389 {
390 int nverr;
391
392 assert(oldlist != NULL && newlist != NULL);
393
394 if ((nverr = nvlist_dup(oldlist, newlist, 0)) != 0)
395 return (nwam_errno_to_nwam_error(nverr));
396
397 return (NWAM_SUCCESS);
398 }
399
400 /* Add child object list to parent object list using property name childname */
401 nwam_error_t
nwam_object_list_add_object_list(void * parentlist,char * childname,void * childlist)402 nwam_object_list_add_object_list(void *parentlist, char *childname,
403 void *childlist)
404 {
405 return (nwam_errno_to_nwam_error(nvlist_add_nvlist(parentlist,
406 childname, childlist)));
407 }
408
409 /* Remove object list from parent object list */
410 nwam_error_t
nwam_object_list_remove_object_list(void * parentlist,char * childname)411 nwam_object_list_remove_object_list(void *parentlist, char *childname)
412 {
413 return (nwam_errno_to_nwam_error(nvlist_remove_all(parentlist,
414 childname)));
415 }
416
417 /*
418 * Get next object list (nvlist) after lastname. Used to walk NCUs, ENMs and
419 * locations, each of which is internally represented as an nvlist.
420 */
421 nwam_error_t
nwam_next_object_list(void * parentlist,char * lastname,char ** childnamep,void * childlistp)422 nwam_next_object_list(void *parentlist, char *lastname, char **childnamep,
423 void *childlistp)
424 {
425 nvpair_t *last = NULL, *next;
426 int nverr;
427
428 if (lastname != NULL) {
429 if ((nverr = nvlist_lookup_nvpair(parentlist, lastname, &last))
430 != 0)
431 return (nwam_errno_to_nwam_error(nverr));
432 }
433 if ((next = nvlist_next_nvpair(parentlist, last)) == NULL)
434 return (NWAM_LIST_END);
435
436 *childnamep = nvpair_name(next);
437
438 if (nvpair_type(next) != DATA_TYPE_NVLIST)
439 return (NWAM_ERROR_INTERNAL);
440
441 if ((nverr = nvpair_value_nvlist(next, childlistp)) != NWAM_SUCCESS)
442 return (nwam_errno_to_nwam_error(nverr));
443
444 return (NWAM_SUCCESS);
445 }
446
447 /*
448 * Pack nvlist into contiguous memory. If packed_listp is NULL, we just
449 * return the size of the memory needed to do so.
450 */
451 nwam_error_t
nwam_pack_object_list(void * list,char ** packed_listp,size_t * packed_sizep)452 nwam_pack_object_list(void *list, char **packed_listp, size_t *packed_sizep)
453 {
454 int nverr;
455
456 assert(list != NULL && packed_sizep != NULL);
457
458 if (packed_listp == NULL) {
459 nverr = nvlist_size(list, packed_sizep, NV_ENCODE_XDR);
460 } else {
461 nverr = nvlist_pack(list, packed_listp, packed_sizep,
462 NV_ENCODE_XDR, 0);
463 }
464
465 if (nverr != 0)
466 return (nwam_errno_to_nwam_error(nverr));
467
468 return (NWAM_SUCCESS);
469 }
470
471 nwam_error_t
nwam_unpack_object_list(char * packed_list,size_t packed_size,void * list)472 nwam_unpack_object_list(char *packed_list, size_t packed_size,
473 void *list)
474 {
475 int nverr;
476
477 assert(packed_list != NULL && list != NULL);
478
479 *((nvlist_t **)list) = NULL;
480
481 nverr = nvlist_unpack(packed_list, packed_size, (nvlist_t **)list, 0);
482
483 if (nverr != 0)
484 return (nwam_errno_to_nwam_error(nverr));
485
486 return (NWAM_SUCCESS);
487 }
488
489 /*
490 * Functions to walk, set and get properties in nvlist, translating
491 * between nwam_value_t and nvlist/nvpair representations.
492 */
493 nwam_error_t
nwam_next_object_prop(void * list,char * lastname,char ** namep,nwam_value_t * valuep)494 nwam_next_object_prop(void *list, char *lastname, char **namep,
495 nwam_value_t *valuep)
496 {
497 nvpair_t *last = NULL, *next;
498 int nverr;
499
500 if (lastname != NULL) {
501 if ((nverr = nvlist_lookup_nvpair(list, lastname, &last)) != 0)
502 return (nwam_errno_to_nwam_error(nverr));
503 }
504 if ((next = nvlist_next_nvpair(list, last)) == NULL)
505 return (NWAM_LIST_END);
506
507 *namep = nvpair_name(next);
508
509 return (nwam_get_prop_value(list, (const char *)*namep, valuep));
510 }
511
512 nwam_error_t
nwam_get_prop_value(void * list,const char * name,nwam_value_t * valuep)513 nwam_get_prop_value(void *list, const char *name, nwam_value_t *valuep)
514 {
515 nvpair_t *prop;
516 nwam_error_t err;
517 int nverr;
518 boolean_t *valbool;
519 int64_t *valint64;
520 uint64_t *valuint64;
521 char **valstr;
522 uint_t numvalues;
523
524 assert(valuep != NULL);
525
526 *valuep = NULL;
527
528 if ((nverr = nvlist_lookup_nvpair(list, name, &prop)) != 0) {
529 /* convert EINVAL to NOT_FOUND */
530 if (nverr == EINVAL)
531 return (NWAM_ENTITY_NOT_FOUND);
532 return (nwam_errno_to_nwam_error(nverr));
533 }
534
535 switch (nvpair_type(prop)) {
536 case DATA_TYPE_BOOLEAN_ARRAY:
537 if ((nverr = nvpair_value_boolean_array(prop,
538 &valbool, &numvalues)) != 0)
539 return (nwam_errno_to_nwam_error(nverr));
540 if ((err = nwam_value_create_boolean_array(valbool, numvalues,
541 valuep)) != NWAM_SUCCESS)
542 return (err);
543 break;
544 case DATA_TYPE_INT64_ARRAY:
545 if ((nverr = nvpair_value_int64_array(prop,
546 &valint64, &numvalues)) != 0)
547 return (nwam_errno_to_nwam_error(nverr));
548 if ((err = nwam_value_create_int64_array(valint64, numvalues,
549 valuep)) != NWAM_SUCCESS)
550 return (err);
551 break;
552 case DATA_TYPE_UINT64_ARRAY:
553 if ((nverr = nvpair_value_uint64_array(prop,
554 &valuint64, &numvalues)) != 0)
555 return (nwam_errno_to_nwam_error(nverr));
556 if ((err = nwam_value_create_uint64_array(valuint64, numvalues,
557 valuep)) != NWAM_SUCCESS)
558 return (err);
559 break;
560 case DATA_TYPE_STRING_ARRAY:
561 if ((nverr = nvpair_value_string_array(prop,
562 &valstr, &numvalues)) != 0)
563 return (nwam_errno_to_nwam_error(nverr));
564 if ((err = nwam_value_create_string_array(valstr, numvalues,
565 valuep)) != NWAM_SUCCESS)
566 return (err);
567 break;
568 default:
569 /* Should not happen */
570 return (NWAM_ERROR_INTERNAL);
571 }
572 return (NWAM_SUCCESS);
573 }
574
575 nwam_error_t
nwam_delete_prop(void * list,const char * name)576 nwam_delete_prop(void *list, const char *name)
577 {
578 int nverr;
579
580 if ((nverr = nvlist_remove_all(list, name)) != 0)
581 return (nwam_errno_to_nwam_error(nverr));
582 return (NWAM_SUCCESS);
583 }
584
585 nwam_error_t
nwam_set_prop_value(void * list,const char * propname,nwam_value_t value)586 nwam_set_prop_value(void *list, const char *propname, nwam_value_t value)
587 {
588 int nverr;
589 nwam_error_t err;
590 nwam_value_type_t type;
591 uint_t numvalues;
592 boolean_t *valbool;
593 int64_t *valint64;
594 uint64_t *valuint64;
595 char **valstr;
596
597 assert(list != NULL && value != NULL);
598
599 if ((err = nwam_value_get_type(value, &type)) != NWAM_SUCCESS)
600 return (err);
601
602 switch (type) {
603 case NWAM_VALUE_TYPE_BOOLEAN:
604 if ((err = nwam_value_get_boolean_array(value, &valbool,
605 &numvalues)) != NWAM_SUCCESS)
606 return (err);
607 if ((nverr = nvlist_add_boolean_array(list, propname,
608 valbool, numvalues)) != 0)
609 return (nwam_errno_to_nwam_error(nverr));
610 break;
611 case NWAM_VALUE_TYPE_INT64:
612 if ((err = nwam_value_get_int64_array(value, &valint64,
613 &numvalues)) != NWAM_SUCCESS)
614 return (err);
615 if ((nverr = nvlist_add_int64_array(list, propname,
616 valint64, numvalues)) != 0)
617 return (nwam_errno_to_nwam_error(nverr));
618 break;
619 case NWAM_VALUE_TYPE_UINT64:
620 if ((err = nwam_value_get_uint64_array(value, &valuint64,
621 &numvalues)) != NWAM_SUCCESS)
622 return (err);
623 if ((nverr = nvlist_add_uint64_array(list, propname,
624 valuint64, numvalues)) != 0)
625 return (nwam_errno_to_nwam_error(nverr));
626 break;
627 case NWAM_VALUE_TYPE_STRING:
628 if ((err = nwam_value_get_string_array(value, &valstr,
629 &numvalues)) != NWAM_SUCCESS)
630 return (err);
631 if ((nverr = nvlist_add_string_array(list, propname,
632 valstr, numvalues)) != 0)
633 return (nwam_errno_to_nwam_error(nverr));
634 break;
635 default:
636 return (NWAM_INVALID_ARG);
637 }
638
639 return (NWAM_SUCCESS);
640 }
641
642 /* Map uint64 values to their string counterparts */
643
644 struct nwam_value_entry {
645 const char *value_string;
646 uint64_t value;
647 };
648
649 struct nwam_value_entry prop_activation_mode_value_entries[] =
650 {
651 { NWAM_ACTIVATION_MODE_MANUAL_STRING, NWAM_ACTIVATION_MODE_MANUAL },
652 { NWAM_ACTIVATION_MODE_SYSTEM_STRING, NWAM_ACTIVATION_MODE_SYSTEM },
653 { NWAM_ACTIVATION_MODE_CONDITIONAL_ANY_STRING,
654 NWAM_ACTIVATION_MODE_CONDITIONAL_ANY },
655 { NWAM_ACTIVATION_MODE_CONDITIONAL_ALL_STRING,
656 NWAM_ACTIVATION_MODE_CONDITIONAL_ALL },
657 { NWAM_ACTIVATION_MODE_PRIORITIZED_STRING,
658 NWAM_ACTIVATION_MODE_PRIORITIZED },
659 { NULL, 0 }
660 };
661
662 struct nwam_value_entry ncu_prop_type_entries[] =
663 {
664 { NWAM_NCU_TYPE_LINK_STRING, NWAM_NCU_TYPE_LINK },
665 { NWAM_NCU_TYPE_INTERFACE_STRING, NWAM_NCU_TYPE_INTERFACE },
666 { NULL, 0 }
667 };
668
669 struct nwam_value_entry ncu_prop_class_entries[] =
670 {
671 { NWAM_NCU_CLASS_PHYS_STRING, NWAM_NCU_CLASS_PHYS },
672 { NWAM_NCU_CLASS_IP_STRING, NWAM_NCU_CLASS_IP },
673 { NULL, 0 }
674 };
675
676 struct nwam_value_entry ncu_prop_ip_version_entries[] =
677 {
678 { NWAM_IP_VERSION_IPV4_STRING, IPV4_VERSION },
679 { NWAM_IP_VERSION_IPV6_STRING, IPV6_VERSION },
680 { NULL, 0 }
681 };
682
683 struct nwam_value_entry ncu_prop_ipv4_addrsrc_entries[] =
684 {
685 { NWAM_ADDRSRC_DHCP_STRING, NWAM_ADDRSRC_DHCP },
686 { NWAM_ADDRSRC_STATIC_STRING, NWAM_ADDRSRC_STATIC },
687 { NULL, 0 }
688 };
689
690 struct nwam_value_entry ncu_prop_ipv6_addrsrc_entries[] =
691 {
692 { NWAM_ADDRSRC_DHCP_STRING, NWAM_ADDRSRC_DHCP },
693 { NWAM_ADDRSRC_STATIC_STRING, NWAM_ADDRSRC_STATIC },
694 { NWAM_ADDRSRC_AUTOCONF_STRING, NWAM_ADDRSRC_AUTOCONF },
695 { NULL, 0 }
696 };
697
698 struct nwam_value_entry ncu_prop_priority_mode_entries[] =
699 {
700 { NWAM_PRIORITY_MODE_EXCLUSIVE_STRING, NWAM_PRIORITY_MODE_EXCLUSIVE },
701 { NWAM_PRIORITY_MODE_SHARED_STRING, NWAM_PRIORITY_MODE_SHARED },
702 { NWAM_PRIORITY_MODE_ALL_STRING, NWAM_PRIORITY_MODE_ALL },
703 { NULL, 0 }
704 };
705
706 struct nwam_value_entry loc_prop_nameservices_entries[] =
707 {
708 { NWAM_NAMESERVICES_DNS_STRING, NWAM_NAMESERVICES_DNS },
709 { NWAM_NAMESERVICES_FILES_STRING, NWAM_NAMESERVICES_FILES },
710 { NWAM_NAMESERVICES_NIS_STRING, NWAM_NAMESERVICES_NIS },
711 { NWAM_NAMESERVICES_LDAP_STRING, NWAM_NAMESERVICES_LDAP },
712 { NULL, 0 }
713 };
714
715 struct nwam_value_entry loc_prop_nameservice_configsrc_entries[] =
716 {
717 { NWAM_CONFIGSRC_MANUAL_STRING, NWAM_CONFIGSRC_MANUAL },
718 { NWAM_CONFIGSRC_DHCP_STRING, NWAM_CONFIGSRC_DHCP },
719 { NULL, 0 }
720 };
721
722 struct nwam_value_entry known_wlan_prop_security_mode_entries[] =
723 {
724 { "none", DLADM_WLAN_SECMODE_NONE },
725 { "wep", DLADM_WLAN_SECMODE_WEP },
726 { "wpa", DLADM_WLAN_SECMODE_WPA },
727 { NULL, 0 }
728 };
729
730 struct nwam_prop_value_entry {
731 const char *prop_name;
732 struct nwam_value_entry *value_entries;
733 } prop_value_entry_table[] =
734 {
735 { NWAM_NCU_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
736 { NWAM_NCU_PROP_TYPE, ncu_prop_type_entries },
737 { NWAM_NCU_PROP_CLASS, ncu_prop_class_entries },
738 { NWAM_NCU_PROP_IP_VERSION, ncu_prop_ip_version_entries },
739 { NWAM_NCU_PROP_IPV4_ADDRSRC, ncu_prop_ipv4_addrsrc_entries },
740 { NWAM_NCU_PROP_IPV6_ADDRSRC, ncu_prop_ipv6_addrsrc_entries },
741 { NWAM_NCU_PROP_PRIORITY_MODE, ncu_prop_priority_mode_entries },
742 { NWAM_ENM_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
743 { NWAM_LOC_PROP_ACTIVATION_MODE, prop_activation_mode_value_entries },
744 { NWAM_LOC_PROP_NAMESERVICES, loc_prop_nameservices_entries },
745 { NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC,
746 loc_prop_nameservice_configsrc_entries },
747 { NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC,
748 loc_prop_nameservice_configsrc_entries },
749 { NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC,
750 loc_prop_nameservice_configsrc_entries },
751 { NWAM_KNOWN_WLAN_PROP_SECURITY_MODE,
752 known_wlan_prop_security_mode_entries },
753 { NULL, NULL }
754 };
755
756 /*
757 * Convert uint64 values for property propname into a string representing
758 * that value. Used by enum values.
759 */
760 nwam_error_t
nwam_uint64_get_value_string(const char * propname,uint64_t val,const char ** valstrp)761 nwam_uint64_get_value_string(const char *propname, uint64_t val,
762 const char **valstrp)
763 {
764 int i, j;
765 int max = 0; /* largest enum value seen so far */
766 struct nwam_value_entry *value_entries;
767
768 assert(propname != NULL && valstrp != NULL);
769
770 for (i = 0; prop_value_entry_table[i].prop_name != NULL; i++) {
771 if (strcmp(prop_value_entry_table[i].prop_name, propname) != 0)
772 continue;
773
774 value_entries = prop_value_entry_table[i].value_entries;
775
776 for (j = 0; value_entries[j].value_string != NULL; j++) {
777 if (value_entries[j].value == val) {
778 *valstrp = value_entries[j].value_string;
779 return (NWAM_SUCCESS);
780 }
781 max = value_entries[j].value > max ?
782 value_entries[j].value : max;
783 }
784 /*
785 * If trying to get the string for an enum value that doesn't
786 * exist, return NWAM_LIST_END. Otherwise, the input enum
787 * value doesn't exist for the given property.
788 */
789 if (val > max)
790 return (NWAM_LIST_END);
791 else
792 return (NWAM_ENTITY_INVALID_VALUE);
793 }
794 return (NWAM_INVALID_ARG);
795 }
796
797 /*
798 * Convert string to appropriate uint64 value.
799 */
800 nwam_error_t
nwam_value_string_get_uint64(const char * propname,const char * valstr,uint64_t * valp)801 nwam_value_string_get_uint64(const char *propname, const char *valstr,
802 uint64_t *valp)
803 {
804 int i, j;
805 struct nwam_value_entry *value_entries;
806
807 assert(propname != NULL && valstr != NULL && valp != NULL);
808
809 for (i = 0; prop_value_entry_table[i].prop_name != NULL; i++) {
810 if (strcmp(prop_value_entry_table[i].prop_name, propname) != 0)
811 continue;
812
813 value_entries = prop_value_entry_table[i].value_entries;
814
815 for (j = 0; value_entries[j].value_string != NULL; j++) {
816 if (strcasecmp(value_entries[j].value_string, valstr)
817 == 0) {
818 *valp = value_entries[j].value;
819 return (NWAM_SUCCESS);
820 }
821 }
822 return (NWAM_ENTITY_INVALID_VALUE);
823 }
824 return (NWAM_INVALID_ARG);
825 }
826
827 /* Conditional activation functions */
828
829 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)830 nwam_condition_to_condition_string(nwam_condition_object_type_t object_type,
831 nwam_condition_t condition, const char *object_name, char **stringp)
832 {
833 char *object_type_string, *condition_string;
834 char *string;
835
836 assert(stringp != NULL);
837
838 *stringp = NULL;
839
840 switch (object_type) {
841 case NWAM_CONDITION_OBJECT_TYPE_NCP:
842 object_type_string = NWAM_CONDITION_OBJECT_TYPE_NCP_STRING;
843 break;
844 case NWAM_CONDITION_OBJECT_TYPE_NCU:
845 object_type_string = NWAM_CONDITION_OBJECT_TYPE_NCU_STRING;
846 break;
847 case NWAM_CONDITION_OBJECT_TYPE_ENM:
848 object_type_string = NWAM_CONDITION_OBJECT_TYPE_ENM_STRING;
849 break;
850 case NWAM_CONDITION_OBJECT_TYPE_LOC:
851 object_type_string = NWAM_CONDITION_OBJECT_TYPE_LOC_STRING;
852 break;
853 case NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS:
854 object_type_string =
855 NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS_STRING;
856 break;
857 case NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN:
858 object_type_string =
859 NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN_STRING;
860 break;
861 case NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN:
862 object_type_string =
863 NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN_STRING;
864 break;
865 case NWAM_CONDITION_OBJECT_TYPE_ESSID:
866 object_type_string = NWAM_CONDITION_OBJECT_TYPE_ESSID_STRING;
867 break;
868 case NWAM_CONDITION_OBJECT_TYPE_BSSID:
869 object_type_string = NWAM_CONDITION_OBJECT_TYPE_BSSID_STRING;
870 break;
871 default:
872 return (NWAM_INVALID_ARG);
873
874 }
875 switch (condition) {
876 case NWAM_CONDITION_IS:
877 condition_string = NWAM_CONDITION_IS_STRING;
878 break;
879 case NWAM_CONDITION_IS_NOT:
880 condition_string = NWAM_CONDITION_IS_NOT_STRING;
881 break;
882 case NWAM_CONDITION_CONTAINS:
883 if (object_type != NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
884 object_type != NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
885 object_type != NWAM_CONDITION_OBJECT_TYPE_ESSID)
886 return (NWAM_INVALID_ARG);
887 condition_string = NWAM_CONDITION_CONTAINS_STRING;
888 break;
889 case NWAM_CONDITION_DOES_NOT_CONTAIN:
890 if (object_type != NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN &&
891 object_type != NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN &&
892 object_type != NWAM_CONDITION_OBJECT_TYPE_ESSID)
893 return (NWAM_INVALID_ARG);
894
895 condition_string = NWAM_CONDITION_DOES_NOT_CONTAIN_STRING;
896 break;
897 case NWAM_CONDITION_IS_IN_RANGE:
898 if (object_type != NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS)
899 return (NWAM_INVALID_ARG);
900 condition_string = NWAM_CONDITION_IS_IN_RANGE_STRING;
901 break;
902 case NWAM_CONDITION_IS_NOT_IN_RANGE:
903 if (object_type != NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS)
904 return (NWAM_INVALID_ARG);
905 condition_string = NWAM_CONDITION_IS_NOT_IN_RANGE_STRING;
906 break;
907 default:
908 return (NWAM_INVALID_ARG);
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