Browse Source

[Settings] Remove assumption that all settings have DHCP tag values

Allow for settings to be described by something other than a DHCP option
tag if desirable.  Currently used only for the MAC address setting.

Separate out fake DHCP packet creation code from dhcp.c to fakedhcp.c.

Remove notion of settings from dhcppkt.c.

Rationalise dhcp.c to use settings API only for final registration of the
DHCP options, rather than using {store,fetch}_setting throughout.
tags/v0.9.4
Michael Brown 17 years ago
parent
commit
92d15eff30

+ 3
- 4
src/arch/i386/image/nbi.c View File

8
 #include <gpxe/segment.h>
8
 #include <gpxe/segment.h>
9
 #include <gpxe/init.h>
9
 #include <gpxe/init.h>
10
 #include <gpxe/netdevice.h>
10
 #include <gpxe/netdevice.h>
11
-#include <gpxe/dhcp.h>
12
-#include <gpxe/dhcppkt.h>
11
+#include <gpxe/fakedhcp.h>
13
 #include <gpxe/image.h>
12
 #include <gpxe/image.h>
14
 #include <gpxe/features.h>
13
 #include <gpxe/features.h>
15
 
14
 
400
 		return -ENODEV;
399
 		return -ENODEV;
401
 	}
400
 	}
402
 
401
 
403
-	if ( ( rc = create_dhcpack ( boot_netdev, basemem_packet,
404
-				     sizeof ( basemem_packet ) ) ) != 0 ) {
402
+	if ( ( rc = create_fakedhcpack ( boot_netdev, basemem_packet,
403
+					 sizeof ( basemem_packet ) ) ) != 0 ) {
405
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
406
 		return rc;
405
 		return rc;
407
 	}
406
 	}

+ 14
- 13
src/core/ibft.c View File

123
 }
123
 }
124
 
124
 
125
 /**
125
 /**
126
- * Fill in an IP address within iBFT from DHCP option
126
+ * Fill in an IP address within iBFT from configuration setting
127
  *
127
  *
128
  * @v ipaddr		IP address field
128
  * @v ipaddr		IP address field
129
+ * @v setting		Configuration setting
129
  * @v tag		DHCP option tag
130
  * @v tag		DHCP option tag
130
  */
131
  */
131
 static void ibft_set_ipaddr_option ( struct ibft_ipaddr *ipaddr,
132
 static void ibft_set_ipaddr_option ( struct ibft_ipaddr *ipaddr,
132
-				     unsigned int tag ) {
133
+				     struct setting *setting ) {
133
 	struct in_addr in = { 0 };
134
 	struct in_addr in = { 0 };
134
-	fetch_ipv4_setting ( NULL, tag, &in );
135
+	fetch_ipv4_setting ( NULL, setting, &in );
135
 	ibft_set_ipaddr ( ipaddr, in );
136
 	ibft_set_ipaddr ( ipaddr, in );
136
 }
137
 }
137
 
138
 
182
 }
183
 }
183
 
184
 
184
 /**
185
 /**
185
- * Fill in a string field within iBFT from DHCP option
186
+ * Fill in a string field within iBFT from configuration setting
186
  *
187
  *
187
  * @v strings		iBFT string block descriptor
188
  * @v strings		iBFT string block descriptor
188
  * @v string		String field
189
  * @v string		String field
189
- * @v tag		DHCP option tag
190
+ * @v setting		Configuration setting
190
  * @ret rc		Return status code
191
  * @ret rc		Return status code
191
  */
192
  */
