Browse Source

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

tags/v0.9.4
Michael Brown 17 years ago
parent
commit
23e077666b
3 changed files with 71 additions and 59 deletions
  1. 17
    39
      src/core/settings.c
  2. 0
    2
      src/include/gpxe/settings.h
  3. 54
    18
      src/net/udp/dhcp.c

+ 17
- 39
src/core/settings.c View File

@@ -498,40 +498,6 @@ unsigned long fetch_uintz_setting ( struct settings *settings,
498 498
 	return value;
499 499
 }
500 500
 
501
-/**
502
- * Copy setting
503
- *
504
- * @v dest		Destination settings block
505
- * @v dest_tag		Destination setting tag number
506
- * @v source		Source settings block
507
- * @v source_tag	Source setting tag number
508
- * @ret rc		Return status code
509
- */
510
-int copy_setting ( struct settings *dest, unsigned int dest_tag,
511
-		   struct settings *source, unsigned int source_tag ) {
512
-	int len;
513
-	int check_len;
514
-	int rc;
515
-
516
-	len = fetch_setting_len ( source, source_tag );
517
-	if ( len < 0 )
518
-		return len;
519
-
520
-	{
521
-		char buf[len];
522
-
523
-		check_len = fetch_setting ( source, source_tag, buf,
524
-					    sizeof ( buf ) );
525
-		assert ( check_len == len );
526
-
527
-		if ( ( rc = store_setting ( dest, dest_tag, buf,
528
-					    sizeof ( buf ) ) ) != 0 )
529
-			return rc;
530
-	}
531
-
532
-	return 0;
533
-}
534
-
535 501
 /**
536 502
  * Copy settings
537 503
  *
@@ -545,6 +511,8 @@ static int copy_encap_settings ( struct settings *dest,
545 511
 				 unsigned int encapsulator ) {
546 512
 	unsigned int subtag;
547 513
 	unsigned int tag;
514
+	int len;
515
+	int check_len;
548 516
 	int rc;
549 517
 
550 518
 	for ( subtag = DHCP_MIN_OPTION; subtag <= DHCP_MAX_OPTION; subtag++ ) {
@@ -552,16 +520,26 @@ static int copy_encap_settings ( struct settings *dest,
552 520
 		switch ( tag ) {
553 521
 		case DHCP_EB_ENCAP:
554 522
 		case DHCP_VENDOR_ENCAP:
555
-			/* Process encapsulated options field */
523
+			/* Process encapsulated settings */
556 524
 			if ( ( rc = copy_encap_settings ( dest, source,
557 525
 							  tag ) ) != 0 )
558 526
 				return rc;
559 527
 			break;
560 528
 		default:
561
-			/* Copy option to reassembled packet */
562
-			if ( ( rc = copy_setting ( dest, tag, source,
563
-						   tag ) ) != 0 )
564
-				return rc;
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
+			}
565 543
 			break;
566 544
 		}
567 545
 	}

+ 0
- 2
src/include/gpxe/settings.h View File

@@ -163,8 +163,6 @@ extern int store_setting ( struct settings *settings, unsigned int tag,
163 163
 			   const void *data, size_t len );
164 164
 extern int fetch_setting ( struct settings *settings, unsigned int tag,
165 165
 			   void *data, size_t len );
166
-extern int copy_setting ( struct settings *dest, unsigned int dest_tag,
167
-			  struct settings *source, unsigned int source_tag );
168 166
 extern int copy_settings ( struct settings *dest, struct settings *source );
169 167
 extern int fetch_setting_len ( struct settings *settings, unsigned int tag );
