Browse Source

Centralise construction of the DHCP request and response packets.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
5e26df0325
4 changed files with 126 additions and 60 deletions
  1. 4
    7
      src/arch/i386/image/nbi.c
  2. 10
    6
      src/include/gpxe/dhcp.h
  3. 8
    10
      src/interface/pxe/pxe_preboot.c
  4. 104
    37
      src/net/udp/dhcp.c

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

@@ -397,16 +397,13 @@ static int nbi_prepare_dhcp ( struct image *image ) {
397 397
 		return -ENODEV;
398 398
 	}
399 399
 
400
-	if ( ( rc = create_dhcp_packet ( boot_netdev, DHCPACK, basemem_packet,
401
-					 sizeof ( basemem_packet ),
402
-					 &dhcppkt ) ) != 0 ) {
400
+	if ( ( rc = create_dhcp_response ( boot_netdev, DHCPACK, NULL,
401
+					   basemem_packet,
402
+					   sizeof ( basemem_packet ),
403
+					   &dhcppkt ) ) != 0 ) {
403 404
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404 405
 		return rc;
405 406
 	}
406
-	if ( ( rc = copy_dhcp_packet_options ( &dhcppkt, NULL ) ) != 0 ) {
407
-		DBGC ( image, "NBI %p failed to copy DHCP options\n", image );
408
-		return rc;
409
-	}
410 407
 
411 408
 	return 0;
412 409
 }

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

@@ -503,15 +503,19 @@ extern void find_global_dhcp_ipv4_option ( unsigned int tag,
503 503
 					   struct in_addr *inp );
504 504
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
505 505
 				 unsigned int tag );
506
+
506 507
 extern int apply_dhcp_options ( struct dhcp_option_block *options );
507 508
 extern int apply_global_dhcp_options ( void );
508 509
 
509
-extern struct dhcp_option_block dhcp_request_options;
510
-extern int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
511
-				void *data, size_t max_len,
512
-				struct dhcp_packet *dhcppkt );
513
-extern int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
514
-				      struct dhcp_option_block *options );
510
+extern int create_dhcp_request ( struct net_device *netdev, int msgtype,
511
+				 struct dhcp_option_block *options,
512
+				 void *data, size_t max_len,
513
+				 struct dhcp_packet *dhcppkt );
514
+extern int create_dhcp_response ( struct net_device *netdev, int msgtype,
515
+				  struct dhcp_option_block *options,
516
+				  void *data, size_t max_len,
517
+				  struct dhcp_packet *dhcppkt );
518
+
515 519
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev,
516 520
 			int (*register_options) ( struct net_device *,
517 521
 						  struct dhcp_option_block * ));

+ 8
- 10
src/interface/pxe/pxe_preboot.c View File