192
 static int ibft_set_string_option ( struct ibft_string_block *strings,
193
 static int ibft_set_string_option ( struct ibft_string_block *strings,
193
 				    struct ibft_string *string,
194
 				    struct ibft_string *string,
194
-				    unsigned int tag ) {
195
+				    struct setting *setting ) {
195
 	int len;
196
 	int len;
196
 	char *dest;
197
 	char *dest;
197
 	int rc;
198
 	int rc;
198
 
199
 
199
-	len = fetch_setting_len ( NULL, tag );
200
+	len = fetch_setting_len ( NULL, setting );
200
 	if ( len < 0 ) {
201
 	if ( len < 0 ) {
201
 		string->offset = 0;
202
 		string->offset = 0;
202
 		string->length = 0;
203
 		string->length = 0;
206
 	if ( ( rc = ibft_alloc_string ( strings, string, len ) ) != 0 )
207
 	if ( ( rc = ibft_alloc_string ( strings, string, len ) ) != 0 )
207
 		return rc;
208
 		return rc;
208
 	dest = ( ( ( char * ) strings->table ) + string->offset );
209
 	dest = ( ( ( char * ) strings->table ) + string->offset );
209
-	fetch_string_setting ( NULL, tag, dest, ( len + 1 ) );
210
+	fetch_string_setting ( NULL, setting, dest, ( len + 1 ) );
210
 	return 0;
211
 	return 0;
211
 }
212
 }
212
 
213
 
226
 	int rc;
227
 	int rc;
227
 
228
 
228
 	/* Extract values from DHCP configuration */
229
 	/* Extract values from DHCP configuration */
229
-	ibft_set_ipaddr_option ( &nic->ip_address, DHCP_EB_YIADDR );
230
-	ibft_set_ipaddr_option ( &nic->gateway, DHCP_ROUTERS );
231
-	ibft_set_ipaddr_option ( &nic->dns[0], DHCP_DNS_SERVERS );
230
+	ibft_set_ipaddr_option ( &nic->ip_address, &ip_setting );
231
+	ibft_set_ipaddr_option ( &nic->gateway, &gateway_setting );
232
+	ibft_set_ipaddr_option ( &nic->dns[0], &dns_setting );
232
 	if ( ( rc = ibft_set_string_option ( strings, &nic->hostname,
233
 	if ( ( rc = ibft_set_string_option ( strings, &nic->hostname,
233
-					     DHCP_HOST_NAME ) ) != 0 )
234
+					     &hostname_setting ) ) != 0 )
234
 		return rc;
235
 		return rc;
235
 
236
 
236
 	/* Derive subnet mask prefix from subnet mask */
237
 	/* Derive subnet mask prefix from subnet mask */
237
-	fetch_ipv4_setting ( NULL, DHCP_SUBNET_MASK, &netmask_addr );
238
+	fetch_ipv4_setting ( NULL, &netmask_setting, &netmask_addr );
238
 	while ( netmask_addr.s_addr ) {
239
 	while ( netmask_addr.s_addr ) {
239
 		if ( netmask_addr.s_addr & 0x1 )
240
 		if ( netmask_addr.s_addr & 0x1 )
240
 			netmask_count++;
241
 			netmask_count++;

+ 7
- 6
src/core/nvo.c View File

138
  * Store value of NVO setting
138
  * Store value of NVO setting
139
  *
139
  *
140
  * @v settings		Settings block
140
  * @v settings		Settings block
141
- * @v tag		Setting tag number
141
+ * @v setting		Setting to store
142
  * @v data		Setting data, or NULL to clear setting
142
  * @v data		Setting data, or NULL to clear setting
143
  * @v len		Length of setting data
143
  * @v len		Length of setting data
144
  * @ret rc		Return status code
144
  * @ret rc		Return status code
145
  */
145
  */
146
-static int nvo_store ( struct settings *settings, unsigned int tag,
146
+static int nvo_store ( struct settings *settings, struct setting *setting,
147
 		       const void *data, size_t len ) {
147
 		       const void *data, size_t len ) {
148
 	struct nvo_block *nvo =
148
 	struct nvo_block *nvo =
149
 		container_of ( settings, struct nvo_block, settings );
149
 		container_of ( settings, struct nvo_block, settings );
150
 	int rc;
150
 	int rc;
151
 
151
 
152
 	/* Update stored options */
152
 	/* Update stored options */
153
-	if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, tag, data, len ) ) != 0 ) {
153
+	if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, setting->tag,
154
+				    data, len ) ) != 0 ) {
154
 		DBGC ( nvo, "NVO %p could not store %zd bytes: %s\n",
155
 		DBGC ( nvo, "NVO %p could not store %zd bytes: %s\n",
155
 		       nvo, len, strerror ( rc ) );
156
 		       nvo, len, strerror ( rc ) );
156
 		return rc;
157
 		return rc;
167
  * Fetch value of NVO setting
168
  * Fetch value of NVO setting
168
  *
169
  *
169
  * @v settings		Settings block
170
  * @v settings		Settings block
170
- * @v tag		Setting tag number
171
+ * @v setting		Setting to fetch
171
  * @v data		Buffer to fill with setting data
172
  * @v data		Buffer to fill with setting data
172
  * @v len		Length of buffer
173
  * @v len		Length of buffer
173
  * @ret len		Length of setting data, or negative error
174
  * @ret len		Length of setting data, or negative error
175
  * The actual length of the setting will be returned even if
176
  * The actual length of the setting will be returned even if
176
  * the buffer was too small.
177
  * the buffer was too small.
177
  */
178
  */
178
-static int nvo_fetch ( struct settings *settings, unsigned int tag,
179
+static int nvo_fetch ( struct settings *settings, struct setting *setting,
179
 		       void *data, size_t len ) {
180
 		       void *data, size_t len ) {
180
 	struct nvo_block *nvo =
181
 	struct nvo_block *nvo =
181
 		container_of ( settings, struct nvo_block, settings );
182
 		container_of ( settings, struct nvo_block, settings );
182
 
183
 
183
-	return dhcpopt_fetch ( &nvo->dhcpopts, tag, data, len );
184
+	return dhcpopt_fetch ( &nvo->dhcpopts, setting->tag, data, len );
184
 }
185
 }
185
 
186
 
186
 /** NVO settings operations */
187
 /** NVO settings operations */

+ 181
- 273
src/core/settings.c View File

35
  *
35
  *
36
  */
36
  */
37
 
37
 
38
+/** Registered settings */
39
+static struct setting settings[0]
40
+	__table_start ( struct setting, settings );
41
+static struct setting settings_end[0]
42
+	__table_end ( struct setting, settings );
43
+
38
 /** Registered setting types */
44
 /** Registered setting types */
39
 static struct setting_type setting_types[0]
45
 static struct setting_type setting_types[0]
40
 	__table_start ( struct setting_type, setting_types );
46
 	__table_start ( struct setting_type, setting_types );
41
 static struct setting_type setting_types_end[0]
47
 static struct setting_type setting_types_end[0]
42
 	__table_end ( struct setting_type, setting_types );
48
 	__table_end ( struct setting_type, setting_types );
43
 
49
 
44
-/** Registered named settings */
45
-static struct named_setting named_settings[0]
46
-	__table_start ( struct named_setting, named_settings );
47
-static struct named_setting named_settings_end[0]
48
-	__table_end ( struct named_setting, named_settings );
49
-
50
 /** Registered settings applicators */
50
 /** Registered settings applicators */
51
 static struct settings_applicator settings_applicators[0]
51
 static struct settings_applicator settings_applicators[0]
52
 	__table_start ( struct settings_applicator, settings_applicators );
52
 	__table_start ( struct settings_applicator, settings_applicators );
53
 static struct settings_applicator settings_applicators_end[0]
53
 static struct settings_applicator settings_applicators_end[0]
54
 	__table_end ( struct settings_applicator, settings_applicators );
54
 	__table_end ( struct settings_applicator, settings_applicators );
55
 
55
 
56
-/**
57
- * Obtain printable version of a settings tag number
58
- *
59
- * @v tag		Settings tag number
60
- * @ret name		String representation of the tag
61
- */
62
-static inline char * setting_tag_name ( unsigned int tag ) {
63
-	static char name[8];
64
-
65
-	if ( DHCP_IS_ENCAP_OPT ( tag ) ) {
66
-		snprintf ( name, sizeof ( name ), "%d.%d",
67
-			   DHCP_ENCAPSULATOR ( tag ),
68
-			   DHCP_ENCAPSULATED ( tag ) );
69
-	} else {
70
-		snprintf ( name, sizeof ( name ), "%d", tag );
71
-	}
72
-	return name;
73
-}
74
-
75
 /******************************************************************************
56
 /******************************************************************************
76
  *
57
  *
77
  * Registered settings blocks
58
  * Registered settings blocks
83
  * Store value of simple setting
64
  * Store value of simple setting
84
  *
65
  *
85
  * @v options		DHCP option block
66
  * @v options		DHCP option block
86
- * @v tag		Setting tag number
67
+ * @v setting		Setting to store
87
  * @v data		Setting data, or NULL to clear setting
68
  * @v data		Setting data, or NULL to clear setting
88
  * @v len		Length of setting data
69
  * @v len		Length of setting data
89
  * @ret rc		Return status code
70
  * @ret rc		Return status code
90
  */
71
  */
91
-int simple_settings_store ( struct settings *settings, unsigned int tag,
72
+int simple_settings_store ( struct settings *settings, struct setting *setting,
92
 			    const void *data, size_t len ) {
73
 			    const void *data, size_t len ) {
93
 	struct simple_settings *simple =
74
 	struct simple_settings *simple =
94
 		container_of ( settings, struct simple_settings, settings );
75
 		container_of ( settings, struct simple_settings, settings );
95
-	return dhcpopt_extensible_store ( &simple->dhcpopts, tag, data, len );
76
+	return dhcpopt_extensible_store ( &simple->dhcpopts, setting->tag,
77
+					  data, len );
96
 }
78
 }
97
 
79
 
98
 /**
80
 /**
99
  * Fetch value of simple setting
81
  * Fetch value of simple setting
100
  *
82
  *
101
  * @v options		DHCP option block
83
  * @v options		DHCP option block
102
- * @v tag		Setting tag number
84
+ * @v setting		Setting to fetch
103
  * @v data		Buffer to fill with setting data
85
  * @v data		Buffer to fill with setting data
104
  * @v len		Length of buffer
86
  * @v len		Length of buffer
105
  * @ret len		Length of setting data, or negative error
87
  * @ret len		Length of setting data, or negative error
106
  */
88
  */
107
-int simple_settings_fetch ( struct settings *settings, unsigned int tag,
89
+int simple_settings_fetch ( struct settings *settings, struct setting *setting,
108
 			    void *data, size_t len ) {
90
 			    void *data, size_t len ) {
109
 	struct simple_settings *simple =
91
 	struct simple_settings *simple =
110
 		container_of ( settings, struct simple_settings, settings );
92
 		container_of ( settings, struct simple_settings, settings );
111
-	return dhcpopt_fetch ( &simple->dhcpopts, tag, data, len );
93
+	return dhcpopt_fetch ( &simple->dhcpopts, setting->tag, data, len );
112
 }
94
 }
113
 
95
 
114
 /** Simple settings operations */
96
 /** Simple settings operations */
174
 		return;
156
 		return;
175
 
157
 
176
 	/* Read priority, if present */
158
 	/* Read priority, if present */
177
-	priority = fetch_intz_setting ( settings, DHCP_EB_PRIORITY );
159
+	priority = fetch_intz_setting ( settings, &priority_setting );
178
 
160
 
179
 	/* Remove from siblings list */
161
 	/* Remove from siblings list */
180
 	list_del ( &settings->siblings );
162
 	list_del ( &settings->siblings );
181
 
163
 
182
 	/* Reinsert after any existing blocks which have a higher priority */
164
 	/* Reinsert after any existing blocks which have a higher priority */
183
 	list_for_each_entry ( tmp, &parent->children, siblings ) {
165
 	list_for_each_entry ( tmp, &parent->children, siblings ) {
184
-		tmp_priority = fetch_intz_setting ( tmp, DHCP_EB_PRIORITY );
166
+		tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
185
 		if ( priority > tmp_priority )
167
 		if ( priority > tmp_priority )
186
 			break;
168
 			break;
187
 	}
169
 	}
292
  * Store value of setting
274
  * Store value of setting
293
  *
275
  *
294
  * @v settings		Settings block
276
  * @v settings		Settings block
295
- * @v tag		Setting tag number
277
+ * @v setting		Setting to store
296
  * @v data		Setting data, or NULL to clear setting
278
  * @v data		Setting data, or NULL to clear setting
297
  * @v len		Length of setting data
279
  * @v len		Length of setting data
298
  * @ret rc		Return status code
280
  * @ret rc		Return status code
299
  */
281
  */
300
-int store_setting ( struct settings *settings, unsigned int tag,
282
+int store_setting ( struct settings *settings, struct setting *setting,
301
 		    const void *data, size_t len ) {
283
 		    const void *data, size_t len ) {
302
 	int rc;
284
 	int rc;
303
 
285
 
306
 		return -ENODEV;
288
 		return -ENODEV;
307
 
289
 
308
 	/* Store setting */
290
 	/* Store setting */
309
-	if ( ( rc = settings->op->store ( settings, tag, data, len ) ) != 0 )
291
+	if ( ( rc = settings->op->store ( settings, setting,
292
+					  data, len ) ) != 0 )
310
 		return rc;
293
 		return rc;
311
 
294
 
312
 	/* Reprioritise settings if necessary */
295
 	/* Reprioritise settings if necessary */
313
-	if ( tag == DHCP_EB_PRIORITY )
296
+	if ( setting_cmp ( setting, &priority_setting ) == 0 )
314
 		reprioritise_settings ( settings );
297
 		reprioritise_settings ( settings );
315
 
298
 
316
 	/* If these settings are registered, apply potentially-updated
299
 	/* If these settings are registered, apply potentially-updated
331
  * Fetch value of setting
314
  * Fetch value of setting
332
  *
315
  *
333
  * @v settings		Settings block, or NULL to search all blocks
316
  * @v settings		Settings block, or NULL to search all blocks
334
- * @v tag		Setting tag number
317
+ * @v setting		Setting to fetch
335
  * @v data		Buffer to fill with setting data
318
  * @v data		Buffer to fill with setting data
336
  * @v len		Length of buffer
319
  * @v len		Length of buffer
337
  * @ret len		Length of setting data, or negative error
320
  * @ret len		Length of setting data, or negative error
339
  * The actual length of the setting will be returned even if
322
  * The actual length of the setting will be returned even if
340
  * the buffer was too small.
323
  * the buffer was too small.
341
  */
324
  */
342
-int fetch_setting ( struct settings *settings, unsigned int tag,
325
+int fetch_setting ( struct settings *settings, struct setting *setting,
343
 		    void *data, size_t len ) {
326
 		    void *data, size_t len ) {
344
 	struct settings *child;
327
 	struct settings *child;
345
 	int ret;
328
 	int ret;
349
 		settings = &settings_root;
332
 		settings = &settings_root;
350
 
333
 
351
 	/* Try this block first */
334
 	/* Try this block first */
352
-	if ( ( ret = settings->op->fetch ( settings, tag, data, len ) ) >= 0)
335
+	if ( ( ret = settings->op->fetch ( settings, setting,
336
+					   data, len ) ) >= 0 )
353
 		return ret;
337
 		return ret;
354
 
338
 
355
 	/* Recurse into each child block in turn */
339
 	/* Recurse into each child block in turn */
356
 	list_for_each_entry ( child, &settings->children, siblings ) {
340
 	list_for_each_entry ( child, &settings->children, siblings ) {
357
-		if ( ( ret = fetch_setting ( child, tag, data, len ) ) >= 0)
341
+		if ( ( ret = fetch_setting ( child, setting,
342
+					     data, len ) ) >= 0 )
358
 			return ret;
343
 			return ret;
359
 	}
344
 	}
360
 
345
 
365
  * Fetch length of setting
350
  * Fetch length of setting
366
  *
351
  *
367
  * @v settings		Settings block, or NULL to search all blocks
352
  * @v settings		Settings block, or NULL to search all blocks
368
- * @v tag		Setting tag number
353
+ * @v setting		Setting to fetch
369
  * @ret len		Length of setting data, or negative error
354
  * @ret len		Length of setting data, or negative error
370
  *
355
  *
371
  * This function can also be used as an existence check for the
356
  * This function can also be used as an existence check for the
372
  * setting.
357
  * setting.
373
  */
358
  */
374
-int fetch_setting_len ( struct settings *settings, unsigned int tag ) {
375
-	return fetch_setting ( settings, tag, NULL, 0 );
359
+int fetch_setting_len ( struct settings *settings, struct setting *setting ) {
360
+	return fetch_setting ( settings, setting, NULL, 0 );
376
 }
361
 }
377
 
362
 
378
 /**
363
 /**
379
  * Fetch value of string setting
364
  * Fetch value of string setting
380
  *
365
  *
381
  * @v settings		Settings block, or NULL to search all blocks
366
  * @v settings		Settings block, or NULL to search all blocks
382
- * @v tag		Setting tag number
367
+ * @v setting		Setting to fetch
383
  * @v data		Buffer to fill with setting string data
368
  * @v data		Buffer to fill with setting string data
384
  * @v len		Length of buffer
369
  * @v len		Length of buffer
385
  * @ret len		Length of string setting, or negative error
370
  * @ret len		Length of string setting, or negative error
388
  * The returned length will be the length of the underlying setting
373
  * The returned length will be the length of the underlying setting
389
  * data.
374
  * data.
390
  */
375
  */
391
-int fetch_string_setting ( struct settings *settings, unsigned int tag,
376
+int fetch_string_setting ( struct settings *settings, struct setting *setting,
392
 			   char *data, size_t len ) {
377
 			   char *data, size_t len ) {
393
 	memset ( data, 0, len );
378
 	memset ( data, 0, len );
394
-	return fetch_setting ( settings, tag, data, ( len - 1 ) );
379
+	return fetch_setting ( settings, setting, data, ( len - 1 ) );
395
 }
380
 }
396
 
381
 
397
 /**
382
 /**
398
  * Fetch value of IPv4 address setting
383
  * Fetch value of IPv4 address setting
399
  *
384
  *
400
  * @v settings		Settings block, or NULL to search all blocks
385
  * @v settings		Settings block, or NULL to search all blocks
401
- * @v tag		Setting tag number
386
+ * @v setting		Setting to fetch
402
  * @v inp		IPv4 address to fill in
387
  * @v inp		IPv4 address to fill in
403
  * @ret len		Length of setting, or negative error
388
  * @ret len		Length of setting, or negative error
404
  */
389
  */
405
-int fetch_ipv4_setting ( struct settings *settings, unsigned int tag,
390
+int fetch_ipv4_setting ( struct settings *settings, struct setting *setting,
406
 			 struct in_addr *inp ) {
391
 			 struct in_addr *inp ) {
407
 	int len;
392
 	int len;
408
 
393
 
409
-	len = fetch_setting ( settings, tag, inp, sizeof ( *inp ) );
394
+	len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) );
410
 	if ( len < 0 )
395
 	if ( len < 0 )
411
 		return len;
396
 		return len;
412
 	if ( len < ( int ) sizeof ( *inp ) )
397
 	if ( len < ( int ) sizeof ( *inp ) )
418
  * Fetch value of signed integer setting
403
  * Fetch value of signed integer setting
419
  *
404
  *
420
  * @v settings		Settings block, or NULL to search all blocks
405
  * @v settings		Settings block, or NULL to search all blocks
421
- * @v tag		Setting tag number
406
+ * @v setting		Setting to fetch
422
  * @v value		Integer value to fill in
407
  * @v value		Integer value to fill in
423
  * @ret len		Length of setting, or negative error
408
  * @ret len		Length of setting, or negative error
424
  */
409
  */
425
-int fetch_int_setting ( struct settings *settings, unsigned int tag,
410
+int fetch_int_setting ( struct settings *settings, struct setting *setting,
426
 			long *value ) {
411
 			long *value ) {
427
 	union {
412
 	union {
428
 		long value;
413
 		long value;
433
 	int i;
418
 	int i;
434
 
419
 
435
 	buf.value = 0;
420
 	buf.value = 0;
436
-	len = fetch_setting ( settings, tag, &buf, sizeof ( buf ) );
421
+	len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
437
 	if ( len < 0 )
422
 	if ( len < 0 )
438
 		return len;
423
 		return len;
439
 	if ( len > ( int ) sizeof ( buf ) )
424
 	if ( len > ( int ) sizeof ( buf ) )
451
  * Fetch value of unsigned integer setting
436
  * Fetch value of unsigned integer setting
452
  *
437
  *
453
  * @v settings		Settings block, or NULL to search all blocks
438
  * @v settings		Settings block, or NULL to search all blocks
454
- * @v tag		Setting tag number
439
+ * @v setting		Setting to fetch
455
  * @v value		Integer value to fill in
440
  * @v value		Integer value to fill in
456
  * @ret len		Length of setting, or negative error
441
  * @ret len		Length of setting, or negative error
457
  */
442
  */
458
-int fetch_uint_setting ( struct settings *settings, unsigned int tag,
443
+int fetch_uint_setting ( struct settings *settings, struct setting *setting,
459
 			 unsigned long *value ) {
444
 			 unsigned long *value ) {
460
 	long svalue;
445
 	long svalue;
461
 	int len;
446
 	int len;
462
 
447
 
463
-	len = fetch_int_setting ( settings, tag, &svalue );
448
+	len = fetch_int_setting ( settings, setting, &svalue );
464
 	if ( len < 0 )
449
 	if ( len < 0 )
465
 		return len;
450
 		return len;
466
 
451
 
473
  * Fetch value of signed integer setting, or zero
458
  * Fetch value of signed integer setting, or zero
474
  *
459
  *
475
  * @v settings		Settings block, or NULL to search all blocks
460
  * @v settings		Settings block, or NULL to search all blocks
476
- * @v tag		Setting tag number
461
+ * @v setting		Setting to fetch
477
  * @ret value		Setting value, or zero
462
  * @ret value		Setting value, or zero
478
  */
463
  */
479
-long fetch_intz_setting ( struct settings *settings, unsigned int tag ) {
464
+long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
480
 	long value = 0;
465
 	long value = 0;
481
 
466
 
482
-	fetch_int_setting ( settings, tag, &value );
467
+	fetch_int_setting ( settings, setting, &value );
483
 	return value;
468
 	return value;
484
 }
469
 }
485
 
470
 
487
  * Fetch value of unsigned integer setting, or zero
472
  * Fetch value of unsigned integer setting, or zero
488
  *
473
  *
489
  * @v settings		Settings block, or NULL to search all blocks
474
  * @v settings		Settings block, or NULL to search all blocks
490
- * @v tag		Setting tag number
475
+ * @v setting		Setting to fetch
491
  * @ret value		Setting value, or zero
476
  * @ret value		Setting value, or zero
492
  */
477
  */
493
 unsigned long fetch_uintz_setting ( struct settings *settings,
478
 unsigned long fetch_uintz_setting ( struct settings *settings,
494
-				    unsigned int tag ) {
479
+				    struct setting *setting ) {
495
 	unsigned long value = 0;
480
 	unsigned long value = 0;
496
 
481
 
497
-	fetch_uint_setting ( settings, tag, &value );
482
+	fetch_uint_setting ( settings, setting, &value );
498
 	return value;
483
 	return value;
499
 }
484
 }
500
 
485
 
501
 /**
486
 /**
502
- * Copy settings
487
+ * Compare two settings
503
  *
488
  *
504
- * @v dest		Destination settings block
505
- * @v source		Source settings block
506
- * @v encapsulator	Encapsulating setting tag number, or zero
507
- * @ret rc		Return status code
489
+ * @v a			Setting to compare
490
+ * @v b			Setting to compare
491
+ * @ret 0		Settings are the same
492
+ * @ret non-zero	Settings are not the same
508
  */
493
  */
509
-static int copy_encap_settings ( struct settings *dest,
510
-				 struct settings *source,
511
-				 unsigned int encapsulator ) {
512
-	unsigned int subtag;
513
-	unsigned int tag;
514
-	int len;
515
-	int check_len;
516
-	int rc;
494
+int setting_cmp ( struct setting *a, struct setting *b ) {
517
 
495
 
518
-	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
519
-		tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
520
-		switch ( tag ) {
521
-		case DHCP_EB_ENCAP:
522
-		case DHCP_VENDOR_ENCAP:
523
-			/* Process encapsulated settings */
524
-			if ( ( rc = copy_encap_settings ( dest, source,
525
-							  tag ) ) != 0 )
526
-				return rc;
527
-			break;
528
-		default:
529
-			/* Copy setting, if present */
530
-			len = fetch_setting_len ( source, tag );
531
-			if ( len < 0 )
532
-				break;
533
-			{
534
-				char buf[len];
535
-
536
-				check_len = fetch_setting ( source, tag, buf,
537
-							    sizeof ( buf ) );
538
-				assert ( check_len == len );
539
-				if ( ( rc = store_setting ( dest, tag, buf,
540
-							    sizeof(buf) )) !=0)
541
-					return rc;
542
-			}
543
-			break;
544
-		}
545
-	}
496
+	/* If the settings have tags, compare them */
497
+	if ( a->tag && ( a->tag == b->tag ) )
498
+		return 0;
546
 
499
 
547
-	return 0;
548
-}
549
-
550
-/**
551
- * Copy settings
552
- *
553
- * @v dest		Destination settings block
554
- * @v source		Source settings block
555
- * @ret rc		Return status code
556
- */
557
-int copy_settings ( struct settings *dest, struct settings *source ) {
558
-	return copy_encap_settings ( dest, source, 0 );
500
+	/* Otherwise, compare the names */
501
+	return strcmp ( a->name, b->name );
559
 }
502
 }
560
 
503
 
561
 /******************************************************************************
504
 /******************************************************************************
562
  *
505
  *
563
- * Named and typed setting routines
506
+ * Formatted setting routines
564
  *
507
  *
565
  ******************************************************************************
508
  ******************************************************************************
566
  */
509
  */
569
  * Store value of typed setting
512
  * Store value of typed setting
570
  *
513
  *
571
  * @v settings		Settings block
514
  * @v settings		Settings block
572
- * @v tag		Setting tag number
515
+ * @v setting		Setting to store
573
  * @v type		Settings type
516
  * @v type		Settings type
574
  * @v value		Formatted setting data, or NULL
517
  * @v value		Formatted setting data, or NULL
575
  * @ret rc		Return status code
518
  * @ret rc		Return status code
576
  */
519
  */
577
-int store_typed_setting ( struct settings *settings,
578
-			  unsigned int tag, struct setting_type *type,
579
-			  const char *value ) {
520
+int storef_setting ( struct settings *settings, struct setting *setting,
521
+		     const char *value ) {
580
 
522
 
581
 	/* NULL value implies deletion.  Avoid imposing the burden of
523
 	/* NULL value implies deletion.  Avoid imposing the burden of
582
 	 * checking for NULL values on each typed setting's storef()
524
 	 * checking for NULL values on each typed setting's storef()
583
 	 * method.
525
 	 * method.
584
 	 */
526
 	 */
585
 	if ( ! value )
527
 	if ( ! value )
586
-		return delete_setting ( settings, tag );
528
+		return delete_setting ( settings, setting );
587
 		
529
 		
588
-	return type->storef ( settings, tag, value );
530
+	return setting->type->storef ( settings, setting, value );
589
 }
531
 }
590
 
532
 
591
 /**
533
 /**
594
  * @v name		Name
536
  * @v name		Name
595
  * @ret setting		Named setting, or NULL
537
  * @ret setting		Named setting, or NULL
596
  */
538
  */
597
-static struct named_setting * find_named_setting ( const char *name ) {
598
-	struct named_setting *setting;
539
+static struct setting * find_setting ( const char *name ) {
540
+	struct setting *setting;
599
 
541
 
600
-	for ( setting = named_settings ; setting < named_settings_end ;
601
-	      setting++ ) {
542
+	for ( setting = settings ; setting < settings_end ; setting++ ) {
602
 		if ( strcmp ( name, setting->name ) == 0 )
543
 		if ( strcmp ( name, setting->name ) == 0 )
603
 			return setting;
544
 			return setting;
604
 	}
545
 	}
625
  * Parse setting name
566
  * Parse setting name
626
  *
567
  *
627
  * @v name		Name of setting
568
  * @v name		Name of setting
628
- * @ret settings	Settings block, or NULL
629
- * @ret tag		Setting tag number
630
- * @ret type		Setting type
569
+ * @v settings		Settings block to fill in
570
+ * @v setting		Setting to fill in
631
  * @ret rc		Return status code
571
  * @ret rc		Return status code
632
  *
572
  *
633
  * Interprets a name of the form
573
  * Interprets a name of the form
635
  * fields.
575
  * fields.
636
  */
576
  */
637
 static int parse_setting_name ( const char *name, struct settings **settings,
577
 static int parse_setting_name ( const char *name, struct settings **settings,
638
-				unsigned int *tag,
639
-				struct setting_type **type ) {
578
+				struct setting *setting ) {
640
 	char tmp_name[ strlen ( name ) + 1 ];
579
 	char tmp_name[ strlen ( name ) + 1 ];
641
 	char *settings_name;
580
 	char *settings_name;
642
-	char *tag_name;
581
+	char *setting_name;
643
 	char *type_name;
582
 	char *type_name;
644
-	struct named_setting *named_setting;
583
+	struct setting *named_setting;
645
 	char *tmp;
584
 	char *tmp;
646
 
585
 
647
 	/* Set defaults */
586
 	/* Set defaults */
648
 	*settings = &settings_root;
587
 	*settings = &settings_root;
649
-	*tag = 0;
650
-	*type = &setting_type_hex;
588
+	memset ( setting, 0, sizeof ( *setting ) );
589
+	setting->type = &setting_type_hex;
651
 
590
 
652
-	/* Split name into "[settings_name/]tag_name[:type_name]" */
591
+	/* Split name into "[settings_name/]setting_name[:type_name]" */
653
 	memcpy ( tmp_name, name, sizeof ( tmp_name ) );
592
 	memcpy ( tmp_name, name, sizeof ( tmp_name ) );
654
-	if ( ( tag_name = strchr ( tmp_name, '/' ) ) != NULL ) {
655
-		*(tag_name++) = 0;
593
+	if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
594
+		*(setting_name++) = 0;
656
 		settings_name = tmp_name;
595
 		settings_name = tmp_name;
657
 	} else {
596
 	} else {
658
-		tag_name = tmp_name;
597
+		setting_name = tmp_name;
659
 		settings_name = NULL;
598
 		settings_name = NULL;
660
 	}
599
 	}
661
-	if ( ( type_name = strchr ( tag_name, ':' ) ) != NULL )
600
+	if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
662
 		*(type_name++) = 0;
601
 		*(type_name++) = 0;
663
 
602
 
664
 	/* Identify settings block, if specified */
603
 	/* Identify settings block, if specified */
672
 	}
611
 	}
673
 
612
 
674
 	/* Identify tag number */
613
 	/* Identify tag number */
675
-	if ( ( named_setting = find_named_setting ( tag_name ) ) != NULL ) {
676
-		*tag = named_setting->tag;
677
-		*type = named_setting->type;
614
+	if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
615
+		memcpy ( setting, named_setting, sizeof ( *setting ) );
678
 	} else {
616
 	} else {
679
 		/* Unrecognised name: try to interpret as a tag number */
617
 		/* Unrecognised name: try to interpret as a tag number */
680
-		tmp = tag_name;
618
+		tmp = setting_name;
681
 		while ( 1 ) {
619
 		while ( 1 ) {
682
-			*tag = ( ( *tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
620
+			setting->tag = ( ( setting->tag << 8 ) |
621
+					 strtoul ( tmp, &tmp, 0 ) );
683
 			if ( *tmp == 0 )
622
 			if ( *tmp == 0 )
684
 				break;
623
 				break;
685
 			if ( *tmp != '.' ) {
624
 			if ( *tmp != '.' ) {
686
-				DBG ( "Invalid tag number \"%s\" in \"%s\"\n",
687
-				      tag_name, name );
625
+				DBG ( "Invalid setting \"%s\" in \"%s\"\n",
626
+				      setting_name, name );
688
 				return -ENOENT;
627
 				return -ENOENT;
689
 			}
628
 			}
690
 			tmp++;
629
 			tmp++;
693
 
632
 
694
 	/* Identify setting type, if specified */
633
 	/* Identify setting type, if specified */
695
 	if ( type_name ) {
634
 	if ( type_name ) {
696
-		*type = find_setting_type ( type_name );
697
-		if ( *type == NULL ) {
635
+		setting->type = find_setting_type ( type_name );
636
+		if ( setting->type == NULL ) {
698
 			DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
637
 			DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
699
 			      type_name, name );
638
 			      type_name, name );
700
 			return -ENOTSUP;
639
 			return -ENOTSUP;
711
  * @v value		Formatted setting data, or NULL
650
  * @v value		Formatted setting data, or NULL
712
  * @ret rc		Return status code
651
  * @ret rc		Return status code
713
  */
652
  */
714
-int store_named_setting ( const char *name, const char *value ) {
653
+int storef_named_setting ( const char *name, const char *value ) {
715
 	struct settings *settings;
654
 	struct settings *settings;
716
-	unsigned int tag;
717
-	struct setting_type *type;
655
+	struct setting setting;
718
 	int rc;
656
 	int rc;
719
 
657
 
720
-	if ( ( rc = parse_setting_name ( name, &settings, &tag,
721
-					 &type ) ) != 0 )
658
+	if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
722
 		return rc;
659
 		return rc;
723
-	return store_typed_setting ( settings, tag, type, value );
660
+	return storef_setting ( settings, &setting, value );
724
 }
661
 }
725
 
662
 
726
 /**
663
 /**
731
  * @v len		Length of buffer
668
  * @v len		Length of buffer
732
  * @ret len		Length of formatted value, or negative error
669
  * @ret len		Length of formatted value, or negative error
733
  */
670
  */
734
-int fetch_named_setting ( const char *name, char *buf, size_t len ) {
671
+int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
735
 	struct settings *settings;
672
 	struct settings *settings;
736
-	unsigned int tag;
737
-	struct setting_type *type;
673
+	struct setting setting;
738
 	int rc;
674
 	int rc;
739
 
675
 
740
-	if ( ( rc = parse_setting_name ( name, &settings, &tag,
741
-					 &type ) ) != 0 )
676
+	if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
742
 		return rc;
677
 		return rc;
743
-	return fetch_typed_setting ( settings, tag, type, buf, len );
678
+	return fetchf_setting ( settings, &setting, buf, len );
744
 }
679
 }
745
 
680
 
746
 /******************************************************************************
681
 /******************************************************************************
754
  * Parse and store value of string setting
689
  * Parse and store value of string setting
755
  *
690
  *
756
  * @v settings		Settings block
691
  * @v settings		Settings block
757
- * @v tag		Setting tag number
692
+ * @v setting		Setting to store
758
  * @v value		Formatted setting data
693
  * @v value		Formatted setting data
759
  * @ret rc		Return status code
694
  * @ret rc		Return status code
760
  */
695
  */
761
-static int storef_string ( struct settings *settings, unsigned int tag,
696
+static int storef_string ( struct settings *settings, struct setting *setting,
762
 			   const char *value ) {
697
 			   const char *value ) {
763
-	return store_setting ( settings, tag, value, strlen ( value ) );
698
+	return store_setting ( settings, setting, value, strlen ( value ) );
764
 }
699
 }
765
 
700
 
766
 /**
701
 /**
767
  * Fetch and format value of string setting
702
  * Fetch and format value of string setting
768
  *
703
  *
769
  * @v settings		Settings block, or NULL to search all blocks
704
  * @v settings		Settings block, or NULL to search all blocks
770
- * @v tag		Setting tag number
705
+ * @v setting		Setting to fetch
771
  * @v buf		Buffer to contain formatted value
706
  * @v buf		Buffer to contain formatted value
772
  * @v len		Length of buffer
707
  * @v len		Length of buffer
773
  * @ret len		Length of formatted value, or negative error
708
  * @ret len		Length of formatted value, or negative error
774
  */
709
  */
775
-static int fetchf_string ( struct settings *settings, unsigned int tag,
710
+static int fetchf_string ( struct settings *settings, struct setting *setting,
776
 			   char *buf, size_t len ) {
711
 			   char *buf, size_t len ) {
777
-	return fetch_string_setting ( settings, tag, buf, len );
712
+	return fetch_string_setting ( settings, setting, buf, len );
778
 }
713
 }
779
 
714
 
780
 /** A string setting type */
715
 /** A string setting type */
788
  * Parse and store value of IPv4 address setting
723
  * Parse and store value of IPv4 address setting
789
  *
724
  *
790
  * @v settings		Settings block
725
  * @v settings		Settings block
791
- * @v tag		Setting tag number
726
+ * @v setting		Setting to store
792
  * @v value		Formatted setting data
727
  * @v value		Formatted setting data
793
  * @ret rc		Return status code
728
  * @ret rc		Return status code
794
  */
729
  */
795
-static int storef_ipv4 ( struct settings *settings, unsigned int tag,
730
+static int storef_ipv4 ( struct settings *settings, struct setting *setting,
796
 			 const char *value ) {
731
 			 const char *value ) {
797
 	struct in_addr ipv4;
732
 	struct in_addr ipv4;
798
 
733
 
799
 	if ( inet_aton ( value, &ipv4 ) == 0 )
734
 	if ( inet_aton ( value, &ipv4 ) == 0 )
800
 		return -EINVAL;
735
 		return -EINVAL;
801
-	return store_setting ( settings, tag, &ipv4, sizeof ( ipv4 ) );
736
+	return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) );
802
 }
737
 }
803
 
738
 
804
 /**
739
 /**
805
  * Fetch and format value of IPv4 address setting
740
  * Fetch and format value of IPv4 address setting
806
  *
741
  *
807
  * @v settings		Settings block, or NULL to search all blocks
742
  * @v settings		Settings block, or NULL to search all blocks
808
- * @v tag		Setting tag number
743
+ * @v setting		Setting to fetch
809
  * @v buf		Buffer to contain formatted value
744
  * @v buf		Buffer to contain formatted value
810
  * @v len		Length of buffer
745
  * @v len		Length of buffer
811
  * @ret len		Length of formatted value, or negative error
746
  * @ret len		Length of formatted value, or negative error
812
  */
747
  */
813
-static int fetchf_ipv4 ( struct settings *settings, unsigned int tag,
748
+static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
814
 			 char *buf, size_t len ) {
749
 			 char *buf, size_t len ) {
815
 	struct in_addr ipv4;
750
 	struct in_addr ipv4;
816
 	int rc;
751
 	int rc;
817
 
752
 
818
-	if ( ( rc = fetch_ipv4_setting ( settings, tag, &ipv4 ) ) < 0 )
753
+	if ( ( rc = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0 )
819
 		return rc;
754
 		return rc;
820
 	return snprintf ( buf, len, inet_ntoa ( ipv4 ) );
755
 	return snprintf ( buf, len, inet_ntoa ( ipv4 ) );
821
 }
756
 }
831
  * Parse and store value of integer setting
766
  * Parse and store value of integer setting
832
  *
767
  *
833
  * @v settings		Settings block
768
  * @v settings		Settings block
834
- * @v tag		Setting tag number
769
+ * @v setting		Setting to store
835
  * @v value		Formatted setting data
770
  * @v value		Formatted setting data
836
  * @v size		Integer size, in bytes
771
  * @v size		Integer size, in bytes
837
  * @ret rc		Return status code
772
  * @ret rc		Return status code
838
  */
773
  */
839
-static int storef_int ( struct settings *settings, unsigned int tag,
774
+static int storef_int ( struct settings *settings, struct setting *setting,
840
 			const char *value, unsigned int size ) {
775
 			const char *value, unsigned int size ) {
841
 	union {
776
 	union {
842
 		uint32_t num;
777
 		uint32_t num;
847
 	u.num = htonl ( strtoul ( value, &endp, 0 ) );
782
 	u.num = htonl ( strtoul ( value, &endp, 0 ) );
848
 	if ( *endp )
783
 	if ( *endp )
849
 		return -EINVAL;
784
 		return -EINVAL;
850
-	return store_setting ( settings, tag, 
785
+	return store_setting ( settings, setting, 
851
 			       &u.bytes[ sizeof ( u ) - size ], size );
786
 			       &u.bytes[ sizeof ( u ) - size ], size );
852
 }
787
 }
853
 
788
 
855
  * Parse and store value of 8-bit integer setting
790
  * Parse and store value of 8-bit integer setting
856
  *
791
  *
857
  * @v settings		Settings block
792
  * @v settings		Settings block
858
- * @v tag		Setting tag number
793
+ * @v setting		Setting to store
859
  * @v value		Formatted setting data
794
  * @v value		Formatted setting data
860
  * @v size		Integer size, in bytes
795
  * @v size		Integer size, in bytes
861
  * @ret rc		Return status code
796
  * @ret rc		Return status code
862
  */
797
  */
863
-static int storef_int8 ( struct settings *settings, unsigned int tag,
798
+static int storef_int8 ( struct settings *settings, struct setting *setting,
864
 			 const char *value ) {
799
 			 const char *value ) {
865
-	return storef_int ( settings, tag, value, 1 );
800
+	return storef_int ( settings, setting, value, 1 );
866
 }
801
 }
867
 
802
 
868
 /**
803
 /**
869
  * Parse and store value of 16-bit integer setting
804
  * Parse and store value of 16-bit integer setting
870
  *
805
  *
871
  * @v settings		Settings block
806
  * @v settings		Settings block
872
- * @v tag		Setting tag number
807
+ * @v setting		Setting to store
873
  * @v value		Formatted setting data
808
  * @v value		Formatted setting data
874
  * @v size		Integer size, in bytes
809
  * @v size		Integer size, in bytes
875
  * @ret rc		Return status code
810
  * @ret rc		Return status code
876
  */
811
  */
877
-static int storef_int16 ( struct settings *settings, unsigned int tag,
812
+static int storef_int16 ( struct settings *settings, struct setting *setting,
878
 			  const char *value ) {
813
 			  const char *value ) {
879
-	return storef_int ( settings, tag, value, 2 );
814
+	return storef_int ( settings, setting, value, 2 );
880
 }
815
 }
881
 
816
 
882
 /**
817
 /**
883
  * Parse and store value of 32-bit integer setting
818
  * Parse and store value of 32-bit integer setting
884
  *
819
  *
885
  * @v settings		Settings block
820
  * @v settings		Settings block
886
- * @v tag		Setting tag number
821
+ * @v setting		Setting to store
887
  * @v value		Formatted setting data
822
  * @v value		Formatted setting data
888
  * @v size		Integer size, in bytes
823
  * @v size		Integer size, in bytes
889
  * @ret rc		Return status code
824
  * @ret rc		Return status code
890
  */
825
  */
891
-static int storef_int32 ( struct settings *settings, unsigned int tag,
826
+static int storef_int32 ( struct settings *settings, struct setting *setting,
892
 			  const char *value ) {
827
 			  const char *value ) {
893
-	return storef_int ( settings, tag, value, 4 );
828
+	return storef_int ( settings, setting, value, 4 );
894
 }
829
 }
895
 
830
 
896
 /**
831
 /**
897
  * Fetch and format value of signed integer setting
832
  * Fetch and format value of signed integer setting
898
  *
833
  *
899
  * @v settings		Settings block, or NULL to search all blocks
834
  * @v settings		Settings block, or NULL to search all blocks
900
- * @v tag		Setting tag number
835
+ * @v setting		Setting to fetch
901
  * @v buf		Buffer to contain formatted value
836
  * @v buf		Buffer to contain formatted value
902
  * @v len		Length of buffer
837
  * @v len		Length of buffer
903
  * @ret len		Length of formatted value, or negative error
838
  * @ret len		Length of formatted value, or negative error
904
  */
839
  */
905
-static int fetchf_int ( struct settings *settings, unsigned int tag,
840
+static int fetchf_int ( struct settings *settings, struct setting *setting,
906
 			char *buf, size_t len ) {
841
 			char *buf, size_t len ) {
907
 	long value;
842
 	long value;
908
 	int rc;
843
 	int rc;
909
 
844
 
910
-	if ( ( rc = fetch_int_setting ( settings, tag, &value ) ) < 0 )
845
+	if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 )
911
 		return rc;
846
 		return rc;
912
 	return snprintf ( buf, len, "%ld", value );
847
 	return snprintf ( buf, len, "%ld", value );
913
 }
848
 }
916
  * Fetch and format value of unsigned integer setting
851
  * Fetch and format value of unsigned integer setting
917
  *
852
  *
918
  * @v settings		Settings block, or NULL to search all blocks
853
  * @v settings		Settings block, or NULL to search all blocks
919
- * @v tag		Setting tag number
854
+ * @v setting		Setting to fetch
920
  * @v buf		Buffer to contain formatted value
855
  * @v buf		Buffer to contain formatted value
921
  * @v len		Length of buffer
856
  * @v len		Length of buffer
922
  * @ret len		Length of formatted value, or negative error
857
  * @ret len		Length of formatted value, or negative error
923
  */
858
  */
924
-static int fetchf_uint ( struct settings *settings, unsigned int tag,
859
+static int fetchf_uint ( struct settings *settings, struct setting *setting,
925
 			 char *buf, size_t len ) {
860
 			 char *buf, size_t len ) {
926
 	unsigned long value;
861
 	unsigned long value;
927
 	int rc;
862
 	int rc;
928
 
863
 
929
-	if ( ( rc = fetch_uint_setting ( settings, tag, &value ) ) < 0 )
864
+	if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 )
930
 		return rc;
865
 		return rc;
931
 	return snprintf ( buf, len, "%#lx", value );
866
 	return snprintf ( buf, len, "%#lx", value );
932
 }
867
 }
977
  * Parse and store value of hex string setting
912
  * Parse and store value of hex string setting
978
  *
913
  *
979
  * @v settings		Settings block
914
  * @v settings		Settings block
980
- * @v tag		Setting tag number
915
+ * @v setting		Setting to store
981
  * @v value		Formatted setting data
916
  * @v value		Formatted setting data
982
  * @ret rc		Return status code
917
  * @ret rc		Return status code
983
  */
918
  */
984
-static int storef_hex ( struct settings *settings, unsigned int tag,
919
+static int storef_hex ( struct settings *settings, struct setting *setting,
985
 			const char *value ) {
920
 			const char *value ) {
986
 	char *ptr = ( char * ) value;
921
 	char *ptr = ( char * ) value;
987
 	uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
922
 	uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
991
 		bytes[len++] = strtoul ( ptr, &ptr, 16 );
926
 		bytes[len++] = strtoul ( ptr, &ptr, 16 );
992
 		switch ( *ptr ) {
927
 		switch ( *ptr ) {
993
 		case '\0' :
928
 		case '\0' :
994
-			return store_setting ( settings, tag, bytes, len );
929
+			return store_setting ( settings, setting, bytes, len );
995
 		case ':' :
930
 		case ':' :
996
 			ptr++;
931
 			ptr++;
997
 			break;
932
 			break;
1005
  * Fetch and format value of hex string setting
940
  * Fetch and format value of hex string setting
1006
  *
941
  *
1007
  * @v settings		Settings block, or NULL to search all blocks
942
  * @v settings		Settings block, or NULL to search all blocks
1008
- * @v tag		Setting tag number
943
+ * @v setting		Setting to fetch
1009
  * @v buf		Buffer to contain formatted value
944
  * @v buf		Buffer to contain formatted value
1010
  * @v len		Length of buffer
945
  * @v len		Length of buffer
1011
  * @ret len		Length of formatted value, or negative error
946
  * @ret len		Length of formatted value, or negative error
1012
  */
947
  */
1013
-static int fetchf_hex ( struct settings *settings, unsigned int tag,
948
+static int fetchf_hex ( struct settings *settings, struct setting *setting,
1014
 			char *buf, size_t len ) {
949
 			char *buf, size_t len ) {
1015
 	int raw_len;
950
 	int raw_len;
1016
 	int check_len;
951
 	int check_len;
1017
 	int used = 0;
952
 	int used = 0;
1018
 	int i;
953
 	int i;
1019
 
954
 
1020
-	raw_len = fetch_setting_len ( settings, tag );
955
+	raw_len = fetch_setting_len ( settings, setting );
1021
 	if ( raw_len < 0 )
956
 	if ( raw_len < 0 )
1022
 		return raw_len;
957
 		return raw_len;
1023
 
958
 
1024
 	{
959
 	{
1025
 		uint8_t raw[raw_len];
960
 		uint8_t raw[raw_len];
1026
 
961
 
1027
-		check_len = fetch_setting ( settings, tag, raw, sizeof (raw) );
962
+		check_len = fetch_setting ( settings, setting, raw,
963
+					    sizeof ( raw ) );
1028
 		assert ( check_len == raw_len );
964
 		assert ( check_len == raw_len );
1029
 		
965
 		
1030
 		if ( len )
966
 		if ( len )
1047
 
983
 
1048
 /******************************************************************************
984
 /******************************************************************************
1049
  *
985
  *
1050
- * Named settings
986
+ * Settings
1051
  *
987
  *
1052
  ******************************************************************************
988
  ******************************************************************************
1053
  */
989
  */
1054
 
990
 
1055
-/** Some basic setting definitions */
1056
-struct named_setting basic_named_settings[] __named_setting = {
1057
-	{
1058
-		.name = "ip",
1059
-		.description = "IPv4 address",
1060
-		.tag = DHCP_EB_YIADDR,
1061
-		.type = &setting_type_ipv4,
1062
-	},
1063
-	{
1064
-		.name = "netmask",
1065
-		.description = "IPv4 subnet mask",
1066
-		.tag = DHCP_SUBNET_MASK,
1067
-		.type = &setting_type_ipv4,
1068
-	},
1069
-	{
1070
-		.name = "gateway",
1071
-		.description = "Default gateway",
1072
-		.tag = DHCP_ROUTERS,
1073
-		.type = &setting_type_ipv4,
1074
-	},
1075
-	{
1076
-		.name = "dns",
1077
-		.description = "DNS server",
1078
-		.tag = DHCP_DNS_SERVERS,
1079
-		.type = &setting_type_ipv4,
1080
-	},
1081
-	{
1082
-		.name = "hostname",
1083
-		.description = "Host name",
1084
-		.tag = DHCP_HOST_NAME,
1085
-		.type = &setting_type_string,
1086
-	},
1087
-	{
1088
-		.name = "next-server",
1089
-		.description = "TFTP server",
1090
-		.tag = DHCP_EB_SIADDR,
1091
-		.type = &setting_type_ipv4,
1092
-	},
1093
-	{
1094
-		.name = "filename",
1095
-		.description = "Boot filename",
1096
-		.tag = DHCP_BOOTFILE_NAME,
1097
-		.type = &setting_type_string,
1098
-	},
1099
-	{
1100
-		.name = "root-path",
1101
-		.description = "NFS/iSCSI root path",
1102
-		.tag = DHCP_ROOT_PATH,
1103
-		.type = &setting_type_string,
1104
-	},
1105
-	{
1106
-		.name = "username",
1107
-		.description = "User name",
1108
-		.tag = DHCP_EB_USERNAME,
1109
-		.type = &setting_type_string,
1110
-	},
1111
-	{
1112
-		.name = "password",
1113
-		.description = "Password",
1114
-		.tag = DHCP_EB_PASSWORD,
1115
-		.type = &setting_type_string,
1116
-	},
1117
-	{
1118
-		.name = "initiator-iqn",
1119
-		.description = "iSCSI initiator name",
1120
-		.tag = DHCP_ISCSI_INITIATOR_IQN,
1121
-		.type = &setting_type_string,
1122
-	},
1123
-	{
1124
-		.name = "priority",
1125
-		.description = "Priority of these settings",
1126
-		.tag = DHCP_EB_PRIORITY,
1127
-		.type = &setting_type_int8,
1128
-	},
991
+/** Hostname setting */
992
+struct setting hostname_setting __setting = {
993
+	.name = "hostname",
994
+	.description = "Host name",
995
+	.tag = DHCP_HOST_NAME,
996
+	.type = &setting_type_string,
997
+};
998
+
999
+/** Filename setting */
1000
+struct setting filename_setting __setting = {
1001
+	.name = "filename",
1002
+	.description = "Boot filename",
1003
+	.tag = DHCP_BOOTFILE_NAME,
1004
+	.type = &setting_type_string,
1005
+};
1006
+
1007
+/** Root path setting */
1008
+struct setting root_path_setting __setting = {
1009
+	.name = "root-path",
1010
+	.description = "NFS/iSCSI root path",
1011
+	.tag = DHCP_ROOT_PATH,
1012
+	.type = &setting_type_string,
1013
+};
1014
+
1015
+/** Username setting */
1016
+struct setting username_setting __setting = {
1017
+	.name = "username",
1018
+	.description = "User name",
1019
+	.tag = DHCP_EB_USERNAME,
1020
+	.type = &setting_type_string,
1021
+};
1022
+
1023
+/** Password setting */
1024
+struct setting password_setting __setting = {
1025
+	.name = "password",
1026
+	.description = "Password",
1027
+	.tag = DHCP_EB_PASSWORD,
1028
+	.type = &setting_type_string,
1029
+};
1030
+
1031
+/** Priority setting */
1032
+struct setting priority_setting __setting = {
1033
+	.name = "priority",
1034
+	.description = "Priority of these settings",
1035
+	.tag = DHCP_EB_PRIORITY,
1036
+	.type = &setting_type_int8,
1129
 };
1037
 };

+ 3
- 3
src/hci/commands/nvo_cmd.c View File

16
 		return 1;
16
 		return 1;
17
 	}
17
 	}
18
 
18
 
19
-	if ( ( rc = fetch_named_setting ( argv[1], buf,
20
-					  sizeof ( buf ) ) ) < 0 ){
19
+	if ( ( rc = fetchf_named_setting ( argv[1], buf,
20
+					   sizeof ( buf ) ) ) < 0 ){
21
 		printf ( "Could not find \"%s\": %s\n",
21
 		printf ( "Could not find \"%s\": %s\n",
22
 			 argv[1], strerror ( rc ) );
22
 			 argv[1], strerror ( rc ) );
23
 		return 1;
23
 		return 1;
35
 		return 1;
35
 		return 1;
36
 	}
36
 	}
37
 
37
 
38
-	if ( ( rc = store_named_setting ( argv[1], argv[2] ) ) != 0 ) {
38
+	if ( ( rc = storef_named_setting ( argv[1], argv[2] ) ) != 0 ) {
39
 		printf ( "Could not set \"%s\"=\"%s\": %s\n",
39
 		printf ( "Could not set \"%s\"=\"%s\": %s\n",
40
 			 argv[1], argv[2], strerror ( rc ) );
40
 			 argv[1], argv[2], strerror ( rc ) );
41
 		return 1;
41
 		return 1;

+ 15
- 16
src/hci/tui/settings_ui.c View File

64
 	/** Settings block */
64
 	/** Settings block */
65
 	struct settings *settings;
65
 	struct settings *settings;
66
 	/** Configuration setting */
66
 	/** Configuration setting */
67
-	struct named_setting *setting;
67
+	struct setting *setting;
68
 	/** Screen row */
68
 	/** Screen row */
69
 	unsigned int row;
69
 	unsigned int row;
70
 	/** Screen column */
70
 	/** Screen column */
78
 };
78
 };
79
 
79
 
80
 /** Registered configuration settings */
80
 /** Registered configuration settings */
81
-static struct named_setting named_settings[0]
82
-	__table_start ( struct named_setting, named_settings );
83
-static struct named_setting named_settings_end[0]
84
-	__table_end ( struct named_setting, named_settings );
85
-#define NUM_SETTINGS ( ( unsigned ) ( named_settings_end - named_settings ) )
81
+static struct setting all_settings[0]
82
+	__table_start ( struct setting, settings );
83
+static struct setting all_settings_end[0]
84
+	__table_end ( struct setting, settings );
85
+#define NUM_SETTINGS ( ( unsigned ) ( all_settings_end - all_settings ) )
86
 
86
 
87
 static void load_setting ( struct setting_widget *widget ) __nonnull;
87
 static void load_setting ( struct setting_widget *widget ) __nonnull;
88
 static int save_setting ( struct setting_widget *widget ) __nonnull;
88
 static int save_setting ( struct setting_widget *widget ) __nonnull;
89
 static void init_setting ( struct setting_widget *widget,
89
 static void init_setting ( struct setting_widget *widget,
90
                            struct settings *settings,
90
                            struct settings *settings,
91
-                           struct named_setting *setting,
91
+                           struct setting *setting,
92
                            unsigned int row, unsigned int col ) __nonnull;
92
                            unsigned int row, unsigned int col ) __nonnull;
93
 static void draw_setting ( struct setting_widget *widget ) __nonnull;
93
 static void draw_setting ( struct setting_widget *widget ) __nonnull;
94
 static int edit_setting ( struct setting_widget *widget, int key ) __nonnull;
94
 static int edit_setting ( struct setting_widget *widget, int key ) __nonnull;
99
 static void msg ( unsigned int row, const char *fmt, ... ) __nonnull;
99
 static void msg ( unsigned int row, const char *fmt, ... ) __nonnull;
100
 static void valert ( const char *fmt, va_list args ) __nonnull;
100
 static void valert ( const char *fmt, va_list args ) __nonnull;
101
 static void alert ( const char *fmt, ... ) __nonnull;
101
 static void alert ( const char *fmt, ... ) __nonnull;
102
-static void draw_info_row ( struct named_setting *setting ) __nonnull;
102
+static void draw_info_row ( struct setting *setting ) __nonnull;
103
 static int main_loop ( struct settings *settings ) __nonnull;
103
 static int main_loop ( struct settings *settings ) __nonnull;
104
 
104
 
105
 /**
105
 /**
114
 	widget->editing = 0;
114
 	widget->editing = 0;
115
 
115
 
116
 	/* Read current setting value */
116
 	/* Read current setting value */
117
-	if ( fetch_typed_setting ( widget->settings, widget->setting->tag,
118
-				   widget->setting->type, widget->value,
119
-				   sizeof ( widget->value ) ) < 0 ) {
117
+	if ( fetchf_setting ( widget->settings, widget->setting,
118
+			      widget->value, sizeof ( widget->value ) ) < 0 ) {
120
 		widget->value[0] = '\0';
119
 		widget->value[0] = '\0';
121
 	}	
120
 	}	
122
 
121
 
133
  * @v widget		Setting widget
132
  * @v widget		Setting widget
134
  */
133
  */
135
 static int save_setting ( struct setting_widget *widget ) {
134
 static int save_setting ( struct setting_widget *widget ) {
136
-	return store_typed_setting ( widget->settings, widget->setting->tag,
137
-				     widget->setting->type, widget->value );
135
+	return storef_setting ( widget->settings, widget->setting,
136
+				widget->value );
138
 }
137
 }
139
 
138
 
140
 /**
139
 /**
148
  */
147
  */
149
 static void init_setting ( struct setting_widget *widget,
148
 static void init_setting ( struct setting_widget *widget,
150
 			   struct settings *settings,
149
 			   struct settings *settings,
151
-			   struct named_setting *setting,
150
+			   struct setting *setting,
152
 			   unsigned int row, unsigned int col ) {
151
 			   unsigned int row, unsigned int col ) {
153
 
152
 
154
 	/* Initialise widget structure */
153
 	/* Initialise widget structure */
224
 static void init_setting_index ( struct setting_widget *widget,
223
 static void init_setting_index ( struct setting_widget *widget,
225
 				 struct settings *settings,
224
 				 struct settings *settings,
226
 				 unsigned int index ) {
225
 				 unsigned int index ) {
227
-	init_setting ( widget, settings, &named_settings[index],
226
+	init_setting ( widget, settings, &all_settings[index],
228
 		       ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL );
227
 		       ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL );
229
 }
228
 }
230
 
229
 
311
  *
310
  *
312
  * @v setting		Current configuration setting
311
  * @v setting		Current configuration setting
313
  */
312
  */
314
-static void draw_info_row ( struct named_setting *setting ) {
313
+static void draw_info_row ( struct setting *setting ) {
315
 	clearmsg ( INFO_ROW );
314
 	clearmsg ( INFO_ROW );
316
 	attron ( A_BOLD );
315
 	attron ( A_BOLD );
317
 	msg ( INFO_ROW, "%s - %s", setting->name, setting->description );
316
 	msg ( INFO_ROW, "%s - %s", setting->name, setting->description );

+ 14
- 15
src/include/gpxe/dhcp.h View File

15
 
15
 
16
 struct net_device;
16
 struct net_device;
17
 struct job_interface;
17
 struct job_interface;
18
+struct dhcp_options;
18
 struct dhcp_packet;
19
 struct dhcp_packet;
19
-struct settings;
20
 
20
 
21
 /** BOOTP/DHCP server port */
21
 /** BOOTP/DHCP server port */
22
 #define BOOTPS_PORT 67
22
 #define BOOTPS_PORT 67
179
  */
179
  */
180
 #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 )
180
 #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 )
181
 
181
 
182
-/** MAC address
183
- *
184
- * This option is used internally to contain the network device
185
- * hardware address, in order to provide a consistent approach to
186
- * storing and processing options.  It should never be present in a
187
- * DHCP packet.
188
- */
189
-#define DHCP_EB_MAC DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 4 )
190
-
191
 /*
182
 /*
192
  * Tags in the range 0x10-0x7f are reserved for feature markers
183
  * Tags in the range 0x10-0x7f are reserved for feature markers
193
  *
184
  *
445
 /** Maximum time that we will wait for ProxyDHCP offers */
436
 /** Maximum time that we will wait for ProxyDHCP offers */
446
 #define PROXYDHCP_WAIT_TIME ( TICKS_PER_SEC * 1 )
437
 #define PROXYDHCP_WAIT_TIME ( TICKS_PER_SEC * 1 )
447
 
438
 
448
-extern int create_dhcpdiscover ( struct net_device *netdev,
449
-				 void *data, size_t max_len );
450
-extern int create_dhcpack ( struct net_device *netdev,
451
-			    void *data, size_t max_len );
452
-extern int create_proxydhcpack ( struct net_device *netdev,
439
+/** Settings block name used for DHCP responses */
440
+#define DHCP_SETTINGS_NAME "dhcp"
441
+
442
+/** Settings block name used for ProxyDHCP responses */
443
+#define PROXYDHCP_SETTINGS_NAME "proxydhcp"
444
+
445
+extern int create_dhcp_packet ( struct dhcp_packet *dhcppkt,
446
+				struct net_device *netdev, uint8_t msgtype,
447
+				struct dhcp_options *options, 
448
+				void *data, size_t max_len );
449
+extern int create_dhcp_request ( struct dhcp_packet *dhcppkt,
450
+				 struct net_device *netdev,
451
+				 struct dhcp_packet *dhcpoffer,
453
 				 void *data, size_t max_len );
452
 				 void *data, size_t max_len );
454
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev );
453
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev );
455
 
454
 

+ 1
- 1
src/include/gpxe/dhcpopts.h View File

7
  *
7
  *
8
  */
8
  */
9
 
9
 
10
-#include <gpxe/dhcp.h>
10
+#include <stdint.h>
11
 
11
 
12
 /** A DHCP options block */
12
 /** A DHCP options block */
13
 struct dhcp_options {
13
 struct dhcp_options {

+ 5
- 4
src/include/gpxe/dhcppkt.h View File

9
 
9
 
10
 #include <gpxe/dhcp.h>
10
 #include <gpxe/dhcp.h>
11
 #include <gpxe/dhcpopts.h>
11
 #include <gpxe/dhcpopts.h>
12
-#include <gpxe/settings.h>
13
 
12
 
14
 /**
13
 /**
15
  * A DHCP packet
14
  * A DHCP packet
16
  *
15
  *
17
  */
16
  */
18
 struct dhcp_packet {
17
 struct dhcp_packet {
19
-	/** Settings block */
20
-	struct settings settings;
21
 	/** The DHCP packet contents */
18
 	/** The DHCP packet contents */
22
 	struct dhcphdr *dhcphdr;
19
 	struct dhcphdr *dhcphdr;
23
 	/** Maximum length of the DHCP packet buffer */
20
 	/** Maximum length of the DHCP packet buffer */
28
 	struct dhcp_options options;
25
 	struct dhcp_options options;
29
 };
26
 };
30
 
27
 
31
-extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct refcnt *refcnt,
28
+extern int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag,
29
+			   const void *data, size_t len );
30
+extern int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag,
31
+			   void *data, size_t len );
32
+extern void dhcppkt_init ( struct dhcp_packet *dhcppkt, 
32
 			   void *data, size_t len );
33
 			   void *data, size_t len );
33
 
34
 
34
 #endif /* _GPXE_DHCPPKT_H */
35
 #endif /* _GPXE_DHCPPKT_H */

+ 21
- 0
src/include/gpxe/fakedhcp.h View File

1
+#ifndef _GPXE_FAKEDHCP_H
2
+#define _GPXE_FAKEDHCP_H
3
+
4
+/** @file
5
+ *
6
+ * Fake DHCP packets
7
+ *
8
+ */
9
+
10
+#include <stdint.h>
11
+
12
+struct net_device;
13
+
14
+extern int create_fakedhcpdiscover ( struct net_device *netdev,
15
+				     void *data, size_t max_len );
16
+extern int create_fakedhcpack ( struct net_device *netdev,
17
+				void *data, size_t max_len );
18
+extern int create_fakeproxydhcpack ( struct net_device *netdev,
19
+				     void *data, size_t max_len );
20
+
21
+#endif /* _GPXE_FAKEDHCP_H */

+ 81
- 67
src/include/gpxe/settings.h View File

16
 struct settings;
16
 struct settings;
17
 struct in_addr;
17
 struct in_addr;
18
 
18
 
19
+/** A setting */
20
+struct setting {
21
+	/** Name
22
+	 *
23
+	 * This is the human-readable name for the setting.
24
+	 */
25
+	const char *name;
26
+	/** Description */
27
+	const char *description;
28
+	/** Setting type
29
+	 *
30
+	 * This identifies the type of setting (e.g. string, IPv4
31
+	 * address, etc.).
32
+	 */
33
+	struct setting_type *type;
34
+	/** DHCP option number, if applicable */
35
+	unsigned int tag;
36
+};
37
+
38
+/** Declare a configuration setting */
39
+#define	__setting __table ( struct setting, settings, 01 )
40
+
19
 /** Settings block operations */
41
 /** Settings block operations */
20
 struct settings_operations {
42
 struct settings_operations {
21
 	/** Store value of setting
43
 	/** Store value of setting
22
 	 *
44
 	 *
23
 	 * @v settings		Settings block
45
 	 * @v settings		Settings block
24
-	 * @v tag		Setting tag number
46
+	 * @v setting		Setting to store
25
 	 * @v data		Setting data, or NULL to clear setting
47
 	 * @v data		Setting data, or NULL to clear setting
26
 	 * @v len		Length of setting data
48
 	 * @v len		Length of setting data
27
 	 * @ret rc		Return status code
49
 	 * @ret rc		Return status code
28
 	 */
50
 	 */
29
-	int ( * store ) ( struct settings *settings, unsigned int tag,
51
+	int ( * store ) ( struct settings *settings, struct setting *setting,
30
 			  const void *data, size_t len );
52
 			  const void *data, size_t len );
31
 	/** Fetch value of setting
53
 	/** Fetch value of setting
32
 	 *
54
 	 *
33
 	 * @v settings		Settings block
55
 	 * @v settings		Settings block
34
-	 * @v tag		Setting tag number
56
+	 * @v setting		Setting to fetch
35
 	 * @v data		Buffer to fill with setting data
57
 	 * @v data		Buffer to fill with setting data
36
 	 * @v len		Length of buffer
58
 	 * @v len		Length of buffer
37
 	 * @ret len		Length of setting data, or negative error
59
 	 * @ret len		Length of setting data, or negative error
39
 	 * The actual length of the setting will be returned even if
61
 	 * The actual length of the setting will be returned even if
40
 	 * the buffer was too small.
62
 	 * the buffer was too small.
41
 	 */
63
 	 */
42
-	int ( * fetch ) ( struct settings *settings, unsigned int tag,
64
+	int ( * fetch ) ( struct settings *settings, struct setting *setting,
43
 			  void *data, size_t len );
65
 			  void *data, size_t len );
44
 };
66
 };
45
 
67
 
74
 	/** Parse and set value of setting
96
 	/** Parse and set value of setting
75
 	 *
97
 	 *
76
 	 * @v settings		Settings block
98
 	 * @v settings		Settings block
77
-	 * @v tag		Setting tag number
99
+	 * @v setting		Setting to store
78
 	 * @v value		Formatted setting data
100
 	 * @v value		Formatted setting data
79
 	 * @ret rc		Return status code
101
 	 * @ret rc		Return status code
80
 	 */
102
 	 */
81
-	int ( * storef ) ( struct settings *settings, unsigned int tag,
103
+	int ( * storef ) ( struct settings *settings, struct setting *setting,
82
 			   const char *value );
104
 			   const char *value );
83
 	/** Fetch and format value of setting
105
 	/** Fetch and format value of setting
84
 	 *
106
 	 *
85
-	 * @v settings		Settings block, or NULL to search all blocks
86
-	 * @v tag		Setting tag number
107
+	 * @v settings		Settings block
108
+	 * @v setting		Setting to fetch
87
 	 * @v buf		Buffer to contain formatted value
109
 	 * @v buf		Buffer to contain formatted value
88
 	 * @v len		Length of buffer
110
 	 * @v len		Length of buffer
89
 	 * @ret len		Length of formatted value, or negative error
111
 	 * @ret len		Length of formatted value, or negative error
90
 	 */
112
 	 */
91
-	int ( * fetchf ) ( struct settings *settings, unsigned int tag,
113
+	int ( * fetchf ) ( struct settings *settings, struct setting *setting,
92
 			   char *buf, size_t len );
114
 			   char *buf, size_t len );
93
 };
115
 };
94
 
116
 
96
 #define	__setting_type \
118
 #define	__setting_type \
97
 	__table ( struct setting_type, setting_types, 01 )
119
 	__table ( struct setting_type, setting_types, 01 )
98
 
120
 
99
-/**
100
- * A named setting
101
- *
102
- * This represents a single setting (e.g. "hostname"), encapsulating
103
- * the information about the setting's tag number and type.
104
- */
105
-struct named_setting {
106
-	/** Name
107
-	 *
108
-	 * This is the human-readable name for the setting.
109
-	 */
110
-	const char *name;
111
-	/** Description */
112
-	const char *description;
113
-	/** Setting tag number */
114
-	unsigned int tag;
115
-	/** Setting type
116
-	 *
117
-	 * This identifies the type of setting (e.g. string, IPv4
118
-	 * address, etc.).
119
-	 */
120
-	struct setting_type *type;
121
-};
122
-
123
-/** Declare a configuration setting */
124
-#define	__named_setting __table ( struct named_setting, named_settings, 01 )
125
-
126
 /**
121
 /**
127
  * A settings applicator
122
  * A settings applicator
128
  *
123
  *
151
 };
146
 };
152
 
147
 
153
 extern struct settings_operations simple_settings_operations;
148
 extern struct settings_operations simple_settings_operations;
154
-
155
-extern int simple_settings_store ( struct settings *settings, unsigned int tag,
149
+extern int simple_settings_store ( struct settings *settings,
150
+				   struct setting *setting,
156
 				   const void *data, size_t len );
151
 				   const void *data, size_t len );
157
-extern int simple_settings_fetch ( struct settings *settings, unsigned int tag,
152
+extern int simple_settings_fetch ( struct settings *settings,
153
+				   struct setting *setting,
158
 				   void *data, size_t len );
154
 				   void *data, size_t len );
155
+
159
 extern int register_settings ( struct settings *settings,
156
 extern int register_settings ( struct settings *settings,
160
 			       struct settings *parent );
157
 			       struct settings *parent );
161
 extern void unregister_settings ( struct settings *settings );
158
 extern void unregister_settings ( struct settings *settings );
162
-extern int store_setting ( struct settings *settings, unsigned int tag,
159
+
160
+extern int store_setting ( struct settings *settings, struct setting *setting,
163
 			   const void *data, size_t len );
161
 			   const void *data, size_t len );
164
-extern int fetch_setting ( struct settings *settings, unsigned int tag,
162
+extern int fetch_setting ( struct settings *settings, struct setting *setting,
165
 			   void *data, size_t len );
163
 			   void *data, size_t len );
166
-extern int copy_settings ( struct settings *dest, struct settings *source );
167
-extern int fetch_setting_len ( struct settings *settings, unsigned int tag );
168
-extern int fetch_string_setting ( struct settings *settings, unsigned int tag,
164
+extern int fetch_setting_len ( struct settings *settings,
165
+			       struct setting *setting );
166
+extern int fetch_string_setting ( struct settings *settings,
167
+				  struct setting *setting,
169
 				  char *data, size_t len );
168
 				  char *data, size_t len );
170
-extern int fetch_ipv4_setting ( struct settings *settings, unsigned int tag,
171
-				struct in_addr *inp );
172
-extern int fetch_int_setting ( struct settings *settings, unsigned int tag,
173
-			       long *value );
174
-extern int fetch_uint_setting ( struct settings *settings, unsigned int tag,
169
+extern int fetch_ipv4_setting ( struct settings *settings,
170
+				struct setting *setting, struct in_addr *inp );
171
+extern int fetch_int_setting ( struct settings *settings,
172
+			       struct setting *setting, long *value );
173
+extern int fetch_uint_setting ( struct settings *settings,
174
+				struct setting *setting,
175
 				unsigned long *value );
175
 				unsigned long *value );
176
-extern long fetch_intz_setting ( struct settings *settings, unsigned int tag );
176
+extern long fetch_intz_setting ( struct settings *settings,
177
+				 struct setting *setting );
177
 extern unsigned long fetch_uintz_setting ( struct settings *settings,
178
 extern unsigned long fetch_uintz_setting ( struct settings *settings,
178
-					   unsigned int tag );
179
+					   struct setting *setting );
180
+extern int setting_cmp ( struct setting *a, struct setting *b );
181
+
179
 extern struct settings * find_child_settings ( struct settings *parent,
182
 extern struct settings * find_child_settings ( struct settings *parent,
180
 					       const char *name );
183
 					       const char *name );
181
 extern struct settings * find_settings ( const char *name );
184
 extern struct settings * find_settings ( const char *name );
182
-extern int store_typed_setting ( struct settings *settings,
183
-				 unsigned int tag, struct setting_type *type,
184
-				 const char *value );
185
-extern int store_named_setting ( const char *name, const char *value );
186
-extern int fetch_named_setting ( const char *name, char *buf, size_t len );
187
 
185
 
188
-extern struct setting_type setting_type_ __setting_type;
186
+extern int storef_setting ( struct settings *settings,
187
+			    struct setting *setting,
188
+			    const char *value );
189
+extern int storef_named_setting ( const char *name, const char *value );
190
+extern int fetchf_named_setting ( const char *name, char *buf, size_t len );
191
+
189
 extern struct setting_type setting_type_string __setting_type;
192
 extern struct setting_type setting_type_string __setting_type;
190
 extern struct setting_type setting_type_ipv4 __setting_type;
193
 extern struct setting_type setting_type_ipv4 __setting_type;
191
 extern struct setting_type setting_type_int8 __setting_type;
194
 extern struct setting_type setting_type_int8 __setting_type;
196
 extern struct setting_type setting_type_uint32 __setting_type;
199
 extern struct setting_type setting_type_uint32 __setting_type;
197
 extern struct setting_type setting_type_hex __setting_type;
200
 extern struct setting_type setting_type_hex __setting_type;
198
 
201
 
202
+extern struct setting ip_setting __setting;
203
+extern struct setting netmask_setting __setting;
204
+extern struct setting gateway_setting __setting;
205
+extern struct setting dns_setting __setting;
206
+extern struct setting hostname_setting __setting;
207
+extern struct setting filename_setting __setting;
208
+extern struct setting root_path_setting __setting;
209
+extern struct setting username_setting __setting;
210
+extern struct setting password_setting __setting;
211
+extern struct setting priority_setting __setting;
212
+extern struct setting bios_drive_setting __setting;
213
+
199
 /**
214
 /**
200
  * Initialise a settings block
215
  * Initialise a settings block
201
  *
216
  *
233
  * Delete setting
248
  * Delete setting
234
  *
249
  *
235
  * @v settings		Settings block
250
  * @v settings		Settings block
236
- * @v tag		Setting tag number
251
+ * @v setting		Setting to delete
237
  * @ret rc		Return status code
252
  * @ret rc		Return status code
238
  */
253
  */
239
 static inline int delete_setting ( struct settings *settings,
254
 static inline int delete_setting ( struct settings *settings,
240
-				   unsigned int tag ) {
241
-	return store_setting ( settings, tag, NULL, 0 );
255
+				   struct setting *setting ) {
256
+	return store_setting ( settings, setting, NULL, 0 );
242
 }
257
 }
243
 
258
 
244
 /**
259
 /**
245
  * Fetch and format value of setting
260
  * Fetch and format value of setting
246
  *
261
  *
247
  * @v settings		Settings block, or NULL to search all blocks
262
  * @v settings		Settings block, or NULL to search all blocks
248
- * @v tag		Setting tag number
263
+ * @v setting		Setting to fetch
249
  * @v type		Settings type
264
  * @v type		Settings type
250
  * @v buf		Buffer to contain formatted value
265
  * @v buf		Buffer to contain formatted value
251
  * @v len		Length of buffer
266
  * @v len		Length of buffer
252
  * @ret len		Length of formatted value, or negative error
267
  * @ret len		Length of formatted value, or negative error
253
  */
268
  */
254
-static inline int fetch_typed_setting ( struct settings *settings,
255
-					unsigned int tag,
256
-					struct setting_type *type,
257
-					char *buf, size_t len ) {
258
-	return type->fetchf ( settings, tag, buf, len );
269
+static inline int fetchf_setting ( struct settings *settings,
270
+				   struct setting *setting,
271
+				   char *buf, size_t len ) {
272
+	return setting->type->fetchf ( settings, setting, buf, len );
259
 }
273
 }
260
 
274
 
261
 /**
275
 /**
265
  * @ret rc		Return status code
279
  * @ret rc		Return status code
266
  */
280
  */
267
 static inline int delete_named_setting ( const char *name ) {
281
 static inline int delete_named_setting ( const char *name ) {
268
-	return store_named_setting ( name, NULL );
282
+	return storef_named_setting ( name, NULL );
269
 }
283
 }
270
 
284
 
271
 #endif /* _GPXE_SETTINGS_H */
285
 #endif /* _GPXE_SETTINGS_H */

+ 4
- 4
src/interface/pxe/pxe_preboot.c View File

28
 #include <stdlib.h>
28
 #include <stdlib.h>
29
 #include <gpxe/uaccess.h>
29
 #include <gpxe/uaccess.h>
30
 #include <gpxe/dhcp.h>
30
 #include <gpxe/dhcp.h>
31
-#include <gpxe/dhcppkt.h>
31
+#include <gpxe/fakedhcp.h>
32
 #include <gpxe/device.h>
32
 #include <gpxe/device.h>
33
 #include <gpxe/netdevice.h>
33
 #include <gpxe/netdevice.h>
34
 #include <gpxe/isapnp.h>
34
 #include <gpxe/isapnp.h>
80
 
80
 
81
 /** PXE DHCP packet creators */
81
 /** PXE DHCP packet creators */
82
 static struct pxe_dhcp_packet_creator pxe_dhcp_packet_creators[] = {
82
 static struct pxe_dhcp_packet_creator pxe_dhcp_packet_creators[] = {
83
-	[CACHED_INFO_DHCPDISCOVER] = { create_dhcpdiscover },
84
-	[CACHED_INFO_DHCPACK] = { create_dhcpack },
85
-	[CACHED_INFO_BINL] = { create_proxydhcpack },
83
+	[CACHED_INFO_DHCPDISCOVER] = { create_fakedhcpdiscover },
84
+	[CACHED_INFO_DHCPACK] = { create_fakedhcpack },
85
+	[CACHED_INFO_BINL] = { create_fakeproxydhcpack },
86
 };
86
 };
87
 
87
 
88
 /* The case in which the caller doesn't supply a buffer is really
88
 /* The case in which the caller doesn't supply a buffer is really

+ 13
- 3
src/net/dhcpopts.c View File

118
 	ssize_t remaining = options->len;
118
 	ssize_t remaining = options->len;
119
 	unsigned int option_len;
119
 	unsigned int option_len;
120
 
120
 
121
+	/* Sanity check */
122
+	if ( tag == DHCP_PAD )
123
+		return -ENOENT;
124
+
125
+	/* Search for option */
121
 	while ( remaining ) {
126
 	while ( remaining ) {
122
 		/* Calculate length of this option.  Abort processing
127
 		/* Calculate length of this option.  Abort processing
123
 		 * if the length is malformed (i.e. takes us beyond
128
 		 * if the length is malformed (i.e. takes us beyond
128
 		remaining -= option_len;
133
 		remaining -= option_len;
129
 		if ( remaining < 0 )
134
 		if ( remaining < 0 )
130
 			break;
135
 			break;
136
+		/* Check for explicit end marker */
137
+		if ( option->tag == DHCP_END )
138
+			break;
131
 		/* Check for matching tag */
139
 		/* Check for matching tag */
132
 		if ( option->tag == tag ) {
140
 		if ( option->tag == tag ) {
133
 			DBGC ( options, "DHCPOPT %p found %s (length %d)\n",
141
 			DBGC ( options, "DHCPOPT %p found %s (length %d)\n",
135
 			       option_len );
143
 			       option_len );
136
 			return offset;
144
 			return offset;
137
 		}
145
 		}
138
-		/* Check for explicit end marker */
139
-		if ( option->tag == DHCP_END )
140
-			break;
141
 		/* Check for start of matching encapsulation block */
146
 		/* Check for start of matching encapsulation block */
142
 		if ( DHCP_IS_ENCAP_OPT ( tag ) &&
147
 		if ( DHCP_IS_ENCAP_OPT ( tag ) &&
143
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
148
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
151
 		}
156
 		}
152
 		offset += option_len;
157
 		offset += option_len;
153
 	}
158
 	}
159
+
154
 	return -ENOENT;
160
 	return -ENOENT;
155
 }
161
 }
156
 
162
 
255
 	size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 );
261
 	size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 );
256
 	int rc;
262
 	int rc;
257
 
263
 
264
+	/* Sanity check */
265
+	if ( tag == DHCP_PAD )
266
+		return -ENOTTY;
267
+
258
 	/* Find old instance of this option, if any */
268
 	/* Find old instance of this option, if any */
259
 	offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
269
 	offset = find_dhcp_option_with_encap ( options, tag, &encap_offset );
260
 	if ( offset >= 0 ) {
270
 	if ( offset >= 0 ) {

+ 8
- 22
src/net/dhcppkt.c View File

92
 	}
92
 	}
93
 	return NULL;
93
 	return NULL;
94
 }
94
 }
95
-				    
95
+
96
 /**
96
 /**
97
  * Store value of DHCP packet setting
97
  * Store value of DHCP packet setting
98
  *
98
  *
99
- * @v settings		Settings block
99
+ * @v dhcppkt		DHCP packet
100
  * @v tag		Setting tag number
100
  * @v tag		Setting tag number
101
  * @v data		Setting data, or NULL to clear setting
101
  * @v data		Setting data, or NULL to clear setting
102
  * @v len		Length of setting data
102
  * @v len		Length of setting data
103
  * @ret rc		Return status code
103
  * @ret rc		Return status code
104
  */
104
  */
105
-static int dhcppkt_store ( struct settings *settings, unsigned int tag,
106
-			   const void *data, size_t len ) {
107
-	struct dhcp_packet *dhcppkt =
108
-		container_of ( settings, struct dhcp_packet, settings );
105
+int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag,
106
+		    const void *data, size_t len ) {
109
 	struct dhcp_packet_field *field;
107
 	struct dhcp_packet_field *field;
110
 	int rc;
108
 	int rc;
111
 
109
 
131
 /**
129
 /**
132
  * Fetch value of DHCP packet setting
130
  * Fetch value of DHCP packet setting
133
  *
131
  *
134
- * @v settings		Settings block
132
+ * @v dhcppkt		DHCP packet
135
  * @v tag		Setting tag number
133
  * @v tag		Setting tag number
136
  * @v data		Buffer to fill with setting data
134
  * @v data		Buffer to fill with setting data
137
  * @v len		Length of buffer
135
  * @v len		Length of buffer
138
  * @ret len		Length of setting data, or negative error
136
  * @ret len		Length of setting data, or negative error
139
  */
137
  */
140
-static int dhcppkt_fetch ( struct settings *settings, unsigned int tag,
141
-			   void *data, size_t len ) {
142
-	struct dhcp_packet *dhcppkt =
143
-		container_of ( settings, struct dhcp_packet, settings );
138
+int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag,
139
+		    void *data, size_t len ) {
144
 	struct dhcp_packet_field *field;
140
 	struct dhcp_packet_field *field;
145
 	
141
 	
146
 	/* If this is a special field, return it */
142
 	/* If this is a special field, return it */
156
 	return dhcpopt_fetch ( &dhcppkt->options, tag, data, len );
152
 	return dhcpopt_fetch ( &dhcppkt->options, tag, data, len );
157
 }
153
 }
158
 
154
 
159
-/** DHCP settings operations */
160
-static struct settings_operations dhcppkt_settings_operations = {
161
-	.store = dhcppkt_store,
162
-	.fetch = dhcppkt_fetch,
163
-};
164
-
165
 /**
155
 /**
166
  * Initialise prepopulated DHCP packet
156
  * Initialise prepopulated DHCP packet
167
  *
157
  *
168
  * @v dhcppkt		Uninitialised DHCP packet
158
  * @v dhcppkt		Uninitialised DHCP packet
169
- * @v refcnt		Reference counter of containing object, or NULL
170
  * @v data		Memory for DHCP packet data
159
  * @v data		Memory for DHCP packet data
171
  * @v max_len		Length of memory for DHCP packet data
160
  * @v max_len		Length of memory for DHCP packet data
172
  *
161
  *
173
  * The memory content must already be filled with valid DHCP options.
162
  * The memory content must already be filled with valid DHCP options.
174
  * A zeroed block counts as a block of valid DHCP options.
163
  * A zeroed block counts as a block of valid DHCP options.
175
  */
164
  */
176
-void dhcppkt_init ( struct dhcp_packet *dhcppkt, struct refcnt *refcnt,
177
-		    void *data, size_t len ) {
165
+void dhcppkt_init ( struct dhcp_packet *dhcppkt, void *data, size_t len ) {
178
 	dhcppkt->dhcphdr = data;
166
 	dhcppkt->dhcphdr = data;
179
 	dhcppkt->max_len = len;
167
 	dhcppkt->max_len = len;
180
 	dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options,
168
 	dhcpopt_init ( &dhcppkt->options, &dhcppkt->dhcphdr->options,
181
 		       ( len - offsetof ( struct dhcphdr, options ) ) );
169
 		       ( len - offsetof ( struct dhcphdr, options ) ) );
182
 	dhcppkt->len = ( offsetof ( struct dhcphdr, options ) +
170
 	dhcppkt->len = ( offsetof ( struct dhcphdr, options ) +
183
 			 dhcppkt->options.len );
171
 			 dhcppkt->options.len );
184
-	settings_init ( &dhcppkt->settings, &dhcppkt_settings_operations,
185
-			refcnt, "dhcp" );
186
 }
172
 }

+ 205
- 0
src/net/fakedhcp.c View File

1
+/*
2
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <stdlib.h>
21
+#include <stdio.h>
22
+#include <errno.h>
23
+#include <string.h>
24
+#include <gpxe/settings.h>
25
+#include <gpxe/netdevice.h>
26
+#include <gpxe/dhcppkt.h>
27
+#include <gpxe/fakedhcp.h>
28
+
29
+/** @file
30
+ *
31
+ * Fake DHCP packets
32
+ *
33
+ */
34
+
35
+/**
36
+ * Copy settings to DHCP packet
37
+ *
38
+ * @v dest		Destination DHCP packet
39
+ * @v source		Source settings block
40
+ * @v encapsulator	Encapsulating setting tag number, or zero
41
+ * @ret rc		Return status code
42
+ */
43
+static int copy_encap_settings ( struct dhcp_packet *dest,
44
+				 struct settings *source,
45
+				 unsigned int encapsulator ) {
46
+	struct setting setting = { .name = "" };
47
+	unsigned int subtag;
48
+	unsigned int tag;
49
+	int len;
50
+	int check_len;
51
+	int rc;
52
+
53
+	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
54
+		tag = DHCP_ENCAP_OPT ( encapsulator, subtag );
55
+		switch ( tag ) {
56
+		case DHCP_EB_ENCAP:
57
+		case DHCP_VENDOR_ENCAP:
58
+			/* Process encapsulated settings */
59
+			if ( ( rc = copy_encap_settings ( dest, source,
60
+							  tag ) ) != 0 )
61
+				return rc;
62
+			break;
63
+		default:
64
+			/* Copy setting, if present */
65
+			setting.tag = tag;
66
+			len = fetch_setting_len ( source, &setting );
67
+			if ( len < 0 )
68
+				break;
69
+			{
70
+				char buf[len];
71
+
72
+				check_len = fetch_setting ( source, &setting,
73
+							    buf, sizeof (buf));
74
+				assert ( check_len == len );
75
+				if ( ( rc = dhcppkt_store ( dest, tag, buf,
76
+							    sizeof(buf) )) !=0)
77
+					return rc;
78
+			}
79
+			break;
80
+		}
81
+	}
82
+
83
+	return 0;
84
+}
85
+
86
+/**
87
+ * Copy settings to DHCP packet
88
+ *
89
+ * @v dest		Destination DHCP packet
90
+ * @v source		Source settings block
91
+ * @ret rc		Return status code
92
+ */
93
+static int copy_settings ( struct dhcp_packet *dest,
94
+			   struct settings *source ) {
95
+	return copy_encap_settings ( dest, source, 0 );
96
+}
97
+
98
+/**
99
+ * Create fake DHCPDISCOVER packet
100
+ *
101
+ * @v netdev		Network device
102
+ * @v data		Buffer for DHCP packet
103
+ * @v max_len		Size of DHCP packet buffer
104
+ * @ret rc		Return status code
105
+ *
106
+ * Used by external code.
107
+ */
108
+int create_fakedhcpdiscover ( struct net_device *netdev,
109
+			      void *data, size_t max_len ) {
110
+	struct dhcp_packet dhcppkt;
111
+	int rc;
112
+
113
+	if ( ( rc = create_dhcp_request ( &dhcppkt, netdev, NULL, data,
114
+					  max_len ) ) != 0 ) {
115
+		DBG ( "Could not create DHCPDISCOVER: %s\n",
116
+		      strerror ( rc ) );
117
+		return rc;
118
+	}
119
+
120
+	return 0;
121
+}
122
+
123
+/**
124
+ * Create fake DHCPACK packet
125
+ *
126
+ * @v netdev		Network device
127
+ * @v data		Buffer for DHCP packet
128
+ * @v max_len		Size of DHCP packet buffer
129
+ * @ret rc		Return status code
130
+ *
131
+ * Used by external code.
132
+ */
133
+int create_fakedhcpack ( struct net_device *netdev,
134
+			 void *data, size_t max_len ) {
135
+	struct dhcp_packet dhcppkt;
136
+	int rc;
137
+
138
+	/* Create base DHCPACK packet */
139
+	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
140
+					 data, max_len ) ) != 0 ) {
141
+		DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
142
+		return rc;
143
+	}
144
+
145
+	/* Merge in globally-scoped settings, then netdev-specific
146
+	 * settings.  Do it in this order so that netdev-specific
147
+	 * settings take precedence regardless of stated priorities.
148
+	 */
149
+	if ( ( rc = copy_settings ( &dhcppkt, NULL ) ) != 0 ) {
150
+		DBG ( "Could not set DHCPACK global settings: %s\n",
151
+		      strerror ( rc ) );
152
+		return rc;
153
+	}
154
+	if ( ( rc = copy_settings ( &dhcppkt,
155
+				    netdev_settings ( netdev ) ) ) != 0 ) {
156
+		DBG ( "Could not set DHCPACK netdev settings: %s\n",
157
+		      strerror ( rc ) );
158
+		return rc;
159
+	}
160
+
161
+	return 0;
162
+}
163
+
164
+/**
165
+ * Create ProxyDHCPACK packet
166
+ *
167
+ * @v netdev		Network device
168
+ * @v data		Buffer for DHCP packet
169
+ * @v max_len		Size of DHCP packet buffer
170
+ * @ret rc		Return status code
171
+ *
172
+ * Used by external code.
173
+ */
174
+int create_fakeproxydhcpack ( struct net_device *netdev,
175
+			      void *data, size_t max_len ) {
176
+	struct dhcp_packet dhcppkt;
177
+	struct settings *settings;
178
+	int rc;
179
+
180
+	/* Identify ProxyDHCP settings */
181
+	settings = find_settings ( PROXYDHCP_SETTINGS_NAME );
182
+
183
+	/* No ProxyDHCP settings => return empty block */
184
+	if ( ! settings ) {
185
+		memset ( data, 0, max_len );
186
+		return 0;
187
+	}
188
+
189
+	/* Create base DHCPACK packet */
190
+	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
191
+					 data, max_len ) ) != 0 ) {
192
+		DBG ( "Could not create ProxyDHCPACK: %s\n",
193
+		      strerror ( rc ) );
194
+		return rc;
195
+	}
196
+
197
+	/* Merge in ProxyDHCP options */
198
+	if ( ( rc = copy_settings ( &dhcppkt, settings ) ) != 0 ) {
199
+		DBG ( "Could not set ProxyDHCPACK settings: %s\n",
200
+		      strerror ( rc ) );
201
+		return rc;
202
+	}
203
+
204
+	return 0;
205
+}

+ 87
- 56
src/net/ipv4.c View File

95
 	free ( miniroute );
95
 	free ( miniroute );
96
 }
96
 }
97
 
97
 
98
-/**
99
- * Create IPv4 routing table
100
- *
101
- * @ret rc		Return status code
102
- */
103
-static int ipv4_create_routes ( void ) {
104
-	struct ipv4_miniroute *miniroute;
105
-	struct ipv4_miniroute *tmp;
106
-	struct net_device *netdev;
107
-	struct settings *settings;
108
-	struct in_addr address = { 0 };
109
-	struct in_addr netmask = { 0 };
110
-	struct in_addr gateway = { INADDR_NONE };
111
-
112
-	/* Delete all existing routes */
113
-	list_for_each_entry_safe ( miniroute, tmp, &ipv4_miniroutes, list )
114
-		del_ipv4_miniroute ( miniroute );
115
-
116
-	/* Create a route for each configured network device */
117
-	for_each_netdev ( netdev ) {
118
-		settings = netdev_settings ( netdev );
119
-		/* Get IPv4 address */
120
-		address.s_addr = 0;
121
-		fetch_ipv4_setting ( settings, DHCP_EB_YIADDR, &address );
122
-		if ( ! address.s_addr )
123
-			continue;
124
-		/* Calculate default netmask */
125
-		if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) {
126
-			netmask.s_addr = htonl ( IN_CLASSA_NET );
127
-		} else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) {
128
-			netmask.s_addr = htonl ( IN_CLASSB_NET );
129
-		} else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) {
130
-			netmask.s_addr = htonl ( IN_CLASSC_NET );
131
-		} else {
132
-			netmask.s_addr = 0;
133
-		}
134
-		/* Override with subnet mask, if present */
135
-		fetch_ipv4_setting ( settings, DHCP_SUBNET_MASK, &netmask );
136
-		/* Get default gateway, if present */
137
-		gateway.s_addr = INADDR_NONE;
138
-		fetch_ipv4_setting ( settings, DHCP_ROUTERS, &gateway );
139
-		/* Configure route */
140
-		miniroute = add_ipv4_miniroute ( netdev, address,
141
-						 netmask, gateway );
142
-		if ( ! miniroute )
143
-			return -ENOMEM;
144
-	}
145
-
146
-	return 0;
147
-}
148
-
149
-/** IPv4 settings applicator */
150
-struct settings_applicator ipv4_settings_applicator __settings_applicator = {
151
-	.apply = ipv4_create_routes,
152
-};
153
-
154
 /**
98
 /**
155
  * Perform IPv4 routing
99
  * Perform IPv4 routing
156
  *
100
  *
600
 	.net_protocol = &ipv4_protocol,
544
 	.net_protocol = &ipv4_protocol,
601
 	.check = ipv4_arp_check,
545
 	.check = ipv4_arp_check,
602
 };
546
 };
547
+
548
+/******************************************************************************
549
+ *
550
+ * Settings
551
+ *
552
+ ******************************************************************************
553
+ */
554
+
555
+/** IPv4 address setting */
556
+struct setting ip_setting __setting = {
557
+	.name = "ip",
558
+	.description = "IPv4 address",
559
+	.tag = DHCP_EB_YIADDR,
560
+	.type = &setting_type_ipv4,
561
+};
562
+
563
+/** IPv4 subnet mask setting */
564
+struct setting netmask_setting __setting = {
565
+	.name = "netmask",
566
+	.description = "IPv4 subnet mask",
567
+	.tag = DHCP_SUBNET_MASK,
568
+	.type = &setting_type_ipv4,
569
+};
570
+
571
+/** Default gateway setting */
572
+struct setting gateway_setting __setting = {
573
+	.name = "gateway",
574
+	.description = "Default gateway",
575
+	.tag = DHCP_ROUTERS,
576
+	.type = &setting_type_ipv4,
577
+};
578
+
579
+/**
580
+ * Create IPv4 routing table based on configured settings
581
+ *
582
+ * @ret rc		Return status code
583
+ */
584
+static int ipv4_create_routes ( void ) {
585
+	struct ipv4_miniroute *miniroute;
586
+	struct ipv4_miniroute *tmp;
587
+	struct net_device *netdev;
588
+	struct settings *settings;
589
+	struct in_addr address = { 0 };
590
+	struct in_addr netmask = { 0 };
591
+	struct in_addr gateway = { INADDR_NONE };
592
+
593
+	/* Delete all existing routes */
594
+	list_for_each_entry_safe ( miniroute, tmp, &ipv4_miniroutes, list )
595
+		del_ipv4_miniroute ( miniroute );
596
+
597
+	/* Create a route for each configured network device */
598
+	for_each_netdev ( netdev ) {
599
+		settings = netdev_settings ( netdev );
600
+		/* Get IPv4 address */
601
+		address.s_addr = 0;
602
+		fetch_ipv4_setting ( settings, &ip_setting, &address );
603
+		if ( ! address.s_addr )
604
+			continue;
605
+		/* Calculate default netmask */
606
+		if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) {
607
+			netmask.s_addr = htonl ( IN_CLASSA_NET );
608
+		} else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) {
609
+			netmask.s_addr = htonl ( IN_CLASSB_NET );
610
+		} else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) {
611
+			netmask.s_addr = htonl ( IN_CLASSC_NET );
612
+		} else {
613
+			netmask.s_addr = 0;
614
+		}
615
+		/* Override with subnet mask, if present */
616
+		fetch_ipv4_setting ( settings, &netmask_setting, &netmask );
617
+		/* Get default gateway, if present */
618
+		gateway.s_addr = INADDR_NONE;
619
+		fetch_ipv4_setting ( settings, &gateway_setting, &gateway );
620
+		/* Configure route */
621
+		miniroute = add_ipv4_miniroute ( netdev, address,
622
+						 netmask, gateway );
623
+		if ( ! miniroute )
624
+			return -ENOMEM;
625
+	}
626
+
627
+	return 0;
628
+}
629
+
630
+/** IPv4 settings applicator */
631
+struct settings_applicator ipv4_settings_applicator __settings_applicator = {
632
+	.apply = ipv4_create_routes,
633
+};

