Browse Source

Allow for calling find_dhcp_option() with "options" set to NULL, in order

to search through all registered option blocks.

Move some static inlines that are likely to be used frequently into
dhcpopts.c as normal functions, to save space.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
e40ebb67de
2 changed files with 103 additions and 70 deletions
  1. 6
    49
      src/include/gpxe/dhcp.h
  2. 97
    21
      src/net/dhcpopts.c

+ 6
- 49
src/include/gpxe/dhcp.h View File

287
 extern unsigned long dhcp_num_option ( struct dhcp_option *option );
287
 extern unsigned long dhcp_num_option ( struct dhcp_option *option );
288
 extern struct dhcp_option *
288
 extern struct dhcp_option *
289
 find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
289
 find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
290
-extern struct dhcp_option * find_global_dhcp_option ( unsigned int tag );
291
 extern void register_dhcp_options ( struct dhcp_option_block *options );
290
 extern void register_dhcp_options ( struct dhcp_option_block *options );
292
 extern void unregister_dhcp_options ( struct dhcp_option_block *options );
291
 extern void unregister_dhcp_options ( struct dhcp_option_block *options );
293
 extern void init_dhcp_options ( struct dhcp_option_block *options,
292
 extern void init_dhcp_options ( struct dhcp_option_block *options,
297
 extern struct dhcp_option *
296
 extern struct dhcp_option *
298
 set_dhcp_option ( struct dhcp_option_block *options, unsigned int tag,
297
 set_dhcp_option ( struct dhcp_option_block *options, unsigned int tag,
299
 		  const void *data, size_t len );
298
 		  const void *data, size_t len );
300
-
301
-/**
302
- * Find DHCP numerical option, and return its value
303
- *
304
- * @v options		DHCP options block
305
- * @v tag		DHCP option tag to search for
306
- * @ret value		Numerical value of the option, or 0 if not found
307
- *
308
- * This function exists merely as a notational shorthand for a call to
309
- * find_dhcp_option() followed by a call to dhcp_num_option().  It is
310
- * not possible to distinguish between the cases "option not found"
311
- * and "option has a value of zero" using this function; if this
312
- * matters to you then issue the two constituent calls directly and
313
- * check that find_dhcp_option() returns a non-NULL value.
314
- */
315
-static inline unsigned long
316
-find_dhcp_num_option ( struct dhcp_option_block *options, unsigned int tag ) {
317
-	return dhcp_num_option ( find_dhcp_option ( options, tag ) );
318
-}
319
-
320
-/**
321
- * Find DHCP numerical option, and return its value
322
- *
323
- * @v tag		DHCP option tag to search for
324
- * @ret value		Numerical value of the option, or 0 if not found
325
- *
326
- * This function exists merely as a notational shorthand for a call to
327
- * find_global_dhcp_option() followed by a call to dhcp_num_option().
328
- * It is not possible to distinguish between the cases "option not
329
- * found" and "option has a value of zero" using this function; if
330
- * this matters to you then issue the two constituent calls directly
331
- * and check that find_global_dhcp_option() returns a non-NULL value.
332
- */
333
-static inline unsigned long
334
-find_global_dhcp_num_option ( unsigned int tag ) {
335
-	return dhcp_num_option ( find_global_dhcp_option ( tag ) );
336
-}
337
-
338
-/**
339
- * Delete DHCP option
340
- *
341
- * @v options		DHCP options block
342
- * @v tag		DHCP option tag
343
- */
344
-static inline void delete_dhcp_option ( struct dhcp_option_block *options,
345
-					unsigned int tag ) {
346
-	set_dhcp_option ( options, tag, NULL, 0 );
347
-}
299
+extern struct dhcp_option * find_global_dhcp_option ( unsigned int tag );
300
+extern unsigned long find_dhcp_num_option ( struct dhcp_option_block *options,
301
+					    unsigned int tag );
302
+extern unsigned long find_global_dhcp_num_option ( unsigned int tag );
303
+extern void delete_dhcp_option ( struct dhcp_option_block *options,
304
+				 unsigned int tag );
348
 
305
 
349
 #endif /* _GPXE_DHCP_H */
306
 #endif /* _GPXE_DHCP_H */

+ 97
- 21
src/net/dhcpopts.c View File

118
  *
118
  *
119
  * @v options		DHCP options block
119
  * @v options		DHCP options block
120
  * @v tag		DHCP option tag to search for
120
  * @v tag		DHCP option tag to search for
121
+ * @ret encapsulator	Encapsulating DHCP option
121
  * @ret option		DHCP option, or NULL if not found
122
  * @ret option		DHCP option, or NULL if not found
122
  *
123
  *
123
  * Searches for the DHCP option matching the specified tag within the
124
  * Searches for the DHCP option matching the specified tag within the
124
- * block of data.  Encapsulated options may be searched for by using
125
- * DHCP_ENCAP_OPT() to construct the tag value.
125
+ * DHCP option block.  Encapsulated options may be searched for by
126
+ * using DHCP_ENCAP_OPT() to construct the tag value.
127
+ *
128
+ * If the option is encapsulated, and @c encapsulator is non-NULL, it
129
+ * will be filled in with a pointer to the encapsulating option.
126
  *
130
  *
127
  * This routine is designed to be paranoid.  It does not assume that
131
  * This routine is designed to be paranoid.  It does not assume that
128
  * the option data is well-formatted, and so must guard against flaws
132
  * the option data is well-formatted, and so must guard against flaws
129
  * such as options missing a @c DHCP_END terminator, or options whose
133
  * such as options missing a @c DHCP_END terminator, or options whose
130
  * length would take them beyond the end of the data block.
134
  * length would take them beyond the end of the data block.
131
  */
135
  */
132
-struct dhcp_option * find_dhcp_option ( struct dhcp_option_block *options,
133
-					unsigned int tag ) {
136
+static struct dhcp_option *
137
+find_dhcp_option_with_encap ( struct dhcp_option_block *options,
138
+			      unsigned int tag,
139
+			      struct dhcp_option **encapsulator ) {
134
 	unsigned int original_tag __attribute__ (( unused )) = tag;
140
 	unsigned int original_tag __attribute__ (( unused )) = tag;
135
 	struct dhcp_option *option = options->data;
141
 	struct dhcp_option *option = options->data;
136
 	ssize_t remaining = options->len;
142
 	ssize_t remaining = options->len;
157
 		/* Check for start of matching encapsulation block */
163
 		/* Check for start of matching encapsulation block */
158
 		if ( DHCP_IS_ENCAP_OPT ( tag ) &&
164
 		if ( DHCP_IS_ENCAP_OPT ( tag ) &&
159
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
165
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
166
+			if ( encapsulator )
167
+				*encapsulator = option;
160
 			/* Continue search within encapsulated option block */
168
 			/* Continue search within encapsulated option block */
161
 			tag = DHCP_ENCAPSULATED ( tag );
169
 			tag = DHCP_ENCAPSULATED ( tag );
162
 			remaining = option->len;
170
 			remaining = option->len;
169
 }
177
 }
170
 
178
 
171
 /**
179
 /**
172
- * Find DHCP option within all registered DHCP options blocks
180
+ * Find DHCP option within DHCP options block
173
  *
181
  *
182
+ * @v options		DHCP options block, or NULL
174
  * @v tag		DHCP option tag to search for
183
  * @v tag		DHCP option tag to search for
175
  * @ret option		DHCP option, or NULL if not found
184
  * @ret option		DHCP option, or NULL if not found
176
  *
185
  *
177
- * Searches within all registered DHCP option blocks for the specified
178
- * tag.  Encapsulated options may be searched for by using
179
- * DHCP_ENCAP_OPT() to construct the tag value.
186
+ * Searches for the DHCP option matching the specified tag within the
187
+ * DHCP option block.  Encapsulated options may be searched for by
188
+ * using DHCP_ENCAP_OPT() to construct the tag value.
180
  *
189
  *
181
- * Where multiple option blocks contain the same DHCP option, the
182
- * option from the highest-priority block will be returned.  (Priority
183
- * of an options block is determined by the value of the @c
184
- * DHCP_EB_PRIORITY option within the block, if present; the default
185
- * priority is zero).
190
+ * If @c options is NULL, all registered option blocks will be
191
+ * searched.  Where multiple option blocks contain the same DHCP
192
+ * option, the option from the highest-priority block will be
193
+ * returned.  (Priority of an options block is determined by the value
194
+ * of the @c DHCP_EB_PRIORITY option within the block, if present; the
195
+ * default priority is zero).
186
  */
196
  */
187
-struct dhcp_option * find_global_dhcp_option ( unsigned int tag ) {
188
-	struct dhcp_option_block *options;
197
+struct dhcp_option * find_dhcp_option ( struct dhcp_option_block *options,
198
+					unsigned int tag ) {
189
 	struct dhcp_option *option;
199
 	struct dhcp_option *option;
190
 
200
 
191
-	list_for_each_entry ( options, &option_blocks, list ) {
192
-		if ( ( option = find_dhcp_option ( options, tag ) ) )
193
-			return option;
201
+	if ( options ) {
202
+		return find_dhcp_option_with_encap ( options, tag, NULL );
203
+	} else {
204
+		list_for_each_entry ( options, &option_blocks, list ) {
205
+			if ( ( option = find_dhcp_option ( options, tag ) ) )
206
+				return option;
207
+		}
208
+		return NULL;
194
 	}
209
 	}
195
-	return NULL;
196
 }
210
 }
197
 
211
 
198
 /**
212
 /**
348
 	size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 );
362
 	size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 );
349
 
363
 
350
 	/* Find old instance of this option, if any */
364
 	/* Find old instance of this option, if any */
351
-	option = find_dhcp_option ( options, tag );
365
+	option = find_dhcp_option_with_encap ( options, tag, &encapsulator );
352
 	if ( option ) {
366
 	if ( option ) {
353
 		old_len = dhcp_option_len ( option );
367
 		old_len = dhcp_option_len ( option );
354
 		DBG ( "Resizing DHCP option %s from length %d to %d\n",
368
 		DBG ( "Resizing DHCP option %s from length %d to %d\n",
361
 	
375
 	
362
 	/* Ensure that encapsulator exists, if required */
376
 	/* Ensure that encapsulator exists, if required */
363
 	if ( DHCP_IS_ENCAP_OPT ( tag ) ) {
377
 	if ( DHCP_IS_ENCAP_OPT ( tag ) ) {
364
-		encapsulator = find_dhcp_option ( options, encap_tag );
365
 		if ( ! encapsulator )
378
 		if ( ! encapsulator )
366
 			encapsulator = set_dhcp_option ( options, encap_tag,
379
 			encapsulator = set_dhcp_option ( options, encap_tag,
367
 							 empty_encapsulator,
380
 							 empty_encapsulator,
393
 
406
 
394
 	return option;
407
 	return option;
395
 }
408
 }
409
+
410
+/**
411
+ * Find DHCP option within all registered DHCP options blocks
412
+ *
413
+ * @v tag		DHCP option tag to search for
414
+ * @ret option		DHCP option, or NULL if not found
415
+ *
416
+ * This function exists merely as a notational shorthand for
417
+ * find_dhcp_option() with @c options set to NULL.
418
+ */
419
+struct dhcp_option * find_global_dhcp_option ( unsigned int tag ) {
420
+	return find_dhcp_option ( NULL, tag );
421
+}
422
+
423
+/**
424
+ * Find DHCP numerical option, and return its value
425
+ *
426
+ * @v options		DHCP options block
427
+ * @v tag		DHCP option tag to search for
428
+ * @ret value		Numerical value of the option, or 0 if not found
429
+ *
430
+ * This function exists merely as a notational shorthand for a call to
431
+ * find_dhcp_option() followed by a call to dhcp_num_option().  It is
432
+ * not possible to distinguish between the cases "option not found"
433
+ * and "option has a value of zero" using this function; if this
434
+ * matters to you then issue the two constituent calls directly and
435
+ * check that find_dhcp_option() returns a non-NULL value.
436
+ */
437
+unsigned long find_dhcp_num_option ( struct dhcp_option_block *options,
438
+				     unsigned int tag ) {
439
+	return dhcp_num_option ( find_dhcp_option ( options, tag ) );
440
+}
441
+
442
+/**
443
+ * Find DHCP numerical option, and return its value
444
+ *
445
+ * @v tag		DHCP option tag to search for
446
+ * @ret value		Numerical value of the option, or 0 if not found
447
+ *
448
+ * This function exists merely as a notational shorthand for a call to
449
+ * find_global_dhcp_option() followed by a call to dhcp_num_option().
450
+ * It is not possible to distinguish between the cases "option not
451
+ * found" and "option has a value of zero" using this function; if
452
+ * this matters to you then issue the two constituent calls directly
453
+ * and check that find_global_dhcp_option() returns a non-NULL value.
454
+ */
455
+unsigned long find_global_dhcp_num_option ( unsigned int tag ) {
456
+	return dhcp_num_option ( find_global_dhcp_option ( tag ) );
457
+}
458
+
459
+/**
460
+ * Delete DHCP option
461
+ *
462
+ * @v options		DHCP options block
463
+ * @v tag		DHCP option tag
464
+ *
465
+ * This function exists merely as a notational shorthand for a call to
466
+ * set_dhcp_option() with @c len set to zero.
467
+ */
468
+void delete_dhcp_option ( struct dhcp_option_block *options,
469
+			  unsigned int tag ) {
470
+	set_dhcp_option ( options, tag, NULL, 0 );
471
+}

Loading…
Cancel
Save