|
@@ -25,6 +25,7 @@
|
25
|
25
|
#include <errno.h>
|
26
|
26
|
#include <assert.h>
|
27
|
27
|
#include <gpxe/in.h>
|
|
28
|
+#include <gpxe/vsprintf.h>
|
28
|
29
|
#include <gpxe/settings.h>
|
29
|
30
|
|
30
|
31
|
/** @file
|
|
@@ -45,6 +46,8 @@ static struct config_setting config_settings[0]
|
45
|
46
|
static struct config_setting config_settings_end[0]
|
46
|
47
|
__table_end ( struct config_setting, config_settings );
|
47
|
48
|
|
|
49
|
+struct config_setting_type config_setting_type_hex __config_setting_type;
|
|
50
|
+
|
48
|
51
|
/**
|
49
|
52
|
* Find configuration setting type
|
50
|
53
|
*
|
|
@@ -108,9 +111,16 @@ find_or_build_config_setting ( const char *name,
|
108
|
111
|
memset ( setting, 0, sizeof ( *setting ) );
|
109
|
112
|
setting->name = name;
|
110
|
113
|
setting->tag = strtoul ( name, &separator, 10 );
|
111
|
|
- if ( *separator != '.' )
|
112
|
|
- return NULL;
|
113
|
|
- setting->type = find_config_setting_type ( separator + 1 );
|
|
114
|
+ switch ( *separator ) {
|
|
115
|
+ case '.' :
|
|
116
|
+ setting->type = find_config_setting_type ( separator + 1 );
|
|
117
|
+ break;
|
|
118
|
+ case '\0' :
|
|
119
|
+ setting->type = &config_setting_type_hex;
|
|
120
|
+ break;
|
|
121
|
+ default :
|
|
122
|
+ break;
|
|
123
|
+ }
|
114
|
124
|
if ( ! setting->type )
|
115
|
125
|
return NULL;
|
116
|
126
|
return setting;
|
|
@@ -340,11 +350,41 @@ static int set_int ( struct config_context *context,
|
340
|
350
|
* @ret rc Return status code
|
341
|
351
|
*/
|
342
|
352
|
static int set_int8 ( struct config_context *context,
|
343
|
|
- struct config_setting *setting,
|
344
|
|
- const char *value ) {
|
|
353
|
+ struct config_setting *setting,
|
|
354
|
+ const char *value ) {
|
345
|
355
|
return set_int ( context, setting, value, 1 );
|
346
|
356
|
}
|
347
|
357
|
|
|
358
|
+/**
|
|
359
|
+ * Set value of 16-bit integer setting
|
|
360
|
+ *
|
|
361
|
+ * @v context Configuration context
|
|
362
|
+ * @v setting Configuration setting
|
|
363
|
+ * @v value Setting value (as a string)
|
|
364
|
+ * @v size Size of integer (in bytes)
|
|
365
|
+ * @ret rc Return status code
|
|
366
|
+ */
|
|
367
|
+static int set_int16 ( struct config_context *context,
|
|
368
|
+ struct config_setting *setting,
|
|
369
|
+ const char *value ) {
|
|
370
|
+ return set_int ( context, setting, value, 2 );
|
|
371
|
+}
|
|
372
|
+
|
|
373
|
+/**
|
|
374
|
+ * Set value of 32-bit integer setting
|
|
375
|
+ *
|
|
376
|
+ * @v context Configuration context
|
|
377
|
+ * @v setting Configuration setting
|
|
378
|
+ * @v value Setting value (as a string)
|
|
379
|
+ * @v size Size of integer (in bytes)
|
|
380
|
+ * @ret rc Return status code
|
|
381
|
+ */
|
|
382
|
+static int set_int32 ( struct config_context *context,
|
|
383
|
+ struct config_setting *setting,
|
|
384
|
+ const char *value ) {
|
|
385
|
+ return set_int ( context, setting, value, 4 );
|
|
386
|
+}
|
|
387
|
+
|
348
|
388
|
/** An 8-bit integer configuration setting */
|
349
|
389
|
struct config_setting_type config_setting_type_int8 __config_setting_type = {
|
350
|
390
|
.name = "int8",
|
|
@@ -353,6 +393,92 @@ struct config_setting_type config_setting_type_int8 __config_setting_type = {
|
353
|
393
|
.set = set_int8,
|
354
|
394
|
};
|
355
|
395
|
|
|
396
|
+/** A 16-bit integer configuration setting */
|
|
397
|
+struct config_setting_type config_setting_type_int16 __config_setting_type = {
|
|
398
|
+ .name = "int16",
|
|
399
|
+ .description = "16-bit integer",
|
|
400
|
+ .show = show_int,
|
|
401
|
+ .set = set_int16,
|
|
402
|
+};
|
|
403
|
+
|
|
404
|
+/** A 32-bit integer configuration setting */
|
|
405
|
+struct config_setting_type config_setting_type_int32 __config_setting_type = {
|
|
406
|
+ .name = "int32",
|
|
407
|
+ .description = "32-bit integer",
|
|
408
|
+ .show = show_int,
|
|
409
|
+ .set = set_int32,
|
|
410
|
+};
|
|
411
|
+
|
|
412
|
+/**
|
|
413
|
+ * Set value of hex-string setting
|
|
414
|
+ *
|
|
415
|
+ * @v context Configuration context
|
|
416
|
+ * @v setting Configuration setting
|
|
417
|
+ * @v value Setting value (as a string)
|
|
418
|
+ * @ret rc Return status code
|
|
419
|
+ */
|
|
420
|
+static int set_hex ( struct config_context *context,
|
|
421
|
+ struct config_setting *setting,
|
|
422
|
+ const char *value ) {
|
|
423
|
+ struct dhcp_option *option;
|
|
424
|
+ char *ptr = ( char * ) value;
|
|
425
|
+ uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
|
|
426
|
+ unsigned int len = 0;
|
|
427
|
+
|
|
428
|
+ while ( 1 ) {
|
|
429
|
+ bytes[len++] = strtoul ( ptr, &ptr, 16 );
|
|
430
|
+ switch ( *ptr ) {
|
|
431
|
+ case '\0' :
|
|
432
|
+ option = set_dhcp_option ( context->options,
|
|
433
|
+ setting->tag, bytes, len );
|
|
434
|
+ if ( ! option )
|
|
435
|
+ return -ENOSPC;
|
|
436
|
+ return 0;
|
|
437
|
+ case ':' :
|
|
438
|
+ ptr++;
|
|
439
|
+ break;
|
|
440
|
+ default :
|
|
441
|
+ return -EINVAL;
|
|
442
|
+ }
|
|
443
|
+ }
|
|
444
|
+}
|
|
445
|
+
|
|
446
|
+/**
|
|
447
|
+ * Show value of hex-string setting
|
|
448
|
+ *
|
|
449
|
+ * @v context Configuration context
|
|
450
|
+ * @v setting Configuration setting
|
|
451
|
+ * @v buf Buffer to contain value
|
|
452
|
+ * @v len Length of buffer
|
|
453
|
+ * @ret len Length of formatted value, or negative error
|
|
454
|
+ */
|
|
455
|
+static int show_hex ( struct config_context *context,
|
|
456
|
+ struct config_setting *setting,
|
|
457
|
+ char *buf, size_t len ) {
|
|
458
|
+ struct dhcp_option *option;
|
|
459
|
+ int used = 0;
|
|
460
|
+ int i;
|
|
461
|
+
|
|
462
|
+ option = find_dhcp_option ( context->options, setting->tag );
|
|
463
|
+ if ( ! option )
|
|
464
|
+ return -ENODATA;
|
|
465
|
+
|
|
466
|
+ for ( i = 0 ; i < option->len ; i++ ) {
|
|
467
|
+ used += ssnprintf ( ( buf + used ), ( len - used ),
|
|
468
|
+ "%s%02x", ( used ? ":" : "" ),
|
|
469
|
+ option->data.bytes[i] );
|
|
470
|
+ }
|
|
471
|
+ return used;
|
|
472
|
+}
|
|
473
|
+
|
|
474
|
+/** A hex-string configuration setting */
|
|
475
|
+struct config_setting_type config_setting_type_hex __config_setting_type = {
|
|
476
|
+ .name = "hex",
|
|
477
|
+ .description = "Hex string",
|
|
478
|
+ .show = show_hex,
|
|
479
|
+ .set = set_hex,
|
|
480
|
+};
|
|
481
|
+
|
356
|
482
|
/** Some basic setting definitions */
|
357
|
483
|
struct config_setting basic_config_settings[] __config_setting = {
|
358
|
484
|
{
|