+ 17
- 22
src/net/netdev_settings.c View File

28
  *
28
  *
29
  */
29
  */
30
 
30
 
31
+/** Network device named settings */
32
+struct setting mac_setting __setting = {
33
+	.name = "mac",
34
+	.description = "MAC address",
35
+	.type = &setting_type_hex,
36
+};
37
+
31
 /**
38
 /**
32
  * Store value of network device setting
39
  * Store value of network device setting
33
  *
40
  *
34
  * @v settings		Settings block
41
  * @v settings		Settings block
35
- * @v tag		Setting tag number
42
+ * @v setting		Setting to store
36
  * @v data		Setting data, or NULL to clear setting
43
  * @v data		Setting data, or NULL to clear setting
37
  * @v len		Length of setting data
44
  * @v len		Length of setting data
38
  * @ret rc		Return status code
45
  * @ret rc		Return status code
39
  */
46
  */
40
-static int netdev_store ( struct settings *settings, unsigned int tag,
47
+static int netdev_store ( struct settings *settings, struct setting *setting,
41
 			  const void *data, size_t len ) {
48
 			  const void *data, size_t len ) {
42
 	struct net_device *netdev = container_of ( settings, struct net_device,
49
 	struct net_device *netdev = container_of ( settings, struct net_device,
43
 						   settings.settings );
50
 						   settings.settings );
44
 
51
 
45
-	switch ( tag ) {
46
-	case DHCP_EB_MAC:
52
+	if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
47
 		if ( len != netdev->ll_protocol->ll_addr_len )
53
 		if ( len != netdev->ll_protocol->ll_addr_len )
48
 			return -EINVAL;
54
 			return -EINVAL;
49
 		memcpy ( netdev->ll_addr, data, len );
55
 		memcpy ( netdev->ll_addr, data, len );
50
 		return 0;
56
 		return 0;
51
-	default :
52
-		return simple_settings_store ( settings, tag, data, len );
57
+	} else {
58
+		return simple_settings_store ( settings, setting, data, len );
53
 	}
59
 	}
54
 }
