1 /* 2 * Copyright (C) 2008 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <stdint.h> 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <strings.h> 26 #include <byteswap.h> 27 #include <errno.h> 28 #include <assert.h> 29 #include <gpxe/in.h> 30 #include <gpxe/vsprintf.h> 31 #include <gpxe/dhcp.h> 32 #include <gpxe/uuid.h> 33 #include <gpxe/uri.h> 34 #include <gpxe/settings.h> 35 36 /** @file 37 * 38 * Configuration settings 39 * 40 */ 41 42 /****************************************************************************** 43 * 44 * Generic settings blocks 45 * 46 ****************************************************************************** 47 */ 48 49 /** 50 * A generic setting 51 * 52 */ 53 struct generic_setting { 54 /** List of generic settings */ 55 struct list_head list; 56 /** Setting */ 57 struct setting setting; 58 /** Size of setting name */ 59 size_t name_len; 60 /** Size of setting data */ 61 size_t data_len; 62 }; 63 64 /** 65 * Get generic setting name 66 * 67 * @v generic Generic setting 68 * @ret name Generic setting name 69 */ 70 static inline void * generic_setting_name ( struct generic_setting *generic ) { 71 return ( ( ( void * ) generic ) + sizeof ( *generic ) ); 72 } 73 74 /** 75 * Get generic setting data 76 * 77 * @v generic Generic setting 78 * @ret data Generic setting data 79 */ 80 static inline void * generic_setting_data ( struct generic_setting *generic ) { 81 return ( ( ( void * ) generic ) + sizeof ( *generic ) + 82 generic->name_len ); 83 } 84 85 /** 86 * Find generic setting 87 * 88 * @v generics Generic settings block 89 * @v setting Setting to find 90 * @ret generic Generic setting, or NULL 91 */ 92 static struct generic_setting * 93 find_generic_setting ( struct generic_settings *generics, 94 struct setting *setting ) { 95 struct generic_setting *generic; 96 97 list_for_each_entry ( generic, &generics->list, list ) { 98 if ( setting_cmp ( &generic->setting, setting ) == 0 ) 99 return generic; 100 } 101 return NULL; 102 } 103 104 /** 105 * Store value of generic setting 106 * 107 * @v settings Settings block 108 * @v setting Setting to store 109 * @v data Setting data, or NULL to clear setting 110 * @v len Length of setting data 111 * @ret rc Return status code 112 */ 113 int generic_settings_store ( struct settings *settings, 114 struct setting *setting, 115 const void *data, size_t len ) { 116 struct generic_settings *generics = 117 container_of ( settings, struct generic_settings, settings ); 118 struct generic_setting *old; 119 struct generic_setting *new = NULL; 120 size_t name_len; 121 122 /* Identify existing generic setting, if any */ 123 old = find_generic_setting ( generics, setting ); 124 125 /* Create new generic setting, if required */ 126 if ( len ) { 127 /* Allocate new generic setting */ 128 name_len = ( strlen ( setting->name ) + 1 ); 129 new = zalloc ( sizeof ( *new ) + name_len + len ); 130 if ( ! new ) 131 return -ENOMEM; 132 133 /* Populate new generic setting */ 134 new->name_len = name_len; 135 new->data_len = len; 136 memcpy ( &new->setting, setting, sizeof ( new->setting ) ); 137 new->setting.name = generic_setting_name ( new ); 138 memcpy ( generic_setting_name ( new ), 139 setting->name, name_len ); 140 memcpy ( generic_setting_data ( new ), data, len ); 141 } 142 143 /* Delete existing generic setting, if any */ 144 if ( old ) { 145 list_del ( &old->list ); 146 free ( old ); 147 } 148 149 /* Add new setting to list, if any */ 150 if ( new ) 151 list_add ( &new->list, &generics->list ); 152 153 return 0; 154 } 155 156 /** 157 * Fetch value of generic setting 158 * 159 * @v settings Settings block 160 * @v setting Setting to fetch 161 * @v data Buffer to fill with setting data 162 * @v len Length of buffer 163 * @ret len Length of setting data, or negative error 164 */ 165 int generic_settings_fetch ( struct settings *settings, 166 struct setting *setting, 167 void *data, size_t len ) { 168 struct generic_settings *generics = 169 container_of ( settings, struct generic_settings, settings ); 170 struct generic_setting *generic; 171 172 /* Find generic setting */ 173 generic = find_generic_setting ( generics, setting ); 174 if ( ! generic ) 175 return -ENOENT; 176 177 /* Copy out generic setting data */ 178 if ( len > generic->data_len ) 179 len = generic->data_len; 180 memcpy ( data, generic_setting_data ( generic ), len ); 181 return generic->data_len; 182 } 183 184 /** 185 * Clear generic settings block 186 * 187 * @v settings Settings block 188 */ 189 void generic_settings_clear ( struct settings *settings ) { 190 struct generic_settings *generics = 191 container_of ( settings, struct generic_settings, settings ); 192 struct generic_setting *generic; 193 struct generic_setting *tmp; 194 195 list_for_each_entry_safe ( generic, tmp, &generics->list, list ) { 196 list_del ( &generic->list ); 197 free ( generic ); 198 } 199 assert ( list_empty ( &generics->list ) ); 200 } 201 202 /** Generic settings operations */ 203 struct settings_operations generic_settings_operations = { 204 .store = generic_settings_store, 205 .fetch = generic_settings_fetch, 206 .clear = generic_settings_clear, 207 }; 208 209 /****************************************************************************** 210 * 211 * Registered settings blocks 212 * 213 ****************************************************************************** 214 */ 215 216 /** Root generic settings block */ 217 struct generic_settings generic_settings_root = { 218 .settings = { 219 .refcnt = NULL, 220 .name = "", 221 .siblings = 222 LIST_HEAD_INIT ( generic_settings_root.settings.siblings ), 223 .children = 224 LIST_HEAD_INIT ( generic_settings_root.settings.children ), 225 .op = &generic_settings_operations, 226 }, 227 .list = LIST_HEAD_INIT ( generic_settings_root.list ), 228 }; 229 230 /** Root settings block */ 231 #define settings_root generic_settings_root.settings 232 233 /** 234 * Find child named settings block 235 * 236 * @v parent Parent settings block 237 * @v name Name within this parent 238 * @ret settings Settings block, or NULL 239 */ 240 static struct settings * find_child_settings ( struct settings *parent, 241 const char *name ) { 242 struct settings *settings; 243 244 /* Treat empty name as meaning "this block" */ 245 if ( ! *name ) 246 return parent; 247 248 /* Look for child with matching name */ 249 list_for_each_entry ( settings, &parent->children, siblings ) { 250 if ( strcmp ( settings->name, name ) == 0 ) 251 return settings; 252 } 253 254 return NULL; 255 } 256 257 /** 258 * Find or create child named settings block 259 * 260 * @v parent Parent settings block 261 * @v name Name within this parent 262 * @ret settings Settings block, or NULL 263 */ 264 static struct settings * autovivify_child_settings ( struct settings *parent, 265 const char *name ) { 266 struct { 267 struct generic_settings generic; 268 char name[ strlen ( name ) + 1 /* NUL */ ]; 269 } *new_child; 270 struct settings *settings; 271 272 /* Return existing settings, if existent */ 273 if ( ( settings = find_child_settings ( parent, name ) ) != NULL ) 274 return settings; 275 276 /* Create new generic settings block */ 277 new_child = zalloc ( sizeof ( *new_child ) ); 278 if ( ! new_child ) { 279 DBGC ( parent, "Settings %p could not create child %s\n", 280 parent, name ); 281 return NULL; 282 } 283 memcpy ( new_child->name, name, sizeof ( new_child->name ) ); 284 generic_settings_init ( &new_child->generic, NULL, new_child->name ); 285 settings = &new_child->generic.settings; 286 register_settings ( settings, parent ); 287 return settings; 288 } 289 290 /** 291 * Return settings block name (for debug only) 292 * 293 * @v settings Settings block 294 * @ret name Settings block name 295 */ 296 static const char * settings_name ( struct settings *settings ) { 297 static char buf[64]; 298 char tmp[ sizeof ( buf ) ]; 299 int count; 300 301 for ( count = 0 ; settings ; settings = settings->parent ) { 302 memcpy ( tmp, buf, sizeof ( tmp ) ); 303 snprintf ( buf, sizeof ( buf ), "%s%c%s", settings->name, 304 ( count++ ? '.' : '\0' ), tmp ); 305 } 306 return ( buf + 1 ); 307 } 308 309 /** 310 * Parse settings block name 311 * 312 * @v name Name 313 * @v get_child Function to find or create child settings block 314 * @ret settings Settings block, or NULL 315 */ 316 static struct settings * 317 parse_settings_name ( const char *name, 318 struct settings * ( * get_child ) ( struct settings *, 319 const char * ) ) { 320 struct settings *settings = &settings_root; 321 char name_copy[ strlen ( name ) + 1 ]; 322 char *subname; 323 char *remainder; 324 325 /* Create modifiable copy of name */ 326 memcpy ( name_copy, name, sizeof ( name_copy ) ); 327 remainder = name_copy; 328 329 /* Parse each name component in turn */ 330 while ( remainder ) { 331 struct net_device *netdev; 332 333 subname = remainder; 334 remainder = strchr ( subname, '.' ); 335 if ( remainder ) 336 *(remainder++) = '\0'; 337 338 /* Special case "netX" root settings block */ 339 if ( ( subname == name_copy ) && ! strcmp ( subname, "netX" ) && 340 ( ( netdev = last_opened_netdev() ) != NULL ) ) 341 settings = get_child ( settings, netdev->name ); 342 else 343 settings = get_child ( settings, subname ); 344 345 if ( ! settings ) 346 break; 347 } 348 349 return settings; 350 } 351 352 /** 353 * Find named settings block 354 * 355 * @v name Name 356 * @ret settings Settings block, or NULL 357 */ 358 struct settings * find_settings ( const char *name ) { 359 360 return parse_settings_name ( name, find_child_settings ); 361 } 362 363 /** 364 * Apply all settings 365 * 366 * @ret rc Return status code 367 */ 368 static int apply_settings ( void ) { 369 struct settings_applicator *applicator; 370 int rc; 371 372 /* Call all settings applicators */ 373 for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) { 374 if ( ( rc = applicator->apply() ) != 0 ) { 375 DBG ( "Could not apply settings using applicator " 376 "%p: %s\n", applicator, strerror ( rc ) ); 377 return rc; 378 } 379 } 380 381 return 0; 382 } 383 384 /** 385 * Reprioritise settings 386 * 387 * @v settings Settings block 388 * 389 * Reorders the settings block amongst its siblings according to its 390 * priority. 391 */ 392 static void reprioritise_settings ( struct settings *settings ) { 393 struct settings *parent = settings->parent; 394 long priority; 395 struct settings *tmp; 396 long tmp_priority; 397 398 /* Stop when we reach the top of the tree */ 399 if ( ! parent ) 400 return; 401 402 /* Read priority, if present */ 403 priority = fetch_intz_setting ( settings, &priority_setting ); 404 405 /* Remove from siblings list */ 406 list_del ( &settings->siblings ); 407 408 /* Reinsert after any existing blocks which have a higher priority */ 409 list_for_each_entry ( tmp, &parent->children, siblings ) { 410 tmp_priority = fetch_intz_setting ( tmp, &priority_setting ); 411 if ( priority > tmp_priority ) 412 break; 413 } 414 list_add_tail ( &settings->siblings, &tmp->siblings ); 415 416 /* Recurse up the tree */ 417 reprioritise_settings ( parent ); 418 } 419 420 /** 421 * Register settings block 422 * 423 * @v settings Settings block 424 * @v parent Parent settings block, or NULL 425 * @ret rc Return status code 426 */ 427 int register_settings ( struct settings *settings, struct settings *parent ) { 428 struct settings *old_settings; 429 430 /* NULL parent => add to settings root */ 431 assert ( settings != NULL ); 432 if ( parent == NULL ) 433 parent = &settings_root; 434 435 /* Remove any existing settings with the same name */ 436 if ( ( old_settings = find_child_settings ( parent, settings->name ) )) 437 unregister_settings ( old_settings ); 438 439 /* Add to list of settings */ 440 ref_get ( settings->refcnt ); 441 ref_get ( parent->refcnt ); 442 settings->parent = parent; 443 list_add_tail ( &settings->siblings, &parent->children ); 444 DBGC ( settings, "Settings %p (\"%s\") registered\n", 445 settings, settings_name ( settings ) ); 446 447 /* Fix up settings priority */ 448 reprioritise_settings ( settings ); 449 450 /* Apply potentially-updated settings */ 451 apply_settings(); 452 453 return 0; 454 } 455 456 /** 457 * Unregister settings block 458 * 459 * @v settings Settings block 460 */ 461 void unregister_settings ( struct settings *settings ) { 462 463 DBGC ( settings, "Settings %p (\"%s\") unregistered\n", 464 settings, settings_name ( settings ) ); 465 466 /* Remove from list of settings */ 467 ref_put ( settings->refcnt ); 468 ref_put ( settings->parent->refcnt ); 469 settings->parent = NULL; 470 list_del ( &settings->siblings ); 471 472 /* Apply potentially-updated settings */ 473 apply_settings(); 474 } 475 476 /****************************************************************************** 477 * 478 * Core settings routines 479 * 480 ****************************************************************************** 481 */ 482 483 /** 484 * Store value of setting 485 * 486 * @v settings Settings block, or NULL 487 * @v setting Setting to store 488 * @v data Setting data, or NULL to clear setting 489 * @v len Length of setting data 490 * @ret rc Return status code 491 */ 492 int store_setting ( struct settings *settings, struct setting *setting, 493 const void *data, size_t len ) { 494 int rc; 495 496 /* NULL settings implies storing into the global settings root */ 497 if ( ! settings ) 498 settings = &settings_root; 499 500 /* Sanity check */ 501 if ( ! settings->op->store ) 502 return -ENOTSUP; 503 504 /* Store setting */ 505 if ( ( rc = settings->op->store ( settings, setting, 506 data, len ) ) != 0 ) 507 return rc; 508 509 /* Reprioritise settings if necessary */ 510 if ( setting_cmp ( setting, &priority_setting ) == 0 ) 511 reprioritise_settings ( settings ); 512 513 /* If these settings are registered, apply potentially-updated 514 * settings 515 */ 516 for ( ; settings ; settings = settings->parent ) { 517 if ( settings == &settings_root ) { 518 if ( ( rc = apply_settings() ) != 0 ) 519 return rc; 520 break; 521 } 522 } 523 524 return 0; 525 } 526 527 /** 528 * Fetch value of setting 529 * 530 * @v settings Settings block, or NULL to search all blocks 531 * @v setting Setting to fetch 532 * @v data Buffer to fill with setting data 533 * @v len Length of buffer 534 * @ret len Length of setting data, or negative error 535 * 536 * The actual length of the setting will be returned even if 537 * the buffer was too small. 538 */ 539 int fetch_setting ( struct settings *settings, struct setting *setting, 540 void *data, size_t len ) { 541 struct settings *child; 542 int ret; 543 544 /* Avoid returning uninitialised data on error */ 545 memset ( data, 0, len ); 546 547 /* NULL settings implies starting at the global settings root */ 548 if ( ! settings ) 549 settings = &settings_root; 550 551 /* Sanity check */ 552 if ( ! settings->op->fetch ) 553 return -ENOTSUP; 554 555 /* Try this block first */ 556 if ( ( ret = settings->op->fetch ( settings, setting, 557 data, len ) ) >= 0 ) 558 return ret; 559 560 /* Recurse into each child block in turn */ 561 list_for_each_entry ( child, &settings->children, siblings ) { 562 if ( ( ret = fetch_setting ( child, setting, 563 data, len ) ) >= 0 ) 564 return ret; 565 } 566 567 return -ENOENT; 568 } 569 570 /** 571 * Fetch length of setting 572 * 573 * @v settings Settings block, or NULL to search all blocks 574 * @v setting Setting to fetch 575 * @ret len Length of setting data, or negative error 576 * 577 * This function can also be used as an existence check for the 578 * setting. 579 */ 580 int fetch_setting_len ( struct settings *settings, struct setting *setting ) { 581 return fetch_setting ( settings, setting, NULL, 0 ); 582 } 583 584 /** 585 * Fetch value of string setting 586 * 587 * @v settings Settings block, or NULL to search all blocks 588 * @v setting Setting to fetch 589 * @v data Buffer to fill with setting string data 590 * @v len Length of buffer 591 * @ret len Length of string setting, or negative error 592 * 593 * The resulting string is guaranteed to be correctly NUL-terminated. 594 * The returned length will be the length of the underlying setting 595 * data. 596 */ 597 int fetch_string_setting ( struct settings *settings, struct setting *setting, 598 char *data, size_t len ) { 599 memset ( data, 0, len ); 600 return fetch_setting ( settings, setting, data, 601 ( ( len > 0 ) ? ( len - 1 ) : 0 ) ); 602 } 603 604 /** 605 * Fetch value of string setting 606 * 607 * @v settings Settings block, or NULL to search all blocks 608 * @v setting Setting to fetch 609 * @v data Buffer to allocate and fill with setting string data 610 * @ret len Length of string setting, or negative error 611 * 612 * The resulting string is guaranteed to be correctly NUL-terminated. 613 * The returned length will be the length of the underlying setting 614 * data. The caller is responsible for eventually freeing the 615 * allocated buffer. 616 */ 617 int fetch_string_setting_copy ( struct settings *settings, 618 struct setting *setting, 619 char **data ) { 620 int len; 621 int check_len = 0; 622 623 len = fetch_setting_len ( settings, setting ); 624 if ( len < 0 ) 625 return len; 626 627 *data = malloc ( len + 1 ); 628 if ( ! *data ) 629 return -ENOMEM; 630 631 check_len = fetch_string_setting ( settings, setting, *data, 632 ( len + 1 ) ); 633 assert ( check_len == len ); 634 return len; 635 } 636 637 /** 638 * Fetch value of IPv4 address setting 639 * 640 * @v settings Settings block, or NULL to search all blocks 641 * @v setting Setting to fetch 642 * @v inp IPv4 address to fill in 643 * @ret len Length of setting, or negative error 644 */ 645 int fetch_ipv4_setting ( struct settings *settings, struct setting *setting, 646 struct in_addr *inp ) { 647 int len; 648 649 len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) ); 650 if ( len < 0 ) 651 return len; 652 if ( len < ( int ) sizeof ( *inp ) ) 653 return -ERANGE; 654 return len; 655 } 656 657 /** 658 * Fetch value of signed integer setting 659 * 660 * @v settings Settings block, or NULL to search all blocks 661 * @v setting Setting to fetch 662 * @v value Integer value to fill in 663 * @ret len Length of setting, or negative error 664 */ 665 int fetch_int_setting ( struct settings *settings, struct setting *setting, 666 long *value ) { 667 union { 668 uint8_t u8[ sizeof ( long ) ]; 669 int8_t s8[ sizeof ( long ) ]; 670 } buf; 671 int len; 672 int i; 673 674 /* Avoid returning uninitialised data on error */ 675 *value = 0; 676 677 /* Fetch raw (network-ordered, variable-length) setting */ 678 len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) ); 679 if ( len < 0 ) 680 return len; 681 if ( len > ( int ) sizeof ( buf ) ) 682 return -ERANGE; 683 684 /* Convert to host-ordered signed long */ 685 *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L ); 686 for ( i = 0 ; i < len ; i++ ) { 687 *value = ( ( *value << 8 ) | buf.u8[i] ); 688 } 689 690 return len; 691 } 692 693 /** 694 * Fetch value of unsigned integer setting 695 * 696 * @v settings Settings block, or NULL to search all blocks 697 * @v setting Setting to fetch 698 * @v value Integer value to fill in 699 * @ret len Length of setting, or negative error 700 */ 701 int fetch_uint_setting ( struct settings *settings, struct setting *setting, 702 unsigned long *value ) { 703 long svalue; 704 int len; 705 706 /* Avoid returning uninitialised data on error */ 707 *value = 0; 708 709 /* Fetch as a signed long */ 710 len = fetch_int_setting ( settings, setting, &svalue ); 711 if ( len < 0 ) 712 return len; 713 714 /* Mask off sign-extended bits */ 715 assert ( len <= ( int ) sizeof ( long ) ); 716 *value = ( svalue & ( -1UL >> ( 8 * ( sizeof ( long ) - len ) ) ) ); 717 718 return len; 719 } 720 721 /** 722 * Fetch value of signed integer setting, or zero 723 * 724 * @v settings Settings block, or NULL to search all blocks 725 * @v setting Setting to fetch 726 * @ret value Setting value, or zero 727 */ 728 long fetch_intz_setting ( struct settings *settings, struct setting *setting ){ 729 long value; 730 731 fetch_int_setting ( settings, setting, &value ); 732 return value; 733 } 734 735 /** 736 * Fetch value of unsigned integer setting, or zero 737 * 738 * @v settings Settings block, or NULL to search all blocks 739 * @v setting Setting to fetch 740 * @ret value Setting value, or zero 741 */ 742 unsigned long fetch_uintz_setting ( struct settings *settings, 743 struct setting *setting ) { 744 unsigned long value; 745 746 fetch_uint_setting ( settings, setting, &value ); 747 return value; 748 } 749 750 /** 751 * Fetch value of UUID setting 752 * 753 * @v settings Settings block, or NULL to search all blocks 754 * @v setting Setting to fetch 755 * @v uuid UUID to fill in 756 * @ret len Length of setting, or negative error 757 */ 758 int fetch_uuid_setting ( struct settings *settings, struct setting *setting, 759 union uuid *uuid ) { 760 int len; 761 762 len = fetch_setting ( settings, setting, uuid, sizeof ( *uuid ) ); 763 if ( len < 0 ) 764 return len; 765 if ( len != sizeof ( *uuid ) ) 766 return -ERANGE; 767 return len; 768 } 769 770 /** 771 * Clear settings block 772 * 773 * @v settings Settings block 774 */ 775 void clear_settings ( struct settings *settings ) { 776 if ( settings->op->clear ) 777 settings->op->clear ( settings ); 778 } 779 780 /** 781 * Compare two settings 782 * 783 * @v a Setting to compare 784 * @v b Setting to compare 785 * @ret 0 Settings are the same 786 * @ret non-zero Settings are not the same 787 */ 788 int setting_cmp ( struct setting *a, struct setting *b ) { 789 790 /* If the settings have tags, compare them */ 791 if ( a->tag && ( a->tag == b->tag ) ) 792 return 0; 793 794 /* Otherwise, if the settings have names, compare them */ 795 if ( a->name && b->name && a->name[0] ) 796 return strcmp ( a->name, b->name ); 797 798 /* Otherwise, return a non-match */ 799 return ( ! 0 ); 800 } 801 802 /****************************************************************************** 803 * 804 * Formatted setting routines 805 * 806 ****************************************************************************** 807 */ 808 809 /** 810 * Store value of typed setting 811 * 812 * @v settings Settings block 813 * @v setting Setting to store 814 * @v type Settings type 815 * @v value Formatted setting data, or NULL 816 * @ret rc Return status code 817 */ 818 int storef_setting ( struct settings *settings, struct setting *setting, 819 const char *value ) { 820 821 /* NULL value implies deletion. Avoid imposing the burden of 822 * checking for NULL values on each typed setting's storef() 823 * method. 824 */ 825 if ( ! value ) 826 return delete_setting ( settings, setting ); 827 828 return setting->type->storef ( settings, setting, value ); 829 } 830 831 /** 832 * Find named setting 833 * 834 * @v name Name 835 * @ret setting Named setting, or NULL 836 */ 837 static struct setting * find_setting ( const char *name ) { 838 struct setting *setting; 839 840 for_each_table_entry ( setting, SETTINGS ) { 841 if ( strcmp ( name, setting->name ) == 0 ) 842 return setting; 843 } 844 return NULL; 845 } 846 847 /** 848 * Parse setting name as tag number 849 * 850 * @v name Name 851 * @ret tag Tag number, or 0 if not a valid number 852 */ 853 static unsigned int parse_setting_tag ( const char *name ) { 854 char *tmp = ( ( char * ) name ); 855 unsigned int tag = 0; 856 857 while ( 1 ) { 858 tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) ); 859 if ( *tmp == 0 ) 860 return tag; 861 if ( *tmp != '.' ) 862 return 0; 863 tmp++; 864 } 865 } 866 867 /** 868 * Find setting type 869 * 870 * @v name Name 871 * @ret type Setting type, or NULL 872 */ 873 static struct setting_type * find_setting_type ( const char *name ) { 874 struct setting_type *type; 875 876 for_each_table_entry ( type, SETTING_TYPES ) { 877 if ( strcmp ( name, type->name ) == 0 ) 878 return type; 879 } 880 return NULL; 881 } 882 883 /** 884 * Parse setting name 885 * 886 * @v name Name of setting 887 * @v get_child Function to find or create child settings block 888 * @v settings Settings block to fill in 889 * @v setting Setting to fill in 890 * @v tmp_name Buffer for copy of setting name 891 * @ret rc Return status code 892 * 893 * Interprets a name of the form 894 * "[settings_name/]tag_name[:type_name]" and fills in the appropriate 895 * fields. 896 * 897 * The @c tmp_name buffer must be large enough to hold a copy of the 898 * setting name. 899 */ 900 static int 901 parse_setting_name ( const char *name, 902 struct settings * ( * get_child ) ( struct settings *, 903 const char * ), 904 struct settings **settings, struct setting *setting, 905 char *tmp_name ) { 906 char *settings_name; 907 char *setting_name; 908 char *type_name; 909 struct setting *named_setting; 910 911 /* Set defaults */ 912 *settings = &settings_root; 913 memset ( setting, 0, sizeof ( *setting ) ); 914 setting->name = ""; 915 setting->type = &setting_type_string; 916 917 /* Split name into "[settings_name/]setting_name[:type_name]" */ 918 strcpy ( tmp_name, name ); 919 if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) { 920 *(setting_name++) = 0; 921 settings_name = tmp_name; 922 } else { 923 setting_name = tmp_name; 924 settings_name = NULL; 925 } 926 if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL ) 927 *(type_name++) = 0; 928 929 /* Identify settings block, if specified */ 930 if ( settings_name ) { 931 *settings = parse_settings_name ( settings_name, get_child ); 932 if ( *settings == NULL ) { 933 DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n", 934 settings_name, name ); 935 return -ENODEV; 936 } 937 } 938 939 /* Identify setting */ 940 if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) { 941 /* Matches a defined named setting; use that setting */ 942 memcpy ( setting, named_setting, sizeof ( *setting ) ); 943 } else if ( ( setting->tag = parse_setting_tag ( setting_name ) ) !=0){ 944 /* Is a valid numeric tag; use the tag */ 945 setting->tag |= (*settings)->tag_magic; 946 } else { 947 /* Use the arbitrary name */ 948 setting->name = setting_name; 949 } 950 951 /* Identify setting type, if specified */ 952 if ( type_name ) { 953 setting->type = find_setting_type ( type_name ); 954 if ( setting->type == NULL ) { 955 DBG ( "Invalid setting type \"%s\" in \"%s\"\n", 956 type_name, name ); 957 return -ENOTSUP; 958 } 959 } 960 961 return 0; 962 } 963 964 /** 965 * Parse and store value of named setting 966 * 967 * @v name Name of setting 968 * @v value Formatted setting data, or NULL 969 * @ret rc Return status code 970 */ 971 int storef_named_setting ( const char *name, const char *value ) { 972 struct settings *settings; 973 struct setting setting; 974 char tmp_name[ strlen ( name ) + 1 ]; 975 int rc; 976 977 if ( ( rc = parse_setting_name ( name, autovivify_child_settings, 978 &settings, &setting, tmp_name )) != 0) 979 return rc; 980 return storef_setting ( settings, &setting, value ); 981 } 982 983 /** 984 * Fetch and format value of named setting 985 * 986 * @v name Name of setting 987 * @v buf Buffer to contain formatted value 988 * @v len Length of buffer 989 * @ret len Length of formatted value, or negative error 990 */ 991 int fetchf_named_setting ( const char *name, char *buf, size_t len ) { 992 struct settings *settings; 993 struct setting setting; 994 char tmp_name[ strlen ( name ) + 1 ]; 995 int rc; 996 997 if ( ( rc = parse_setting_name ( name, find_child_settings, 998 &settings, &setting, tmp_name )) != 0) 999 return rc; 1000 return fetchf_setting ( settings, &setting, buf, len ); 1001 } 1002 1003 /****************************************************************************** 1004 * 1005 * Setting types 1006 * 1007 ****************************************************************************** 1008 */ 1009 1010 /** 1011 * Parse and store value of string setting 1012 * 1013 * @v settings Settings block 1014 * @v setting Setting to store 1015 * @v value Formatted setting data 1016 * @ret rc Return status code 1017 */ 1018 static int storef_string ( struct settings *settings, struct setting *setting, 1019 const char *value ) { 1020 return store_setting ( settings, setting, value, strlen ( value ) ); 1021 } 1022 1023 /** 1024 * Fetch and format value of string setting 1025 * 1026 * @v settings Settings block, or NULL to search all blocks 1027 * @v setting Setting to fetch 1028 * @v buf Buffer to contain formatted value 1029 * @v len Length of buffer 1030 * @ret len Length of formatted value, or negative error 1031 */ 1032 static int fetchf_string ( struct settings *settings, struct setting *setting, 1033 char *buf, size_t len ) { 1034 return fetch_string_setting ( settings, setting, buf, len ); 1035 } 1036 1037 /** A string setting type */ 1038 struct setting_type setting_type_string __setting_type = { 1039 .name = "string", 1040 .storef = storef_string, 1041 .fetchf = fetchf_string, 1042 }; 1043 1044 /** 1045 * Parse and store value of URI-encoded string setting 1046 * 1047 * @v settings Settings block 1048 * @v setting Setting to store 1049 * @v value Formatted setting data 1050 * @ret rc Return status code 1051 */ 1052 static int storef_uristring ( struct settings *settings, 1053 struct setting *setting, 1054 const char *value ) { 1055 char buf[ strlen ( value ) + 1 ]; /* Decoding never expands string */ 1056 size_t len; 1057 1058 len = uri_decode ( value, buf, sizeof ( buf ) ); 1059 return store_setting ( settings, setting, buf, len ); 1060 } 1061 1062 /** 1063 * Fetch and format value of URI-encoded string setting 1064 * 1065 * @v settings Settings block, or NULL to search all blocks 1066 * @v setting Setting to fetch 1067 * @v buf Buffer to contain formatted value 1068 * @v len Length of buffer 1069 * @ret len Length of formatted value, or negative error 1070 */ 1071 static int fetchf_uristring ( struct settings *settings, 1072 struct setting *setting, 1073 char *buf, size_t len ) { 1074 ssize_t raw_len; 1075 1076 /* We need to always retrieve the full raw string to know the 1077 * length of the encoded string. 1078 */ 1079 raw_len = fetch_setting ( settings, setting, NULL, 0 ); 1080 if ( raw_len < 0 ) 1081 return raw_len; 1082 1083 { 1084 char raw_buf[ raw_len + 1 ]; 1085 1086 fetch_string_setting ( settings, setting, raw_buf, 1087 sizeof ( raw_buf ) ); 1088 return uri_encode ( raw_buf, buf, len, URI_FRAGMENT ); 1089 } 1090 } 1091 1092 /** A URI-encoded string setting type */ 1093 struct setting_type setting_type_uristring __setting_type = { 1094 .name = "uristring", 1095 .storef = storef_uristring, 1096 .fetchf = fetchf_uristring, 1097 }; 1098 1099 /** 1100 * Parse and store value of IPv4 address setting 1101 * 1102 * @v settings Settings block 1103 * @v setting Setting to store 1104 * @v value Formatted setting data 1105 * @ret rc Return status code 1106 */ 1107 static int storef_ipv4 ( struct settings *settings, struct setting *setting, 1108 const char *value ) { 1109 struct in_addr ipv4; 1110 1111 if ( inet_aton ( value, &ipv4 ) == 0 ) 1112 return -EINVAL; 1113 return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) ); 1114 } 1115 1116 /** 1117 * Fetch and format value of IPv4 address setting 1118 * 1119 * @v settings Settings block, or NULL to search all blocks 1120 * @v setting Setting to fetch 1121 * @v buf Buffer to contain formatted value 1122 * @v len Length of buffer 1123 * @ret len Length of formatted value, or negative error 1124 */ 1125 static int fetchf_ipv4 ( struct settings *settings, struct setting *setting, 1126 char *buf, size_t len ) { 1127 struct in_addr ipv4; 1128 int raw_len; 1129 1130 if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0) 1131 return raw_len; 1132 return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) ); 1133 } 1134 1135 /** An IPv4 address setting type */ 1136 struct setting_type setting_type_ipv4 __setting_type = { 1137 .name = "ipv4", 1138 .storef = storef_ipv4, 1139 .fetchf = fetchf_ipv4, 1140 }; 1141 1142 /** 1143 * Parse and store value of integer setting 1144 * 1145 * @v settings Settings block 1146 * @v setting Setting to store 1147 * @v value Formatted setting data 1148 * @v size Integer size, in bytes 1149 * @ret rc Return status code 1150 */ 1151 static int storef_int ( struct settings *settings, struct setting *setting, 1152 const char *value, unsigned int size ) { 1153 union { 1154 uint32_t num; 1155 uint8_t bytes[4]; 1156 } u; 1157 char *endp; 1158 1159 u.num = htonl ( strtoul ( value, &endp, 0 ) ); 1160 if ( *endp ) 1161 return -EINVAL; 1162 return store_setting ( settings, setting, 1163 &u.bytes[ sizeof ( u ) - size ], size ); 1164 } 1165 1166 /** 1167 * Parse and store value of 8-bit integer setting 1168 * 1169 * @v settings Settings block 1170 * @v setting Setting to store 1171 * @v value Formatted setting data 1172 * @v size Integer size, in bytes 1173 * @ret rc Return status code 1174 */ 1175 static int storef_int8 ( struct settings *settings, struct setting *setting, 1176 const char *value ) { 1177 return storef_int ( settings, setting, value, 1 ); 1178 } 1179 1180 /** 1181 * Parse and store value of 16-bit integer setting 1182 * 1183 * @v settings Settings block 1184 * @v setting Setting to store 1185 * @v value Formatted setting data 1186 * @v size Integer size, in bytes 1187 * @ret rc Return status code 1188 */ 1189 static int storef_int16 ( struct settings *settings, struct setting *setting, 1190 const char *value ) { 1191 return storef_int ( settings, setting, value, 2 ); 1192 } 1193 1194 /** 1195 * Parse and store value of 32-bit integer setting 1196 * 1197 * @v settings Settings block 1198 * @v setting Setting to store 1199 * @v value Formatted setting data 1200 * @v size Integer size, in bytes 1201 * @ret rc Return status code 1202 */ 1203 static int storef_int32 ( struct settings *settings, struct setting *setting, 1204 const char *value ) { 1205 return storef_int ( settings, setting, value, 4 ); 1206 } 1207 1208 /** 1209 * Fetch and format value of signed integer setting 1210 * 1211 * @v settings Settings block, or NULL to search all blocks 1212 * @v setting Setting to fetch 1213 * @v buf Buffer to contain formatted value 1214 * @v len Length of buffer 1215 * @ret len Length of formatted value, or negative error 1216 */ 1217 static int fetchf_int ( struct settings *settings, struct setting *setting, 1218 char *buf, size_t len ) { 1219 long value; 1220 int rc; 1221 1222 if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 ) 1223 return rc; 1224 return snprintf ( buf, len, "%ld", value ); 1225 } 1226 1227 /** 1228 * Fetch and format value of unsigned integer setting 1229 * 1230 * @v settings Settings block, or NULL to search all blocks 1231 * @v setting Setting to fetch 1232 * @v buf Buffer to contain formatted value 1233 * @v len Length of buffer 1234 * @ret len Length of formatted value, or negative error 1235 */ 1236 static int fetchf_uint ( struct settings *settings, struct setting *setting, 1237 char *buf, size_t len ) { 1238 unsigned long value; 1239 int rc; 1240 1241 if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 ) 1242 return rc; 1243 return snprintf ( buf, len, "%#lx", value ); 1244 } 1245 1246 /** A signed 8-bit integer setting type */ 1247 struct setting_type setting_type_int8 __setting_type = { 1248 .name = "int8", 1249 .storef = storef_int8, 1250 .fetchf = fetchf_int, 1251 }; 1252 1253 /** A signed 16-bit integer setting type */ 1254 struct setting_type setting_type_int16 __setting_type = { 1255 .name = "int16", 1256 .storef = storef_int16, 1257 .fetchf = fetchf_int, 1258 }; 1259 1260 /** A signed 32-bit integer setting type */ 1261 struct setting_type setting_type_int32 __setting_type = { 1262 .name = "int32", 1263 .storef = storef_int32, 1264 .fetchf = fetchf_int, 1265 }; 1266 1267 /** An unsigned 8-bit integer setting type */ 1268 struct setting_type setting_type_uint8 __setting_type = { 1269 .name = "uint8", 1270 .storef = storef_int8, 1271 .fetchf = fetchf_uint, 1272 }; 1273 1274 /** An unsigned 16-bit integer setting type */ 1275 struct setting_type setting_type_uint16 __setting_type = { 1276 .name = "uint16", 1277 .storef = storef_int16, 1278 .fetchf = fetchf_uint, 1279 }; 1280 1281 /** An unsigned 32-bit integer setting type */ 1282 struct setting_type setting_type_uint32 __setting_type = { 1283 .name = "uint32", 1284 .storef = storef_int32, 1285 .fetchf = fetchf_uint, 1286 }; 1287 1288 /** 1289 * Parse and store value of hex string setting 1290 * 1291 * @v settings Settings block 1292 * @v setting Setting to store 1293 * @v value Formatted setting data 1294 * @ret rc Return status code 1295 */ 1296 static int storef_hex ( struct settings *settings, struct setting *setting, 1297 const char *value ) { 1298 char *ptr = ( char * ) value; 1299 uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */ 1300 unsigned int len = 0; 1301 1302 while ( 1 ) { 1303 bytes[len++] = strtoul ( ptr, &ptr, 16 ); 1304 switch ( *ptr ) { 1305 case '\0' : 1306 return store_setting ( settings, setting, bytes, len ); 1307 case ':' : 1308 ptr++; 1309 break; 1310 default : 1311 return -EINVAL; 1312 } 1313 } 1314 } 1315 1316 /** 1317 * Fetch and format value of hex string setting 1318 * 1319 * @v settings Settings block, or NULL to search all blocks 1320 * @v setting Setting to fetch 1321 * @v buf Buffer to contain formatted value 1322 * @v len Length of buffer 1323 * @ret len Length of formatted value, or negative error 1324 */ 1325 static int fetchf_hex ( struct settings *settings, struct setting *setting, 1326 char *buf, size_t len ) { 1327 int raw_len; 1328 int check_len; 1329 int used = 0; 1330 int i; 1331 1332 raw_len = fetch_setting_len ( settings, setting ); 1333 if ( raw_len < 0 ) 1334 return raw_len; 1335 1336 { 1337 uint8_t raw[raw_len]; 1338 1339 check_len = fetch_setting ( settings, setting, raw, 1340 sizeof ( raw ) ); 1341 if ( check_len < 0 ) 1342 return check_len; 1343 assert ( check_len == raw_len ); 1344 1345 if ( len ) 1346 buf[0] = 0; /* Ensure that a terminating NUL exists */ 1347 for ( i = 0 ; i < raw_len ; i++ ) { 1348 used += ssnprintf ( ( buf + used ), ( len - used ), 1349 "%s%02x", ( used ? ":" : "" ), 1350 raw[i] ); 1351 } 1352 return used; 1353 } 1354 } 1355 1356 /** A hex-string setting */ 1357 struct setting_type setting_type_hex __setting_type = { 1358 .name = "hex", 1359 .storef = storef_hex, 1360 .fetchf = fetchf_hex, 1361 }; 1362 1363 /** 1364 * Parse and store value of UUID setting 1365 * 1366 * @v settings Settings block 1367 * @v setting Setting to store 1368 * @v value Formatted setting data 1369 * @ret rc Return status code 1370 */ 1371 static int storef_uuid ( struct settings *settings __unused, 1372 struct setting *setting __unused, 1373 const char *value __unused ) { 1374 return -ENOTSUP; 1375 } 1376 1377 /** 1378 * Fetch and format value of UUID setting 1379 * 1380 * @v settings Settings block, or NULL to search all blocks 1381 * @v setting Setting to fetch 1382 * @v buf Buffer to contain formatted value 1383 * @v len Length of buffer 1384 * @ret len Length of formatted value, or negative error 1385 */ 1386 static int fetchf_uuid ( struct settings *settings, struct setting *setting, 1387 char *buf, size_t len ) { 1388 union uuid uuid; 1389 int raw_len; 1390 1391 if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0) 1392 return raw_len; 1393 return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) ); 1394 } 1395 1396 /** UUID setting type */ 1397 struct setting_type setting_type_uuid __setting_type = { 1398 .name = "uuid", 1399 .storef = storef_uuid, 1400 .fetchf = fetchf_uuid, 1401 }; 1402 1403 /****************************************************************************** 1404 * 1405 * Settings 1406 * 1407 ****************************************************************************** 1408 */ 1409 1410 /** Hostname setting */ 1411 struct setting hostname_setting __setting = { 1412 .name = "hostname", 1413 .description = "Host name", 1414 .tag = DHCP_HOST_NAME, 1415 .type = &setting_type_string, 1416 }; 1417 1418 /** Filename setting */ 1419 struct setting filename_setting __setting = { 1420 .name = "filename", 1421 .description = "Boot filename", 1422 .tag = DHCP_BOOTFILE_NAME, 1423 .type = &setting_type_string, 1424 }; 1425 1426 /** Root path setting */ 1427 struct setting root_path_setting __setting = { 1428 .name = "root-path", 1429 .description = "iSCSI root path", 1430 .tag = DHCP_ROOT_PATH, 1431 .type = &setting_type_string, 1432 }; 1433 1434 /** Username setting */ 1435 struct setting username_setting __setting = { 1436 .name = "username", 1437 .description = "User name", 1438 .tag = DHCP_EB_USERNAME, 1439 .type = &setting_type_string, 1440 }; 1441 1442 /** Password setting */ 1443 struct setting password_setting __setting = { 1444 .name = "password", 1445 .description = "Password", 1446 .tag = DHCP_EB_PASSWORD, 1447 .type = &setting_type_string, 1448 }; 1449 1450 /** Priority setting */ 1451 struct setting priority_setting __setting = { 1452 .name = "priority", 1453 .description = "Priority of these settings", 1454 .tag = DHCP_EB_PRIORITY, 1455 .type = &setting_type_int8, 1456 }; 1457