diff --git a/src/arch/i386/image/nbi.c b/src/arch/i386/image/nbi.c index 79dc8d1a..73791be9 100644 --- a/src/arch/i386/image/nbi.c +++ b/src/arch/i386/image/nbi.c @@ -8,8 +8,7 @@ #include #include #include -#include -#include +#include #include #include @@ -400,8 +399,8 @@ static int nbi_prepare_dhcp ( struct image *image ) { return -ENODEV; } - if ( ( rc = create_dhcpack ( boot_netdev, basemem_packet, - sizeof ( basemem_packet ) ) ) != 0 ) { + if ( ( rc = create_fakedhcpack ( boot_netdev, basemem_packet, + sizeof ( basemem_packet ) ) ) != 0 ) { DBGC ( image, "NBI %p failed to build DHCP packet\n", image ); return rc; } diff --git a/src/core/ibft.c b/src/core/ibft.c index 61e00a8d..fda14704 100644 --- a/src/core/ibft.c +++ b/src/core/ibft.c @@ -123,15 +123,16 @@ static void ibft_set_ipaddr ( struct ibft_ipaddr *ipaddr, struct in_addr in ) { } /** - * Fill in an IP address within iBFT from DHCP option + * Fill in an IP address within iBFT from configuration setting * * @v ipaddr IP address field + * @v setting Configuration setting * @v tag DHCP option tag */ static void ibft_set_ipaddr_option ( struct ibft_ipaddr *ipaddr, - unsigned int tag ) { + struct setting *setting ) { struct in_addr in = { 0 }; - fetch_ipv4_setting ( NULL, tag, &in ); + fetch_ipv4_setting ( NULL, setting, &in ); ibft_set_ipaddr ( ipaddr, in ); } @@ -182,21 +183,21 @@ static int ibft_set_string ( struct ibft_string_block *strings, } /** - * Fill in a string field within iBFT from DHCP option + * Fill in a string field within iBFT from configuration setting * * @v strings iBFT string block descriptor * @v string String field - * @v tag DHCP option tag + * @v setting Configuration setting * @ret rc Return status code */ static int ibft_set_string_option ( struct ibft_string_block *strings, struct ibft_string *string, - unsigned int tag ) { + struct setting *setting ) { int len; char *dest; int rc; - len = fetch_setting_len ( NULL, tag ); + len = fetch_setting_len ( NULL, setting ); if ( len < 0 ) { string->offset = 0; string->length = 0; @@ -206,7 +207,7 @@ static int ibft_set_string_option ( struct ibft_string_block *strings, if ( ( rc = ibft_alloc_string ( strings, string, len ) ) != 0 ) return rc; dest = ( ( ( char * ) strings->table ) + string->offset ); - fetch_string_setting ( NULL, tag, dest, ( len + 1 ) ); + fetch_string_setting ( NULL, setting, dest, ( len + 1 ) ); return 0; } @@ -226,15 +227,15 @@ static int ibft_fill_nic ( struct ibft_nic *nic, int rc; /* Extract values from DHCP configuration */ - ibft_set_ipaddr_option ( &nic->ip_address, DHCP_EB_YIADDR ); - ibft_set_ipaddr_option ( &nic->gateway, DHCP_ROUTERS ); - ibft_set_ipaddr_option ( &nic->dns[0], DHCP_DNS_SERVERS ); + ibft_set_ipaddr_option ( &nic->ip_address, &ip_setting ); + ibft_set_ipaddr_option ( &nic->gateway, &gateway_setting ); + ibft_set_ipaddr_option ( &nic->dns[0], &dns_setting ); if ( ( rc = ibft_set_string_option ( strings, &nic->hostname, - DHCP_HOST_NAME ) ) != 0 ) + &hostname_setting ) ) != 0 ) return rc; /* Derive subnet mask prefix from subnet mask */ - fetch_ipv4_setting ( NULL, DHCP_SUBNET_MASK, &netmask_addr ); + fetch_ipv4_setting ( NULL, &netmask_setting, &netmask_addr ); while ( netmask_addr.s_addr ) { if ( netmask_addr.s_addr & 0x1 ) netmask_count++; diff --git a/src/core/nvo.c b/src/core/nvo.c index 951539f1..13078022 100644 --- a/src/core/nvo.c +++ b/src/core/nvo.c @@ -138,19 +138,20 @@ static void nvo_init_dhcpopts ( struct nvo_block *nvo ) { * Store value of NVO setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ -static int nvo_store ( struct settings *settings, unsigned int tag, +static int nvo_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { struct nvo_block *nvo = container_of ( settings, struct nvo_block, settings ); int rc; /* Update stored options */ - if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, tag, data, len ) ) != 0 ) { + if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, setting->tag, + data, len ) ) != 0 ) { DBGC ( nvo, "NVO %p could not store %zd bytes: %s\n", nvo, len, strerror ( rc ) ); return rc; @@ -167,7 +168,7 @@ static int nvo_store ( struct settings *settings, unsigned int tag, * Fetch value of NVO setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error @@ -175,12 +176,12 @@ static int nvo_store ( struct settings *settings, unsigned int tag, * The actual length of the setting will be returned even if * the buffer was too small. */ -static int nvo_fetch ( struct settings *settings, unsigned int tag, +static int nvo_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct nvo_block *nvo = container_of ( settings, struct nvo_block, settings ); - return dhcpopt_fetch ( &nvo->dhcpopts, tag, data, len ); + return dhcpopt_fetch ( &nvo->dhcpopts, setting->tag, data, len ); } /** NVO settings operations */ diff --git a/src/core/settings.c b/src/core/settings.c index 809779ae..b793ae68 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -35,43 +35,24 @@ * */ +/** Registered settings */ +static struct setting settings[0] + __table_start ( struct setting, settings ); +static struct setting settings_end[0] + __table_end ( struct setting, settings ); + /** Registered setting types */ static struct setting_type setting_types[0] __table_start ( struct setting_type, setting_types ); static struct setting_type setting_types_end[0] __table_end ( struct setting_type, setting_types ); -/** Registered named settings */ -static struct named_setting named_settings[0] - __table_start ( struct named_setting, named_settings ); -static struct named_setting named_settings_end[0] - __table_end ( struct named_setting, named_settings ); - /** Registered settings applicators */ static struct settings_applicator settings_applicators[0] __table_start ( struct settings_applicator, settings_applicators ); static struct settings_applicator settings_applicators_end[0] __table_end ( struct settings_applicator, settings_applicators ); -/** - * Obtain printable version of a settings tag number - * - * @v tag Settings tag number - * @ret name String representation of the tag - */ -static inline char * setting_tag_name ( unsigned int tag ) { - static char name[8]; - - if ( DHCP_IS_ENCAP_OPT ( tag ) ) { - snprintf ( name, sizeof ( name ), "%d.%d", - DHCP_ENCAPSULATOR ( tag ), - DHCP_ENCAPSULATED ( tag ) ); - } else { - snprintf ( name, sizeof ( name ), "%d", tag ); - } - return name; -} - /****************************************************************************** * * Registered settings blocks @@ -83,32 +64,33 @@ static inline char * setting_tag_name ( unsigned int tag ) { * Store value of simple setting * * @v options DHCP option block - * @v tag Setting tag number + * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ -int simple_settings_store ( struct settings *settings, unsigned int tag, +int simple_settings_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { struct simple_settings *simple = container_of ( settings, struct simple_settings, settings ); - return dhcpopt_extensible_store ( &simple->dhcpopts, tag, data, len ); + return dhcpopt_extensible_store ( &simple->dhcpopts, setting->tag, + data, len ); } /** * Fetch value of simple setting * * @v options DHCP option block - * @v tag Setting tag number + * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error */ -int simple_settings_fetch ( struct settings *settings, unsigned int tag, +int simple_settings_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct simple_settings *simple = container_of ( settings, struct simple_settings, settings ); - return dhcpopt_fetch ( &simple->dhcpopts, tag, data, len ); + return dhcpopt_fetch ( &simple->dhcpopts, setting->tag, data, len ); } /** Simple settings operations */ @@ -174,14 +156,14 @@ static void reprioritise_settings ( struct settings *settings ) { return; /* Read priority, if present */ - priority = fetch_intz_setting ( settings, DHCP_EB_PRIORITY ); + priority = fetch_intz_setting ( settings, &priority_setting ); /* Remove from siblings list */ list_del ( &settings->siblings ); /* Reinsert after any existing blocks which have a higher priority */ list_for_each_entry ( tmp, &parent->children, siblings ) { - tmp_priority = fetch_intz_setting ( tmp, DHCP_EB_PRIORITY ); + tmp_priority = fetch_intz_setting ( tmp, &priority_setting ); if ( priority > tmp_priority ) break; } @@ -292,12 +274,12 @@ struct settings * find_settings ( const char *name ) { * Store value of setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ -int store_setting ( struct settings *settings, unsigned int tag, +int store_setting ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { int rc; @@ -306,11 +288,12 @@ int store_setting ( struct settings *settings, unsigned int tag, return -ENODEV; /* Store setting */ - if ( ( rc = settings->op->store ( settings, tag, data, len ) ) != 0 ) + if ( ( rc = settings->op->store ( settings, setting, + data, len ) ) != 0 ) return rc; /* Reprioritise settings if necessary */ - if ( tag == DHCP_EB_PRIORITY ) + if ( setting_cmp ( setting, &priority_setting ) == 0 ) reprioritise_settings ( settings ); /* If these settings are registered, apply potentially-updated @@ -331,7 +314,7 @@ int store_setting ( struct settings *settings, unsigned int tag, * Fetch value of setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error @@ -339,7 +322,7 @@ int store_setting ( struct settings *settings, unsigned int tag, * The actual length of the setting will be returned even if * the buffer was too small. */ -int fetch_setting ( struct settings *settings, unsigned int tag, +int fetch_setting ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct settings *child; int ret; @@ -349,12 +332,14 @@ int fetch_setting ( struct settings *settings, unsigned int tag, settings = &settings_root; /* Try this block first */ - if ( ( ret = settings->op->fetch ( settings, tag, data, len ) ) >= 0) + if ( ( ret = settings->op->fetch ( settings, setting, + data, len ) ) >= 0 ) return ret; /* Recurse into each child block in turn */ list_for_each_entry ( child, &settings->children, siblings ) { - if ( ( ret = fetch_setting ( child, tag, data, len ) ) >= 0) + if ( ( ret = fetch_setting ( child, setting, + data, len ) ) >= 0 ) return ret; } @@ -365,21 +350,21 @@ int fetch_setting ( struct settings *settings, unsigned int tag, * Fetch length of setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @ret len Length of setting data, or negative error * * This function can also be used as an existence check for the * setting. */ -int fetch_setting_len ( struct settings *settings, unsigned int tag ) { - return fetch_setting ( settings, tag, NULL, 0 ); +int fetch_setting_len ( struct settings *settings, struct setting *setting ) { + return fetch_setting ( settings, setting, NULL, 0 ); } /** * Fetch value of string setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v data Buffer to fill with setting string data * @v len Length of buffer * @ret len Length of string setting, or negative error @@ -388,25 +373,25 @@ int fetch_setting_len ( struct settings *settings, unsigned int tag ) { * The returned length will be the length of the underlying setting * data. */ -int fetch_string_setting ( struct settings *settings, unsigned int tag, +int fetch_string_setting ( struct settings *settings, struct setting *setting, char *data, size_t len ) { memset ( data, 0, len ); - return fetch_setting ( settings, tag, data, ( len - 1 ) ); + return fetch_setting ( settings, setting, data, ( len - 1 ) ); } /** * Fetch value of IPv4 address setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v inp IPv4 address to fill in * @ret len Length of setting, or negative error */ -int fetch_ipv4_setting ( struct settings *settings, unsigned int tag, +int fetch_ipv4_setting ( struct settings *settings, struct setting *setting, struct in_addr *inp ) { int len; - len = fetch_setting ( settings, tag, inp, sizeof ( *inp ) ); + len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) ); if ( len < 0 ) return len; if ( len < ( int ) sizeof ( *inp ) ) @@ -418,11 +403,11 @@ int fetch_ipv4_setting ( struct settings *settings, unsigned int tag, * Fetch value of signed integer setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v value Integer value to fill in * @ret len Length of setting, or negative error */ -int fetch_int_setting ( struct settings *settings, unsigned int tag, +int fetch_int_setting ( struct settings *settings, struct setting *setting, long *value ) { union { long value; @@ -433,7 +418,7 @@ int fetch_int_setting ( struct settings *settings, unsigned int tag, int i; buf.value = 0; - len = fetch_setting ( settings, tag, &buf, sizeof ( buf ) ); + len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) ); if ( len < 0 ) return len; if ( len > ( int ) sizeof ( buf ) ) @@ -451,16 +436,16 @@ int fetch_int_setting ( struct settings *settings, unsigned int tag, * Fetch value of unsigned integer setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v value Integer value to fill in * @ret len Length of setting, or negative error */ -int fetch_uint_setting ( struct settings *settings, unsigned int tag, +int fetch_uint_setting ( struct settings *settings, struct setting *setting, unsigned long *value ) { long svalue; int len; - len = fetch_int_setting ( settings, tag, &svalue ); + len = fetch_int_setting ( settings, setting, &svalue ); if ( len < 0 ) return len; @@ -473,13 +458,13 @@ int fetch_uint_setting ( struct settings *settings, unsigned int tag, * Fetch value of signed integer setting, or zero * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @ret value Setting value, or zero */ -long fetch_intz_setting ( struct settings *settings, unsigned int tag ) { +long fetch_intz_setting ( struct settings *settings, struct setting *setting ){ long value = 0; - fetch_int_setting ( settings, tag, &value ); + fetch_int_setting ( settings, setting, &value ); return value; } @@ -487,80 +472,38 @@ long fetch_intz_setting ( struct settings *settings, unsigned int tag ) { * Fetch value of unsigned integer setting, or zero * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @ret value Setting value, or zero */ unsigned long fetch_uintz_setting ( struct settings *settings, - unsigned int tag ) { + struct setting *setting ) { unsigned long value = 0; - fetch_uint_setting ( settings, tag, &value ); + fetch_uint_setting ( settings, setting, &value ); return value; } /** - * Copy settings + * Compare two settings * - * @v dest Destination settings block - * @v source Source settings block - * @v encapsulator Encapsulating setting tag number, or zero - * @ret rc Return status code + * @v a Setting to compare + * @v b Setting to compare + * @ret 0 Settings are the same + * @ret non-zero Settings are not the same */ -static int copy_encap_settings ( struct settings *dest, - struct settings *source, - unsigned int encapsulator ) { - unsigned int subtag; - unsigned int tag; - int len; - int check_len; - int rc; +int setting_cmp ( struct setting *a, struct setting *b ) { - for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) { - tag = DHCP_ENCAP_OPT ( encapsulator, subtag ); - switch ( tag ) { - case DHCP_EB_ENCAP: - case DHCP_VENDOR_ENCAP: - /* Process encapsulated settings */ - if ( ( rc = copy_encap_settings ( dest, source, - tag ) ) != 0 ) - return rc; - break; - default: - /* Copy setting, if present */ - len = fetch_setting_len ( source, tag ); - if ( len < 0 ) - break; - { - char buf[len]; + /* If the settings have tags, compare them */ + if ( a->tag && ( a->tag == b->tag ) ) + return 0; - check_len = fetch_setting ( source, tag, buf, - sizeof ( buf ) ); - assert ( check_len == len ); - if ( ( rc = store_setting ( dest, tag, buf, - sizeof(buf) )) !=0) - return rc; - } - break; - } - } - - return 0; -} - -/** - * Copy settings - * - * @v dest Destination settings block - * @v source Source settings block - * @ret rc Return status code - */ -int copy_settings ( struct settings *dest, struct settings *source ) { - return copy_encap_settings ( dest, source, 0 ); + /* Otherwise, compare the names */ + return strcmp ( a->name, b->name ); } /****************************************************************************** * - * Named and typed setting routines + * Formatted setting routines * ****************************************************************************** */ @@ -569,23 +512,22 @@ int copy_settings ( struct settings *dest, struct settings *source ) { * Store value of typed setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v type Settings type * @v value Formatted setting data, or NULL * @ret rc Return status code */ -int store_typed_setting ( struct settings *settings, - unsigned int tag, struct setting_type *type, - const char *value ) { +int storef_setting ( struct settings *settings, struct setting *setting, + const char *value ) { /* NULL value implies deletion. Avoid imposing the burden of * checking for NULL values on each typed setting's storef() * method. */ if ( ! value ) - return delete_setting ( settings, tag ); + return delete_setting ( settings, setting ); - return type->storef ( settings, tag, value ); + return setting->type->storef ( settings, setting, value ); } /** @@ -594,11 +536,10 @@ int store_typed_setting ( struct settings *settings, * @v name Name * @ret setting Named setting, or NULL */ -static struct named_setting * find_named_setting ( const char *name ) { - struct named_setting *setting; +static struct setting * find_setting ( const char *name ) { + struct setting *setting; - for ( setting = named_settings ; setting < named_settings_end ; - setting++ ) { + for ( setting = settings ; setting < settings_end ; setting++ ) { if ( strcmp ( name, setting->name ) == 0 ) return setting; } @@ -625,9 +566,8 @@ static struct setting_type * find_setting_type ( const char *name ) { * Parse setting name * * @v name Name of setting - * @ret settings Settings block, or NULL - * @ret tag Setting tag number - * @ret type Setting type + * @v settings Settings block to fill in + * @v setting Setting to fill in * @ret rc Return status code * * Interprets a name of the form @@ -635,30 +575,29 @@ static struct setting_type * find_setting_type ( const char *name ) { * fields. */ static int parse_setting_name ( const char *name, struct settings **settings, - unsigned int *tag, - struct setting_type **type ) { + struct setting *setting ) { char tmp_name[ strlen ( name ) + 1 ]; char *settings_name; - char *tag_name; + char *setting_name; char *type_name; - struct named_setting *named_setting; + struct setting *named_setting; char *tmp; /* Set defaults */ *settings = &settings_root; - *tag = 0; - *type = &setting_type_hex; + memset ( setting, 0, sizeof ( *setting ) ); + setting->type = &setting_type_hex; - /* Split name into "[settings_name/]tag_name[:type_name]" */ + /* Split name into "[settings_name/]setting_name[:type_name]" */ memcpy ( tmp_name, name, sizeof ( tmp_name ) ); - if ( ( tag_name = strchr ( tmp_name, '/' ) ) != NULL ) { - *(tag_name++) = 0; + if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) { + *(setting_name++) = 0; settings_name = tmp_name; } else { - tag_name = tmp_name; + setting_name = tmp_name; settings_name = NULL; } - if ( ( type_name = strchr ( tag_name, ':' ) ) != NULL ) + if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL ) *(type_name++) = 0; /* Identify settings block, if specified */ @@ -672,19 +611,19 @@ static int parse_setting_name ( const char *name, struct settings **settings, } /* Identify tag number */ - if ( ( named_setting = find_named_setting ( tag_name ) ) != NULL ) { - *tag = named_setting->tag; - *type = named_setting->type; + if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) { + memcpy ( setting, named_setting, sizeof ( *setting ) ); } else { /* Unrecognised name: try to interpret as a tag number */ - tmp = tag_name; + tmp = setting_name; while ( 1 ) { - *tag = ( ( *tag << 8 ) | strtoul ( tmp, &tmp, 0 ) ); + setting->tag = ( ( setting->tag << 8 ) | + strtoul ( tmp, &tmp, 0 ) ); if ( *tmp == 0 ) break; if ( *tmp != '.' ) { - DBG ( "Invalid tag number \"%s\" in \"%s\"\n", - tag_name, name ); + DBG ( "Invalid setting \"%s\" in \"%s\"\n", + setting_name, name ); return -ENOENT; } tmp++; @@ -693,8 +632,8 @@ static int parse_setting_name ( const char *name, struct settings **settings, /* Identify setting type, if specified */ if ( type_name ) { - *type = find_setting_type ( type_name ); - if ( *type == NULL ) { + setting->type = find_setting_type ( type_name ); + if ( setting->type == NULL ) { DBG ( "Invalid setting type \"%s\" in \"%s\"\n", type_name, name ); return -ENOTSUP; @@ -711,16 +650,14 @@ static int parse_setting_name ( const char *name, struct settings **settings, * @v value Formatted setting data, or NULL * @ret rc Return status code */ -int store_named_setting ( const char *name, const char *value ) { +int storef_named_setting ( const char *name, const char *value ) { struct settings *settings; - unsigned int tag; - struct setting_type *type; + struct setting setting; int rc; - if ( ( rc = parse_setting_name ( name, &settings, &tag, - &type ) ) != 0 ) + if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 ) return rc; - return store_typed_setting ( settings, tag, type, value ); + return storef_setting ( settings, &setting, value ); } /** @@ -731,16 +668,14 @@ int store_named_setting ( const char *name, const char *value ) { * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -int fetch_named_setting ( const char *name, char *buf, size_t len ) { +int fetchf_named_setting ( const char *name, char *buf, size_t len ) { struct settings *settings; - unsigned int tag; - struct setting_type *type; + struct setting setting; int rc; - if ( ( rc = parse_setting_name ( name, &settings, &tag, - &type ) ) != 0 ) + if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 ) return rc; - return fetch_typed_setting ( settings, tag, type, buf, len ); + return fetchf_setting ( settings, &setting, buf, len ); } /****************************************************************************** @@ -754,27 +689,27 @@ int fetch_named_setting ( const char *name, char *buf, size_t len ) { * Parse and store value of string setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ -static int storef_string ( struct settings *settings, unsigned int tag, +static int storef_string ( struct settings *settings, struct setting *setting, const char *value ) { - return store_setting ( settings, tag, value, strlen ( value ) ); + return store_setting ( settings, setting, value, strlen ( value ) ); } /** * Fetch and format value of string setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int fetchf_string ( struct settings *settings, unsigned int tag, +static int fetchf_string ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { - return fetch_string_setting ( settings, tag, buf, len ); + return fetch_string_setting ( settings, setting, buf, len ); } /** A string setting type */ @@ -788,34 +723,34 @@ struct setting_type setting_type_string __setting_type = { * Parse and store value of IPv4 address setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ -static int storef_ipv4 ( struct settings *settings, unsigned int tag, +static int storef_ipv4 ( struct settings *settings, struct setting *setting, const char *value ) { struct in_addr ipv4; if ( inet_aton ( value, &ipv4 ) == 0 ) return -EINVAL; - return store_setting ( settings, tag, &ipv4, sizeof ( ipv4 ) ); + return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) ); } /** * Fetch and format value of IPv4 address setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int fetchf_ipv4 ( struct settings *settings, unsigned int tag, +static int fetchf_ipv4 ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { struct in_addr ipv4; int rc; - if ( ( rc = fetch_ipv4_setting ( settings, tag, &ipv4 ) ) < 0 ) + if ( ( rc = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0 ) return rc; return snprintf ( buf, len, inet_ntoa ( ipv4 ) ); } @@ -831,12 +766,12 @@ struct setting_type setting_type_ipv4 __setting_type = { * Parse and store value of integer setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ -static int storef_int ( struct settings *settings, unsigned int tag, +static int storef_int ( struct settings *settings, struct setting *setting, const char *value, unsigned int size ) { union { uint32_t num; @@ -847,7 +782,7 @@ static int storef_int ( struct settings *settings, unsigned int tag, u.num = htonl ( strtoul ( value, &endp, 0 ) ); if ( *endp ) return -EINVAL; - return store_setting ( settings, tag, + return store_setting ( settings, setting, &u.bytes[ sizeof ( u ) - size ], size ); } @@ -855,59 +790,59 @@ static int storef_int ( struct settings *settings, unsigned int tag, * Parse and store value of 8-bit integer setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ -static int storef_int8 ( struct settings *settings, unsigned int tag, +static int storef_int8 ( struct settings *settings, struct setting *setting, const char *value ) { - return storef_int ( settings, tag, value, 1 ); + return storef_int ( settings, setting, value, 1 ); } /** * Parse and store value of 16-bit integer setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ -static int storef_int16 ( struct settings *settings, unsigned int tag, +static int storef_int16 ( struct settings *settings, struct setting *setting, const char *value ) { - return storef_int ( settings, tag, value, 2 ); + return storef_int ( settings, setting, value, 2 ); } /** * Parse and store value of 32-bit integer setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @v size Integer size, in bytes * @ret rc Return status code */ -static int storef_int32 ( struct settings *settings, unsigned int tag, +static int storef_int32 ( struct settings *settings, struct setting *setting, const char *value ) { - return storef_int ( settings, tag, value, 4 ); + return storef_int ( settings, setting, value, 4 ); } /** * Fetch and format value of signed integer setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int fetchf_int ( struct settings *settings, unsigned int tag, +static int fetchf_int ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { long value; int rc; - if ( ( rc = fetch_int_setting ( settings, tag, &value ) ) < 0 ) + if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 ) return rc; return snprintf ( buf, len, "%ld", value ); } @@ -916,17 +851,17 @@ static int fetchf_int ( struct settings *settings, unsigned int tag, * Fetch and format value of unsigned integer setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int fetchf_uint ( struct settings *settings, unsigned int tag, +static int fetchf_uint ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { unsigned long value; int rc; - if ( ( rc = fetch_uint_setting ( settings, tag, &value ) ) < 0 ) + if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 ) return rc; return snprintf ( buf, len, "%#lx", value ); } @@ -977,11 +912,11 @@ struct setting_type setting_type_uint32 __setting_type = { * Parse and store value of hex string setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ -static int storef_hex ( struct settings *settings, unsigned int tag, +static int storef_hex ( struct settings *settings, struct setting *setting, const char *value ) { char *ptr = ( char * ) value; uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */ @@ -991,7 +926,7 @@ static int storef_hex ( struct settings *settings, unsigned int tag, bytes[len++] = strtoul ( ptr, &ptr, 16 ); switch ( *ptr ) { case '\0' : - return store_setting ( settings, tag, bytes, len ); + return store_setting ( settings, setting, bytes, len ); case ':' : ptr++; break; @@ -1005,26 +940,27 @@ static int storef_hex ( struct settings *settings, unsigned int tag, * Fetch and format value of hex string setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int fetchf_hex ( struct settings *settings, unsigned int tag, +static int fetchf_hex ( struct settings *settings, struct setting *setting, char *buf, size_t len ) { int raw_len; int check_len; int used = 0; int i; - raw_len = fetch_setting_len ( settings, tag ); + raw_len = fetch_setting_len ( settings, setting ); if ( raw_len < 0 ) return raw_len; { uint8_t raw[raw_len]; - check_len = fetch_setting ( settings, tag, raw, sizeof (raw) ); + check_len = fetch_setting ( settings, setting, raw, + sizeof ( raw ) ); assert ( check_len == raw_len ); if ( len ) @@ -1047,83 +983,55 @@ struct setting_type setting_type_hex __setting_type = { /****************************************************************************** * - * Named settings + * Settings * ****************************************************************************** */ -/** Some basic setting definitions */ -struct named_setting basic_named_settings[] __named_setting = { - { - .name = "ip", - .description = "IPv4 address", - .tag = DHCP_EB_YIADDR, - .type = &setting_type_ipv4, - }, - { - .name = "netmask", - .description = "IPv4 subnet mask", - .tag = DHCP_SUBNET_MASK, - .type = &setting_type_ipv4, - }, - { - .name = "gateway", - .description = "Default gateway", - .tag = DHCP_ROUTERS, - .type = &setting_type_ipv4, - }, - { - .name = "dns", - .description = "DNS server", - .tag = DHCP_DNS_SERVERS, - .type = &setting_type_ipv4, - }, - { - .name = "hostname", - .description = "Host name", - .tag = DHCP_HOST_NAME, - .type = &setting_type_string, - }, - { - .name = "next-server", - .description = "TFTP server", - .tag = DHCP_EB_SIADDR, - .type = &setting_type_ipv4, - }, - { - .name = "filename", - .description = "Boot filename", - .tag = DHCP_BOOTFILE_NAME, - .type = &setting_type_string, - }, - { - .name = "root-path", - .description = "NFS/iSCSI root path", - .tag = DHCP_ROOT_PATH, - .type = &setting_type_string, - }, - { - .name = "username", - .description = "User name", - .tag = DHCP_EB_USERNAME, - .type = &setting_type_string, - }, - { - .name = "password", - .description = "Password", - .tag = DHCP_EB_PASSWORD, - .type = &setting_type_string, - }, - { - .name = "initiator-iqn", - .description = "iSCSI initiator name", - .tag = DHCP_ISCSI_INITIATOR_IQN, - .type = &setting_type_string, - }, - { - .name = "priority", - .description = "Priority of these settings", - .tag = DHCP_EB_PRIORITY, - .type = &setting_type_int8, - }, +/** Hostname setting */ +struct setting hostname_setting __setting = { + .name = "hostname", + .description = "Host name", + .tag = DHCP_HOST_NAME, + .type = &setting_type_string, +}; + +/** Filename setting */ +struct setting filename_setting __setting = { + .name = "filename", + .description = "Boot filename", + .tag = DHCP_BOOTFILE_NAME, + .type = &setting_type_string, +}; + +/** Root path setting */ +struct setting root_path_setting __setting = { + .name = "root-path", + .description = "NFS/iSCSI root path", + .tag = DHCP_ROOT_PATH, + .type = &setting_type_string, +}; + +/** Username setting */ +struct setting username_setting __setting = { + .name = "username", + .description = "User name", + .tag = DHCP_EB_USERNAME, + .type = &setting_type_string, +}; + +/** Password setting */ +struct setting password_setting __setting = { + .name = "password", + .description = "Password", + .tag = DHCP_EB_PASSWORD, + .type = &setting_type_string, +}; + +/** Priority setting */ +struct setting priority_setting __setting = { + .name = "priority", + .description = "Priority of these settings", + .tag = DHCP_EB_PRIORITY, + .type = &setting_type_int8, }; diff --git a/src/hci/commands/nvo_cmd.c b/src/hci/commands/nvo_cmd.c index e2fdd8fb..c0c07280 100644 --- a/src/hci/commands/nvo_cmd.c +++ b/src/hci/commands/nvo_cmd.c @@ -16,8 +16,8 @@ static int show_exec ( int argc, char **argv ) { return 1; } - if ( ( rc = fetch_named_setting ( argv[1], buf, - sizeof ( buf ) ) ) < 0 ){ + if ( ( rc = fetchf_named_setting ( argv[1], buf, + sizeof ( buf ) ) ) < 0 ){ printf ( "Could not find \"%s\": %s\n", argv[1], strerror ( rc ) ); return 1; @@ -35,7 +35,7 @@ static int set_exec ( int argc, char **argv ) { return 1; } - if ( ( rc = store_named_setting ( argv[1], argv[2] ) ) != 0 ) { + if ( ( rc = storef_named_setting ( argv[1], argv[2] ) ) != 0 ) { printf ( "Could not set \"%s\"=\"%s\": %s\n", argv[1], argv[2], strerror ( rc ) ); return 1; diff --git a/src/hci/tui/settings_ui.c b/src/hci/tui/settings_ui.c index 83146b58..0907bfd3 100644 --- a/src/hci/tui/settings_ui.c +++ b/src/hci/tui/settings_ui.c @@ -64,7 +64,7 @@ struct setting_widget { /** Settings block */ struct settings *settings; /** Configuration setting */ - struct named_setting *setting; + struct setting *setting; /** Screen row */ unsigned int row; /** Screen column */ @@ -78,17 +78,17 @@ struct setting_widget { }; /** Registered configuration settings */ -static struct named_setting named_settings[0] - __table_start ( struct named_setting, named_settings ); -static struct named_setting named_settings_end[0] - __table_end ( struct named_setting, named_settings ); -#define NUM_SETTINGS ( ( unsigned ) ( named_settings_end - named_settings ) ) +static struct setting all_settings[0] + __table_start ( struct setting, settings ); +static struct setting all_settings_end[0] + __table_end ( struct setting, settings ); +#define NUM_SETTINGS ( ( unsigned ) ( all_settings_end - all_settings ) ) static void load_setting ( struct setting_widget *widget ) __nonnull; static int save_setting ( struct setting_widget *widget ) __nonnull; static void init_setting ( struct setting_widget *widget, struct settings *settings, - struct named_setting *setting, + struct setting *setting, unsigned int row, unsigned int col ) __nonnull; static void draw_setting ( struct setting_widget *widget ) __nonnull; static int edit_setting ( struct setting_widget *widget, int key ) __nonnull; @@ -99,7 +99,7 @@ static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull; static void msg ( unsigned int row, const char *fmt, ... ) __nonnull; static void valert ( const char *fmt, va_list args ) __nonnull; static void alert ( const char *fmt, ... ) __nonnull; -static void draw_info_row ( struct named_setting *setting ) __nonnull; +static void draw_info_row ( struct setting *setting ) __nonnull; static int main_loop ( struct settings *settings ) __nonnull; /** @@ -114,9 +114,8 @@ static void load_setting ( struct setting_widget *widget ) { widget->editing = 0; /* Read current setting value */ - if ( fetch_typed_setting ( widget->settings, widget->setting->tag, - widget->setting->type, widget->value, - sizeof ( widget->value ) ) < 0 ) { + if ( fetchf_setting ( widget->settings, widget->setting, + widget->value, sizeof ( widget->value ) ) < 0 ) { widget->value[0] = '\0'; } @@ -133,8 +132,8 @@ static void load_setting ( struct setting_widget *widget ) { * @v widget Setting widget */ static int save_setting ( struct setting_widget *widget ) { - return store_typed_setting ( widget->settings, widget->setting->tag, - widget->setting->type, widget->value ); + return storef_setting ( widget->settings, widget->setting, + widget->value ); } /** @@ -148,7 +147,7 @@ static int save_setting ( struct setting_widget *widget ) { */ static void init_setting ( struct setting_widget *widget, struct settings *settings, - struct named_setting *setting, + struct setting *setting, unsigned int row, unsigned int col ) { /* Initialise widget structure */ @@ -224,7 +223,7 @@ static int edit_setting ( struct setting_widget *widget, int key ) { static void init_setting_index ( struct setting_widget *widget, struct settings *settings, unsigned int index ) { - init_setting ( widget, settings, &named_settings[index], + init_setting ( widget, settings, &all_settings[index], ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL ); } @@ -311,7 +310,7 @@ static void draw_title_row ( void ) { * * @v setting Current configuration setting */ -static void draw_info_row ( struct named_setting *setting ) { +static void draw_info_row ( struct setting *setting ) { clearmsg ( INFO_ROW ); attron ( A_BOLD ); msg ( INFO_ROW, "%s - %s", setting->name, setting->description ); diff --git a/src/include/gpxe/dhcp.h b/src/include/gpxe/dhcp.h index bc0e9a3b..94cc2010 100644 --- a/src/include/gpxe/dhcp.h +++ b/src/include/gpxe/dhcp.h @@ -15,8 +15,8 @@ struct net_device; struct job_interface; +struct dhcp_options; struct dhcp_packet; -struct settings; /** BOOTP/DHCP server port */ #define BOOTPS_PORT 67 @@ -179,15 +179,6 @@ struct settings; */ #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 ) -/** MAC address - * - * This option is used internally to contain the network device - * hardware address, in order to provide a consistent approach to - * storing and processing options. It should never be present in a - * DHCP packet. - */ -#define DHCP_EB_MAC DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 4 ) - /* * Tags in the range 0x10-0x7f are reserved for feature markers * @@ -445,11 +436,19 @@ struct dhcphdr { /** Maximum time that we will wait for ProxyDHCP offers */ #define PROXYDHCP_WAIT_TIME ( TICKS_PER_SEC * 1 ) -extern int create_dhcpdiscover ( struct net_device *netdev, - void *data, size_t max_len ); -extern int create_dhcpack ( struct net_device *netdev, - void *data, size_t max_len ); -extern int create_proxydhcpack ( struct net_device *netdev, +/** Settings block name used for DHCP responses */ +#define DHCP_SETTINGS_NAME "dhcp" + +/** Settings block name used for ProxyDHCP responses */ +#define PROXYDHCP_SETTINGS_NAME "proxydhcp" + +extern int create_dhcp_packet ( struct dhcp_packet *dhcppkt, + struct net_device *netdev, uint8_t msgtype, + struct dhcp_options *options, + void *data, size_t max_len ); +extern int create_dhcp_request ( struct dhcp_packet *dhcppkt, + struct net_device *netdev, + struct dhcp_packet *dhcpoffer, void *data, size_t max_len ); extern int start_dhcp ( struct job_interface *job, struct net_device *netdev ); diff --git a/src/include/gpxe/dhcpopts.h b/src/include/gpxe/dhcpopts.h index b16c5f22..8391a9d4 100644 --- a/src/include/gpxe/dhcpopts.h +++ b/src/include/gpxe/dhcpopts.h @@ -7,7 +7,7 @@ * */ -#include +#include /** A DHCP options block */ struct dhcp_options { diff --git a/src/include/gpxe/dhcppkt.h b/src/include/gpxe/dhcppkt.h index 98b8dad8..179be2f8 100644 --- a/src/include/gpxe/dhcppkt.h +++ b/src/include/gpxe/dhcppkt.h @@ -9,15 +9,12 @@ #include #include -#include /** * A DHCP packet * */ struct dhcp_packet { - /** Settings block */ - struct settings settings; /** The DHCP packet contents */ struct dhcphdr *dhcphdr; /** Maximum length of the DHCP packet buffer */ @@ -28,7 +25,11 @@ struct dhcp_packet { struct dhcp_options options; }; -extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct refcnt *refcnt, +extern int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag, + const void *data, size_t len ); +extern int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag, + void *data, size_t len ); +extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, void *data, size_t len ); #endif /* _GPXE_DHCPPKT_H */ diff --git a/src/include/gpxe/fakedhcp.h b/src/include/gpxe/fakedhcp.h new file mode 100644 index 00000000..990b56af --- /dev/null +++ b/src/include/gpxe/fakedhcp.h @@ -0,0 +1,21 @@ +#ifndef _GPXE_FAKEDHCP_H +#define _GPXE_FAKEDHCP_H + +/** @file + * + * Fake DHCP packets + * + */ + +#include + +struct net_device; + +extern int create_fakedhcpdiscover ( struct net_device *netdev, + void *data, size_t max_len ); +extern int create_fakedhcpack ( struct net_device *netdev, + void *data, size_t max_len ); +extern int create_fakeproxydhcpack ( struct net_device *netdev, + void *data, size_t max_len ); + +#endif /* _GPXE_FAKEDHCP_H */ diff --git a/src/include/gpxe/settings.h b/src/include/gpxe/settings.h index f32d3ec9..40825698 100644 --- a/src/include/gpxe/settings.h +++ b/src/include/gpxe/settings.h @@ -16,22 +16,44 @@ struct settings; struct in_addr; +/** A setting */ +struct setting { + /** Name + * + * This is the human-readable name for the setting. + */ + const char *name; + /** Description */ + const char *description; + /** Setting type + * + * This identifies the type of setting (e.g. string, IPv4 + * address, etc.). + */ + struct setting_type *type; + /** DHCP option number, if applicable */ + unsigned int tag; +}; + +/** Declare a configuration setting */ +#define __setting __table ( struct setting, settings, 01 ) + /** Settings block operations */ struct settings_operations { /** Store value of setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ - int ( * store ) ( struct settings *settings, unsigned int tag, + int ( * store ) ( struct settings *settings, struct setting *setting, const void *data, size_t len ); /** Fetch value of setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to fetch * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error @@ -39,7 +61,7 @@ struct settings_operations { * The actual length of the setting will be returned even if * the buffer was too small. */ - int ( * fetch ) ( struct settings *settings, unsigned int tag, + int ( * fetch ) ( struct settings *settings, struct setting *setting, void *data, size_t len ); }; @@ -74,21 +96,21 @@ struct setting_type { /** Parse and set value of setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v value Formatted setting data * @ret rc Return status code */ - int ( * storef ) ( struct settings *settings, unsigned int tag, + int ( * storef ) ( struct settings *settings, struct setting *setting, const char *value ); /** Fetch and format value of setting * - * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v settings Settings block + * @v setting Setting to fetch * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ - int ( * fetchf ) ( struct settings *settings, unsigned int tag, + int ( * fetchf ) ( struct settings *settings, struct setting *setting, char *buf, size_t len ); }; @@ -96,33 +118,6 @@ struct setting_type { #define __setting_type \ __table ( struct setting_type, setting_types, 01 ) -/** - * A named setting - * - * This represents a single setting (e.g. "hostname"), encapsulating - * the information about the setting's tag number and type. - */ -struct named_setting { - /** Name - * - * This is the human-readable name for the setting. - */ - const char *name; - /** Description */ - const char *description; - /** Setting tag number */ - unsigned int tag; - /** Setting type - * - * This identifies the type of setting (e.g. string, IPv4 - * address, etc.). - */ - struct setting_type *type; -}; - -/** Declare a configuration setting */ -#define __named_setting __table ( struct named_setting, named_settings, 01 ) - /** * A settings applicator * @@ -151,41 +146,49 @@ struct simple_settings { }; extern struct settings_operations simple_settings_operations; - -extern int simple_settings_store ( struct settings *settings, unsigned int tag, +extern int simple_settings_store ( struct settings *settings, + struct setting *setting, const void *data, size_t len ); -extern int simple_settings_fetch ( struct settings *settings, unsigned int tag, +extern int simple_settings_fetch ( struct settings *settings, + struct setting *setting, void *data, size_t len ); + extern int register_settings ( struct settings *settings, struct settings *parent ); extern void unregister_settings ( struct settings *settings ); -extern int store_setting ( struct settings *settings, unsigned int tag, + +extern int store_setting ( struct settings *settings, struct setting *setting, const void *data, size_t len ); -extern int fetch_setting ( struct settings *settings, unsigned int tag, +extern int fetch_setting ( struct settings *settings, struct setting *setting, void *data, size_t len ); -extern int copy_settings ( struct settings *dest, struct settings *source ); -extern int fetch_setting_len ( struct settings *settings, unsigned int tag ); -extern int fetch_string_setting ( struct settings *settings, unsigned int tag, +extern int fetch_setting_len ( struct settings *settings, + struct setting *setting ); +extern int fetch_string_setting ( struct settings *settings, + struct setting *setting, char *data, size_t len ); -extern int fetch_ipv4_setting ( struct settings *settings, unsigned int tag, - struct in_addr *inp ); -extern int fetch_int_setting ( struct settings *settings, unsigned int tag, - long *value ); -extern int fetch_uint_setting ( struct settings *settings, unsigned int tag, +extern int fetch_ipv4_setting ( struct settings *settings, + struct setting *setting, struct in_addr *inp ); +extern int fetch_int_setting ( struct settings *settings, + struct setting *setting, long *value ); +extern int fetch_uint_setting ( struct settings *settings, + struct setting *setting, unsigned long *value ); -extern long fetch_intz_setting ( struct settings *settings, unsigned int tag ); +extern long fetch_intz_setting ( struct settings *settings, + struct setting *setting ); extern unsigned long fetch_uintz_setting ( struct settings *settings, - unsigned int tag ); + struct setting *setting ); +extern int setting_cmp ( struct setting *a, struct setting *b ); + extern struct settings * find_child_settings ( struct settings *parent, const char *name ); extern struct settings * find_settings ( const char *name ); -extern int store_typed_setting ( struct settings *settings, - unsigned int tag, struct setting_type *type, - const char *value ); -extern int store_named_setting ( const char *name, const char *value ); -extern int fetch_named_setting ( const char *name, char *buf, size_t len ); -extern struct setting_type setting_type_ __setting_type; +extern int storef_setting ( struct settings *settings, + struct setting *setting, + const char *value ); +extern int storef_named_setting ( const char *name, const char *value ); +extern int fetchf_named_setting ( const char *name, char *buf, size_t len ); + extern struct setting_type setting_type_string __setting_type; extern struct setting_type setting_type_ipv4 __setting_type; extern struct setting_type setting_type_int8 __setting_type; @@ -196,6 +199,18 @@ extern struct setting_type setting_type_uint16 __setting_type; extern struct setting_type setting_type_uint32 __setting_type; extern struct setting_type setting_type_hex __setting_type; +extern struct setting ip_setting __setting; +extern struct setting netmask_setting __setting; +extern struct setting gateway_setting __setting; +extern struct setting dns_setting __setting; +extern struct setting hostname_setting __setting; +extern struct setting filename_setting __setting; +extern struct setting root_path_setting __setting; +extern struct setting username_setting __setting; +extern struct setting password_setting __setting; +extern struct setting priority_setting __setting; +extern struct setting bios_drive_setting __setting; + /** * Initialise a settings block * @@ -233,29 +248,28 @@ static inline void simple_settings_init ( struct simple_settings *simple, * Delete setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to delete * @ret rc Return status code */ static inline int delete_setting ( struct settings *settings, - unsigned int tag ) { - return store_setting ( settings, tag, NULL, 0 ); + struct setting *setting ) { + return store_setting ( settings, setting, NULL, 0 ); } /** * Fetch and format value of setting * * @v settings Settings block, or NULL to search all blocks - * @v tag Setting tag number + * @v setting Setting to fetch * @v type Settings type * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static inline int fetch_typed_setting ( struct settings *settings, - unsigned int tag, - struct setting_type *type, - char *buf, size_t len ) { - return type->fetchf ( settings, tag, buf, len ); +static inline int fetchf_setting ( struct settings *settings, + struct setting *setting, + char *buf, size_t len ) { + return setting->type->fetchf ( settings, setting, buf, len ); } /** @@ -265,7 +279,7 @@ static inline int fetch_typed_setting ( struct settings *settings, * @ret rc Return status code */ static inline int delete_named_setting ( const char *name ) { - return store_named_setting ( name, NULL ); + return storef_named_setting ( name, NULL ); } #endif /* _GPXE_SETTINGS_H */ diff --git a/src/interface/pxe/pxe_preboot.c b/src/interface/pxe/pxe_preboot.c index 2a10b1a5..302953eb 100644 --- a/src/interface/pxe/pxe_preboot.c +++ b/src/interface/pxe/pxe_preboot.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -80,9 +80,9 @@ struct pxe_dhcp_packet_creator { /** PXE DHCP packet creators */ static struct pxe_dhcp_packet_creator pxe_dhcp_packet_creators[] = { - [CACHED_INFO_DHCPDISCOVER] = { create_dhcpdiscover }, - [CACHED_INFO_DHCPACK] = { create_dhcpack }, - [CACHED_INFO_BINL] = { create_proxydhcpack }, + [CACHED_INFO_DHCPDISCOVER] = { create_fakedhcpdiscover }, + [CACHED_INFO_DHCPACK] = { create_fakedhcpack }, + [CACHED_INFO_BINL] = { create_fakeproxydhcpack }, }; /* The case in which the caller doesn't supply a buffer is really diff --git a/src/net/dhcpopts.c b/src/net/dhcpopts.c index 64b310d4..1898011a 100644 --- a/src/net/dhcpopts.c +++ b/src/net/dhcpopts.c @@ -118,6 +118,11 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options, ssize_t remaining = options->len; unsigned int option_len; + /* Sanity check */ + if ( tag == DHCP_PAD ) + return -ENOENT; + + /* Search for option */ while ( remaining ) { /* Calculate length of this option. Abort processing * if the length is malformed (i.e. takes us beyond @@ -128,6 +133,9 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options, remaining -= option_len; if ( remaining < 0 ) break; + /* Check for explicit end marker */ + if ( option->tag == DHCP_END ) + break; /* Check for matching tag */ if ( option->tag == tag ) { DBGC ( options, "DHCPOPT %p found %s (length %d)\n", @@ -135,9 +143,6 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options, option_len ); return offset; } - /* Check for explicit end marker */ - if ( option->tag == DHCP_END ) - break; /* Check for start of matching encapsulation block */ if ( DHCP_IS_ENCAP_OPT ( tag ) && ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) { @@ -151,6 +156,7 @@ static int find_dhcp_option_with_encap ( struct dhcp_options *options, } offset += option_len; } + return -ENOENT; } @@ -255,6 +261,10 @@ static int set_dhcp_option ( struct dhcp_options *options, unsigned int tag, size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 ); int rc; + /* Sanity check */ + if ( tag == DHCP_PAD ) + return -ENOTTY; + /* Find old instance of this option, if any */ offset = find_dhcp_option_with_encap ( options, tag, &encap_offset ); if ( offset >= 0 ) { diff --git a/src/net/dhcppkt.c b/src/net/dhcppkt.c index 0a11520f..1cf99d8d 100644 --- a/src/net/dhcppkt.c +++ b/src/net/dhcppkt.c @@ -92,20 +92,18 @@ find_dhcp_packet_field ( unsigned int tag ) { } return NULL; } - + /** * Store value of DHCP packet setting * - * @v settings Settings block + * @v dhcppkt DHCP packet * @v tag Setting tag number * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ -static int dhcppkt_store ( struct settings *settings, unsigned int tag, - const void *data, size_t len ) { - struct dhcp_packet *dhcppkt = - container_of ( settings, struct dhcp_packet, settings ); +int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag, + const void *data, size_t len ) { struct dhcp_packet_field *field; int rc; @@ -131,16 +129,14 @@ static int dhcppkt_store ( struct settings *settings, unsigned int tag, /** * Fetch value of DHCP packet setting * - * @v settings Settings block + * @v dhcppkt DHCP packet * @v tag Setting tag number * @v data Buffer to fill with setting data * @v len Length of buffer * @ret len Length of setting data, or negative error */ -static int dhcppkt_fetch ( struct settings *settings, unsigned int tag, - void *data, size_t len ) { - struct dhcp_packet *dhcppkt = - container_of ( settings, struct dhcp_packet, settings ); +int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag, + void *data, size_t len ) { struct dhcp_packet_field *field; /* If this is a special field, return it */ @@ -156,31 +152,21 @@ static int dhcppkt_fetch ( struct settings *settings, unsigned int tag, return dhcpopt_fetch ( &dhcppkt->options, tag, data, len ); } -/** DHCP settings operations */ -static struct settings_operations dhcppkt_settings_operations = { - .store = dhcppkt_store, - .fetch = dhcppkt_fetch, -}; - /** * Initialise prepopulated DHCP packet * * @v dhcppkt Uninitialised DHCP packet - * @v refcnt Reference counter of containing object, or NULL * @v data Memory for DHCP packet data * @v max_len Length of memory for DHCP packet data * * The memory content must already be filled with valid DHCP options. * A zeroed block counts as a block of valid DHCP options. */ -void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct refcnt *refcnt, - void *data, size_t len ) { +void dhcppkt_init ( struct dhcp_packet *dhcppkt, void *data, size_t len ) { dhcppkt->dhcphdr = data; dhcppkt->max_len = len; dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options, ( len - offsetof ( struct dhcphdr, options ) ) ); dhcppkt->len = ( offsetof ( struct dhcphdr, options ) + dhcppkt->options.len ); - settings_init ( &dhcppkt->settings, &dhcppkt_settings_operations, - refcnt, "dhcp" ); } diff --git a/src/net/fakedhcp.c b/src/net/fakedhcp.c new file mode 100644 index 00000000..c3054db1 --- /dev/null +++ b/src/net/fakedhcp.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2008 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** @file + * + * Fake DHCP packets + * + */ + +/** + * Copy settings to DHCP packet + * + * @v dest Destination DHCP packet + * @v source Source settings block + * @v encapsulator Encapsulating setting tag number, or zero + * @ret rc Return status code + */ +static int copy_encap_settings ( struct dhcp_packet *dest, + struct settings *source, + unsigned int encapsulator ) { + struct setting setting = { .name = "" }; + unsigned int subtag; + unsigned int tag; + int len; + int check_len; + int rc; + + for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) { + tag = DHCP_ENCAP_OPT ( encapsulator, subtag ); + switch ( tag ) { + case DHCP_EB_ENCAP: + case DHCP_VENDOR_ENCAP: + /* Process encapsulated settings */ + if ( ( rc = copy_encap_settings ( dest, source, + tag ) ) != 0 ) + return rc; + break; + default: + /* Copy setting, if present */ + setting.tag = tag; + len = fetch_setting_len ( source, &setting ); + if ( len < 0 ) + break; + { + char buf[len]; + + check_len = fetch_setting ( source, &setting, + buf, sizeof (buf)); + assert ( check_len == len ); + if ( ( rc = dhcppkt_store ( dest, tag, buf, + sizeof(buf) )) !=0) + return rc; + } + break; + } + } + + return 0; +} + +/** + * Copy settings to DHCP packet + * + * @v dest Destination DHCP packet + * @v source Source settings block + * @ret rc Return status code + */ +static int copy_settings ( struct dhcp_packet *dest, + struct settings *source ) { + return copy_encap_settings ( dest, source, 0 ); +} + +/** + * Create fake DHCPDISCOVER packet + * + * @v netdev Network device + * @v data Buffer for DHCP packet + * @v max_len Size of DHCP packet buffer + * @ret rc Return status code + * + * Used by external code. + */ +int create_fakedhcpdiscover ( struct net_device *netdev, + void *data, size_t max_len ) { + struct dhcp_packet dhcppkt; + int rc; + + if ( ( rc = create_dhcp_request ( &dhcppkt, netdev, NULL, data, + max_len ) ) != 0 ) { + DBG ( "Could not create DHCPDISCOVER: %s\n", + strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * Create fake DHCPACK packet + * + * @v netdev Network device + * @v data Buffer for DHCP packet + * @v max_len Size of DHCP packet buffer + * @ret rc Return status code + * + * Used by external code. + */ +int create_fakedhcpack ( struct net_device *netdev, + void *data, size_t max_len ) { + struct dhcp_packet dhcppkt; + int rc; + + /* Create base DHCPACK packet */ + if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL, + data, max_len ) ) != 0 ) { + DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) ); + return rc; + } + + /* Merge in globally-scoped settings, then netdev-specific + * settings. Do it in this order so that netdev-specific + * settings take precedence regardless of stated priorities. + */ + if ( ( rc = copy_settings ( &dhcppkt, NULL ) ) != 0 ) { + DBG ( "Could not set DHCPACK global settings: %s\n", + strerror ( rc ) ); + return rc; + } + if ( ( rc = copy_settings ( &dhcppkt, + netdev_settings ( netdev ) ) ) != 0 ) { + DBG ( "Could not set DHCPACK netdev settings: %s\n", + strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * Create ProxyDHCPACK packet + * + * @v netdev Network device + * @v data Buffer for DHCP packet + * @v max_len Size of DHCP packet buffer + * @ret rc Return status code + * + * Used by external code. + */ +int create_fakeproxydhcpack ( struct net_device *netdev, + void *data, size_t max_len ) { + struct dhcp_packet dhcppkt; + struct settings *settings; + int rc; + + /* Identify ProxyDHCP settings */ + settings = find_settings ( PROXYDHCP_SETTINGS_NAME ); + + /* No ProxyDHCP settings => return empty block */ + if ( ! settings ) { + memset ( data, 0, max_len ); + return 0; + } + + /* Create base DHCPACK packet */ + if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL, + data, max_len ) ) != 0 ) { + DBG ( "Could not create ProxyDHCPACK: %s\n", + strerror ( rc ) ); + return rc; + } + + /* Merge in ProxyDHCP options */ + if ( ( rc = copy_settings ( &dhcppkt, settings ) ) != 0 ) { + DBG ( "Could not set ProxyDHCPACK settings: %s\n", + strerror ( rc ) ); + return rc; + } + + return 0; +} diff --git a/src/net/ipv4.c b/src/net/ipv4.c index 67bfc2d6..591293b7 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -95,62 +95,6 @@ static void del_ipv4_miniroute ( struct ipv4_miniroute *miniroute ) { free ( miniroute ); } -/** - * Create IPv4 routing table - * - * @ret rc Return status code - */ -static int ipv4_create_routes ( void ) { - struct ipv4_miniroute *miniroute; - struct ipv4_miniroute *tmp; - struct net_device *netdev; - struct settings *settings; - struct in_addr address = { 0 }; - struct in_addr netmask = { 0 }; - struct in_addr gateway = { INADDR_NONE }; - - /* Delete all existing routes */ - list_for_each_entry_safe ( miniroute, tmp, &ipv4_miniroutes, list ) - del_ipv4_miniroute ( miniroute ); - - /* Create a route for each configured network device */ - for_each_netdev ( netdev ) { - settings = netdev_settings ( netdev ); - /* Get IPv4 address */ - address.s_addr = 0; - fetch_ipv4_setting ( settings, DHCP_EB_YIADDR, &address ); - if ( ! address.s_addr ) - continue; - /* Calculate default netmask */ - if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) { - netmask.s_addr = htonl ( IN_CLASSA_NET ); - } else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) { - netmask.s_addr = htonl ( IN_CLASSB_NET ); - } else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) { - netmask.s_addr = htonl ( IN_CLASSC_NET ); - } else { - netmask.s_addr = 0; - } - /* Override with subnet mask, if present */ - fetch_ipv4_setting ( settings, DHCP_SUBNET_MASK, &netmask ); - /* Get default gateway, if present */ - gateway.s_addr = INADDR_NONE; - fetch_ipv4_setting ( settings, DHCP_ROUTERS, &gateway ); - /* Configure route */ - miniroute = add_ipv4_miniroute ( netdev, address, - netmask, gateway ); - if ( ! miniroute ) - return -ENOMEM; - } - - return 0; -} - -/** IPv4 settings applicator */ -struct settings_applicator ipv4_settings_applicator __settings_applicator = { - .apply = ipv4_create_routes, -}; - /** * Perform IPv4 routing * @@ -600,3 +544,90 @@ struct arp_net_protocol ipv4_arp_protocol __arp_net_protocol = { .net_protocol = &ipv4_protocol, .check = ipv4_arp_check, }; + +/****************************************************************************** + * + * Settings + * + ****************************************************************************** + */ + +/** IPv4 address setting */ +struct setting ip_setting __setting = { + .name = "ip", + .description = "IPv4 address", + .tag = DHCP_EB_YIADDR, + .type = &setting_type_ipv4, +}; + +/** IPv4 subnet mask setting */ +struct setting netmask_setting __setting = { + .name = "netmask", + .description = "IPv4 subnet mask", + .tag = DHCP_SUBNET_MASK, + .type = &setting_type_ipv4, +}; + +/** Default gateway setting */ +struct setting gateway_setting __setting = { + .name = "gateway", + .description = "Default gateway", + .tag = DHCP_ROUTERS, + .type = &setting_type_ipv4, +}; + +/** + * Create IPv4 routing table based on configured settings + * + * @ret rc Return status code + */ +static int ipv4_create_routes ( void ) { + struct ipv4_miniroute *miniroute; + struct ipv4_miniroute *tmp; + struct net_device *netdev; + struct settings *settings; + struct in_addr address = { 0 }; + struct in_addr netmask = { 0 }; + struct in_addr gateway = { INADDR_NONE }; + + /* Delete all existing routes */ + list_for_each_entry_safe ( miniroute, tmp, &ipv4_miniroutes, list ) + del_ipv4_miniroute ( miniroute ); + + /* Create a route for each configured network device */ + for_each_netdev ( netdev ) { + settings = netdev_settings ( netdev ); + /* Get IPv4 address */ + address.s_addr = 0; + fetch_ipv4_setting ( settings, &ip_setting, &address ); + if ( ! address.s_addr ) + continue; + /* Calculate default netmask */ + if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) { + netmask.s_addr = htonl ( IN_CLASSA_NET ); + } else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) { + netmask.s_addr = htonl ( IN_CLASSB_NET ); + } else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) { + netmask.s_addr = htonl ( IN_CLASSC_NET ); + } else { + netmask.s_addr = 0; + } + /* Override with subnet mask, if present */ + fetch_ipv4_setting ( settings, &netmask_setting, &netmask ); + /* Get default gateway, if present */ + gateway.s_addr = INADDR_NONE; + fetch_ipv4_setting ( settings, &gateway_setting, &gateway ); + /* Configure route */ + miniroute = add_ipv4_miniroute ( netdev, address, + netmask, gateway ); + if ( ! miniroute ) + return -ENOMEM; + } + + return 0; +} + +/** IPv4 settings applicator */ +struct settings_applicator ipv4_settings_applicator __settings_applicator = { + .apply = ipv4_create_routes, +}; diff --git a/src/net/netdev_settings.c b/src/net/netdev_settings.c index c8e630a9..44aca7d8 100644 --- a/src/net/netdev_settings.c +++ b/src/net/netdev_settings.c @@ -28,28 +28,34 @@ * */ +/** Network device named settings */ +struct setting mac_setting __setting = { + .name = "mac", + .description = "MAC address", + .type = &setting_type_hex, +}; + /** * Store value of network device setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to store * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ -static int netdev_store ( struct settings *settings, unsigned int tag, +static int netdev_store ( struct settings *settings, struct setting *setting, const void *data, size_t len ) { struct net_device *netdev = container_of ( settings, struct net_device, settings.settings ); - switch ( tag ) { - case DHCP_EB_MAC: + if ( setting_cmp ( setting, &mac_setting ) == 0 ) { if ( len != netdev->ll_protocol->ll_addr_len ) return -EINVAL; memcpy ( netdev->ll_addr, data, len ); return 0; - default : - return simple_settings_store ( settings, tag, data, len ); + } else { + return simple_settings_store ( settings, setting, data, len ); } } @@ -57,24 +63,23 @@ static int netdev_store ( struct settings *settings, unsigned int tag, * Fetch value of network device setting * * @v settings Settings block - * @v tag Setting tag number + * @v setting Setting to fetch * @v data Setting data, or NULL to clear setting * @v len Length of setting data * @ret rc Return status code */ -static int netdev_fetch ( struct settings *settings, unsigned int tag, +static int netdev_fetch ( struct settings *settings, struct setting *setting, void *data, size_t len ) { struct net_device *netdev = container_of ( settings, struct net_device, settings.settings ); - switch ( tag ) { - case DHCP_EB_MAC: + if ( setting_cmp ( setting, &mac_setting ) == 0 ) { if ( len > netdev->ll_protocol->ll_addr_len ) len = netdev->ll_protocol->ll_addr_len; memcpy ( data, netdev->ll_addr, len ); return netdev->ll_protocol->ll_addr_len; - default : - return simple_settings_fetch ( settings, tag, data, len ); + } else { + return simple_settings_fetch ( settings, setting, data, len ); } } @@ -83,13 +88,3 @@ struct settings_operations netdev_settings_operations = { .store = netdev_store, .fetch = netdev_fetch, }; - -/** Network device named settings */ -struct named_setting netdev_named_settings[] __named_setting = { - { - .name = "mac", - .description = "MAC address", - .tag = DHCP_EB_MAC, - .type = &setting_type_hex, - }, -}; diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index f071b04a..c01ca44b 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -1591,14 +1591,22 @@ int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) { /**************************************************************************** * - * Settings applicators + * Settings * */ +/** iSCSI initiator IQN setting */ +struct setting initiator_iqn_setting __setting = { + .name = "initiator-iqn", + .description = "iSCSI initiator name", + .tag = DHCP_ISCSI_INITIATOR_IQN, + .type = &setting_type_string, +}; + /** An iSCSI string setting */ struct iscsi_string_setting { - /** Setting tag number */ - unsigned int tag; + /** Setting */ + struct setting *setting; /** String to update */ char **string; /** String prefix */ @@ -1608,22 +1616,22 @@ struct iscsi_string_setting { /** iSCSI string settings */ static struct iscsi_string_setting iscsi_string_settings[] = { { - .tag = DHCP_ISCSI_INITIATOR_IQN, + .setting = &initiator_iqn_setting, .string = &iscsi_explicit_initiator_iqn, .prefix = "", }, { - .tag = DHCP_EB_USERNAME, + .setting = &username_setting, .string = &iscsi_username, .prefix = "", }, { - .tag = DHCP_EB_PASSWORD, + .setting = &password_setting, .string = &iscsi_password, .prefix = "", }, { - .tag = DHCP_HOST_NAME, + .setting = &hostname_setting, .string = &iscsi_default_initiator_iqn, .prefix = "iqn.2000-09.org.etherboot:", }, @@ -1648,7 +1656,7 @@ static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){ /* Allocate new string */ prefix_len = strlen ( setting->prefix ); - setting_len = fetch_setting_len ( NULL, setting->tag ); + setting_len = fetch_setting_len ( NULL, setting->setting ); if ( setting_len < 0 ) { /* Missing settings are not errors; leave strings as NULL */ return 0; @@ -1660,7 +1668,7 @@ static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){ /* Fill new string */ strcpy ( p, setting->prefix ); - check_len = fetch_string_setting ( NULL, setting->tag, + check_len = fetch_string_setting ( NULL, setting->setting, ( p + prefix_len ), ( len - prefix_len ) ); assert ( check_len == setting_len ); @@ -1682,8 +1690,8 @@ static int apply_iscsi_settings ( void ) { sizeof ( iscsi_string_settings[0] ) ) ; i++ ) { setting = &iscsi_string_settings[i]; if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) { - DBG ( "iSCSI could not apply setting %d\n", - setting->tag ); + DBG ( "iSCSI could not apply setting %s\n", + setting->setting->name ); return rc; } } diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 8789f925..98b8af0b 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -130,9 +130,6 @@ static uint32_t dhcp_xid ( struct net_device *netdev ) { return xid; } -/** Settings block name used for ProxyDHCP responses */ -#define PROXYDHCP_SETTINGS_NAME "proxydhcp" - /** * Create a DHCP packet * @@ -180,12 +177,12 @@ int create_dhcp_packet ( struct dhcp_packet *dhcppkt, memcpy ( dhcphdr->chaddr, netdev->ll_addr, hlen ); memcpy ( dhcphdr->options, options->data, options_len ); - /* Initialise DHCP packet structure and settings interface */ + /* Initialise DHCP packet structure */ memset ( dhcppkt, 0, sizeof ( *dhcppkt ) ); - dhcppkt_init ( dhcppkt, NULL, data, max_len ); + dhcppkt_init ( dhcppkt, data, max_len ); /* Set DHCP_MESSAGE_TYPE option */ - if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_MESSAGE_TYPE, + if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype, sizeof ( msgtype ) ) ) != 0 ) return rc; @@ -230,10 +227,10 @@ struct dhcp_client_uuid { * @v max_len Size of DHCP packet buffer * @ret rc Return status code */ -static int create_dhcp_request ( struct dhcp_packet *dhcppkt, - struct net_device *netdev, - struct dhcp_packet *dhcpoffer, - void *data, size_t max_len ) { +int create_dhcp_request ( struct dhcp_packet *dhcppkt, + struct net_device *netdev, + struct dhcp_packet *dhcpoffer, + void *data, size_t max_len ) { struct device_description *desc = &netdev->dev->desc; struct dhcp_netdev_desc dhcp_desc; struct dhcp_client_id client_id; @@ -258,27 +255,26 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt, struct in_addr server_id; struct in_addr requested_ip; - if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings, - DHCP_SERVER_IDENTIFIER, - &server_id ) ) < 0 ) { + if ( dhcppkt_fetch ( dhcpoffer, DHCP_SERVER_IDENTIFIER, + &server_id, sizeof ( server_id ) ) + != sizeof ( server_id ) ) { DBG ( "DHCP offer missing server identifier\n" ); return -EINVAL; } - if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings, - DHCP_EB_YIADDR, - &requested_ip ) ) < 0 ) { + if ( dhcppkt_fetch ( dhcpoffer, DHCP_EB_YIADDR, + &requested_ip, sizeof ( requested_ip ) ) + != sizeof ( requested_ip ) ) { DBG ( "DHCP offer missing IP address\n" ); return -EINVAL; } - if ( ( rc = store_setting ( &dhcppkt->settings, - DHCP_SERVER_IDENTIFIER, &server_id, + if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER, + &server_id, sizeof ( server_id ) ) ) != 0 ) { DBG ( "DHCP could not set server identifier: %s\n ", strerror ( rc ) ); return rc; } - if ( ( rc = store_setting ( &dhcppkt->settings, - DHCP_REQUESTED_ADDRESS, + if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS, &requested_ip, sizeof ( requested_ip ) ) ) != 0 ){ DBG ( "DHCP could not set requested address: %s\n", @@ -289,8 +285,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt, /* Add options to identify the feature list */ dhcp_features_len = ( dhcp_features_end - dhcp_features ); - if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_EB_ENCAP, - dhcp_features, dhcp_features_len ) ) !=0 ){ + if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features, + dhcp_features_len ) ) != 0 ) { DBG ( "DHCP could not set features list option: %s\n", strerror ( rc ) ); return rc; @@ -300,8 +296,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt, dhcp_desc.type = desc->bus_type; dhcp_desc.vendor = htons ( desc->vendor ); dhcp_desc.device = htons ( desc->device ); - if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_EB_BUS_ID, - &dhcp_desc, sizeof ( dhcp_desc ) ) ) !=0 ){ + if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc, + sizeof ( dhcp_desc ) ) ) != 0 ) { DBG ( "DHCP could not set bus ID option: %s\n", strerror ( rc ) ); return rc; @@ -314,8 +310,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt, ll_addr_len = netdev->ll_protocol->ll_addr_len; assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) ); memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len ); - if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_CLIENT_ID, - &client_id, ( ll_addr_len + 1 ) ) ) != 0 ){ + if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id, + ( ll_addr_len + 1 ) ) ) != 0 ) { DBG ( "DHCP could not set client ID: %s\n", strerror ( rc ) ); return rc; @@ -324,8 +320,8 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt, /* Add client UUID, if we have one. Required for PXE. */ client_uuid.type = DHCP_CLIENT_UUID_TYPE; if ( ( rc = get_uuid ( &client_uuid.uuid ) ) == 0 ) { - if ( ( rc = store_setting ( &dhcppkt->settings, - DHCP_CLIENT_UUID, &client_uuid, + if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID, + &client_uuid, sizeof ( client_uuid ) ) ) != 0 ) { DBG ( "DHCP could not set client UUID: %s\n", strerror ( rc ) ); @@ -336,169 +332,109 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt, return 0; } -/** - * Create DHCPDISCOVER packet - * - * @v netdev Network device - * @v data Buffer for DHCP packet - * @v max_len Size of DHCP packet buffer - * @ret rc Return status code - * - * Used by external code. - */ -int create_dhcpdiscover ( struct net_device *netdev, - void *data, size_t max_len ) { - struct dhcp_packet dhcppkt; - int rc; - - if ( ( rc = create_dhcp_request ( &dhcppkt, netdev, NULL, data, - max_len ) ) != 0 ) { - DBG ( "Could not create DHCPDISCOVER: %s\n", - strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Create DHCPACK packet - * - * @v netdev Network device - * @v data Buffer for DHCP packet - * @v max_len Size of DHCP packet buffer - * @ret rc Return status code - * - * Used by external code. - */ -int create_dhcpack ( struct net_device *netdev, - void *data, size_t max_len ) { - struct dhcp_packet dhcppkt; - int rc; - - /* Create base DHCPACK packet */ - if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL, - data, max_len ) ) != 0 ) { - DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) ); - return rc; - } - - /* Merge in globally-scoped settings, then netdev-specific - * settings. Do it in this order so that netdev-specific - * settings take precedence regardless of stated priorities. - */ - if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 ) { - DBG ( "Could not set DHCPACK global settings: %s\n", - strerror ( rc ) ); - return rc; - } - if ( ( rc = copy_settings ( &dhcppkt.settings, - netdev_settings ( netdev ) ) ) != 0 ) { - DBG ( "Could not set DHCPACK netdev settings: %s\n", - strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Create ProxyDHCPACK packet - * - * @v netdev Network device - * @v data Buffer for DHCP packet - * @v max_len Size of DHCP packet buffer - * @ret rc Return status code - * - * Used by external code. - */ -int create_proxydhcpack ( struct net_device *netdev, - void *data, size_t max_len ) { - struct dhcp_packet dhcppkt; - struct settings *settings; - int rc; - - /* Identify ProxyDHCP settings */ - settings = find_settings ( PROXYDHCP_SETTINGS_NAME ); - - /* No ProxyDHCP settings => return empty block */ - if ( ! settings ) { - memset ( data, 0, max_len ); - return 0; - } - - /* Create base DHCPACK packet */ - if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL, - data, max_len ) ) != 0 ) { - DBG ( "Could not create ProxyDHCPACK: %s\n", - strerror ( rc ) ); - return rc; - } - - /* Merge in ProxyDHCP options */ - if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 ) { - DBG ( "Could not set ProxyDHCPACK settings: %s\n", - strerror ( rc ) ); - return rc; - } - - return 0; -} - /**************************************************************************** * - * DHCP packets contained in I/O buffers + * DHCP settings * */ -/** A DHCP packet contained in an I/O buffer */ -struct dhcp_iobuf_packet { - /** DHCP packet */ - struct dhcp_packet dhcppkt; +/** A DHCP settings block */ +struct dhcp_settings { /** Reference counter */ struct refcnt refcnt; /** Containing I/O buffer */ struct io_buffer *iobuf; + /** DHCP packet */ + struct dhcp_packet dhcppkt; + /** Setting interface */ + struct settings settings; }; /** - * Free DHCP packet contained in an I/O buffer + * Free DHCP settings block * * @v refcnt Reference counter */ -static void dhcpiob_free ( struct refcnt *refcnt ) { - struct dhcp_iobuf_packet *dhcpiob = - container_of ( refcnt, struct dhcp_iobuf_packet, refcnt ); +static void dhcpset_free ( struct refcnt *refcnt ) { + struct dhcp_settings *dhcpset = + container_of ( refcnt, struct dhcp_settings, refcnt ); - free_iob ( dhcpiob->iobuf ); - free ( dhcpiob ); + free_iob ( dhcpset->iobuf ); + free ( dhcpset ); } /** - * Create DHCP packet from I/O buffer + * Decrement reference count on DHCP settings block * - * @v iobuf I/O buffer - * @ret dhcpiob DHCP packet contained in I/O buffer - * - * This function takes ownership of the I/O buffer. Future accesses - * must be via the @c dhcpiob data structure. + * @v dhcpset DHCP settings block */ -static struct dhcp_iobuf_packet * dhcpiob_create ( struct io_buffer *iobuf ) { - struct dhcp_iobuf_packet *dhcpiob; - - dhcpiob = zalloc ( sizeof ( *dhcpiob ) ); - if ( dhcpiob ) { - dhcpiob->refcnt.free = dhcpiob_free; - dhcpiob->iobuf = iobuf; - dhcppkt_init ( &dhcpiob->dhcppkt, &dhcpiob->refcnt, - iobuf->data, iob_len ( iobuf ) ); - } - return dhcpiob; +static inline void dhcpset_put ( struct dhcp_settings *dhcpset ) { + ref_put ( &dhcpset->refcnt ); } -static void dhcpiob_put ( struct dhcp_iobuf_packet *dhcpiob ) { - if ( dhcpiob ) - ref_put ( &dhcpiob->refcnt ); +/** + * Store value of DHCP setting + * + * @v settings Settings block + * @v setting Setting to store + * @v data Setting data, or NULL to clear setting + * @v len Length of setting data + * @ret rc Return status code + */ +static int dhcpset_store ( struct settings *settings, struct setting *setting, + const void *data, size_t len ) { + struct dhcp_settings *dhcpset = + container_of ( settings, struct dhcp_settings, settings ); + + return dhcppkt_store ( &dhcpset->dhcppkt, setting->tag, data, len ); +} + +/** + * Fetch value of setting + * + * @v settings Settings block, or NULL to search all blocks + * @v setting Setting to fetch + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @ret len Length of setting data, or negative error + */ +static int dhcpset_fetch ( struct settings *settings, struct setting *setting, + void *data, size_t len ) { + struct dhcp_settings *dhcpset = + container_of ( settings, struct dhcp_settings, settings ); + + return dhcppkt_fetch ( &dhcpset->dhcppkt, setting->tag, data, len ); +} + +/** DHCP settings operations */ +static struct settings_operations dhcpset_settings_operations = { + .store = dhcpset_store, + .fetch = dhcpset_fetch, +}; + +/** + * Create DHCP setting block from I/O buffer + * + * @v iobuf I/O buffer + * @ret dhcpset DHCP settings block + * + * This function takes ownership of the I/O buffer. Future accesses + * must be via the @c dhcpset data structure. + */ +static struct dhcp_settings * dhcpset_create_iob ( struct io_buffer *iobuf ) { + struct dhcp_settings *dhcpset; + + dhcpset = zalloc ( sizeof ( *dhcpset ) ); + if ( dhcpset ) { + dhcpset->refcnt.free = dhcpset_free; + dhcpset->iobuf = iobuf; + dhcppkt_init ( &dhcpset->dhcppkt, + iobuf->data, iob_len ( iobuf ) ); + settings_init ( &dhcpset->settings, + &dhcpset_settings_operations, &dhcpset->refcnt, + DHCP_SETTINGS_NAME ); + } + return dhcpset; } /**************************************************************************** @@ -526,9 +462,9 @@ struct dhcp_session { */ int state; /** Response obtained from DHCP server */ - struct dhcp_iobuf_packet *response; + struct dhcp_settings *response; /** Response obtained from ProxyDHCP server */ - struct dhcp_iobuf_packet *proxy_response; + struct dhcp_settings *proxy_response; /** Retransmission timer */ struct retry_timer timer; /** Session start time (in ticks) */ @@ -545,8 +481,8 @@ static void dhcp_free ( struct refcnt *refcnt ) { container_of ( refcnt, struct dhcp_session, refcnt ); netdev_put ( dhcp->netdev ); - dhcpiob_put ( dhcp->response ); - dhcpiob_put ( dhcp->proxy_response ); + dhcpset_put ( dhcp->response ); + dhcpset_put ( dhcp->proxy_response ); free ( dhcp ); } @@ -584,7 +520,7 @@ static int dhcp_register_settings ( struct dhcp_session *dhcp ) { /* Register ProxyDHCP settings, if present */ if ( dhcp->proxy_response ) { - settings = &dhcp->proxy_response->dhcppkt.settings; + settings = &dhcp->proxy_response->settings; settings->name = PROXYDHCP_SETTINGS_NAME; old_settings = find_settings ( settings->name ); if ( old_settings ) @@ -595,7 +531,7 @@ static int dhcp_register_settings ( struct dhcp_session *dhcp ) { /* Register DHCP settings */ parent = netdev_settings ( dhcp->netdev ); - settings = &dhcp->response->dhcppkt.settings; + settings = &dhcp->response->settings; old_settings = find_child_settings ( parent, settings->name ); if ( old_settings ) unregister_settings ( old_settings ); @@ -701,24 +637,24 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, struct xfer_metadata *meta __unused ) { struct dhcp_session *dhcp = container_of ( xfer, struct dhcp_session, xfer ); - struct dhcp_iobuf_packet *response; - struct dhcp_iobuf_packet **store_response; + struct dhcp_settings *response; + struct dhcp_settings **store_response; struct dhcphdr *dhcphdr; - struct settings *settings; - unsigned int msgtype; + uint8_t msgtype = 0; + uint8_t priority = 0; + uint8_t existing_priority = 0; unsigned long elapsed; int is_proxy; - int ignore_proxy; + uint8_t ignore_proxy = 0; int rc; /* Convert packet into a DHCP-packet-in-iobuf */ - response = dhcpiob_create ( iobuf ); + response = dhcpset_create_iob ( iobuf ); if ( ! response ) { DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp ); return -ENOMEM; } dhcphdr = response->dhcppkt.dhcphdr; - settings = &response->dhcppkt.settings; /* Check for matching transaction ID */ if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) { @@ -730,7 +666,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, /* Determine and verify message type */ is_proxy = ( dhcphdr->yiaddr.s_addr == 0 ); - msgtype = fetch_uintz_setting ( settings, DHCP_MESSAGE_TYPE ); + dhcppkt_fetch ( &response->dhcppkt, DHCP_MESSAGE_TYPE, &msgtype, + sizeof ( msgtype ) ); DBGC ( dhcp, "DHCP %p received %s%s\n", dhcp, ( is_proxy ? "Proxy" : "" ), dhcp_msgtype_name ( msgtype ) ); if ( ( ( dhcp->state != DHCPDISCOVER ) || ( msgtype != DHCPOFFER ) ) && @@ -746,14 +683,18 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, * currently-stored options. */ store_response = ( is_proxy ? &dhcp->proxy_response : &dhcp->response); - if ( ( ! *store_response ) || - ( fetch_uintz_setting ( settings, DHCP_EB_PRIORITY ) >= - fetch_uintz_setting ( &(*store_response)->dhcppkt.settings, - DHCP_EB_PRIORITY ) ) ) { - dhcpiob_put ( *store_response ); + if ( *store_response ) { + dhcppkt_fetch ( &(*store_response)->dhcppkt, DHCP_EB_PRIORITY, + &existing_priority, + sizeof ( existing_priority ) ); + } + dhcppkt_fetch ( &response->dhcppkt, DHCP_EB_PRIORITY, &priority, + sizeof ( priority ) ); + if ( priority >= existing_priority ) { + dhcpset_put ( *store_response ); *store_response = response; } else { - dhcpiob_put ( response ); + dhcpset_put ( response ); } /* If we don't yet have a standard DHCP response (i.e. one @@ -763,8 +704,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, goto out; /* Handle DHCP response */ - ignore_proxy = fetch_uintz_setting ( &dhcp->response->dhcppkt.settings, - DHCP_EB_NO_PROXYDHCP ); + dhcppkt_fetch ( &dhcp->response->dhcppkt, DHCP_EB_NO_PROXYDHCP, + &ignore_proxy, sizeof ( ignore_proxy ) ); switch ( dhcp->state ) { case DHCPDISCOVER: /* If we have allowed sufficient time for ProxyDHCP @@ -780,7 +721,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, case DHCPREQUEST: /* DHCP finished; register options and exit */ if ( ignore_proxy && dhcp->proxy_response ) { - dhcpiob_put ( dhcp->proxy_response ); + dhcpset_put ( dhcp->proxy_response ); dhcp->proxy_response = NULL; } if ( ( rc = dhcp_register_settings ( dhcp ) ) != 0 ) { @@ -797,7 +738,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, return 0; out_discard: - dhcpiob_put ( response ); + dhcpset_put ( response ); return 0; } diff --git a/src/net/udp/dns.c b/src/net/udp/dns.c index 5e632d18..1bcdbc7e 100644 --- a/src/net/udp/dns.c +++ b/src/net/udp/dns.c @@ -506,6 +506,21 @@ struct resolver dns_resolver __resolver ( RESOLV_NORMAL ) = { .resolv = dns_resolv, }; +/****************************************************************************** + * + * Settings + * + ****************************************************************************** + */ + +/** DNS server setting */ +struct setting dns_setting __setting = { + .name = "dns", + .description = "DNS server", + .tag = DHCP_DNS_SERVERS, + .type = &setting_type_ipv4, +}; + /** * Apply nameserver setting * @@ -516,7 +531,7 @@ static int apply_nameserver_setting ( void ) { ( struct sockaddr_in * ) &nameserver; int len; - if ( ( len = fetch_ipv4_setting ( NULL, DHCP_DNS_SERVERS, + if ( ( len = fetch_ipv4_setting ( NULL, &dns_setting, &sin_nameserver->sin_addr ) ) >= 0 ){ sin_nameserver->sin_family = AF_INET; DBG ( "DNS using nameserver %s\n", diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index 8bd2b80b..e49bcf9f 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -1093,6 +1093,21 @@ struct uri_opener mtftp_uri_opener __uri_opener = { .open = mtftp_open, }; +/****************************************************************************** + * + * Settings + * + ****************************************************************************** + */ + +/** TFTP server setting */ +struct setting next_server_setting __setting = { + .name = "next-server", + .description = "TFTP server", + .tag = DHCP_EB_SIADDR, + .type = &setting_type_ipv4, +}; + /** * Apply TFTP configuration settings * @@ -1106,7 +1121,7 @@ static int tftp_apply_settings ( void ) { /* Retrieve TFTP server setting */ last_tftp_server = tftp_server; - fetch_ipv4_setting ( NULL, DHCP_EB_SIADDR, &tftp_server ); + fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server ); /* If TFTP server setting has changed, set the current working * URI to match. Do it only when the TFTP server has changed diff --git a/src/usr/aoeboot.c b/src/usr/aoeboot.c index 6bf56a87..f0e481bd 100644 --- a/src/usr/aoeboot.c +++ b/src/usr/aoeboot.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -56,7 +55,6 @@ int aoeboot ( const char *root_path ) { container_of ( ata.backend, struct aoe_session, refcnt ); abft_fill_data ( aoe ); - drive.drive = fetch_uintz_setting ( NULL, DHCP_EB_BIOS_DRIVE ); drive.blockdev = &ata.blockdev; register_int13_drive ( &drive ); diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c index bc86d05e..c1a61ec0 100644 --- a/src/usr/autoboot.c +++ b/src/usr/autoboot.c @@ -147,14 +147,14 @@ static int netboot ( struct net_device *netdev ) { return rc; /* Try to download and boot whatever we are given as a filename */ - fetch_string_setting ( NULL, DHCP_BOOTFILE_NAME, buf, sizeof ( buf ) ); + fetch_string_setting ( NULL, &filename_setting, buf, sizeof ( buf ) ); if ( buf[0] ) { printf ( "Booting from filename \"%s\"\n", buf ); return boot_filename ( buf ); } /* No filename; try the root path */ - fetch_string_setting ( NULL, DHCP_ROOT_PATH, buf, sizeof ( buf ) ); + fetch_string_setting ( NULL, &root_path_setting, buf, sizeof ( buf ) ); if ( buf[0] ) { printf ( "Booting from root path \"%s\"\n", buf ); return boot_root_path ( buf ); diff --git a/src/usr/iscsiboot.c b/src/usr/iscsiboot.c index c3a477c4..99edc879 100644 --- a/src/usr/iscsiboot.c +++ b/src/usr/iscsiboot.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +45,6 @@ int iscsiboot ( const char *root_path ) { goto error_init; } - drive.drive = fetch_uintz_setting ( NULL, DHCP_EB_BIOS_DRIVE ); drive.blockdev = &scsi.blockdev; /* FIXME: ugly, ugly hack */