60
 }
55
 
61
 
57
  * Fetch value of network device setting
63
  * Fetch value of network device setting
58
  *
64
  *
59
  * @v settings		Settings block
65
  * @v settings		Settings block
60
- * @v tag		Setting tag number
66
+ * @v setting		Setting to fetch
61
  * @v data		Setting data, or NULL to clear setting
67
  * @v data		Setting data, or NULL to clear setting
62
  * @v len		Length of setting data
68
  * @v len		Length of setting data
63
  * @ret rc		Return status code
69
  * @ret rc		Return status code
64
  */
70
  */
65
-static int netdev_fetch ( struct settings *settings, unsigned int tag,
71
+static int netdev_fetch ( struct settings *settings, struct setting *setting,
66
 			  void *data, size_t len ) {
72
 			  void *data, size_t len ) {
67
 	struct net_device *netdev = container_of ( settings, struct net_device,
73
 	struct net_device *netdev = container_of ( settings, struct net_device,
68
 						   settings.settings );
74
 						   settings.settings );
69
 
75
 
70
-	switch ( tag ) {
71
-	case DHCP_EB_MAC:
76
+	if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
72
 		if ( len > netdev->ll_protocol->ll_addr_len )
77
 		if ( len > netdev->ll_protocol->ll_addr_len )
73
 			len = netdev->ll_protocol->ll_addr_len;
78
 			len = netdev->ll_protocol->ll_addr_len;
74
 		memcpy ( data, netdev->ll_addr, len );
79
 		memcpy ( data, netdev->ll_addr, len );
75
 		return netdev->ll_protocol->ll_addr_len;
80
 		return netdev->ll_protocol->ll_addr_len;
76
-	default :
77
-		return simple_settings_fetch ( settings, tag, data, len );
81
+	} else {
82
+		return simple_settings_fetch ( settings, setting, data, len );
78
 	}
83
 	}
79
 }
