/** * Load non-volatile stored options from non-volatile storage device * * @v nvo Non-volatile options block * @ret rc Return status code */ static int nvo_load ( struct nvo_block *nvo ) { uint8_t *options_data = nvo->dhcpopts.data; int rc; /* Skip reading zero-length NVO fields */ if ( nvo->len == 0 ) { DBGC ( nvo, "NVO %p is empty; skipping load\n", nvo ); return 0; } /* Read data */ if ( ( rc = nvs_read ( nvo->nvs, nvo->address, nvo->data, nvo->len ) ) != 0 ) { DBGC ( nvo, "NVO %p could not read %zd bytes at %#04x: %s\n", nvo, nvo->len, nvo->address, strerror ( rc ) ); return rc; } /* If checksum fails, or options data starts with a zero, * assume the whole block is invalid. This should capture the * case of random initial contents. */ if ( ( nvo_checksum ( nvo ) != 0 ) || ( options_data[0] == 0 ) ) { DBGC ( nvo, "NVO %p has checksum %02x and initial byte %02x; " "assuming empty\n", nvo, nvo_checksum ( nvo ), options_data[0] ); memset ( nvo->data, 0, nvo->len ); } /* Rescan DHCP option block */ dhcpopt_update_used_len ( &nvo->dhcpopts ); DBGC ( nvo, "NVO %p loaded from non-volatile storage\n", nvo ); return 0; }
/** * Initialise prepopulated block of DHCP options * * @v options Uninitialised DHCP option block * @v data Memory for DHCP option data * @v alloc_len Length of memory for DHCP option data * @v realloc DHCP option block reallocator * * The memory content must already be filled with valid DHCP options. * A zeroed block counts as a block of valid DHCP options. */ void dhcpopt_init ( struct dhcp_options *options, void *data, size_t alloc_len, int ( * realloc ) ( struct dhcp_options *options, size_t len ) ) { /* Fill in fields */ options->data = data; options->alloc_len = alloc_len; options->realloc = realloc; /* Update length */ dhcpopt_update_used_len ( options ); DBGC ( options, "DHCPOPT %p created (data %p lengths %#zx,%#zx)\n", options, options->data, options->used_len, options->alloc_len ); }