170 168
 extern int fetch_string_setting ( struct settings *settings, unsigned int tag,

+ 54
- 18
src/net/udp/dhcp.c View File

@@ -255,20 +255,34 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
255 255
 
256 256
 	/* Copy any required options from previous server repsonse */
257 257
 	if ( dhcpoffer ) {
258
-		if ( ( rc = copy_setting ( &dhcppkt->settings,
259
-					   DHCP_SERVER_IDENTIFIER,
260
-					   &dhcpoffer->settings,
261
-					   DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
262
-			DBG ( "DHCP could not set server identifier "
263
-			      "option: %s\n", strerror ( rc ) );
258
+		struct in_addr server_id;
259
+		struct in_addr requested_ip;
260
+
261
+		if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
262
+						 DHCP_SERVER_IDENTIFIER,
263
+						 &server_id ) ) < 0 ) {
264
+			DBG ( "DHCP offer missing server identifier\n" );
265
+			return -EINVAL;
266
+		}
267
+		if ( ( rc = fetch_ipv4_setting ( &dhcpoffer->settings,
268
+						 DHCP_EB_YIADDR,
269
+						 &requested_ip ) ) < 0 ) {
270
+			DBG ( "DHCP offer missing IP address\n" );
271
+			return -EINVAL;
272
+		}
273
+		if ( ( rc = store_setting ( &dhcppkt->settings,
274
+					    DHCP_SERVER_IDENTIFIER, &server_id,
275
+					    sizeof ( server_id ) ) ) != 0 ) {
276
+			DBG ( "DHCP could not set server identifier: %s\n ",
277
+			      strerror ( rc ) );
264 278
 			return rc;
265 279
 		}
266
-		if ( ( rc = copy_setting ( &dhcppkt->settings,
267
-					   DHCP_REQUESTED_ADDRESS,
268
-					   &dhcpoffer->settings,
269
-					   DHCP_EB_YIADDR ) ) != 0 ) {
270
-			DBG ( "DHCP could not set requested address "
271
-			      "option: %s\n", strerror ( rc ) );
280
+		if ( ( rc = store_setting ( &dhcppkt->settings,
281
+					    DHCP_REQUESTED_ADDRESS,
282
+					    &requested_ip,
283
+					    sizeof ( requested_ip ) ) ) != 0 ){
284
+			DBG ( "DHCP could not set requested address: %s\n",
285
+			      strerror ( rc ) );
272 286
 			return rc;
273 287
 		}
274 288
 	}
@@ -335,8 +349,16 @@ static int create_dhcp_request ( struct dhcp_packet *dhcppkt,
335 349
 int create_dhcpdiscover ( struct net_device *netdev,
336 350
 			  void *data, size_t max_len ) {
337 351
 	struct dhcp_packet dhcppkt;
352
+	int rc;
353
+
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
+	}
338 360
 
339
-	return create_dhcp_request ( &dhcppkt, netdev, NULL, data, max_len );
361
+	return 0;
340 362
 }
341 363
 
342 364
 /**
@@ -356,18 +378,26 @@ int create_dhcpack ( struct net_device *netdev,
356 378
 
357 379
 	/* Create base DHCPACK packet */
358 380
 	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
359
-					 data, max_len ) ) != 0 )
381
+					 data, max_len ) ) != 0 ) {
382
+		DBG ( "Could not create DHCPACK: %s\n", strerror ( rc ) );
360 383
 		return rc;
384
+	}
361 385
 
362 386
 	/* Merge in globally-scoped settings, then netdev-specific
363 387
 	 * settings.  Do it in this order so that netdev-specific
364 388
 	 * settings take precedence regardless of stated priorities.
365 389
 	 */
366
-	if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 )
390
+	if ( ( rc = copy_settings ( &dhcppkt.settings, NULL ) ) != 0 ) {
391
+		DBG ( "Could not set DHCPACK global settings: %s\n",
392
+		      strerror ( rc ) );
367 393
 		return rc;
394
+	}
368 395
 	if ( ( rc = copy_settings ( &dhcppkt.settings,
369
-				    netdev_settings ( netdev ) ) ) != 0 )
396
+				    netdev_settings ( netdev ) ) ) != 0 ) {
397
+		DBG ( "Could not set DHCPACK netdev settings: %s\n",
398
+		      strerror ( rc ) );
370 399
 		return rc;
400
+	}
371 401
 
372 402
 	return 0;
373 403
 }
@@ -399,12 +429,18 @@ int create_proxydhcpack ( struct net_device *netdev,
399 429
 
400 430
 	/* Create base DHCPACK packet */
401 431
 	if ( ( rc = create_dhcp_packet ( &dhcppkt, netdev, DHCPACK, NULL,
402
-					 data, max_len ) ) != 0 )
432
+					 data, max_len ) ) != 0 ) {
433
+		DBG ( "Could not create ProxyDHCPACK: %s\n",
434
+		      strerror ( rc ) );
403 435
 		return rc;
436
+	}
404 437
 
405 438
 	/* Merge in ProxyDHCP options */
406
-	if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 )
439
+	if ( ( rc = copy_settings ( &dhcppkt.settings, settings ) ) != 0 ) {
440
+		DBG ( "Could not set ProxyDHCPACK settings: %s\n",
441
+		      strerror ( rc ) );
407 442
 		return rc;
443
+	}
408 444
 
409 445
 	return 0;
410 446
 }

Loading…
Cancel
Save