david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[Settings] copy_settings() should not fail if some settings are missing!

This commit is contained in:
Michael Brown 2008-03-23 23:28:21 +00:00
parent 978865da2f
commit 23e077666b
3 changed files with 71 additions and 59 deletions

View File

@ -498,40 +498,6 @@ unsigned long fetch_uintz_setting ( struct settings *settings,
return value; return value;
} }
/**
* Copy setting
*
* @v dest Destination settings block
* @v dest_tag Destination setting tag number
* @v source Source settings block
* @v source_tag Source setting tag number
* @ret rc Return status code
*/
int copy_setting ( struct settings *dest, unsigned int dest_tag,
struct settings *source, unsigned int source_tag ) {
int len;
int check_len;
int rc;
len = fetch_setting_len ( source, source_tag );
if ( len < 0 )
return len;
{
char buf[len];
check_len = fetch_setting ( source, source_tag, buf,
sizeof ( buf ) );
assert ( check_len == len );
if ( ( rc = store_setting ( dest, dest_tag, buf,
sizeof ( buf ) ) ) != 0 )
return rc;
}
return 0;
}
/** /**
* Copy settings * Copy settings
* *
@ -545,6 +511,8 @@ static int copy_encap_settings ( struct settings *dest,
unsigned int encapsulator ) { unsigned int encapsulator ) {
unsigned int subtag; unsigned int subtag;
unsigned int tag; unsigned int tag;
int len;
int check_len;
int rc; int rc;
for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) { for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
@ -552,16 +520,26 @@ static int copy_encap_settings ( struct settings *dest,
switch ( tag ) { switch ( tag ) {
case DHCP_EB_ENCAP: case DHCP_EB_ENCAP:
case DHCP_VENDOR_ENCAP: case DHCP_VENDOR_ENCAP:
/* Process encapsulated options field */ /* Process encapsulated settings */
if ( ( rc = copy_encap_settings ( dest, source, if ( ( rc = copy_encap_settings ( dest, source,
tag ) ) != 0 ) tag ) ) != 0 )
return rc; return rc;
break; break;
default: default:
/* Copy option to reassembled packet */ /* Copy setting, if present */
if ( ( rc = copy_setting ( dest, tag, source, len = fetch_setting_len ( source, tag );
tag ) ) != 0 ) if ( len < 0 )
return rc; break;
{
char buf[len];
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; break;
} }
} }

View File

@ -163,8 +163,6 @@ extern int store_setting ( struct settings *settings, unsigned int tag,
const void *data, size_t len ); const void *data, size_t len );
extern int fetch_setting ( struct settings *settings, unsigned int tag, extern int fetch_setting ( struct settings *settings, unsigned int tag,
void *data, size_t len ); void *data, size_t len );
extern int copy_setting ( struct settings *dest, unsigned int dest_tag,
struct settings *source, unsigned int source_tag );
extern int copy_settings ( struct settings *dest, struct settings *source ); extern int copy_settings ( struct settings *dest, struct settings *source );
extern int fetch_setting_len ( struct settings *settings, unsigned int tag ); 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_string_setting ( struct settings *settings, unsigned int tag,

View File

@ -255,20 +255,34 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
/* Copy any required options from previous server repsonse */ /* Copy any required options from previous server repsonse */
if ( dhcpoffer ) { if ( dhcpoffer ) {
if ( ( rc = copy_setting ( &dhcppkt->settings, struct in_addr server_id;
DHCP_SERVER_IDENTIFIER, struct in_addr requested_ip;
&dhcpoffer->settings,
DHCP_SERVER_IDENTIFIER ) ) != 0 ) { if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
DBG ( "DHCP could not set server identifier " DHCP_SERVER_IDENTIFIER,
"option: %s\n", strerror ( rc ) ); &server_id ) ) < 0 ) {
DBG ( "DHCP offer missing server identifier\n" );
return -EINVAL;
}
if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
DHCP_EB_YIADDR,
&requested_ip ) ) < 0 ) {
DBG ( "DHCP offer missing IP address\n" );
return -EINVAL;
}
if ( ( rc = store_setting ( &dhcppkt->settings,
DHCP_SERVER_IDENTIFIER, &server_id,
sizeof ( server_id ) ) ) != 0 ) {
DBG ( "DHCP could not set server identifier: %s\n ",
strerror ( rc ) );
return rc; return rc;
} }
if ( ( rc = copy_setting ( &dhcppkt->settings, if ( ( rc = store_setting ( &dhcppkt->settings,
DHCP_REQUESTED_ADDRESS, DHCP_REQUESTED_ADDRESS,
&dhcpoffer->settings, &requested_ip,
DHCP_EB_YIADDR ) ) != 0 ) { sizeof ( requested_ip ) ) ) != 0 ){
DBG ( "DHCP could not set requested address " DBG ( "DHCP could not set requested address: %s\n",
"option: %s\n", strerror ( rc ) ); strerror ( rc ) );
return rc; return rc;
} }
} }
@ -335,8 +349,16 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
int create_dhcpdiscover ( struct net_device *netdev, int create_dhcpdiscover ( struct net_device *netdev,
void *data, size_t max_len ) { void *data, size_t max_len ) {
struct dhcp_packet dhcppkt; struct dhcp_packet dhcppkt;
int rc;
return create_dhcp_request ( &dhcppkt, netdev, NULL, data, max_len ); 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;
} }
/** /**
@ -356,18 +378,26 @@ int create_dhcpack ( struct net_device *netdev,
/* Create base DHCPACK packet */ /* Create base DHCPACK packet */
if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL, if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
data, max_len ) ) != 0 ) data, max_len ) ) != 0 ) {
DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
return rc; return rc;
}
/* Merge in globally-scoped settings, then netdev-specific /* Merge in globally-scoped settings, then netdev-specific
* settings. Do it in this order so that netdev-specific * settings. Do it in this order so that netdev-specific
* settings take precedence regardless of stated priorities. * settings take precedence regardless of stated priorities.
*/ */
if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 ) if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 ) {
DBG ( "Could not set DHCPACK global settings: %s\n",
strerror ( rc ) );
return rc; return rc;
}
if ( ( rc = copy_settings ( &dhcppkt.settings, if ( ( rc = copy_settings ( &dhcppkt.settings,
netdev_settings ( netdev ) ) ) != 0 ) netdev_settings ( netdev ) ) ) != 0 ) {
DBG ( "Could not set DHCPACK netdev settings: %s\n",
strerror ( rc ) );
return rc; return rc;
}
return 0; return 0;
} }
@ -399,12 +429,18 @@ int create_proxydhcpack ( struct net_device *netdev,
/* Create base DHCPACK packet */ /* Create base DHCPACK packet */
if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL, if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
data, max_len ) ) != 0 ) data, max_len ) ) != 0 ) {
DBG ( "Could not create ProxyDHCPACK: %s\n",
strerror ( rc ) );
return rc; return rc;
}
/* Merge in ProxyDHCP options */ /* Merge in ProxyDHCP options */
if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 ) if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 ) {
DBG ( "Could not set ProxyDHCPACK settings: %s\n",
strerror ( rc ) );
return rc; return rc;
}
return 0; return 0;
} }