84
 }
80
 
85
 
83
 	.store = netdev_store,
88
 	.store = netdev_store,
84
 	.fetch = netdev_fetch,
89
 	.fetch = netdev_fetch,
85
 };
90
 };
86
-
87
-/** Network device named settings */
88
-struct named_setting netdev_named_settings[] __named_setting = {
89
-	{
90
-		.name = "mac",
91
-		.description = "MAC address",
92
-		.tag = DHCP_EB_MAC,
93
-		.type = &setting_type_hex,
94
-	},
95
-};

+ 19
- 11
src/net/tcp/iscsi.c View File

1591
 
1591
 
1592
 /****************************************************************************
1592
 /****************************************************************************
1593
  *
1593
  *
1594
- * Settings applicators
1594
+ * Settings
1595
  *
1595
  *
1596
  */
1596
  */
1597
 
1597
 
1598
+/** iSCSI initiator IQN setting */
1599
+struct setting initiator_iqn_setting __setting = {
1600
+	.name = "initiator-iqn",
1601
+	.description = "iSCSI initiator name",
1602
+	.tag = DHCP_ISCSI_INITIATOR_IQN,
1603
+	.type = &setting_type_string,
1604
+};
1605
+
1598
 /** An iSCSI string setting */
1606
 /** An iSCSI string setting */
