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