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