1599
 struct iscsi_string_setting {
1607
 struct iscsi_string_setting {
1600
-	/** Setting tag number */
1601
-	unsigned int tag;
1608
+	/** Setting */
1609
+	struct setting *setting;
1602
 	/** String to update */
1610
 	/** String to update */
1603
 	char **string;
1611
 	char **string;
1604
 	/** String prefix */
1612
 	/** String prefix */
1608
 /** iSCSI string settings */
1616
 /** iSCSI string settings */
1609
 static struct iscsi_string_setting iscsi_string_settings[] = {
1617
 static struct iscsi_string_setting iscsi_string_settings[] = {
1610
 	{
1618
 	{
1611
-		.tag = DHCP_ISCSI_INITIATOR_IQN,
1619
+		.setting = &initiator_iqn_setting,
1612
 		.string = &iscsi_explicit_initiator_iqn,
1620
 		.string = &iscsi_explicit_initiator_iqn,
1613
 		.prefix = "",
1621
 		.prefix = "",
1614
 	},
1622
 	},
1615
 	{
1623
 	{
1616
-		.tag = DHCP_EB_USERNAME,
1624
+		.setting = &username_setting,
1617
 		.string = &iscsi_username,
1625
 		.string = &iscsi_username,
1618
 		.prefix = "",
1626
 		.prefix = "",
1619
 	},
1627
 	},
1620
 	{
1628
 	{
1621
-		.tag = DHCP_EB_PASSWORD,
1629
+		.setting = &password_setting,
1622
 		.string = &iscsi_password,
1630
 		.string = &iscsi_password,
1623
 		.prefix = "",
1631
 		.prefix = "",
1624
 	},
1632
 	},
1625
 	{
1633
 	{
1626
-		.tag = DHCP_HOST_NAME,
1634
+		.setting = &hostname_setting,
1627
 		.string = &iscsi_default_initiator_iqn,
1635
 		.string = &iscsi_default_initiator_iqn,
1628
 		.prefix = "iqn.2000-09.org.etherboot:",
1636
 		.prefix = "iqn.2000-09.org.etherboot:",
1629
 	},
1637
 	},
1648
 
1656
 
1649
 	/* Allocate new string */
1657
 	/* Allocate new string */
1650
 	prefix_len = strlen ( setting->prefix );
1658
 	prefix_len = strlen ( setting->prefix );
1651
-	setting_len = fetch_setting_len ( NULL, setting->tag );
1659
+	setting_len = fetch_setting_len ( NULL, setting->setting );
1652
 	if ( setting_len < 0 ) {
1660
 	if ( setting_len < 0 ) {
1653
 		/* Missing settings are not errors; leave strings as NULL */
1661
 		/* Missing settings are not errors; leave strings as NULL */
1654
 		return 0;
1662
 		return 0;
1660
 
1668
 
1661
 	/* Fill new string */
1669
 	/* Fill new string */
1662
 	strcpy ( p, setting->prefix );
1670
 	strcpy ( p, setting->prefix );
1663
-	check_len = fetch_string_setting ( NULL, setting->tag,
1671
+	check_len = fetch_string_setting ( NULL, setting->setting,
1664
 					   ( p + prefix_len ),
1672
 					   ( p + prefix_len ),
1665
 					   ( len - prefix_len ) );
1673
 					   ( len - prefix_len ) );
1666
 	assert ( check_len == setting_len );
1674
 	assert ( check_len == setting_len );
1682
 			    sizeof ( iscsi_string_settings[0] ) ) ; i++ ) {
1690
 			    sizeof ( iscsi_string_settings[0] ) ) ; i++ ) {
1683
 		setting = &iscsi_string_settings[i];
1691
 		setting = &iscsi_string_settings[i];
1684
 		if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) {
1692
 		if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) {
1685
-			DBG ( "iSCSI could not apply setting %d\n",
1686
-			      setting->tag );
1693
+			DBG ( "iSCSI could not apply setting %s\n",
1694
+			      setting->setting->name );
1687
 			return rc;
1695
 			return rc;
1688
 		}
1696
 		}
1689
 	}
1697
 	}

