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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 380 nwam_free_object_list(void *list) 381 { 382 if (list != NULL) 383 nvlist_free(list); 384 } 385 386 nwam_error_t 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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