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,7 +287,6 @@ struct dhcp_session {
287 287
 extern unsigned long dhcp_num_option ( struct dhcp_option *option );
288 288
 extern struct dhcp_option *
289 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 290
 extern void register_dhcp_options ( struct dhcp_option_block *options );
292 291
 extern void unregister_dhcp_options ( struct dhcp_option_block *options );
293 292
 extern void init_dhcp_options ( struct dhcp_option_block *options,
@@ -297,53 +296,11 @@ extern void free_dhcp_options ( struct dhcp_option_block *options );
297 296
 extern struct dhcp_option *
298 297
 set_dhcp_option ( struct dhcp_option_block *options, unsigned int tag,
299 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 306
 #endif /* _GPXE_DHCP_H */

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

@@ -118,19 +118,25 @@ static inline unsigned int dhcp_any_option_len ( struct dhcp_option *option ) {
118 118
  *
119 119
  * @v options		DHCP options block
120 120
  * @v tag		DHCP option tag to search for
121
+ * @ret encapsulator	Encapsulating DHCP option
121 122
  * @ret option		DHCP option, or NULL if not found
122 123
  *
123 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 131
  * This routine is designed to be paranoid.  It does not assume that
128 132
  * the option data is well-formatted, and so must guard against flaws
129 133
  * such as options missing a @c DHCP_END terminator, or options whose
130 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 140
 	unsigned int original_tag __attribute__ (( unused )) = tag;
135 141
 	struct dhcp_option *option = options->data;
136 142
 	ssize_t remaining = options->len;
@@ -157,6 +163,8 @@ struct dhcp_option * find_dhcp_option ( struct dhcp_option_block *options,
157 163
 		/* Check for start of matching encapsulation block */
158 164
 		if ( DHCP_IS_ENCAP_OPT ( tag ) &&
159 165
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
166
+			if ( encapsulator )
167
+				*encapsulator = option;
160 168
 			/* Continue search within encapsulated option block */
161 169
 			tag = DHCP_ENCAPSULATED ( tag );
162 170
 			remaining = option->len;
@@ -169,30 +177,36 @@ struct dhcp_option * find_dhcp_option ( struct dhcp_option_block *options,
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 183
  * @v tag		DHCP option tag to search for
175 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 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,7 +362,7 @@ struct dhcp_option * set_dhcp_option ( struct dhcp_option_block *options,
348 362
 	size_t new_len = ( len ? ( len + DHCP_OPTION_HEADER_LEN ) : 0 );
349 363
 
350 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 366
 	if ( option ) {
353 367
 		old_len = dhcp_option_len ( option );
354 368
 		DBG ( "Resizing DHCP option %s from length %d to %d\n",
@@ -361,7 +375,6 @@ struct dhcp_option * set_dhcp_option ( struct dhcp_option_block *options,
361 375
 	
362 376
 	/* Ensure that encapsulator exists, if required */
363 377
 	if ( DHCP_IS_ENCAP_OPT ( tag ) ) {
364
-		encapsulator = find_dhcp_option ( options, encap_tag );
365 378
 		if ( ! encapsulator )
366 379
 			encapsulator = set_dhcp_option ( options, encap_tag,
367 380
 							 empty_encapsulator,
@@ -393,3 +406,66 @@ struct dhcp_option * set_dhcp_option ( struct dhcp_option_block *options,
393 406
 
394 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