+ 122
- 181
src/net/udp/dhcp.c View File

130
 	return xid;
130
 	return xid;
131
 }
131
 }
132
 
132
 
133
-/** Settings block name used for ProxyDHCP responses */
134
-#define PROXYDHCP_SETTINGS_NAME "proxydhcp"
135
-
136
 /**
133
 /**
137
  * Create a DHCP packet
134
  * Create a DHCP packet
138
  *
135
  *
180
 	memcpy ( dhcphdr->chaddr, netdev->ll_addr, hlen );
177
 	memcpy ( dhcphdr->chaddr, netdev->ll_addr, hlen );
181
 	memcpy ( dhcphdr->options, options->data, options_len );
178
 	memcpy ( dhcphdr->options, options->data, options_len );
182
 
179
 
183
-	/* Initialise DHCP packet structure and settings interface */
180
+	/* Initialise DHCP packet structure */
184
 	memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
181
 	memset ( dhcppkt, 0, sizeof ( *dhcppkt ) );
185
-	dhcppkt_init ( dhcppkt, NULL, data, max_len );
182
+	dhcppkt_init ( dhcppkt, data, max_len );
186
 	
183
 	
187
 	/* Set DHCP_MESSAGE_TYPE option */
184
 	/* Set DHCP_MESSAGE_TYPE option */
188
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_MESSAGE_TYPE,
185
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_MESSAGE_TYPE,
189
 				    &msgtype, sizeof ( msgtype ) ) ) != 0 )
186
 				    &msgtype, sizeof ( msgtype ) ) ) != 0 )
190
 		return rc;
187
 		return rc;
191
 
188
 
230
  * @v max_len		Size of DHCP packet buffer
227
  * @v max_len		Size of DHCP packet buffer
231
  * @ret rc		Return status code
228
  * @ret rc		Return status code
232
  */
229
  */
233
-static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
234
-				 struct net_device *netdev,
235
-				 struct dhcp_packet *dhcpoffer,
236
-				 void *data, size_t max_len ) {
230
+int create_dhcp_request ( struct dhcp_packet *dhcppkt,
231
+			  struct net_device *netdev,
232
+			  struct dhcp_packet *dhcpoffer,
233
+			  void *data, size_t max_len ) {
237
 	struct device_description *desc = &netdev->dev->desc;
234
 	struct device_description *desc = &netdev->dev->desc;
238
 	struct dhcp_netdev_desc dhcp_desc;
235
 	struct dhcp_netdev_desc dhcp_desc;
239
 	struct dhcp_client_id client_id;
236
 	struct dhcp_client_id client_id;
258
 		struct in_addr server_id;
255
 		struct in_addr server_id;
259
 		struct in_addr requested_ip;
256
 		struct in_addr requested_ip;
260
 
257
 
261
-		if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
262
-						 DHCP_SERVER_IDENTIFIER,
263
-						 &server_id ) ) < 0 ) {
258
+		if ( dhcppkt_fetch ( dhcpoffer, DHCP_SERVER_IDENTIFIER,
259
+				     &server_id, sizeof ( server_id ) )
260
+		     != sizeof ( server_id ) ) {
264
 			DBG ( "DHCP offer missing server identifier\n" );
261
 			DBG ( "DHCP offer missing server identifier\n" );
265
 			return -EINVAL;
262
 			return -EINVAL;
266
 		}
263
 		}
267
-		if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
268
-						 DHCP_EB_YIADDR,
269
-						 &requested_ip ) ) < 0 ) {
264
+		if ( dhcppkt_fetch ( dhcpoffer, DHCP_EB_YIADDR,
265
+				     &requested_ip, sizeof ( requested_ip ) )
266
+		     != sizeof ( requested_ip ) ) {
270
 			DBG ( "DHCP offer missing IP address\n" );
267
 			DBG ( "DHCP offer missing IP address\n" );
271
 			return -EINVAL;
268
 			return -EINVAL;
272
 		}
269
 		}
273
-		if ( ( rc = store_setting ( &dhcppkt->settings,
274
-					    DHCP_SERVER_IDENTIFIER, &server_id,
270
+		if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
271
+					    &server_id,
275
 					    sizeof ( server_id ) ) ) != 0 ) {
272
 					    sizeof ( server_id ) ) ) != 0 ) {
276
 			DBG ( "DHCP could not set server identifier: %s\n ",
273
 			DBG ( "DHCP could not set server identifier: %s\n ",
277
 			      strerror ( rc ) );
274
 			      strerror ( rc ) );
278
 			return rc;
275
 			return rc;
279
 		}
276
 		}
280
-		if ( ( rc = store_setting ( &dhcppkt->settings,
281
-					    DHCP_REQUESTED_ADDRESS,
277
+		if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
282
 					    &requested_ip,
278
 					    &requested_ip,
283
 					    sizeof ( requested_ip ) ) ) != 0 ){
279
 					    sizeof ( requested_ip ) ) ) != 0 ){
284
 			DBG ( "DHCP could not set requested address: %s\n",
280
 			DBG ( "DHCP could not set requested address: %s\n",
289
 
285
 
290
 	/* Add options to identify the feature list */
286
 	/* Add options to identify the feature list */
291
 	dhcp_features_len = ( dhcp_features_end - dhcp_features );
287
 	dhcp_features_len = ( dhcp_features_end - dhcp_features );
292
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_EB_ENCAP,
293
-				    dhcp_features, dhcp_features_len ) ) !=0 ){
288
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_ENCAP, dhcp_features,
289
+				    dhcp_features_len ) ) != 0 ) {
294
 		DBG ( "DHCP could not set features list option: %s\n",
290
 		DBG ( "DHCP could not set features list option: %s\n",
295
 		      strerror ( rc ) );
291
 		      strerror ( rc ) );
296
 		return rc;
292
 		return rc;
300
 	dhcp_desc.type = desc->bus_type;
296
 	dhcp_desc.type = desc->bus_type;
301
 	dhcp_desc.vendor = htons ( desc->vendor );
297
 	dhcp_desc.vendor = htons ( desc->vendor );
302
 	dhcp_desc.device = htons ( desc->device );
298
 	dhcp_desc.device = htons ( desc->device );
303
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_EB_BUS_ID,
304
-				    &dhcp_desc, sizeof ( dhcp_desc ) ) ) !=0 ){
299
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_EB_BUS_ID, &dhcp_desc,
300
+				    sizeof ( dhcp_desc ) ) ) != 0 ) {
305
 		DBG ( "DHCP could not set bus ID option: %s\n",
301
 		DBG ( "DHCP could not set bus ID option: %s\n",
306
 		      strerror ( rc ) );
302
 		      strerror ( rc ) );
307
 		return rc;
303
 		return rc;
314
 	ll_addr_len = netdev->ll_protocol->ll_addr_len;
310
 	ll_addr_len = netdev->ll_protocol->ll_addr_len;
315
 	assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
311
 	assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) );
316
 	memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
312
 	memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len );
317
-	if ( ( rc = store_setting ( &dhcppkt->settings, DHCP_CLIENT_ID,
318
-				    &client_id, ( ll_addr_len + 1 ) ) ) != 0 ){
313
+	if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_ID, &client_id,
314
+				    ( ll_addr_len + 1 ) ) ) != 0 ) {
319
 		DBG ( "DHCP could not set client ID: %s\n",
315
 		DBG ( "DHCP could not set client ID: %s\n",
320
 		      strerror ( rc ) );
316
 		      strerror ( rc ) );
321
 		return rc;
317
 		return rc;
324
 	/* Add client UUID, if we have one.  Required for PXE. */
320
 	/* Add client UUID, if we have one.  Required for PXE. */
325
 	client_uuid.type = DHCP_CLIENT_UUID_TYPE;
321
 	client_uuid.type = DHCP_CLIENT_UUID_TYPE;
326
 	if ( ( rc = get_uuid ( &client_uuid.uuid ) ) == 0 ) {
322
 	if ( ( rc = get_uuid ( &client_uuid.uuid ) ) == 0 ) {
327
-		if ( ( rc = store_setting ( &dhcppkt->settings,
328
-					    DHCP_CLIENT_UUID, &client_uuid,
323
+		if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
324
+					    &client_uuid,
329
 					    sizeof ( client_uuid ) ) ) != 0 ) {
325
 					    sizeof ( client_uuid ) ) ) != 0 ) {
330
 			DBG ( "DHCP could not set client UUID: %s\n",
326
 			DBG ( "DHCP could not set client UUID: %s\n",
331
 			      strerror ( rc ) );
327
 			      strerror ( rc ) );
336
 	return 0;
332
 	return 0;
337
 }
333
 }
338
 
334
 
339
-/**
340
- * Create DHCPDISCOVER packet
335
+/****************************************************************************
341
  *
336
  *
342
- * @v netdev		Network device
343
- * @v data		Buffer for DHCP packet
344
- * @v max_len		Size of DHCP packet buffer
345
- * @ret rc		Return status code
337
+ * DHCP settings
346
  *
338
  *
347
- * Used by external code.
348
  */
339
  */
349
-int create_dhcpdiscover ( struct net_device *netdev,
350
-			  void *data, size_t max_len ) {
351
-	struct dhcp_packet dhcppkt;
352
-	int rc;
353
 
340
 
354
-	if ( ( rc = create_dhcp_request ( &dhcppkt, netdev, NULL, data,
355
-					  max_len ) ) != 0 ) {
356
-		DBG ( "Could not create DHCPDISCOVER: %s\n",
357
-		      strerror ( rc ) );
358
-		return rc;
359
-	}
360
-
361
-	return 0;
362
-}
341
+/** A DHCP settings block */
342
+struct dhcp_settings {
343
+	/** Reference counter */
344
+	struct refcnt refcnt;
345
+	/** Containing I/O buffer */
346
+	struct io_buffer *iobuf;
347
+	/** DHCP packet */
348
+	struct dhcp_packet dhcppkt;
349
+	/** Setting interface */
350
+	struct settings settings;
351
+};
363
 
352
 
364
 /**
353
 /**
365
- * Create DHCPACK packet
354
+ * Free DHCP settings block
366
  *
355
  *
367
- * @v netdev		Network device
368
- * @v data		Buffer for DHCP packet
369
- * @v max_len		Size of DHCP packet buffer
370
- * @ret rc		Return status code
371
- *
372
- * Used by external code.
356
+ * @v refcnt		Reference counter
373
  */
357
  */
374
-int create_dhcpack ( struct net_device *netdev,
375
-		     void *data, size_t max_len ) {
376
-	struct dhcp_packet dhcppkt;
377
-	int rc;
378
-
379
-	/* Create base DHCPACK packet */
380
-	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
381
-					 data, max_len ) ) != 0 ) {
382
-		DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
383
-		return rc;
384
-	}
385
-
386
-	/* Merge in globally-scoped settings, then netdev-specific
387
-	 * settings.  Do it in this order so that netdev-specific
388
-	 * settings take precedence regardless of stated priorities.
389
-	 */
390
-	if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 ) {
391
-		DBG ( "Could not set DHCPACK global settings: %s\n",
392
-		      strerror ( rc ) );
393
-		return rc;
394
-	}
395
-	if ( ( rc = copy_settings ( &dhcppkt.settings,
396
-				    netdev_settings ( netdev ) ) ) != 0 ) {
397
-		DBG ( "Could not set DHCPACK netdev settings: %s\n",
398
-		      strerror ( rc ) );
399
-		return rc;
400
-	}
358
+static void dhcpset_free ( struct refcnt *refcnt ) {
359
+	struct dhcp_settings *dhcpset =
360
+		container_of ( refcnt, struct dhcp_settings, refcnt );
401
 
361
 
402
-	return 0;
362
+	free_iob ( dhcpset->iobuf );
363
+	free ( dhcpset );
403
 }
364
 }
404
 
365
 
405
 /**
366
 /**
406
- * Create ProxyDHCPACK packet
407
- *
408
- * @v netdev		Network device
409
- * @v data		Buffer for DHCP packet
410
- * @v max_len		Size of DHCP packet buffer
411
- * @ret rc		Return status code
367
+ * Decrement reference count on DHCP settings block
412
  *
368
  *
413
- * Used by external code.
369
+ * @v dhcpset		DHCP settings block
414
  */
370
  */
415
-int create_proxydhcpack ( struct net_device *netdev,
416
-			  void *data, size_t max_len ) {
417
-	struct dhcp_packet dhcppkt;
418
-	struct settings *settings;
419
-	int rc;
420
-
421
-	/* Identify ProxyDHCP settings */
422
-	settings = find_settings ( PROXYDHCP_SETTINGS_NAME );
423
-
424
-	/* No ProxyDHCP settings => return empty block */
425
-	if ( ! settings ) {
426
-		memset ( data, 0, max_len );
427
-		return 0;
428
-	}
429
-
430
-	/* Create base DHCPACK packet */
431
-	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
432
-					 data, max_len ) ) != 0 ) {
433
-		DBG ( "Could not create ProxyDHCPACK: %s\n",
434
-		      strerror ( rc ) );
435
-		return rc;
436
-	}
437
-
438
-	/* Merge in ProxyDHCP options */
439
-	if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 ) {
440
-		DBG ( "Could not set ProxyDHCPACK settings: %s\n",
441
-		      strerror ( rc ) );
442
-		return rc;
443
-	}
444
-
445
-	return 0;
371
+static inline void dhcpset_put ( struct dhcp_settings *dhcpset ) {
372
+	ref_put ( &dhcpset->refcnt );
446
 }
373
 }
447
 
374
 
448
-/****************************************************************************
449
- *
450
- * DHCP packets contained in I/O buffers
375
+/**
376
+ * Store value of DHCP setting
451
  *
377
  *
378
+ * @v settings		Settings block
379
+ * @v setting		Setting to store
380
+ * @v data		Setting data, or NULL to clear setting
381
+ * @v len		Length of setting data
382
+ * @ret rc		Return status code
452
  */
383
  */
384
+static int dhcpset_store ( struct settings *settings, struct setting *setting,
385
+			   const void *data, size_t len ) {
386
+	struct dhcp_settings *dhcpset =
387
+		container_of ( settings, struct dhcp_settings, settings );
453
 
388
 
454
-/** A DHCP packet contained in an I/O buffer */
455
-struct dhcp_iobuf_packet {
456
-	/** DHCP packet */
457
-	struct dhcp_packet dhcppkt;
458
-	/** Reference counter */
459
-	struct refcnt refcnt;
460
-	/** Containing I/O buffer */
461
-	struct io_buffer *iobuf;
462
-};
389
+	return dhcppkt_store ( &dhcpset->dhcppkt, setting->tag, data, len );
390
+}
463
 
391
 
464
 /**
392
 /**
465
- * Free DHCP packet contained in an I/O buffer
393
+ * Fetch value of setting
466
  *
394
  *
467
- * @v refcnt		Reference counter
395
+ * @v settings		Settings block, or NULL to search all blocks
396
+ * @v setting		Setting to fetch
397
+ * @v data		Buffer to fill with setting data
398
+ * @v len		Length of buffer
399
+ * @ret len		Length of setting data, or negative error
468
  */
400
  */
469
-static void dhcpiob_free ( struct refcnt *refcnt ) {
470
-	struct dhcp_iobuf_packet *dhcpiob =
471
-		container_of ( refcnt, struct dhcp_iobuf_packet, refcnt );
401
+static int dhcpset_fetch ( struct settings *settings, struct setting *setting,
402
+			   void *data, size_t len ) {
403
+	struct dhcp_settings *dhcpset =
404
+		container_of ( settings, struct dhcp_settings, settings );
472
 
405
 
473
-	free_iob ( dhcpiob->iobuf );
474
-	free ( dhcpiob );
406
+	return dhcppkt_fetch ( &dhcpset->dhcppkt, setting->tag, data, len );
475
 }
407
 }