@@ -69,10 +69,12 @@ PXENV_EXIT_t pxenv_unload_stack ( struct s_PXENV_UNLOAD_STACK *unload_stack ) {
69 69
 PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
70 70
 				     *get_cached_info ) {
71 71
 	struct dhcp_packet dhcppkt;
72
+	int ( * dhcp_packet_creator ) ( struct net_device *, int,
73
+					struct dhcp_option_block *, void *,
74
+					size_t, struct dhcp_packet * );
75
+	unsigned int msgtype;
72 76
 	void *data = NULL;
73 77
 	size_t len;
74
-	int msgtype;
75
-	struct dhcp_option_block *options;
76 78
 	userptr_t buffer;
77 79
 	int rc;
78 80
 
@@ -102,21 +104,17 @@ PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
102 104
 
103 105
 	/* Construct DHCP packet */
104 106
 	if ( get_cached_info->PacketType == PXENV_PACKET_TYPE_DHCP_DISCOVER ) {
107
+		dhcp_packet_creator = create_dhcp_request;
105 108
 		msgtype = DHCPDISCOVER;
106
-		options = &dhcp_request_options;
107 109
 	} else {
110
+		dhcp_packet_creator = create_dhcp_response;
108 111
 		msgtype = DHCPACK;
109
-		options = NULL;
110 112
 	}
111
-	if ( ( rc = create_dhcp_packet ( pxe_netdev, msgtype, data, len,
112
-					 &dhcppkt ) ) != 0 ) {
113
+	if ( ( rc = dhcp_packet_creator ( pxe_netdev, msgtype, NULL,
114
+					  data, len, &dhcppkt ) ) != 0 ) {
113 115
 		DBG ( " failed to build packet" );
114 116
 		goto err;
115 117
 	}
116
-	if ( ( rc = copy_dhcp_packet_options ( &dhcppkt, options ) ) != 0 ) {
117
-		DBG ( " failed to copy options" );
118
-		goto err;
119
-	}
120 118
 
121 119
 	/* Overwrite filename to work around Microsoft RIS bug */
122 120
 	if ( pxe_ris_filename ) {

+ 104
- 37
src/net/udp/dhcp.c View File

@@ -108,7 +108,7 @@ static uint32_t dhcp_xid ( struct net_device *netdev ) {
108 108
 }
109 109
 
110 110
 /** Options common to all DHCP requests */
111
-struct dhcp_option_block dhcp_request_options = {
111
+static struct dhcp_option_block dhcp_request_options = {
112 112
 	.data = dhcp_request_options_data,
113 113
 	.max_len = sizeof ( dhcp_request_options_data ),
114 114
 	.len = sizeof ( dhcp_request_options_data ),
@@ -270,8 +270,8 @@ static int copy_dhcp_packet_encap_options ( struct dhcp_packet *dhcppkt,
270 270
  * @c options may specify a single options block, or be left as NULL
271 271
  * in order to copy options from all registered options blocks.
272 272
  */
273
-int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
274
-			       struct dhcp_option_block *options ) {
273
+static int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
274
+				      struct dhcp_option_block *options ) {
275 275
 	return copy_dhcp_packet_encap_options ( dhcppkt, options, 0 );
276 276
 }
277 277
 
@@ -289,9 +289,10 @@ int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
289 289
  * dhcp_packet structure that can be passed to
290 290
  * set_dhcp_packet_option() or copy_dhcp_packet_options().
291 291
  */
292
-int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
293
-			 void *data, size_t max_len,
294
-			 struct dhcp_packet *dhcppkt ) {
292
+static int create_dhcp_packet ( struct net_device *netdev,
293
+				unsigned int msgtype,
294
+				void *data, size_t max_len,
295
+				struct dhcp_packet *dhcppkt ) {
295 296
 	struct dhcphdr *dhcphdr = data;
296 297
 	int rc;
297 298
 
@@ -473,6 +474,97 @@ static struct dhcp_option_block * dhcp_parse ( const struct dhcphdr *dhcphdr,
473 474
 	return options;
474 475
 }
475 476
 
477
+/****************************************************************************
478
+ *
479
+ * Whole-packet construction
480
+ *
481
+ */
482
+
483
+/**
484
+ * Create DHCP request
485
+ *
486
+ * @v netdev		Network device
487
+ * @v msgtype		DHCP message type
488
+ * @v options		DHCP server response options, or NULL
489
+ * @v data		Buffer for DHCP packet
490
+ * @v max_len		Size of DHCP packet buffer
491
+ * @v dhcppkt		DHCP packet structure to fill in
492
+ * @ret rc		Return status code
493
+ */
494
+int create_dhcp_request ( struct net_device *netdev, int msgtype,
495
+			  struct dhcp_option_block *options,
496
+			  void *data, size_t max_len,
497
+			  struct dhcp_packet *dhcppkt ) {
498
+	int rc;
499
+
500
+	/* Create DHCP packet */
501
+	if ( ( rc = create_dhcp_packet ( netdev, msgtype, data, max_len,
502
+					 dhcppkt ) ) != 0 ) {
503
+		DBG ( "DHCP could not create DHCP packet: %s\n",
504
+		      strerror ( rc ) );
505
+		return rc;
506
+	}
507
+
508
+	/* Copy in options common to all requests */
509
+	if ( ( rc = copy_dhcp_packet_options ( dhcppkt,
510
+					       &dhcp_request_options )) !=0 ){
511
+		DBG ( "DHCP could not set common DHCP options: %s\n",
512
+		      strerror ( rc ) );
513
+		return rc;
514
+	}
515
+
516
+	/* Copy any required options from previous server repsonse */
517
+	if ( options ) {
518
+		if ( ( rc = copy_dhcp_packet_option ( dhcppkt, options,
519
+					  DHCP_SERVER_IDENTIFIER,
520
+					  DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
521
+			DBG ( "DHCP could not set server identifier "
522
+			      "option: %s\n", strerror ( rc ) );
523
+			return rc;
524
+		}
525
+		if ( ( rc = copy_dhcp_packet_option ( dhcppkt, options,
526
+					  DHCP_EB_YIADDR,
527
+					  DHCP_REQUESTED_ADDRESS ) ) != 0 ) {
528
+			DBG ( "DHCP could not set requested address "
529
+			      "option: %s\n", strerror ( rc ) );
530
+			return rc;
531
+		}
532
+	}
533
+
534
+	return 0;
535
+}
536
+
537
+/**
538
+ * Create DHCP response
539
+ *
540
+ * @v netdev		Network device
541
+ * @v msgtype		DHCP message type
542
+ * @v options		DHCP options, or NULL
543
+ * @v data		Buffer for DHCP packet
544
+ * @v max_len		Size of DHCP packet buffer
545
+ * @v dhcppkt		DHCP packet structure to fill in
546
+ * @ret rc		Return status code
547
+ */
548
+int create_dhcp_response ( struct net_device *netdev, int msgtype,
549
+			   struct dhcp_option_block *options,
550
+			   void *data, size_t max_len,
551
+			   struct dhcp_packet *dhcppkt ) {
552
+	int rc;
553
+
554
+	/* Create packet and copy in options */
555
+	if ( ( rc = create_dhcp_packet ( netdev, msgtype, data, max_len,
556
+					 dhcppkt ) ) != 0 ) {
557
+		DBG ( " failed to build packet" );
558
+		return rc;
559
+	}
560
+	if ( ( rc = copy_dhcp_packet_options ( dhcppkt, options ) ) != 0 ) {
561
+		DBG ( " failed to copy options" );
562
+		return rc;
563
+	}
564
+
565
+	return 0;
566
+}
567
+
476 568
 /****************************************************************************
477 569
  *
478 570
  * DHCP to UDP interface
@@ -556,8 +648,8 @@ static int dhcp_send_request ( struct dhcp_session *dhcp ) {
556 648
 	struct xfer_metadata meta = {
557 649
 		.netdev = dhcp->netdev,
558 650
 	};
559
-	struct dhcp_packet dhcppkt;
560 651
 	struct io_buffer *iobuf;
652
+	struct dhcp_packet dhcppkt;
561 653
 	int rc;
562 654
 	
563 655
 	DBGC ( dhcp, "DHCP %p transmitting %s\n",
@@ -577,40 +669,15 @@ static int dhcp_send_request ( struct dhcp_session *dhcp ) {
577 669
 		return -ENOMEM;
578 670
 
579 671
 	/* Create DHCP packet in temporary buffer */
580
-	if ( ( rc = create_dhcp_packet ( dhcp->netdev, dhcp->state,
581
-					 iobuf->data, iob_tailroom ( iobuf ),
582
-					 &dhcppkt ) ) != 0 ) {
583
-		DBGC ( dhcp, "DHCP %p could not create DHCP packet: %s\n",
584
-		       dhcp, strerror ( rc ) );
585
-		goto done;
586
-	}
587
-
588
-	/* Copy in options common to all requests */
589
-	if ( ( rc = copy_dhcp_packet_options ( &dhcppkt,
590
-					       &dhcp_request_options ) ) != 0){
591
-		DBGC ( dhcp, "DHCP %p could not set common DHCP options: %s\n",
672
+	if ( ( rc = create_dhcp_request ( dhcp->netdev, dhcp->state,
673
+					  dhcp->options, iobuf->data,
674
+					  iob_tailroom ( iobuf ),
675
+					  &dhcppkt ) ) != 0 ) {
676
+		DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
592 677
 		       dhcp, strerror ( rc ) );
593 678
 		goto done;
594 679
 	}
595 680
 
596
-	/* Copy any required options from previous server repsonse */
597
-	if ( dhcp->options ) {
598
-		if ( ( rc = copy_dhcp_packet_option ( &dhcppkt, dhcp->options,
599
-					    DHCP_SERVER_IDENTIFIER,
600
-					    DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
601
-			DBGC ( dhcp, "DHCP %p could not set server identifier "
602
-			       "option: %s\n", dhcp, strerror ( rc ) );
603
-			goto done;
604
-		}
605
-		if ( ( rc = copy_dhcp_packet_option ( &dhcppkt, dhcp->options,
606
-					    DHCP_EB_YIADDR,
607
-					    DHCP_REQUESTED_ADDRESS ) ) != 0 ) {
608
-			DBGC ( dhcp, "DHCP %p could not set requested address "
609
-			       "option: %s\n", dhcp, strerror ( rc ) );
610
-			goto done;
611
-		}
612
-	}
613
-
614 681
 	/* Transmit the packet */
615 682
 	iob_put ( iobuf, dhcppkt.len );
616 683
 	rc = xfer_deliver_iob_meta ( &dhcp->xfer, iobuf, &meta );

Loading…
Cancel
Save