1 /*
2 * Copyright (C) 2008 Michael Brown <mbrown@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., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <byteswap.h>
32 #include <errno.h>
33 #include <assert.h>
34 #include <time.h>
35 #include <ipxe/in.h>
36 #include <ipxe/ip.h>
37 #include <ipxe/ipv6.h>
38 #include <ipxe/vsprintf.h>
39 #include <ipxe/dhcp.h>
40 #include <ipxe/uuid.h>
41 #include <ipxe/uri.h>
42 #include <ipxe/base16.h>
43 #include <ipxe/base64.h>
44 #include <ipxe/pci.h>
45 #include <ipxe/init.h>
46 #include <ipxe/version.h>
47 #include <ipxe/settings.h>
48
49 /** @file
50 *
51 * Configuration settings
52 *
53 */
54
55 /******************************************************************************
56 *
57 * Generic settings blocks
58 *
59 ******************************************************************************
60 */
61
62 /**
63 * A generic setting
64 *
65 */
66 struct generic_setting {
67 /** List of generic settings */
68 struct list_head list;
69 /** Setting */
70 struct setting setting;
71 /** Size of setting name */
72 size_t name_len;
73 /** Size of setting data */
74 size_t data_len;
75 };
76
77 /**
78 * Get generic setting name
79 *
80 * @v generic Generic setting
81 * @ret name Generic setting name
82 */
generic_setting_name(struct generic_setting * generic)83 static inline void * generic_setting_name ( struct generic_setting *generic ) {
84 return ( ( ( void * ) generic ) + sizeof ( *generic ) );
85 }
86
87 /**
88 * Get generic setting data
89 *
90 * @v generic Generic setting
91 * @ret data Generic setting data
92 */
generic_setting_data(struct generic_setting * generic)93 static inline void * generic_setting_data ( struct generic_setting *generic ) {
94 return ( ( ( void * ) generic ) + sizeof ( *generic ) +
95 generic->name_len );
96 }
97
98 /**
99 * Find generic setting
100 *
101 * @v generics Generic settings block
102 * @v setting Setting to find
103 * @ret generic Generic setting, or NULL
104 */
105 static struct generic_setting *
find_generic_setting(struct generic_settings * generics,const struct setting * setting)106 find_generic_setting ( struct generic_settings *generics,
107 const struct setting *setting ) {
108 struct generic_setting *generic;
109
110 list_for_each_entry ( generic, &generics->list, list ) {
111 if ( setting_cmp ( &generic->setting, setting ) == 0 )
112 return generic;
113 }
114 return NULL;
115 }
116
117 /**
118 * Store value of generic setting
119 *
120 * @v settings Settings block
121 * @v setting Setting to store
122 * @v data Setting data, or NULL to clear setting
123 * @v len Length of setting data
124 * @ret rc Return status code
125 */
generic_settings_store(struct settings * settings,const struct setting * setting,const void * data,size_t len)126 int generic_settings_store ( struct settings *settings,
127 const struct setting *setting,
128 const void *data, size_t len ) {
129 struct generic_settings *generics =
130 container_of ( settings, struct generic_settings, settings );
131 struct generic_setting *old;
132 struct generic_setting *new = NULL;
133 size_t name_len;
134
135 /* Identify existing generic setting, if any */
136 old = find_generic_setting ( generics, setting );
137
138 /* Create new generic setting, if required */
139 if ( len ) {
140 /* Allocate new generic setting */
141 name_len = ( strlen ( setting->name ) + 1 );
142 new = zalloc ( sizeof ( *new ) + name_len + len );
143 if ( ! new )
144 return -ENOMEM;
145
146 /* Populate new generic setting */
147 new->name_len = name_len;
148 new->data_len = len;
149 memcpy ( &new->setting, setting, sizeof ( new->setting ) );
150 new->setting.name = generic_setting_name ( new );
151 memcpy ( generic_setting_name ( new ),
152 setting->name, name_len );
153 memcpy ( generic_setting_data ( new ), data, len );
154 }
155
156 /* Delete existing generic setting, if any */
157 if ( old ) {
158 list_del ( &old->list );
159 free ( old );
160 }
161
162 /* Add new setting to list, if any */
163 if ( new )
164 list_add ( &new->list, &generics->list );
165
166 return 0;
167 }
168
169 /**
170 * Fetch value of generic setting
171 *
172 * @v settings Settings block
173 * @v setting Setting to fetch
174 * @v data Buffer to fill with setting data
175 * @v len Length of buffer
176 * @ret len Length of setting data, or negative error
177 */
generic_settings_fetch(struct settings * settings,struct setting * setting,void * data,size_t len)178 int generic_settings_fetch ( struct settings *settings,
179 struct setting *setting,
180 void *data, size_t len ) {
181 struct generic_settings *generics =
182 container_of ( settings, struct generic_settings, settings );
183 struct generic_setting *generic;
184
185 /* Find generic setting */
186 generic = find_generic_setting ( generics, setting );
187 if ( ! generic )
188 return -ENOENT;
189
190 /* Copy out generic setting data */
191 if ( len > generic->data_len )
192 len = generic->data_len;
193 memcpy ( data, generic_setting_data ( generic ), len );
194
195 /* Set setting type, if not yet specified */
196 if ( ! setting->type )
197 setting->type = generic->setting.type;
198
199 return generic->data_len;
200 }
201
202 /**
203 * Clear generic settings block
204 *
205 * @v settings Settings block
206 */
generic_settings_clear(struct settings * settings)207 void generic_settings_clear ( struct settings *settings ) {
208 struct generic_settings *generics =
209 container_of ( settings, struct generic_settings, settings );
210 struct generic_setting *generic;
211 struct generic_setting *tmp;
212
213 list_for_each_entry_safe ( generic, tmp, &generics->list, list ) {
214 list_del ( &generic->list );
215 free ( generic );
216 }
217 assert ( list_empty ( &generics->list ) );
218 }
219
220 /** Generic settings operations */
221 struct settings_operations generic_settings_operations = {
222 .store = generic_settings_store,
223 .fetch = generic_settings_fetch,
224 .clear = generic_settings_clear,
225 };
226
227 /******************************************************************************
228 *
229 * Registered settings blocks
230 *
231 ******************************************************************************
232 */
233
234 /** Root generic settings block */
235 struct generic_settings generic_settings_root = {
236 .settings = {
237 .refcnt = NULL,
238 .name = "",
239 .siblings =
240 LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
241 .children =
242 LIST_HEAD_INIT ( generic_settings_root.settings.children ),
243 .op = &generic_settings_operations,
244 },
245 .list = LIST_HEAD_INIT ( generic_settings_root.list ),
246 };
247
248 /** Root settings block */
249 #define settings_root generic_settings_root.settings
250
251 /** Autovivified settings block */
252 struct autovivified_settings {
253 /** Reference count */
254 struct refcnt refcnt;
255 /** Generic settings block */
256 struct generic_settings generic;
257 };
258
259 /**
260 * Free autovivified settings block
261 *
262 * @v refcnt Reference count
263 */
autovivified_settings_free(struct refcnt * refcnt)264 static void autovivified_settings_free ( struct refcnt *refcnt ) {
265 struct autovivified_settings *autovivified =
266 container_of ( refcnt, struct autovivified_settings, refcnt );
267
268 generic_settings_clear ( &autovivified->generic.settings );
269 free ( autovivified );
270 }
271
272 /**
273 * Find child settings block
274 *
275 * @v parent Parent settings block
276 * @v name Name within this parent
277 * @ret settings Settings block, or NULL
278 */
find_child_settings(struct settings * parent,const char * name)279 struct settings * find_child_settings ( struct settings *parent,
280 const char *name ) {
281 struct settings *settings;
282
283 /* Find target parent settings block */
284 parent = settings_target ( parent );
285
286 /* Treat empty name as meaning "this block" */
287 if ( ! *name )
288 return parent;
289
290 /* Look for child with matching name */
291 list_for_each_entry ( settings, &parent->children, siblings ) {
292 if ( strcmp ( settings->name, name ) == 0 )
293 return settings_target ( settings );
294 }
295
296 return NULL;
297 }
298
299 /**
300 * Find or create child settings block
301 *
302 * @v parent Parent settings block
303 * @v name Name within this parent
304 * @ret settings Settings block, or NULL
305 */
autovivify_child_settings(struct settings * parent,const char * name)306 struct settings * autovivify_child_settings ( struct settings *parent,
307 const char *name ) {
308 struct {
309 struct autovivified_settings autovivified;
310 char name[ strlen ( name ) + 1 /* NUL */ ];
311 } *new_child;
312 struct settings *settings;
313
314 /* Find target parent settings block */
315 parent = settings_target ( parent );
316
317 /* Return existing settings, if existent */
318 if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
319 return settings;
320
321 /* Create new generic settings block */
322 new_child = zalloc ( sizeof ( *new_child ) );
323 if ( ! new_child ) {
324 DBGC ( parent, "Settings %p could not create child %s\n",
325 parent, name );
326 return NULL;
327 }
328 memcpy ( new_child->name, name, sizeof ( new_child->name ) );
329 ref_init ( &new_child->autovivified.refcnt,
330 autovivified_settings_free );
331 generic_settings_init ( &new_child->autovivified.generic,
332 &new_child->autovivified.refcnt );
333 settings = &new_child->autovivified.generic.settings;
334 register_settings ( settings, parent, new_child->name );
335 ref_put ( settings->refcnt );
336 return settings;
337 }
338
339 /**
340 * Return settings block name
341 *
342 * @v settings Settings block
343 * @ret name Settings block name
344 */
settings_name(struct settings * settings)345 const char * settings_name ( struct settings *settings ) {
346 static char buf[16];
347 char tmp[ 1 /* '.' */ + sizeof ( buf ) ];
348
349 /* Find target settings block */
350 settings = settings_target ( settings );
351
352 /* Construct name */
353 buf[0] = '\0';
354 tmp[0] = '\0';
355 for ( ; settings->parent ; settings = settings->parent ) {
356 memcpy ( ( tmp + 1 ), buf, ( sizeof ( tmp ) - 1 ) );
357 snprintf ( buf, sizeof ( buf ), "%s%s", settings->name, tmp );
358 tmp[0] = '.';
359 }
360 return buf;
361 }
362
363 /**
364 * Parse settings block name
365 *
366 * @v name Name
367 * @v get_child Function to find or create child settings block
368 * @ret settings Settings block, or NULL
369 */
370 static struct settings *
parse_settings_name(const char * name,get_child_settings_t get_child)371 parse_settings_name ( const char *name, get_child_settings_t get_child ) {
372 struct settings *settings = &settings_root;
373 char *name_copy;
374 char *subname;
375 char *remainder;
376
377 /* Create modifiable copy of name */
378 name_copy = strdup ( name );
379 if ( ! name_copy )
380 return NULL;
381 remainder = name_copy;
382
383 /* Parse each name component in turn */
384 while ( remainder ) {
385 subname = remainder;
386 remainder = strchr ( subname, '.' );
387 if ( remainder )
388 *(remainder++) = '\0';
389 settings = get_child ( settings, subname );
390 if ( ! settings )
391 break;
392 }
393
394 /* Free modifiable copy of name */
395 free ( name_copy );
396
397 return settings;
398 }
399
400 /**
401 * Find settings block
402 *
403 * @v name Name
404 * @ret settings Settings block, or NULL
405 */
find_settings(const char * name)406 struct settings * find_settings ( const char *name ) {
407
408 return parse_settings_name ( name, find_child_settings );
409 }
410
411 /**
412 * Apply all settings
413 *
414 * @ret rc Return status code
415 */
apply_settings(void)416 static int apply_settings ( void ) {
417 struct settings_applicator *applicator;
418 int rc;
419
420 /* Call all settings applicators */
421 for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) {
422 if ( ( rc = applicator->apply() ) != 0 ) {
423 DBG ( "Could not apply settings using applicator "
424 "%p: %s\n", applicator, strerror ( rc ) );
425 return rc;
426 }
427 }
428
429 return 0;
430 }
431
432 /**
433 * Reprioritise settings
434 *
435 * @v settings Settings block
436 *
437 * Reorders the settings block amongst its siblings according to its
438 * priority.
439 */
reprioritise_settings(struct settings * settings)440 static void reprioritise_settings ( struct settings *settings ) {
441 struct settings *parent = settings->parent;
442 long priority;
443 struct settings *tmp;
444 long tmp_priority;
445
446 /* Stop when we reach the top of the tree */
447 if ( ! parent )
448 return;
449
450 /* Read priority, if present */
451 priority = fetch_intz_setting ( settings, &priority_setting );
452
453 /* Remove from siblings list */
454 list_del ( &settings->siblings );
455
456 /* Reinsert after any existing blocks which have a higher priority */
457 list_for_each_entry ( tmp, &parent->children, siblings ) {
458 tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
459 if ( priority > tmp_priority )
460 break;
461 if ( settings->order > tmp->order )
462 break;
463 }
464 list_add_tail ( &settings->siblings, &tmp->siblings );
465
466 /* Recurse up the tree */
467 reprioritise_settings ( parent );
468 }
469
470 /**
471 * Register settings block
472 *
473 * @v settings Settings block
474 * @v parent Parent settings block, or NULL
475 * @v name Settings block name
476 * @ret rc Return status code
477 */
register_settings(struct settings * settings,struct settings * parent,const char * name)478 int register_settings ( struct settings *settings, struct settings *parent,
479 const char *name ) {
480 struct settings *old_settings;
481
482 /* Sanity check */
483 assert ( settings != NULL );
484
485 /* Find target parent settings block */
486 parent = settings_target ( parent );
487
488 /* Apply settings block name */
489 settings->name = name;
490
491 /* Remove any existing settings with the same name */
492 if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
493 unregister_settings ( old_settings );
494
495 /* Add to list of settings */
496 ref_get ( settings->refcnt );
497 ref_get ( parent->refcnt );
498 settings->parent = parent;
499 list_add_tail ( &settings->siblings, &parent->children );
500 DBGC ( settings, "Settings %p (\"%s\") registered\n",
501 settings, settings_name ( settings ) );
502
503 /* Fix up settings priority */
504 reprioritise_settings ( settings );
505
506 /* Apply potentially-updated settings */
507 apply_settings();
508
509 return 0;
510 }
511
512 /**
513 * Unregister settings block
514 *
515 * @v settings Settings block
516 */
unregister_settings(struct settings * settings)517 void unregister_settings ( struct settings *settings ) {
518 struct settings *child;
519
520 /* Unregister child settings */
521 while ( ( child = list_first_entry ( &settings->children,
522 struct settings, siblings ) ) ) {
523 unregister_settings ( child );
524 }
525
526 DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
527 settings, settings_name ( settings ) );
528
529 /* Remove from list of settings */
530 ref_put ( settings->parent->refcnt );
531 settings->parent = NULL;
532 list_del ( &settings->siblings );
533 ref_put ( settings->refcnt );
534
535 /* Apply potentially-updated settings */
536 apply_settings();
537 }
538
539 /******************************************************************************
540 *
541 * Core settings routines
542 *
543 ******************************************************************************
544 */
545
546 /**
547 * Redirect to target settings block
548 *
549 * @v settings Settings block, or NULL
550 * @ret settings Underlying settings block
551 */
settings_target(struct settings * settings)552 struct settings * settings_target ( struct settings *settings ) {
553
554 /* NULL settings implies the global settings root */
555 if ( ! settings )
556 settings = &settings_root;
557
558 /* Redirect to underlying settings block, if applicable */
559 if ( settings->op->redirect )
560 return settings->op->redirect ( settings );
561
562 /* Otherwise, return this settings block */
563 return settings;
564 }
565
566 /**
567 * Check applicability of setting
568 *
569 * @v settings Settings block
570 * @v setting Setting
571 * @ret applies Setting applies within this settings block
572 */
setting_applies(struct settings * settings,const struct setting * setting)573 int setting_applies ( struct settings *settings,
574 const struct setting *setting ) {
575
576 /* Find target settings block */
577 settings = settings_target ( settings );
578
579 /* Check applicability of setting */
580 return ( settings->op->applies ?
581 settings->op->applies ( settings, setting ) : 1 );
582 }
583
584 /**
585 * Find setting applicable to settings block, if any
586 *
587 * @v settings Settings block
588 * @v setting Setting
589 * @ret setting Applicable setting, if any
590 */
591 static const struct setting *
applicable_setting(struct settings * settings,const struct setting * setting)592 applicable_setting ( struct settings *settings, const struct setting *setting ){
593 const struct setting *applicable;
594
595 /* If setting is already applicable, use it */
596 if ( setting_applies ( settings, setting ) )
597 return setting;
598
599 /* Otherwise, look for a matching predefined setting which does apply */
600 for_each_table_entry ( applicable, SETTINGS ) {
601 if ( ( setting_cmp ( setting, applicable ) == 0 ) &&
602 ( setting_applies ( settings, applicable ) ) )
603 return applicable;
604 }
605
606 return NULL;
607 }
608
609 /**
610 * Store value of setting
611 *
612 * @v settings Settings block, or NULL
613 * @v setting Setting to store
614 * @v data Setting data, or NULL to clear setting
615 * @v len Length of setting data
616 * @ret rc Return status code
617 */
store_setting(struct settings * settings,const struct setting * setting,const void * data,size_t len)618 int store_setting ( struct settings *settings, const struct setting *setting,
619 const void *data, size_t len ) {
620 int rc;
621
622 /* Find target settings block */
623 settings = settings_target ( settings );
624
625 /* Fail if setting does not apply to this settings block */
626 if ( ! setting_applies ( settings, setting ) )
627 return -ENOTTY;
628
629 /* Sanity check */
630 if ( ! settings->op->store )
631 return -ENOTSUP;
632
633 /* Store setting */
634 if ( ( rc = settings->op->store ( settings, setting,
635 data, len ) ) != 0 )
636 return rc;
637
638 /* Reprioritise settings if necessary */
639 if ( setting_cmp ( setting, &priority_setting ) == 0 )
640 reprioritise_settings ( settings );
641
642 /* If these settings are registered, apply potentially-updated
643 * settings
644 */
645 for ( ; settings ; settings = settings->parent ) {
646 if ( settings == &settings_root ) {
647 if ( ( rc = apply_settings() ) != 0 )
648 return rc;
649 break;
650 }
651 }
652
653 return 0;
654 }
655
656 /**
657 * Fetch setting
658 *
659 * @v settings Settings block, or NULL to search all blocks
660 * @v setting Setting to fetch
661 * @v origin Origin of setting to fill in, or NULL
662 * @v fetched Fetched setting to fill in, or NULL
663 * @v data Buffer to fill with setting data
664 * @v len Length of buffer
665 * @ret len Length of setting data, or negative error
666 *
667 * The actual length of the setting will be returned even if
668 * the buffer was too small.
669 */
fetch_setting(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,void * data,size_t len)670 int fetch_setting ( struct settings *settings, const struct setting *setting,
671 struct settings **origin, struct setting *fetched,
672 void *data, size_t len ) {
673 const struct setting *applicable;
674 struct settings *child;
675 struct setting tmp;
676 int ret;
677
678 /* Avoid returning uninitialised data on error */
679 memset ( data, 0, len );
680 if ( origin )
681 *origin = NULL;
682 if ( fetched )
683 memcpy ( fetched, setting, sizeof ( *fetched ) );
684
685 /* Find target settings block */
686 settings = settings_target ( settings );
687
688 /* Sanity check */
689 if ( ! settings->op->fetch )
690 return -ENOTSUP;
691
692 /* Try this block first, if an applicable setting exists */
693 if ( ( applicable = applicable_setting ( settings, setting ) ) ) {
694
695 /* Create modifiable copy of setting */
696 memcpy ( &tmp, applicable, sizeof ( tmp ) );
697 if ( ( ret = settings->op->fetch ( settings, &tmp,
698 data, len ) ) >= 0 ) {
699
700 /* Default to string type, if not yet specified */
701 if ( ! tmp.type )
702 tmp.type = &setting_type_string;
703
704 /* Record origin, if applicable */
705 if ( origin )
706 *origin = settings;
707
708 /* Record fetched setting, if applicable */
709 if ( fetched )
710 memcpy ( fetched, &tmp, sizeof ( *fetched ) );
711
712 return ret;
713 }
714 }
715
716 /* Recurse into each child block in turn */
717 list_for_each_entry ( child, &settings->children, siblings ) {
718 if ( ( ret = fetch_setting ( child, setting, origin, fetched,
719 data, len ) ) >= 0 )
720 return ret;
721 }
722
723 return -ENOENT;
724 }
725
726 /**
727 * Fetch allocated copy of setting
728 *
729 * @v settings Settings block, or NULL to search all blocks
730 * @v setting Setting to fetch
731 * @v origin Origin of setting to fill in, or NULL
732 * @v fetched Fetched setting to fill in, or NULL
733 * @v data Buffer to allocate and fill with setting data
734 * @v alloc Allocation function
735 * @ret len Length of setting, or negative error
736 *
737 * The caller is responsible for eventually freeing the allocated
738 * buffer.
739 */
fetch_setting_alloc(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,void ** data,void * (* alloc)(size_t len))740 static int fetch_setting_alloc ( struct settings *settings,
741 const struct setting *setting,
742 struct settings **origin,
743 struct setting *fetched,
744 void **data,
745 void * ( * alloc ) ( size_t len ) ) {
746 struct settings *tmp_origin;
747 struct setting tmp_fetched;
748 int len;
749 int check_len;
750
751 /* Use local buffers if necessary */
752 if ( ! origin )
753 origin = &tmp_origin;
754 if ( ! fetched )
755 fetched = &tmp_fetched;
756
757 /* Avoid returning uninitialised data on error */
758 *data = NULL;
759
760 /* Check existence, and fetch setting length */
761 len = fetch_setting ( settings, setting, origin, fetched, NULL, 0 );
762 if ( len < 0 )
763 return len;
764
765 /* Allocate buffer */
766 *data = alloc ( len );
767 if ( ! *data )
768 return -ENOMEM;
769
770 /* Fetch setting value */
771 check_len = fetch_setting ( *origin, fetched, NULL, NULL, *data, len );
772 assert ( check_len == len );
773 return len;
774 }
775
776 /**
777 * Fetch copy of setting
778 *
779 * @v settings Settings block, or NULL to search all blocks
780 * @v setting Setting to fetch
781 * @v origin Origin of setting to fill in, or NULL
782 * @v fetched Fetched setting to fill in, or NULL
783 * @v data Buffer to allocate and fill with setting data
784 * @ret len Length of setting, or negative error
785 *
786 * The caller is responsible for eventually freeing the allocated
787 * buffer.
788 */
fetch_setting_copy(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,void ** data)789 int fetch_setting_copy ( struct settings *settings,
790 const struct setting *setting,
791 struct settings **origin, struct setting *fetched,
792 void **data ) {
793
794 return fetch_setting_alloc ( settings, setting, origin, fetched,
795 data, malloc );
796 }
797
798 /**
799 * Fetch value of setting
800 *
801 * @v settings Settings block, or NULL to search all blocks
802 * @v setting Setting to fetch
803 * @v data Buffer to fill with setting string data
804 * @v len Length of buffer
805 * @ret len Length of setting, or negative error
806 */
fetch_raw_setting(struct settings * settings,const struct setting * setting,void * data,size_t len)807 int fetch_raw_setting ( struct settings *settings,
808 const struct setting *setting,
809 void *data, size_t len ) {
810
811 return fetch_setting ( settings, setting, NULL, NULL, data, len );
812 }
813
814 /**
815 * Fetch value of setting
816 *
817 * @v settings Settings block, or NULL to search all blocks
818 * @v setting Setting to fetch
819 * @v data Buffer to allocate and fill with setting data
820 * @ret len Length of setting, or negative error
821 *
822 * The caller is responsible for eventually freeing the allocated
823 * buffer.
824 */
fetch_raw_setting_copy(struct settings * settings,const struct setting * setting,void ** data)825 int fetch_raw_setting_copy ( struct settings *settings,
826 const struct setting *setting,
827 void **data ) {
828
829 return fetch_setting_copy ( settings, setting, NULL, NULL, data );
830 }
831
832 /**
833 * Fetch value of string setting
834 *
835 * @v settings Settings block, or NULL to search all blocks
836 * @v setting Setting to fetch
837 * @v data Buffer to fill with setting string data
838 * @v len Length of buffer
839 * @ret len Length of string setting, or negative error
840 *
841 * The resulting string is guaranteed to be correctly NUL-terminated.
842 * The returned length will be the length of the underlying setting
843 * data.
844 */
fetch_string_setting(struct settings * settings,const struct setting * setting,char * data,size_t len)845 int fetch_string_setting ( struct settings *settings,
846 const struct setting *setting,
847 char *data, size_t len ) {
848
849 memset ( data, 0, len );
850 return fetch_raw_setting ( settings, setting, data,
851 ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
852 }
853
854 /**
855 * Allocate memory for copy of string setting
856 *
857 * @v len Length of setting
858 * @ret ptr Allocated memory
859 */
fetch_string_setting_copy_alloc(size_t len)860 static void * fetch_string_setting_copy_alloc ( size_t len ) {
861 return zalloc ( len + 1 /* NUL */ );
862 }
863
864 /**
865 * Fetch value of string setting
866 *
867 * @v settings Settings block, or NULL to search all blocks
868 * @v setting Setting to fetch
869 * @v data Buffer to allocate and fill with setting string data
870 * @ret len Length of string setting, or negative error
871 *
872 * The resulting string is guaranteed to be correctly NUL-terminated.
873 * The returned length will be the length of the underlying setting
874 * data. The caller is responsible for eventually freeing the
875 * allocated buffer.
876 */
fetch_string_setting_copy(struct settings * settings,const struct setting * setting,char ** data)877 int fetch_string_setting_copy ( struct settings *settings,
878 const struct setting *setting, char **data ) {
879
880 return fetch_setting_alloc ( settings, setting, NULL, NULL,
881 ( ( void ** ) data ),
882 fetch_string_setting_copy_alloc );
883 }
884
885 /**
886 * Fetch value of IPv4 address setting
887 *
888 * @v settings Settings block, or NULL to search all blocks
889 * @v setting Setting to fetch
890 * @v inp IPv4 addresses to fill in
891 * @v count Maximum number of IPv4 addresses
892 * @ret len Length of setting, or negative error
893 */
fetch_ipv4_array_setting(struct settings * settings,const struct setting * setting,struct in_addr * inp,unsigned int count)894 int fetch_ipv4_array_setting ( struct settings *settings,
895 const struct setting *setting,
896 struct in_addr *inp, unsigned int count ) {
897 int len;
898
899 len = fetch_raw_setting ( settings, setting, inp,
900 ( sizeof ( *inp ) * count ) );
901 if ( len < 0 )
902 return len;
903 if ( ( len % sizeof ( *inp ) ) != 0 )
904 return -ERANGE;
905 return len;
906 }
907
908 /**
909 * Fetch value of IPv4 address setting
910 *
911 * @v settings Settings block, or NULL to search all blocks
912 * @v setting Setting to fetch
913 * @v inp IPv4 address to fill in
914 * @ret len Length of setting, or negative error
915 */
fetch_ipv4_setting(struct settings * settings,const struct setting * setting,struct in_addr * inp)916 int fetch_ipv4_setting ( struct settings *settings,
917 const struct setting *setting,
918 struct in_addr *inp ) {
919
920 return fetch_ipv4_array_setting ( settings, setting, inp, 1 );
921 }
922
923 /**
924 * Fetch value of IPv6 address setting
925 *
926 * @v settings Settings block, or NULL to search all blocks
927 * @v setting Setting to fetch
928 * @v inp IPv6 addresses to fill in
929 * @v count Maximum number of IPv6 addresses
930 * @ret len Length of setting, or negative error
931 */
fetch_ipv6_array_setting(struct settings * settings,const struct setting * setting,struct in6_addr * inp,unsigned int count)932 int fetch_ipv6_array_setting ( struct settings *settings,
933 const struct setting *setting,
934 struct in6_addr *inp, unsigned int count ) {
935 int len;
936
937 len = fetch_raw_setting ( settings, setting, inp,
938 ( sizeof ( *inp ) * count ) );
939 if ( len < 0 )
940 return len;
941 if ( ( len % sizeof ( *inp ) ) != 0 )
942 return -ERANGE;
943 return len;
944 }
945
946 /**
947 * Fetch value of IPv6 address setting
948 *
949 * @v settings Settings block, or NULL to search all blocks
950 * @v setting Setting to fetch
951 * @v inp IPv6 address to fill in
952 * @ret len Length of setting, or negative error
953 */
fetch_ipv6_setting(struct settings * settings,const struct setting * setting,struct in6_addr * inp)954 int fetch_ipv6_setting ( struct settings *settings,
955 const struct setting *setting,
956 struct in6_addr *inp ) {
957
958 return fetch_ipv6_array_setting ( settings, setting, inp, 1 );
959 }
960
961 /**
962 * Extract numeric value of setting
963 *
964 * @v is_signed Treat value as a signed integer
965 * @v raw Raw setting data
966 * @v len Length of raw setting data
967 * @ret value Numeric value
968 * @ret len Length of setting, or negative error
969 */
numeric_setting_value(int is_signed,const void * raw,size_t len,unsigned long * value)970 static int numeric_setting_value ( int is_signed, const void *raw, size_t len,
971 unsigned long *value ) {
972 const uint8_t *unsigned_bytes = raw;
973 const int8_t *signed_bytes = raw;
974 int is_negative;
975 unsigned int i;
976 uint8_t pad;
977 uint8_t byte;
978
979 /* Convert to host-ordered longs */
980 is_negative = ( len && ( signed_bytes[0] < 0 ) );
981 *value = ( ( is_signed && is_negative ) ? -1L : 0 );
982 pad = *value;
983 for ( i = 0 ; i < len ; i++ ) {
984 byte = unsigned_bytes[i];
985 *value = ( ( *value << 8 ) | byte );
986 if ( ( ( i + sizeof ( *value ) ) < len ) && ( byte != pad ) )
987 return -ERANGE;
988 }
989
990 return len;
991 }
992
993 /**
994 * Fetch value of numeric setting
995 *
996 * @v settings Settings block, or NULL to search all blocks
997 * @v setting Setting to fetch
998 * @v value Integer value to fill in
999 * @ret len Length of setting, or negative error
1000 */
fetch_numeric_setting(struct settings * settings,const struct setting * setting,unsigned long * value,int is_signed)1001 int fetch_numeric_setting ( struct settings *settings,
1002 const struct setting *setting,
1003 unsigned long *value, int is_signed ) {
1004 unsigned long tmp;
1005 int len;
1006
1007 /* Avoid returning uninitialised data on error */
1008 *value = 0;
1009
1010 /* Fetch raw (network-ordered, variable-length) setting */
1011 len = fetch_raw_setting ( settings, setting, &tmp, sizeof ( tmp ) );
1012 if ( len < 0 )
1013 return len;
1014
1015 /* Extract numeric value */
1016 return numeric_setting_value ( is_signed, &tmp, len, value );
1017 }
1018
1019 /**
1020 * Fetch value of signed integer setting
1021 *
1022 * @v settings Settings block, or NULL to search all blocks
1023 * @v setting Setting to fetch
1024 * @v value Integer value to fill in
1025 * @ret len Length of setting, or negative error
1026 */
fetch_int_setting(struct settings * settings,const struct setting * setting,long * value)1027 int fetch_int_setting ( struct settings *settings,
1028 const struct setting *setting,
1029 long *value ) {
1030
1031 return fetch_numeric_setting ( settings, setting,
1032 ( ( unsigned long * ) value ), 1 );
1033 }
1034
1035 /**
1036 * Fetch value of unsigned integer setting
1037 *
1038 * @v settings Settings block, or NULL to search all blocks
1039 * @v setting Setting to fetch
1040 * @v value Integer value to fill in
1041 * @ret len Length of setting, or negative error
1042 */
fetch_uint_setting(struct settings * settings,const struct setting * setting,unsigned long * value)1043 int fetch_uint_setting ( struct settings *settings,
1044 const struct setting *setting,
1045 unsigned long *value ) {
1046
1047 return fetch_numeric_setting ( settings, setting, value, 0 );
1048 }
1049
1050 /**
1051 * Fetch value of signed integer setting, or zero
1052 *
1053 * @v settings Settings block, or NULL to search all blocks
1054 * @v setting Setting to fetch
1055 * @ret value Setting value, or zero
1056 */
fetch_intz_setting(struct settings * settings,const struct setting * setting)1057 long fetch_intz_setting ( struct settings *settings,
1058 const struct setting *setting ) {
1059 unsigned long value;
1060
1061 fetch_numeric_setting ( settings, setting, &value, 1 );
1062 return value;
1063 }
1064
1065 /**
1066 * Fetch value of unsigned integer setting, or zero
1067 *
1068 * @v settings Settings block, or NULL to search all blocks
1069 * @v setting Setting to fetch
1070 * @ret value Setting value, or zero
1071 */
fetch_uintz_setting(struct settings * settings,const struct setting * setting)1072 unsigned long fetch_uintz_setting ( struct settings *settings,
1073 const struct setting *setting ) {
1074 unsigned long value;
1075
1076 fetch_numeric_setting ( settings, setting, &value, 0 );
1077 return value;
1078 }
1079
1080 /**
1081 * Fetch value of UUID setting
1082 *
1083 * @v settings Settings block, or NULL to search all blocks
1084 * @v setting Setting to fetch
1085 * @v uuid UUID to fill in
1086 * @ret len Length of setting, or negative error
1087 */
fetch_uuid_setting(struct settings * settings,const struct setting * setting,union uuid * uuid)1088 int fetch_uuid_setting ( struct settings *settings,
1089 const struct setting *setting,
1090 union uuid *uuid ) {
1091 int len;
1092
1093 len = fetch_raw_setting ( settings, setting, uuid, sizeof ( *uuid ) );
1094 if ( len < 0 )
1095 return len;
1096 if ( len != sizeof ( *uuid ) )
1097 return -ERANGE;
1098 return len;
1099 }
1100
1101 /**
1102 * Clear settings block
1103 *
1104 * @v settings Settings block
1105 */
clear_settings(struct settings * settings)1106 void clear_settings ( struct settings *settings ) {
1107
1108 /* Find target settings block */
1109 settings = settings_target ( settings );
1110
1111 /* Clear settings, if applicable */
1112 if ( settings->op->clear )
1113 settings->op->clear ( settings );
1114 }
1115
1116 /**
1117 * Compare two settings
1118 *
1119 * @v a Setting to compare
1120 * @v b Setting to compare
1121 * @ret 0 Settings are the same
1122 * @ret non-zero Settings are not the same
1123 */
setting_cmp(const struct setting * a,const struct setting * b)1124 int setting_cmp ( const struct setting *a, const struct setting *b ) {
1125
1126 /* If the settings have tags, compare them */
1127 if ( a->tag && ( a->tag == b->tag ) && ( a->scope == b->scope ) )
1128 return 0;
1129
1130 /* Otherwise, if the settings have names, compare them */
1131 if ( a->name && b->name && a->name[0] )
1132 return strcmp ( a->name, b->name );
1133
1134 /* Otherwise, return a non-match */
1135 return ( ! 0 );
1136 }
1137
1138 /******************************************************************************
1139 *
1140 * Formatted setting routines
1141 *
1142 ******************************************************************************
1143 */
1144
1145 /**
1146 * Format setting value as a string
1147 *
1148 * @v type Setting type
1149 * @v raw Raw setting value
1150 * @v raw_len Length of raw setting value
1151 * @v buf Buffer to contain formatted value
1152 * @v len Length of buffer
1153 * @ret len Length of formatted value, or negative error
1154 */
setting_format(const struct setting_type * type,const void * raw,size_t raw_len,char * buf,size_t len)1155 int setting_format ( const struct setting_type *type, const void *raw,
1156 size_t raw_len, char *buf, size_t len ) {
1157
1158 /* Sanity check */
1159 if ( ! type->format )
1160 return -ENOTSUP;
1161
1162 return type->format ( type, raw, raw_len, buf, len );
1163 }
1164
1165 /**
1166 * Parse formatted string to setting value
1167 *
1168 * @v type Setting type
1169 * @v value Formatted setting value
1170 * @v buf Buffer to contain raw value
1171 * @v len Length of buffer
1172 * @ret len Length of raw value, or negative error
1173 */
setting_parse(const struct setting_type * type,const char * value,void * buf,size_t len)1174 int setting_parse ( const struct setting_type *type, const char *value,
1175 void *buf, size_t len ) {
1176
1177 /* Sanity check */
1178 if ( ! type->parse )
1179 return -ENOTSUP;
1180
1181 return type->parse ( type, value, buf, len );
1182 }
1183
1184 /**
1185 * Convert setting value to number
1186 *
1187 * @v type Setting type
1188 * @v raw Raw setting value
1189 * @v raw_len Length of raw setting value
1190 * @ret value Numeric value
1191 * @ret rc Return status code
1192 */
setting_numerate(const struct setting_type * type,const void * raw,size_t raw_len,unsigned long * value)1193 int setting_numerate ( const struct setting_type *type, const void *raw,
1194 size_t raw_len, unsigned long *value ) {
1195
1196 /* Sanity check */
1197 if ( ! type->numerate )
1198 return -ENOTSUP;
1199
1200 return type->numerate ( type, raw, raw_len, value );
1201 }
1202
1203 /**
1204 * Convert number to setting value
1205 *
1206 * @v type Setting type
1207 * @v value Numeric value
1208 * @v buf Buffer to contain raw value
1209 * @v len Length of buffer
1210 * @ret len Length of raw value, or negative error
1211 */
setting_denumerate(const struct setting_type * type,unsigned long value,void * buf,size_t len)1212 int setting_denumerate ( const struct setting_type *type, unsigned long value,
1213 void *buf, size_t len ) {
1214
1215 /* Sanity check */
1216 if ( ! type->denumerate )
1217 return -ENOTSUP;
1218
1219 return type->denumerate ( type, value, buf, len );
1220 }
1221
1222 /**
1223 * Fetch formatted value of setting
1224 *
1225 * @v settings Settings block, or NULL to search all blocks
1226 * @v setting Setting to fetch
1227 * @v origin Origin of setting to fill in, or NULL
1228 * @v fetched Fetched setting to fill in, or NULL
1229 * @v buf Buffer to contain formatted value
1230 * @v len Length of buffer
1231 * @ret len Length of formatted value, or negative error
1232 */
fetchf_setting(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,char * buf,size_t len)1233 int fetchf_setting ( struct settings *settings, const struct setting *setting,
1234 struct settings **origin, struct setting *fetched,
1235 char *buf, size_t len ) {
1236 struct setting tmp_fetched;
1237 void *raw;
1238 int raw_len;
1239 int ret;
1240
1241 /* Use local buffers if necessary */
1242 if ( ! fetched )
1243 fetched = &tmp_fetched;
1244
1245 /* Fetch raw value */
1246 raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
1247 &raw );
1248 if ( raw_len < 0 ) {
1249 ret = raw_len;
1250 goto err_fetch_copy;
1251 }
1252
1253 /* Sanity check */
1254 assert ( fetched->type != NULL );
1255
1256 /* Format setting */
1257 if ( ( ret = setting_format ( fetched->type, raw, raw_len, buf,
1258 len ) ) < 0 )
1259 goto err_format;
1260
1261 err_format:
1262 free ( raw );
1263 err_fetch_copy:
1264 return ret;
1265 }
1266
1267 /**
1268 * Fetch copy of formatted value of setting
1269 *
1270 * @v settings Settings block, or NULL to search all blocks
1271 * @v setting Setting to fetch
1272 * @v origin Origin of setting to fill in, or NULL
1273 * @v fetched Fetched setting to fill in, or NULL
1274 * @v value Buffer to allocate and fill with formatted value
1275 * @ret len Length of formatted value, or negative error
1276 *
1277 * The caller is responsible for eventually freeing the allocated
1278 * buffer.
1279 */
fetchf_setting_copy(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,char ** value)1280 int fetchf_setting_copy ( struct settings *settings,
1281 const struct setting *setting,
1282 struct settings **origin, struct setting *fetched,
1283 char **value ) {
1284 struct settings *tmp_origin;
1285 struct setting tmp_fetched;
1286 int len;
1287 int check_len;
1288
1289 /* Use local buffers if necessary */
1290 if ( ! origin )
1291 origin = &tmp_origin;
1292 if ( ! fetched )
1293 fetched = &tmp_fetched;
1294
1295 /* Avoid returning uninitialised data on error */
1296 *value = NULL;
1297
1298 /* Check existence, and fetch formatted value length */
1299 len = fetchf_setting ( settings, setting, origin, fetched, NULL, 0 );
1300 if ( len < 0 )
1301 return len;
1302
1303 /* Allocate buffer */
1304 *value = zalloc ( len + 1 /* NUL */ );
1305 if ( ! *value )
1306 return -ENOMEM;
1307
1308 /* Fetch formatted value */
1309 check_len = fetchf_setting ( *origin, fetched, NULL, NULL, *value,
1310 ( len + 1 /* NUL */ ) );
1311 assert ( check_len == len );
1312 return len;
1313 }
1314
1315 /**
1316 * Store formatted value of setting
1317 *
1318 * @v settings Settings block
1319 * @v setting Setting to store
1320 * @v value Formatted setting data, or NULL
1321 * @ret rc Return status code
1322 */
storef_setting(struct settings * settings,const struct setting * setting,const char * value)1323 int storef_setting ( struct settings *settings, const struct setting *setting,
1324 const char *value ) {
1325 void *raw;
1326 int raw_len;
1327 int check_len;
1328 int rc;
1329
1330 /* NULL value or empty string implies deletion */
1331 if ( ( ! value ) || ( ! value[0] ) )
1332 return delete_setting ( settings, setting );
1333
1334 /* Sanity check */
1335 assert ( setting->type != NULL );
1336
1337 /* Get raw value length */
1338 raw_len = setting_parse ( setting->type, value, NULL, 0 );
1339 if ( raw_len < 0 ) {
1340 rc = raw_len;
1341 goto err_raw_len;
1342 }
1343
1344 /* Allocate buffer for raw value */
1345 raw = malloc ( raw_len );
1346 if ( ! raw ) {
1347 rc = -ENOMEM;
1348 goto err_alloc_raw;
1349 }
1350
1351 /* Parse formatted value */
1352 check_len = setting_parse ( setting->type, value, raw, raw_len );
1353 assert ( check_len == raw_len );
1354
1355 /* Store raw value */
1356 if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1357 goto err_store;
1358
1359 err_store:
1360 free ( raw );
1361 err_alloc_raw:
1362 err_raw_len:
1363 return rc;
1364 }
1365
1366 /**
1367 * Fetch numeric value of setting
1368 *
1369 * @v settings Settings block, or NULL to search all blocks
1370 * @v setting Setting to fetch
1371 * @v origin Origin of setting to fill in, or NULL
1372 * @v fetched Fetched setting to fill in, or NULL
1373 * @v value Numeric value to fill in
1374 * @ret rc Return status code
1375 */
fetchn_setting(struct settings * settings,const struct setting * setting,struct settings ** origin,struct setting * fetched,unsigned long * value)1376 int fetchn_setting ( struct settings *settings, const struct setting *setting,
1377 struct settings **origin, struct setting *fetched,
1378 unsigned long *value ) {
1379 struct setting tmp_fetched;
1380 void *raw;
1381 int raw_len;
1382 int rc;
1383
1384 /* Use local buffers if necessary */
1385 if ( ! fetched )
1386 fetched = &tmp_fetched;
1387
1388 /* Fetch raw value */
1389 raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
1390 &raw );
1391 if ( raw_len < 0 ) {
1392 rc = raw_len;
1393 goto err_fetch_copy;
1394 }
1395
1396 /* Sanity check */
1397 assert ( fetched->type != NULL );
1398
1399 /* Numerate setting */
1400 if ( ( rc = setting_numerate ( fetched->type, raw, raw_len,
1401 value ) ) < 0 )
1402 goto err_numerate;
1403
1404 err_numerate:
1405 free ( raw );
1406 err_fetch_copy:
1407 return rc;
1408 }
1409
1410 /**
1411 * Store numeric value of setting
1412 *
1413 * @v settings Settings block
1414 * @v setting Setting
1415 * @v value Numeric value
1416 * @ret rc Return status code
1417 */
storen_setting(struct settings * settings,const struct setting * setting,unsigned long value)1418 int storen_setting ( struct settings *settings, const struct setting *setting,
1419 unsigned long value ) {
1420 void *raw;
1421 int raw_len;
1422 int check_len;
1423 int rc;
1424
1425 /* Sanity check */
1426 assert ( setting->type != NULL );
1427
1428 /* Get raw value length */
1429 raw_len = setting_denumerate ( setting->type, value, NULL, 0 );
1430 if ( raw_len < 0 ) {
1431 rc = raw_len;
1432 goto err_raw_len;
1433 }
1434
1435 /* Allocate buffer for raw value */
1436 raw = malloc ( raw_len );
1437 if ( ! raw ) {
1438 rc = -ENOMEM;
1439 goto err_alloc_raw;
1440 }
1441
1442 /* Denumerate value */
1443 check_len = setting_denumerate ( setting->type, value, raw, raw_len );
1444 assert ( check_len == raw_len );
1445
1446 /* Store raw value */
1447 if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1448 goto err_store;
1449
1450 err_store:
1451 free ( raw );
1452 err_alloc_raw:
1453 err_raw_len:
1454 return rc;
1455 }
1456
1457 /******************************************************************************
1458 *
1459 * Named settings
1460 *
1461 ******************************************************************************
1462 */
1463
1464 /**
1465 * Find predefined setting
1466 *
1467 * @v name Name
1468 * @ret setting Setting, or NULL
1469 */
find_setting(const char * name)1470 struct setting * find_setting ( const char *name ) {
1471 struct setting *setting;
1472
1473 for_each_table_entry ( setting, SETTINGS ) {
1474 if ( strcmp ( name, setting->name ) == 0 )
1475 return setting;
1476 }
1477 return NULL;
1478 }
1479
1480 /**
1481 * Parse setting name as tag number
1482 *
1483 * @v name Name
1484 * @ret tag Tag number, or 0 if not a valid number
1485 */
parse_setting_tag(const char * name)1486 static uint64_t parse_setting_tag ( const char *name ) {
1487 char *tmp = ( ( char * ) name );
1488 uint64_t tag = 0;
1489
1490 while ( 1 ) {
1491 tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
1492 if ( *tmp == 0 )
1493 return tag;
1494 if ( *tmp != '.' )
1495 return 0;
1496 tmp++;
1497 }
1498 }
1499
1500 /**
1501 * Find setting type
1502 *
1503 * @v name Name
1504 * @ret type Setting type, or NULL
1505 */
find_setting_type(const char * name)1506 static const struct setting_type * find_setting_type ( const char *name ) {
1507 const struct setting_type *type;
1508
1509 for_each_table_entry ( type, SETTING_TYPES ) {
1510 if ( strcmp ( name, type->name ) == 0 )
1511 return type;
1512 }
1513 return NULL;
1514 }
1515
1516 /**
1517 * Parse setting name
1518 *
1519 * @v name Name of setting
1520 * @v get_child Function to find or create child settings block
1521 * @v settings Settings block to fill in
1522 * @v setting Setting to fill in
1523 * @ret rc Return status code
1524 *
1525 * Interprets a name of the form
1526 * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
1527 * fields.
1528 *
1529 * Note that on success, this function will have modified the original
1530 * setting @c name.
1531 */
parse_setting_name(char * name,get_child_settings_t get_child,struct settings ** settings,struct setting * setting)1532 int parse_setting_name ( char *name, get_child_settings_t get_child,
1533 struct settings **settings, struct setting *setting ) {
1534 char *settings_name;
1535 char *setting_name;
1536 char *type_name;
1537 struct setting *predefined;
1538 int rc;
1539
1540 /* Set defaults */
1541 *settings = &settings_root;
1542 memset ( setting, 0, sizeof ( *setting ) );
1543 setting->name = "";
1544
1545 /* Split name into "[settings_name/]setting_name[:type_name]" */
1546 if ( ( setting_name = strchr ( name, '/' ) ) != NULL ) {
1547 *(setting_name++) = 0;
1548 settings_name = name;
1549 } else {
1550 setting_name = name;
1551 settings_name = NULL;
1552 }
1553 if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
1554 *(type_name++) = 0;
1555
1556 /* Identify settings block, if specified */
1557 if ( settings_name ) {
1558 *settings = parse_settings_name ( settings_name, get_child );
1559 if ( *settings == NULL ) {
1560 DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
1561 settings_name, name );
1562 rc = -ENODEV;
1563 goto err;
1564 }
1565 }
1566
1567 /* Identify setting */
1568 setting->tag = parse_setting_tag ( setting_name );
1569 setting->scope = (*settings)->default_scope;
1570 setting->name = setting_name;
1571 for_each_table_entry ( predefined, SETTINGS ) {
1572 /* Matches a predefined setting; use that setting */
1573 if ( setting_cmp ( predefined, setting ) == 0 ) {
1574 memcpy ( setting, predefined, sizeof ( *setting ) );
1575 break;
1576 }
1577 }
1578
1579 /* Identify setting type, if specified */
1580 if ( type_name ) {
1581 setting->type = find_setting_type ( type_name );
1582 if ( setting->type == NULL ) {
1583 DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
1584 type_name, name );
1585 rc = -ENOTSUP;
1586 goto err;
1587 }
1588 }
1589
1590 return 0;
1591
1592 err:
1593 /* Restore original name */
1594 if ( settings_name )
1595 *( setting_name - 1 ) = '/';
1596 if ( type_name )
1597 *( type_name - 1 ) = ':';
1598 return rc;
1599 }
1600
1601 /**
1602 * Return full setting name
1603 *
1604 * @v settings Settings block, or NULL
1605 * @v setting Setting
1606 * @v buf Buffer
1607 * @v len Length of buffer
1608 * @ret len Length of setting name, or negative error
1609 */
setting_name(struct settings * settings,const struct setting * setting,char * buf,size_t len)1610 int setting_name ( struct settings *settings, const struct setting *setting,
1611 char *buf, size_t len ) {
1612 const char *name;
1613
1614 settings = settings_target ( settings );
1615 name = settings_name ( settings );
1616 return snprintf ( buf, len, "%s%s%s:%s", name, ( name[0] ? "/" : "" ),
1617 setting->name, setting->type->name );
1618 }
1619
1620 /******************************************************************************
1621 *
1622 * Setting types
1623 *
1624 ******************************************************************************
1625 */
1626
1627 /**
1628 * Parse string setting value
1629 *
1630 * @v type Setting type
1631 * @v value Formatted setting value
1632 * @v buf Buffer to contain raw value
1633 * @v len Length of buffer
1634 * @ret len Length of raw value, or negative error
1635 */
parse_string_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)1636 static int parse_string_setting ( const struct setting_type *type __unused,
1637 const char *value, void *buf, size_t len ) {
1638 size_t raw_len = strlen ( value ); /* Exclude terminating NUL */
1639
1640 /* Copy string to buffer */
1641 if ( len > raw_len )
1642 len = raw_len;
1643 memcpy ( buf, value, len );
1644
1645 return raw_len;
1646 }
1647
1648 /**
1649 * Format string setting value
1650 *
1651 * @v type Setting type
1652 * @v raw Raw setting value
1653 * @v raw_len Length of raw setting value
1654 * @v buf Buffer to contain formatted value
1655 * @v len Length of buffer
1656 * @ret len Length of formatted value, or negative error
1657 */
format_string_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)1658 static int format_string_setting ( const struct setting_type *type __unused,
1659 const void *raw, size_t raw_len, char *buf,
1660 size_t len ) {
1661
1662 /* Copy string to buffer, and terminate */
1663 memset ( buf, 0, len );
1664 if ( len > raw_len )
1665 len = raw_len;
1666 memcpy ( buf, raw, len );
1667
1668 return raw_len;
1669 }
1670
1671 /** A string setting type */
1672 const struct setting_type setting_type_string __setting_type = {
1673 .name = "string",
1674 .parse = parse_string_setting,
1675 .format = format_string_setting,
1676 };
1677
1678 /**
1679 * Parse URI-encoded string setting value
1680 *
1681 * @v type Setting type
1682 * @v value Formatted setting value
1683 * @v buf Buffer to contain raw value
1684 * @v len Length of buffer
1685 * @ret len Length of raw value, or negative error
1686 */
parse_uristring_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)1687 static int parse_uristring_setting ( const struct setting_type *type __unused,
1688 const char *value, void *buf, size_t len ){
1689
1690 return uri_decode ( value, buf, len );
1691 }
1692
1693 /**
1694 * Format URI-encoded string setting value
1695 *
1696 * @v type Setting type
1697 * @v raw Raw setting value
1698 * @v raw_len Length of raw setting value
1699 * @v buf Buffer to contain formatted value
1700 * @v len Length of buffer
1701 * @ret len Length of formatted value, or negative error
1702 */
format_uristring_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)1703 static int format_uristring_setting ( const struct setting_type *type __unused,
1704 const void *raw, size_t raw_len,
1705 char *buf, size_t len ) {
1706
1707 return uri_encode ( 0, raw, raw_len, buf, len );
1708 }
1709
1710 /** A URI-encoded string setting type */
1711 const struct setting_type setting_type_uristring __setting_type = {
1712 .name = "uristring",
1713 .parse = parse_uristring_setting,
1714 .format = format_uristring_setting,
1715 };
1716
1717 /**
1718 * Parse IPv4 address setting value (when IPv4 support is not present)
1719 *
1720 * @v type Setting type
1721 * @v value Formatted setting value
1722 * @v buf Buffer to contain raw value
1723 * @v len Length of buffer
1724 * @ret len Length of raw value, or negative error
1725 */
parse_ipv4_setting(const struct setting_type * type __unused,const char * value __unused,void * buf __unused,size_t len __unused)1726 __weak int parse_ipv4_setting ( const struct setting_type *type __unused,
1727 const char *value __unused, void *buf __unused,
1728 size_t len __unused ) {
1729 return -ENOTSUP;
1730 }
1731
1732 /**
1733 * Format IPv4 address setting value (when IPv4 support is not present)
1734 *
1735 * @v type Setting type
1736 * @v raw Raw setting value
1737 * @v raw_len Length of raw setting value
1738 * @v buf Buffer to contain formatted value
1739 * @v len Length of buffer
1740 * @ret len Length of formatted value, or negative error
1741 */
format_ipv4_setting(const struct setting_type * type __unused,const void * raw __unused,size_t raw_len __unused,char * buf __unused,size_t len __unused)1742 __weak int format_ipv4_setting ( const struct setting_type *type __unused,
1743 const void *raw __unused,
1744 size_t raw_len __unused, char *buf __unused,
1745 size_t len __unused ) {
1746 return -ENOTSUP;
1747 }
1748
1749 /** An IPv4 address setting type */
1750 const struct setting_type setting_type_ipv4 __setting_type = {
1751 .name = "ipv4",
1752 .parse = parse_ipv4_setting,
1753 .format = format_ipv4_setting,
1754 };
1755
1756 /**
1757 * Parse IPv6 address setting value (when IPv6 support is not present)
1758 *
1759 * @v type Setting type
1760 * @v value Formatted setting value
1761 * @v buf Buffer to contain raw value
1762 * @v len Length of buffer
1763 * @ret len Length of raw value, or negative error
1764 */
parse_ipv6_setting(const struct setting_type * type __unused,const char * value __unused,void * buf __unused,size_t len __unused)1765 __weak int parse_ipv6_setting ( const struct setting_type *type __unused,
1766 const char *value __unused, void *buf __unused,
1767 size_t len __unused ) {
1768 return -ENOTSUP;
1769 }
1770
1771 /**
1772 * Format IPv6 address setting value (when IPv6 support is not present)
1773 *
1774 * @v type Setting type
1775 * @v raw Raw setting value
1776 * @v raw_len Length of raw setting value
1777 * @v buf Buffer to contain formatted value
1778 * @v len Length of buffer
1779 * @ret len Length of formatted value, or negative error
1780 */
format_ipv6_setting(const struct setting_type * type __unused,const void * raw __unused,size_t raw_len __unused,char * buf __unused,size_t len __unused)1781 __weak int format_ipv6_setting ( const struct setting_type *type __unused,
1782 const void *raw __unused,
1783 size_t raw_len __unused, char *buf __unused,
1784 size_t len __unused ) {
1785 return -ENOTSUP;
1786 }
1787
1788 /** An IPv6 address setting type */
1789 const struct setting_type setting_type_ipv6 __setting_type = {
1790 .name = "ipv6",
1791 .parse = parse_ipv6_setting,
1792 .format = format_ipv6_setting,
1793 };
1794
1795 /** IPv6 settings scope */
1796 const struct settings_scope dhcpv6_scope;
1797
1798 /**
1799 * Integer setting type indices
1800 *
1801 * These indexes are defined such that (1<<index) gives the width of
1802 * the integer, in bytes.
1803 */
1804 enum setting_type_int_index {
1805 SETTING_TYPE_INT8 = 0,
1806 SETTING_TYPE_INT16 = 1,
1807 SETTING_TYPE_INT32 = 2,
1808 };
1809
1810 /**
1811 * Integer setting type names
1812 *
1813 * These names exist as a static array in order to allow the type's
1814 * integer size and signedness to be determined from the type's name.
1815 * Note that there are no separate entries for the signed integer
1816 * types: the name pointers simply point to the second character of
1817 * the relevant string.
1818 */
1819 static const char setting_type_int_name[][8] = {
1820 [SETTING_TYPE_INT8] = "uint8",
1821 [SETTING_TYPE_INT16] = "uint16",
1822 [SETTING_TYPE_INT32] = "uint32",
1823 };
1824
1825 /**
1826 * Get unsigned integer setting type name
1827 *
1828 * @v index Integer setting type index
1829 * @ret name Setting type name
1830 */
1831 #define SETTING_TYPE_UINT_NAME( index ) setting_type_int_name[index]
1832
1833 /**
1834 * Get signed integer setting type name
1835 *
1836 * @v index Integer setting type index
1837 * @ret name Setting type name
1838 */
1839 #define SETTING_TYPE_INT_NAME( index ) ( setting_type_int_name[index] + 1 )
1840
1841 /**
1842 * Get integer setting type index
1843 *
1844 * @v type Setting type
1845 * @ret index Integer setting type index
1846 */
setting_type_int_index(const struct setting_type * type)1847 static unsigned int setting_type_int_index ( const struct setting_type *type ) {
1848
1849 return ( ( type->name - setting_type_int_name[0] ) /
1850 sizeof ( setting_type_int_name[0] ) );
1851 }
1852
1853 /**
1854 * Get integer setting type width
1855 *
1856 * @v type Setting type
1857 * @ret index Integer setting type width
1858 */
setting_type_int_width(const struct setting_type * type)1859 static unsigned int setting_type_int_width ( const struct setting_type *type ) {
1860
1861 return ( 1 << setting_type_int_index ( type ) );
1862 }
1863
1864 /**
1865 * Get integer setting type signedness
1866 *
1867 * @v type Setting type
1868 * @ret is_signed Integer setting type is signed
1869 */
setting_type_int_is_signed(const struct setting_type * type)1870 static int setting_type_int_is_signed ( const struct setting_type *type ) {
1871 return ( ( type->name - setting_type_int_name[0] ) & 1 );
1872 }
1873
1874 /**
1875 * Convert number to setting value
1876 *
1877 * @v type Setting type
1878 * @v value Numeric value
1879 * @v buf Buffer to contain raw value
1880 * @v len Length of buffer
1881 * @ret len Length of raw value, or negative error
1882 */
denumerate_int_setting(const struct setting_type * type,unsigned long value,void * buf,size_t len)1883 static int denumerate_int_setting ( const struct setting_type *type,
1884 unsigned long value, void *buf,
1885 size_t len ) {
1886 unsigned int size = setting_type_int_width ( type );
1887 union {
1888 uint32_t num;
1889 uint8_t bytes[4];
1890 } u;
1891
1892 u.num = htonl ( value );
1893 if ( len > size )
1894 len = size;
1895 memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len );
1896
1897 return size;
1898 }
1899
1900 /**
1901 * Convert setting value to number
1902 *
1903 * @v type Setting type
1904 * @v raw Raw setting value
1905 * @v raw_len Length of raw setting value
1906 * @v value Numeric value to fill in
1907 * @ret rc Return status code
1908 */
numerate_int_setting(const struct setting_type * type,const void * raw,size_t raw_len,unsigned long * value)1909 static int numerate_int_setting ( const struct setting_type *type,
1910 const void *raw, size_t raw_len,
1911 unsigned long *value ) {
1912 int is_signed = setting_type_int_is_signed ( type );
1913 int check_len;
1914
1915 /* Extract numeric value */
1916 check_len = numeric_setting_value ( is_signed, raw, raw_len, value );
1917 if ( check_len < 0 )
1918 return check_len;
1919 assert ( check_len == ( int ) raw_len );
1920
1921 return 0;
1922 }
1923
1924 /**
1925 * Parse integer setting value
1926 *
1927 * @v type Setting type
1928 * @v value Formatted setting value
1929 * @v buf Buffer to contain raw value
1930 * @v len Length of buffer
1931 * @ret len Length of raw value, or negative error
1932 */
parse_int_setting(const struct setting_type * type,const char * value,void * buf,size_t len)1933 static int parse_int_setting ( const struct setting_type *type,
1934 const char *value, void *buf, size_t len ) {
1935 char *endp;
1936 unsigned long num_value;
1937
1938 /* Parse value */
1939 num_value = strtoul ( value, &endp, 0 );
1940 if ( *endp )
1941 return -EINVAL;
1942
1943 return type->denumerate ( type, num_value, buf, len );
1944 }
1945
1946 /**
1947 * Format signed integer setting value
1948 *
1949 * @v type Setting type
1950 * @v raw Raw setting value
1951 * @v raw_len Length of raw setting value
1952 * @v buf Buffer to contain formatted value
1953 * @v len Length of buffer
1954 * @ret len Length of formatted value, or negative error
1955 */
format_int_setting(const struct setting_type * type,const void * raw,size_t raw_len,char * buf,size_t len)1956 static int format_int_setting ( const struct setting_type *type,
1957 const void *raw, size_t raw_len,
1958 char *buf, size_t len ) {
1959 unsigned long value;
1960 int ret;
1961
1962 /* Extract numeric value */
1963 if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1964 return ret;
1965
1966 /* Format value */
1967 return snprintf ( buf, len, "%ld", value );
1968 }
1969
1970 /**
1971 * Format unsigned integer setting value
1972 *
1973 * @v type Setting type
1974 * @v raw Raw setting value
1975 * @v raw_len Length of raw setting value
1976 * @v buf Buffer to contain formatted value
1977 * @v len Length of buffer
1978 * @ret len Length of formatted value, or negative error
1979 */
format_uint_setting(const struct setting_type * type,const void * raw,size_t raw_len,char * buf,size_t len)1980 static int format_uint_setting ( const struct setting_type *type,
1981 const void *raw, size_t raw_len,
1982 char *buf, size_t len ) {
1983 unsigned long value;
1984 int ret;
1985
1986 /* Extract numeric value */
1987 if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1988 return ret;
1989
1990 /* Format value */
1991 return snprintf ( buf, len, "%#lx", value );
1992 }
1993
1994 /**
1995 * Define a signed integer setting type
1996 *
1997 * @v index Integer setting type index
1998 * @ret type Setting type
1999 */
2000 #define SETTING_TYPE_INT( index ) { \
2001 .name = SETTING_TYPE_INT_NAME ( index ), \
2002 .parse = parse_int_setting, \
2003 .format = format_int_setting, \
2004 .denumerate = denumerate_int_setting, \
2005 .numerate = numerate_int_setting, \
2006 }
2007
2008 /**
2009 * Define an unsigned integer setting type
2010 *
2011 * @v index Integer setting type index
2012 * @ret type Setting type
2013 */
2014 #define SETTING_TYPE_UINT( index ) { \
2015 .name = SETTING_TYPE_UINT_NAME ( index ), \
2016 .parse = parse_int_setting, \
2017 .format = format_uint_setting, \
2018 .denumerate = denumerate_int_setting, \
2019 .numerate = numerate_int_setting, \
2020 }
2021
2022 /** A signed 8-bit integer setting type */
2023 const struct setting_type setting_type_int8 __setting_type =
2024 SETTING_TYPE_INT ( SETTING_TYPE_INT8 );
2025
2026 /** A signed 16-bit integer setting type */
2027 const struct setting_type setting_type_int16 __setting_type =
2028 SETTING_TYPE_INT ( SETTING_TYPE_INT16 );
2029
2030 /** A signed 32-bit integer setting type */
2031 const struct setting_type setting_type_int32 __setting_type =
2032 SETTING_TYPE_INT ( SETTING_TYPE_INT32 );
2033
2034 /** An unsigned 8-bit integer setting type */
2035 const struct setting_type setting_type_uint8 __setting_type =
2036 SETTING_TYPE_UINT ( SETTING_TYPE_INT8 );
2037
2038 /** An unsigned 16-bit integer setting type */
2039 const struct setting_type setting_type_uint16 __setting_type =
2040 SETTING_TYPE_UINT ( SETTING_TYPE_INT16 );
2041
2042 /** An unsigned 32-bit integer setting type */
2043 const struct setting_type setting_type_uint32 __setting_type =
2044 SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
2045
2046 /**
2047 * Parse hex string setting value (using colon delimiter)
2048 *
2049 * @v type Setting type
2050 * @v value Formatted setting value
2051 * @v buf Buffer to contain raw value
2052 * @v len Length of buffer
2053 * @v size Integer size, in bytes
2054 * @ret len Length of raw value, or negative error
2055 */
parse_hex_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2056 static int parse_hex_setting ( const struct setting_type *type __unused,
2057 const char *value, void *buf, size_t len ) {
2058 return hex_decode ( ':', value, buf, len );
2059 }
2060
2061 /**
2062 * Format hex string setting value (using colon delimiter)
2063 *
2064 * @v type Setting type
2065 * @v raw Raw setting value
2066 * @v raw_len Length of raw setting value
2067 * @v buf Buffer to contain formatted value
2068 * @v len Length of buffer
2069 * @ret len Length of formatted value, or negative error
2070 */
format_hex_colon_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2071 static int format_hex_colon_setting ( const struct setting_type *type __unused,
2072 const void *raw, size_t raw_len,
2073 char *buf, size_t len ) {
2074 return hex_encode ( ':', raw, raw_len, buf, len );
2075 }
2076
2077 /**
2078 * Parse hex string setting value (using hyphen delimiter)
2079 *
2080 * @v type Setting type
2081 * @v value Formatted setting value
2082 * @v buf Buffer to contain raw value
2083 * @v len Length of buffer
2084 * @v size Integer size, in bytes
2085 * @ret len Length of raw value, or negative error
2086 */
parse_hex_hyphen_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2087 static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
2088 const char *value, void *buf,
2089 size_t len ) {
2090 return hex_decode ( '-', value, buf, len );
2091 }
2092
2093 /**
2094 * Format hex string setting value (using hyphen delimiter)
2095 *
2096 * @v type Setting type
2097 * @v raw Raw setting value
2098 * @v raw_len Length of raw setting value
2099 * @v buf Buffer to contain formatted value
2100 * @v len Length of buffer
2101 * @ret len Length of formatted value, or negative error
2102 */
format_hex_hyphen_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2103 static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
2104 const void *raw, size_t raw_len,
2105 char *buf, size_t len ) {
2106 return hex_encode ( '-', raw, raw_len, buf, len );
2107 }
2108
2109 /**
2110 * Parse hex string setting value (using no delimiter)
2111 *
2112 * @v type Setting type
2113 * @v value Formatted setting value
2114 * @v buf Buffer to contain raw value
2115 * @v len Length of buffer
2116 * @v size Integer size, in bytes
2117 * @ret len Length of raw value, or negative error
2118 */
parse_hex_raw_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2119 static int parse_hex_raw_setting ( const struct setting_type *type __unused,
2120 const char *value, void *buf, size_t len ) {
2121 return hex_decode ( 0, value, buf, len );
2122 }
2123
2124 /**
2125 * Format hex string setting value (using no delimiter)
2126 *
2127 * @v type Setting type
2128 * @v raw Raw setting value
2129 * @v raw_len Length of raw setting value
2130 * @v buf Buffer to contain formatted value
2131 * @v len Length of buffer
2132 * @ret len Length of formatted value, or negative error
2133 */
format_hex_raw_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2134 static int format_hex_raw_setting ( const struct setting_type *type __unused,
2135 const void *raw, size_t raw_len,
2136 char *buf, size_t len ) {
2137 return hex_encode ( 0, raw, raw_len, buf, len );
2138 }
2139
2140 /** A hex-string setting (colon-delimited) */
2141 const struct setting_type setting_type_hex __setting_type = {
2142 .name = "hex",
2143 .parse = parse_hex_setting,
2144 .format = format_hex_colon_setting,
2145 };
2146
2147 /** A hex-string setting (hyphen-delimited) */
2148 const struct setting_type setting_type_hexhyp __setting_type = {
2149 .name = "hexhyp",
2150 .parse = parse_hex_hyphen_setting,
2151 .format = format_hex_hyphen_setting,
2152 };
2153
2154 /** A hex-string setting (non-delimited) */
2155 const struct setting_type setting_type_hexraw __setting_type = {
2156 .name = "hexraw",
2157 .parse = parse_hex_raw_setting,
2158 .format = format_hex_raw_setting,
2159 };
2160
2161 /**
2162 * Parse Base64-encoded setting value
2163 *
2164 * @v type Setting type
2165 * @v value Formatted setting value
2166 * @v buf Buffer to contain raw value
2167 * @v len Length of buffer
2168 * @v size Integer size, in bytes
2169 * @ret len Length of raw value, or negative error
2170 */
parse_base64_setting(const struct setting_type * type __unused,const char * value,void * buf,size_t len)2171 static int parse_base64_setting ( const struct setting_type *type __unused,
2172 const char *value, void *buf, size_t len ) {
2173
2174 return base64_decode ( value, buf, len );
2175 }
2176
2177 /**
2178 * Format Base64-encoded setting value
2179 *
2180 * @v type Setting type
2181 * @v raw Raw setting value
2182 * @v raw_len Length of raw setting value
2183 * @v buf Buffer to contain formatted value
2184 * @v len Length of buffer
2185 * @ret len Length of formatted value, or negative error
2186 */
format_base64_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2187 static int format_base64_setting ( const struct setting_type *type __unused,
2188 const void *raw, size_t raw_len,
2189 char *buf, size_t len ) {
2190
2191 return base64_encode ( raw, raw_len, buf, len );
2192 }
2193
2194 /** A Base64-encoded setting */
2195 const struct setting_type setting_type_base64 __setting_type = {
2196 .name = "base64",
2197 .parse = parse_base64_setting,
2198 .format = format_base64_setting,
2199 };
2200
2201 /**
2202 * Format UUID setting value
2203 *
2204 * @v type Setting type
2205 * @v raw Raw setting value
2206 * @v raw_len Length of raw setting value
2207 * @v buf Buffer to contain formatted value
2208 * @v len Length of buffer
2209 * @ret len Length of formatted value, or negative error
2210 */
format_uuid_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2211 static int format_uuid_setting ( const struct setting_type *type __unused,
2212 const void *raw, size_t raw_len, char *buf,
2213 size_t len ) {
2214 const union uuid *uuid = raw;
2215
2216 /* Range check */
2217 if ( raw_len != sizeof ( *uuid ) )
2218 return -ERANGE;
2219
2220 /* Format value */
2221 return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) );
2222 }
2223
2224 /** UUID setting type */
2225 const struct setting_type setting_type_uuid __setting_type = {
2226 .name = "uuid",
2227 .format = format_uuid_setting,
2228 };
2229
2230 /**
2231 * Format PCI bus:dev.fn setting value
2232 *
2233 * @v type Setting type
2234 * @v raw Raw setting value
2235 * @v raw_len Length of raw setting value
2236 * @v buf Buffer to contain formatted value
2237 * @v len Length of buffer
2238 * @ret len Length of formatted value, or negative error
2239 */
format_busdevfn_setting(const struct setting_type * type __unused,const void * raw,size_t raw_len,char * buf,size_t len)2240 static int format_busdevfn_setting ( const struct setting_type *type __unused,
2241 const void *raw, size_t raw_len, char *buf,
2242 size_t len ) {
2243 unsigned long busdevfn;
2244 unsigned int seg;
2245 unsigned int bus;
2246 unsigned int slot;
2247 unsigned int func;
2248 int check_len;
2249
2250 /* Extract numeric value */
2251 check_len = numeric_setting_value ( 0, raw, raw_len, &busdevfn );
2252 if ( check_len < 0 )
2253 return check_len;
2254 assert ( check_len == ( int ) raw_len );
2255
2256 /* Extract PCI address components */
2257 seg = PCI_SEG ( busdevfn );
2258 bus = PCI_BUS ( busdevfn );
2259 slot = PCI_SLOT ( busdevfn );
2260 func = PCI_FUNC ( busdevfn );
2261
2262 /* Format value */
2263 return snprintf ( buf, len, "%04x:%02x:%02x.%x", seg, bus, slot, func );
2264 }
2265
2266 /** PCI bus:dev.fn setting type */
2267 const struct setting_type setting_type_busdevfn __setting_type = {
2268 .name = "busdevfn",
2269 .format = format_busdevfn_setting,
2270 };
2271
2272 /******************************************************************************
2273 *
2274 * Setting expansion
2275 *
2276 ******************************************************************************
2277 */
2278
2279 /**
2280 * Expand variables within string
2281 *
2282 * @v string String
2283 * @ret expstr Expanded string
2284 *
2285 * The expanded string is allocated with malloc() and the caller must
2286 * eventually free() it.
2287 */
expand_settings(const char * string)2288 char * expand_settings ( const char *string ) {
2289 struct settings *settings;
2290 struct setting setting;
2291 char *expstr;
2292 char *start;
2293 char *end;
2294 char *head;
2295 char *name;
2296 char *tail;
2297 char *value;
2298 char *tmp;
2299 int new_len;
2300 int rc;
2301
2302 /* Obtain temporary modifiable copy of string */
2303 expstr = strdup ( string );
2304 if ( ! expstr )
2305 return NULL;
2306
2307 /* Expand while expansions remain */
2308 while ( 1 ) {
2309
2310 head = expstr;
2311
2312 /* Locate setting to be expanded */
2313 start = NULL;
2314 end = NULL;
2315 for ( tmp = expstr ; *tmp ; tmp++ ) {
2316 if ( ( tmp[0] == '$' ) && ( tmp[1] == '{' ) )
2317 start = tmp;
2318 if ( start && ( tmp[0] == '}' ) ) {
2319 end = tmp;
2320 break;
2321 }
2322 }
2323 if ( ! end )
2324 break;
2325 *start = '\0';
2326 name = ( start + 2 );
2327 *end = '\0';
2328 tail = ( end + 1 );
2329
2330 /* Expand setting */
2331 if ( ( rc = parse_setting_name ( name, find_child_settings,
2332 &settings,
2333 &setting ) ) != 0 ) {
2334 /* Treat invalid setting names as empty */
2335 value = NULL;
2336 } else {
2337 /* Fetch and format setting value. Ignore
2338 * errors; treat non-existent settings as empty.
2339 */
2340 fetchf_setting_copy ( settings, &setting, NULL, NULL,
2341 &value );
2342 }
2343
2344 /* Construct expanded string and discard old string */
2345 tmp = expstr;
2346 new_len = asprintf ( &expstr, "%s%s%s",
2347 head, ( value ? value : "" ), tail );
2348 free ( value );
2349 free ( tmp );
2350 if ( new_len < 0 )
2351 return NULL;
2352 }
2353
2354 return expstr;
2355 }
2356
2357 /******************************************************************************
2358 *
2359 * Settings
2360 *
2361 ******************************************************************************
2362 */
2363
2364 /** Hostname setting */
2365 const struct setting hostname_setting __setting ( SETTING_HOST, hostname ) = {
2366 .name = "hostname",
2367 .description = "Host name",
2368 .tag = DHCP_HOST_NAME,
2369 .type = &setting_type_string,
2370 };
2371
2372 /** Domain name setting */
2373 const struct setting domain_setting __setting ( SETTING_IP_EXTRA, domain ) = {
2374 .name = "domain",
2375 .description = "DNS domain",
2376 .tag = DHCP_DOMAIN_NAME,
2377 .type = &setting_type_string,
2378 };
2379
2380 /** TFTP server setting */
2381 const struct setting next_server_setting __setting ( SETTING_BOOT,next-server)={
2382 .name = "next-server",
2383 .description = "TFTP server",
2384 .tag = DHCP_EB_SIADDR,
2385 .type = &setting_type_ipv4,
2386 };
2387
2388 /** Filename setting */
2389 const struct setting filename_setting __setting ( SETTING_BOOT, filename ) = {
2390 .name = "filename",
2391 .description = "Boot filename",
2392 .tag = DHCP_BOOTFILE_NAME,
2393 .type = &setting_type_string,
2394 };
2395
2396 /** Root path setting */
2397 const struct setting root_path_setting __setting ( SETTING_SANBOOT, root-path)={
2398 .name = "root-path",
2399 .description = "SAN root path",
2400 .tag = DHCP_ROOT_PATH,
2401 .type = &setting_type_string,
2402 };
2403
2404 /** SAN filename setting */
2405 const struct setting san_filename_setting __setting ( SETTING_SANBOOT,
2406 san-filename ) = {
2407 .name = "san-filename",
2408 .description = "SAN filename",
2409 .tag = DHCP_EB_SAN_FILENAME,
2410 .type = &setting_type_string,
2411 };
2412
2413 /** Username setting */
2414 const struct setting username_setting __setting ( SETTING_AUTH, username ) = {
2415 .name = "username",
2416 .description = "User name",
2417 .tag = DHCP_EB_USERNAME,
2418 .type = &setting_type_string,
2419 };
2420
2421 /** Password setting */
2422 const struct setting password_setting __setting ( SETTING_AUTH, password ) = {
2423 .name = "password",
2424 .description = "Password",
2425 .tag = DHCP_EB_PASSWORD,
2426 .type = &setting_type_string,
2427 };
2428
2429 /** Priority setting */
2430 const struct setting priority_setting __setting ( SETTING_MISC, priority ) = {
2431 .name = "priority",
2432 .description = "Settings priority",
2433 .tag = DHCP_EB_PRIORITY,
2434 .type = &setting_type_int8,
2435 };
2436
2437 /** DHCP user class setting */
2438 const struct setting user_class_setting __setting ( SETTING_HOST_EXTRA,
2439 user-class ) = {
2440 .name = "user-class",
2441 .description = "DHCP user class",
2442 .tag = DHCP_USER_CLASS_ID,
2443 .type = &setting_type_string,
2444 };
2445
2446 /** DHCP vendor class setting */
2447 const struct setting vendor_class_setting __setting ( SETTING_HOST_EXTRA,
2448 vendor-class ) = {
2449 .name = "vendor-class",
2450 .description = "DHCP vendor class",
2451 .tag = DHCP_VENDOR_CLASS_ID,
2452 .type = &setting_type_string,
2453 };
2454
2455 /******************************************************************************
2456 *
2457 * Built-in settings block
2458 *
2459 ******************************************************************************
2460 */
2461
2462 /** Built-in setting scope */
2463 const struct settings_scope builtin_scope;
2464
2465 /**
2466 * Fetch error number setting
2467 *
2468 * @v data Buffer to fill with setting data
2469 * @v len Length of buffer
2470 * @ret len Length of setting data, or negative error
2471 */
errno_fetch(void * data,size_t len)2472 static int errno_fetch ( void *data, size_t len ) {
2473 uint32_t content;
2474
2475 /* Return current error */
2476 content = htonl ( errno );
2477 if ( len > sizeof ( content ) )
2478 len = sizeof ( content );
2479 memcpy ( data, &content, len );
2480 return sizeof ( content );
2481 }
2482
2483 /** Error number setting */
2484 const struct setting errno_setting __setting ( SETTING_MISC, errno ) = {
2485 .name = "errno",
2486 .description = "Last error",
2487 .type = &setting_type_uint32,
2488 .scope = &builtin_scope,
2489 };
2490
2491 /** Error number built-in setting */
2492 struct builtin_setting errno_builtin_setting __builtin_setting = {
2493 .setting = &errno_setting,
2494 .fetch = errno_fetch,
2495 };
2496
2497 /**
2498 * Fetch build architecture setting
2499 *
2500 * @v data Buffer to fill with setting data
2501 * @v len Length of buffer
2502 * @ret len Length of setting data, or negative error
2503 */
buildarch_fetch(void * data,size_t len)2504 static int buildarch_fetch ( void *data, size_t len ) {
2505 static const char buildarch[] = _S2 ( ARCH );
2506
2507 strncpy ( data, buildarch, len );
2508 return ( sizeof ( buildarch ) - 1 /* NUL */ );
2509 }
2510
2511 /** Build architecture setting */
2512 const struct setting buildarch_setting __setting ( SETTING_MISC, buildarch ) = {
2513 .name = "buildarch",
2514 .description = "Build architecture",
2515 .type = &setting_type_string,
2516 .scope = &builtin_scope,
2517 };
2518
2519 /** Build architecture built-in setting */
2520 struct builtin_setting buildarch_builtin_setting __builtin_setting = {
2521 .setting = &buildarch_setting,
2522 .fetch = buildarch_fetch,
2523 };
2524
2525 /**
2526 * Fetch platform setting
2527 *
2528 * @v data Buffer to fill with setting data
2529 * @v len Length of buffer
2530 * @ret len Length of setting data, or negative error
2531 */
platform_fetch(void * data,size_t len)2532 static int platform_fetch ( void *data, size_t len ) {
2533 static const char platform[] = _S2 ( PLATFORM );
2534
2535 strncpy ( data, platform, len );
2536 return ( sizeof ( platform ) - 1 /* NUL */ );
2537 }
2538
2539 /** Platform setting */
2540 const struct setting platform_setting __setting ( SETTING_MISC, platform ) = {
2541 .name = "platform",
2542 .description = "Platform",
2543 .type = &setting_type_string,
2544 .scope = &builtin_scope,
2545 };
2546
2547 /** Platform built-in setting */
2548 struct builtin_setting platform_builtin_setting __builtin_setting = {
2549 .setting = &platform_setting,
2550 .fetch = platform_fetch,
2551 };
2552
2553 /**
2554 * Fetch version setting
2555 *
2556 * @v data Buffer to fill with setting data
2557 * @v len Length of buffer
2558 * @ret len Length of setting data, or negative error
2559 */
version_fetch(void * data,size_t len)2560 static int version_fetch ( void *data, size_t len ) {
2561 strncpy ( data, product_version, len );
2562 return ( strlen ( product_version ) );
2563 }
2564
2565 /** Version setting */
2566 const struct setting version_setting __setting ( SETTING_MISC, version ) = {
2567 .name = "version",
2568 .description = "Version",
2569 .type = &setting_type_string,
2570 .scope = &builtin_scope,
2571 };
2572
2573 /** Version built-in setting */
2574 struct builtin_setting version_builtin_setting __builtin_setting = {
2575 .setting = &version_setting,
2576 .fetch = version_fetch,
2577 };
2578
2579 /**
2580 * Fetch current time setting
2581 *
2582 * @v data Buffer to fill with setting data
2583 * @v len Length of buffer
2584 * @ret len Length of setting data, or negative error
2585 */
unixtime_fetch(void * data,size_t len)2586 static int unixtime_fetch ( void *data, size_t len ) {
2587 uint32_t content;
2588
2589 /* Return current time */
2590 content = htonl ( time(NULL) );
2591 if ( len > sizeof ( content ) )
2592 len = sizeof ( content );
2593 memcpy ( data, &content, len );
2594 return sizeof ( content );
2595 }
2596
2597 /** Current time setting */
2598 const struct setting unixtime_setting __setting ( SETTING_MISC, unixtime ) = {
2599 .name = "unixtime",
2600 .description = "Seconds since the Epoch",
2601 .type = &setting_type_uint32,
2602 .scope = &builtin_scope,
2603 };
2604
2605 /** Current time built-in setting */
2606 struct builtin_setting unixtime_builtin_setting __builtin_setting = {
2607 .setting = &unixtime_setting,
2608 .fetch = unixtime_fetch,
2609 };
2610
2611 /**
2612 * Fetch built-in setting
2613 *
2614 * @v settings Settings block
2615 * @v setting Setting to fetch
2616 * @v data Buffer to fill with setting data
2617 * @v len Length of buffer
2618 * @ret len Length of setting data, or negative error
2619 */
builtin_fetch(struct settings * settings __unused,struct setting * setting,void * data,size_t len)2620 static int builtin_fetch ( struct settings *settings __unused,
2621 struct setting *setting,
2622 void *data, size_t len ) {
2623 struct builtin_setting *builtin;
2624
2625 for_each_table_entry ( builtin, BUILTIN_SETTINGS ) {
2626 if ( setting_cmp ( setting, builtin->setting ) == 0 )
2627 return builtin->fetch ( data, len );
2628 }
2629 return -ENOENT;
2630 }
2631
2632 /**
2633 * Check applicability of built-in setting
2634 *
2635 * @v settings Settings block
2636 * @v setting Setting
2637 * @ret applies Setting applies within this settings block
2638 */
builtin_applies(struct settings * settings __unused,const struct setting * setting)2639 static int builtin_applies ( struct settings *settings __unused,
2640 const struct setting *setting ) {
2641
2642 return ( setting->scope == &builtin_scope );
2643 }
2644
2645 /** Built-in settings operations */
2646 static struct settings_operations builtin_settings_operations = {
2647 .applies = builtin_applies,
2648 .fetch = builtin_fetch,
2649 };
2650
2651 /** Built-in settings */
2652 static struct settings builtin_settings = {
2653 .refcnt = NULL,
2654 .siblings = LIST_HEAD_INIT ( builtin_settings.siblings ),
2655 .children = LIST_HEAD_INIT ( builtin_settings.children ),
2656 .op = &builtin_settings_operations,
2657 };
2658
2659 /** Initialise built-in settings */
builtin_init(void)2660 static void builtin_init ( void ) {
2661 int rc;
2662
2663 if ( ( rc = register_settings ( &builtin_settings, NULL,
2664 "builtin" ) ) != 0 ) {
2665 DBG ( "Could not register built-in settings: %s\n",
2666 strerror ( rc ) );
2667 return;
2668 }
2669 }
2670
2671 /** Built-in settings initialiser */
2672 struct init_fn builtin_init_fn __init_fn ( INIT_NORMAL ) = {
2673 .initialise = builtin_init,
2674 };
2675