476
 
408
 
409
+/** DHCP settings operations */
410
+static struct settings_operations dhcpset_settings_operations = {
411
+	.store = dhcpset_store,
412
+	.fetch = dhcpset_fetch,
413
+};
414
+
477
 /**
415
 /**
478
- * Create DHCP packet from I/O buffer
416
+ * Create DHCP setting block from I/O buffer
479
  *
417
  *
480
  * @v iobuf		I/O buffer
418
  * @v iobuf		I/O buffer
481
- * @ret dhcpiob		DHCP packet contained in I/O buffer
419
+ * @ret dhcpset		DHCP settings block
482
  *
420
  *
483
  * This function takes ownership of the I/O buffer.  Future accesses
421
  * This function takes ownership of the I/O buffer.  Future accesses
484
- * must be via the @c dhcpiob data structure.
422
+ * must be via the @c dhcpset data structure.
485
  */
423
  */
486
-static struct dhcp_iobuf_packet * dhcpiob_create ( struct io_buffer *iobuf ) {
487
-	struct dhcp_iobuf_packet *dhcpiob;
488
-
489
-	dhcpiob = zalloc ( sizeof ( *dhcpiob ) );
490
-	if ( dhcpiob ) {
491
-		dhcpiob->refcnt.free = dhcpiob_free;
492
-		dhcpiob->iobuf = iobuf;
493
-		dhcppkt_init ( &dhcpiob->dhcppkt, &dhcpiob->refcnt,
424
+static struct dhcp_settings * dhcpset_create_iob ( struct io_buffer *iobuf ) {
425
+	struct dhcp_settings *dhcpset;
426
+
427
+	dhcpset = zalloc ( sizeof ( *dhcpset ) );
428
+	if ( dhcpset ) {
429
+		dhcpset->refcnt.free = dhcpset_free;
430
+		dhcpset->iobuf = iobuf;
431
+		dhcppkt_init ( &dhcpset->dhcppkt,
494
 			       iobuf->data, iob_len ( iobuf ) );
432
 			       iobuf->data, iob_len ( iobuf ) );
433
+		settings_init ( &dhcpset->settings,
434
+				&dhcpset_settings_operations, &dhcpset->refcnt,
435
+				DHCP_SETTINGS_NAME );
495
 	}
436
 	}
496
-	return dhcpiob;
497
-}
498
-
499
-static void dhcpiob_put ( struct dhcp_iobuf_packet *dhcpiob ) {
500
-	if ( dhcpiob )
501
-		ref_put ( &dhcpiob->refcnt );
437
+	return dhcpset;
502
 }
438
 }
503
 
439
 
504
 /****************************************************************************
440
 /****************************************************************************
526
 	 */
462
 	 */
527
 	int state;
463
 	int state;
528
 	/** Response obtained from DHCP server */
464
 	/** Response obtained from DHCP server */
529
-	struct dhcp_iobuf_packet *response;
465
+	struct dhcp_settings *response;
530
 	/** Response obtained from ProxyDHCP server */
466
 	/** Response obtained from ProxyDHCP server */
531
-	struct dhcp_iobuf_packet *proxy_response;
467
+	struct dhcp_settings *proxy_response;
532
 	/** Retransmission timer */
468
 	/** Retransmission timer */
533
 	struct retry_timer timer;
469
 	struct retry_timer timer;
534
 	/** Session start time (in ticks) */
470
 	/** Session start time (in ticks) */
545
 		container_of ( refcnt, struct dhcp_session, refcnt );
481
 		container_of ( refcnt, struct dhcp_session, refcnt );
546
 
482
 
547
 	netdev_put ( dhcp->netdev );
483
 	netdev_put ( dhcp->netdev );
548
-	dhcpiob_put ( dhcp->response );
549
-	dhcpiob_put ( dhcp->proxy_response );
484
+	dhcpset_put ( dhcp->response );
485
+	dhcpset_put ( dhcp->proxy_response );
550
 	free ( dhcp );
486
 	free ( dhcp );
551
 }
487
 }
552
 
488
 
584
 
520
 
585
 	/* Register ProxyDHCP settings, if present */
521
 	/* Register ProxyDHCP settings, if present */
586
 	if ( dhcp->proxy_response ) {
522
 	if ( dhcp->proxy_response ) {
587
-		settings = &dhcp->proxy_response->dhcppkt.settings;
523
+		settings = &dhcp->proxy_response->settings;
588
 		settings->name = PROXYDHCP_SETTINGS_NAME;
524
 		settings->name = PROXYDHCP_SETTINGS_NAME;
589
 		old_settings = find_settings ( settings->name );
525
 		old_settings = find_settings ( settings->name );
590
 		if ( old_settings )
526
 		if ( old_settings )
595
 
531
 
596
 	/* Register DHCP settings */
532
 	/* Register DHCP settings */
597
 	parent = netdev_settings ( dhcp->netdev );
533
 	parent = netdev_settings ( dhcp->netdev );
598
-	settings = &dhcp->response->dhcppkt.settings;
534
+	settings = &dhcp->response->settings;
599
 	old_settings = find_child_settings ( parent, settings->name );
535
 	old_settings = find_child_settings ( parent, settings->name );
600
 	if ( old_settings )
536
 	if ( old_settings )
601
 		unregister_settings ( old_settings );
537
 		unregister_settings ( old_settings );
701
 			      struct xfer_metadata *meta __unused ) {
637
 			      struct xfer_metadata *meta __unused ) {
702
 	struct dhcp_session *dhcp =
638
 	struct dhcp_session *dhcp =
703
 		container_of ( xfer, struct dhcp_session, xfer );
639
 		container_of ( xfer, struct dhcp_session, xfer );
704
-	struct dhcp_iobuf_packet *response;
705
-	struct dhcp_iobuf_packet **store_response;
640
+	struct dhcp_settings *response;
641
+	struct dhcp_settings **store_response;
706
 	struct dhcphdr *dhcphdr;
642
 	struct dhcphdr *dhcphdr;
707
-	struct settings *settings;
708
-	unsigned int msgtype;
643
+	uint8_t msgtype = 0;
644
+	uint8_t priority = 0;
645
+	uint8_t existing_priority = 0;
709
 	unsigned long elapsed;
646
 	unsigned long elapsed;
710
 	int is_proxy;
647
 	int is_proxy;
711
-	int ignore_proxy;
648
+	uint8_t ignore_proxy = 0;
712
 	int rc;
649
 	int rc;
713
 
650
 
714
 	/* Convert packet into a DHCP-packet-in-iobuf */
651
 	/* Convert packet into a DHCP-packet-in-iobuf */
715
-	response = dhcpiob_create ( iobuf );
652
+	response = dhcpset_create_iob ( iobuf );
716
 	if ( ! response ) {
653
 	if ( ! response ) {
717
 		DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp );
654
 		DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp );
718
 		return -ENOMEM;
655
 		return -ENOMEM;
719
 	}
656
 	}
720
 	dhcphdr = response->dhcppkt.dhcphdr;
657
 	dhcphdr = response->dhcppkt.dhcphdr;
721
-	settings = &response->dhcppkt.settings;
722
 
658
 
723
 	/* Check for matching transaction ID */
659
 	/* Check for matching transaction ID */
724
 	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
660
 	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
730
 
666
 
731
 	/* Determine and verify message type */
667
 	/* Determine and verify message type */
732
 	is_proxy = ( dhcphdr->yiaddr.s_addr == 0 );
668
 	is_proxy = ( dhcphdr->yiaddr.s_addr == 0 );
733
-	msgtype = fetch_uintz_setting ( settings, DHCP_MESSAGE_TYPE );
669
+	dhcppkt_fetch ( &response->dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
670
+			sizeof ( msgtype ) );
734
 	DBGC ( dhcp, "DHCP %p received %s%s\n", dhcp,
671
 	DBGC ( dhcp, "DHCP %p received %s%s\n", dhcp,
735
 	       ( is_proxy ? "Proxy" : "" ), dhcp_msgtype_name ( msgtype ) );
672
 	       ( is_proxy ? "Proxy" : "" ), dhcp_msgtype_name ( msgtype ) );
736
 	if ( ( ( dhcp->state != DHCPDISCOVER ) || ( msgtype != DHCPOFFER ) ) &&
673
 	if ( ( ( dhcp->state != DHCPDISCOVER ) || ( msgtype != DHCPOFFER ) ) &&
746
 	 * currently-stored options.
683
 	 * currently-stored options.
747
 	 */
684
 	 */
748
 	store_response = ( is_proxy ? &dhcp->proxy_response : &dhcp->response);
685
 	store_response = ( is_proxy ? &dhcp->proxy_response : &dhcp->response);
749
-	if ( ( ! *store_response ) || 
750
-	     ( fetch_uintz_setting ( settings, DHCP_EB_PRIORITY ) >=
751
-	       fetch_uintz_setting ( &(*store_response)->dhcppkt.settings,
752
-				     DHCP_EB_PRIORITY ) ) ) {
753
-		dhcpiob_put ( *store_response );
686
+	if ( *store_response ) {
687
+		dhcppkt_fetch ( &(*store_response)->dhcppkt, DHCP_EB_PRIORITY,
688
+				&existing_priority,
689
+				sizeof ( existing_priority ) );
690
+	}
691
+	dhcppkt_fetch ( &response->dhcppkt, DHCP_EB_PRIORITY, &priority,
692
+			sizeof ( priority ) );
693
+	if ( priority >= existing_priority ) {
694
+		dhcpset_put ( *store_response );
754
 		*store_response = response;
695
 		*store_response = response;
755
 	} else {
696
 	} else {
756
-		dhcpiob_put ( response );
697
+		dhcpset_put ( response );
757
 	}
698
 	}
758
 
699
 
759
 	/* If we don't yet have a standard DHCP response (i.e. one
700
 	/* If we don't yet have a standard DHCP response (i.e. one
763
 		goto out;
704
 		goto out;
764
 
705
 
765
 	/* Handle DHCP response */
706
 	/* Handle DHCP response */
766
-	ignore_proxy = fetch_uintz_setting ( &dhcp->response->dhcppkt.settings,
767
-					     DHCP_EB_NO_PROXYDHCP );
707
+	dhcppkt_fetch ( &dhcp->response->dhcppkt, DHCP_EB_NO_PROXYDHCP,
708
+			&ignore_proxy, sizeof ( ignore_proxy ) );
768
 	switch ( dhcp->state ) {
709
 	switch ( dhcp->state ) {
769
 	case DHCPDISCOVER:
710
 	case DHCPDISCOVER:
770
 		/* If we have allowed sufficient time for ProxyDHCP
711
 		/* If we have allowed sufficient time for ProxyDHCP
780
 	case DHCPREQUEST:
721
 	case DHCPREQUEST:
781
 		/* DHCP finished; register options and exit */
722
 		/* DHCP finished; register options and exit */
782
 		if ( ignore_proxy && dhcp->proxy_response ) {
723
 		if ( ignore_proxy && dhcp->proxy_response ) {
783
-			dhcpiob_put ( dhcp->proxy_response );
724
+			dhcpset_put ( dhcp->proxy_response );
784
 			dhcp->proxy_response = NULL;
725
 			dhcp->proxy_response = NULL;
785
 		}
726
 		}
786
 		if ( ( rc = dhcp_register_settings ( dhcp ) ) != 0 ) {
727
 		if ( ( rc = dhcp_register_settings ( dhcp ) ) != 0 ) {
797
 	return 0;
738
 	return 0;
798
 
739
 
799
  out_discard:
740
  out_discard:
800
-	dhcpiob_put ( response );
741
+	dhcpset_put ( response );
801
 	return 0;
742
 	return 0;
802
 }
743
 }
803
 
744
 

+ 16
- 1
src/net/udp/dns.c View File

506
 	.resolv = dns_resolv,
506
 	.resolv = dns_resolv,
507
 };
507
 };
508
 
508
 
509
+/******************************************************************************
510
+ *
511
+ * Settings
512
+ *
513
+ ******************************************************************************
514
+ */
515
+
516
+/** DNS server setting */
517
+struct setting dns_setting __setting = {
518
+	.name = "dns",
519
+	.description = "DNS server",
520
+	.tag = DHCP_DNS_SERVERS,
521
+	.type = &setting_type_ipv4,
522
+};
523
+
509
 /**
524
 /**
510
  * Apply nameserver setting
525
  * Apply nameserver setting
511
  *
526
  *
516
 		( struct sockaddr_in * ) &nameserver;
531
 		( struct sockaddr_in * ) &nameserver;
517
 	int len;
532
 	int len;
518
 
533
 
519
-	if ( ( len = fetch_ipv4_setting ( NULL, DHCP_DNS_SERVERS,
534
+	if ( ( len = fetch_ipv4_setting ( NULL, &dns_setting,
520
 					  &sin_nameserver->sin_addr ) ) >= 0 ){
535
 					  &sin_nameserver->sin_addr ) ) >= 0 ){
521
 		sin_nameserver->sin_family = AF_INET;
536
 		sin_nameserver->sin_family = AF_INET;
522
 		DBG ( "DNS using nameserver %s\n",
537
 		DBG ( "DNS using nameserver %s\n",

+ 16
- 1
src/net/udp/tftp.c View File

1093
 	.open	= mtftp_open,
1093
 	.open	= mtftp_open,
1094
 };
1094
 };
1095
 
1095
 
1096
+/******************************************************************************
1097
+ *
1098
+ * Settings
1099
+ *
1100
+ ******************************************************************************
1101
+ */
1102
+
1103
+/** TFTP server setting */
1104
+struct setting next_server_setting __setting = {
1105
+	.name = "next-server",
1106
+	.description = "TFTP server",
1107
+	.tag = DHCP_EB_SIADDR,
1108
+	.type = &setting_type_ipv4,
1109
+};
1110
+
1096
 /**
1111
 /**
1097
  * Apply TFTP configuration settings
1112
  * Apply TFTP configuration settings
1098
  *
1113
  *
1106
 
1121
 
1107
 	/* Retrieve TFTP server setting */
1122
 	/* Retrieve TFTP server setting */
1108
 	last_tftp_server = tftp_server;
1123
 	last_tftp_server = tftp_server;
1109
-	fetch_ipv4_setting ( NULL, DHCP_EB_SIADDR, &tftp_server );
1124
+	fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
1110
 
1125
 
1111
 	/* If TFTP server setting has changed, set the current working
1126
 	/* If TFTP server setting has changed, set the current working
1112
 	 * URI to match.  Do it only when the TFTP server has changed
1127
 	 * URI to match.  Do it only when the TFTP server has changed

+ 0
- 2
src/usr/aoeboot.c View File

5
 #include <gpxe/aoe.h>
5
 #include <gpxe/aoe.h>
6
 #include <gpxe/ata.h>
6
 #include <gpxe/ata.h>
7
 #include <gpxe/netdevice.h>
7
 #include <gpxe/netdevice.h>
8
-#include <gpxe/dhcp.h>
9
 #include <gpxe/settings.h>
8
 #include <gpxe/settings.h>
10
 #include <gpxe/abft.h>
9
 #include <gpxe/abft.h>
11
 #include <int13.h>
10
 #include <int13.h>
56
 		container_of ( ata.backend, struct aoe_session, refcnt );
55
 		container_of ( ata.backend, struct aoe_session, refcnt );
57
 	abft_fill_data ( aoe );
56
 	abft_fill_data ( aoe );
58
 
57
 
59
-	drive.drive = fetch_uintz_setting ( NULL, DHCP_EB_BIOS_DRIVE );
60
 	drive.blockdev = &ata.blockdev;
58
 	drive.blockdev = &ata.blockdev;
61
 
59
 
62
 	register_int13_drive ( &drive );
60
 	register_int13_drive ( &drive );

+ 2
- 2
src/usr/autoboot.c View File

147
 		return rc;
147
 		return rc;
148
 
148
 
149
 	/* Try to download and boot whatever we are given as a filename */
149
 	/* Try to download and boot whatever we are given as a filename */
150
-	fetch_string_setting ( NULL, DHCP_BOOTFILE_NAME, buf, sizeof ( buf ) );
150
+	fetch_string_setting ( NULL, &filename_setting, buf, sizeof ( buf ) );
151
 	if ( buf[0] ) {
151
 	if ( buf[0] ) {
152
 		printf ( "Booting from filename \"%s\"\n", buf );
152
 		printf ( "Booting from filename \"%s\"\n", buf );
153
 		return boot_filename ( buf );
153
 		return boot_filename ( buf );
154
 	}
154
 	}
155
 	
155
 	
156
 	/* No filename; try the root path */
156
 	/* No filename; try the root path */
157
-	fetch_string_setting ( NULL, DHCP_ROOT_PATH, buf, sizeof ( buf ) );
157
+	fetch_string_setting ( NULL, &root_path_setting, buf, sizeof ( buf ) );
158
 	if ( buf[0] ) {
158
 	if ( buf[0] ) {
159
 		printf ( "Booting from root path \"%s\"\n", buf );
159
 		printf ( "Booting from root path \"%s\"\n", buf );
160
 		return boot_root_path ( buf );
160
 		return boot_root_path ( buf );

+ 0
- 2
src/usr/iscsiboot.c View File

2
 #include <string.h>
2
 #include <string.h>
3
 #include <stdio.h>
3
 #include <stdio.h>
4
 #include <gpxe/iscsi.h>
4
 #include <gpxe/iscsi.h>
5
-#include <gpxe/dhcp.h>
6
 #include <gpxe/settings.h>
5
 #include <gpxe/settings.h>
7
 #include <gpxe/netdevice.h>
6
 #include <gpxe/netdevice.h>
8
 #include <gpxe/ibft.h>
7
 #include <gpxe/ibft.h>
46
 		goto error_init;
45
 		goto error_init;
47
 	}
46
 	}
48
 
47
 
49
-	drive.drive = fetch_uintz_setting ( NULL, DHCP_EB_BIOS_DRIVE );
50
 	drive.blockdev = &scsi.blockdev;
48
 	drive.blockdev = &scsi.blockdev;
51
 
49
 
52
 	/* FIXME: ugly, ugly hack */
50
 	/* FIXME: ugly, ugly hack */

Loading…
Cancel
Save