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
 		return -ENODEV;
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
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404
 		return rc;
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
 	return 0;
408
 	return 0;
412
 }
409
 }

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

503
 					   struct in_addr *inp );
503
 					   struct in_addr *inp );
504
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
504
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
505
 				 unsigned int tag );
505
 				 unsigned int tag );
506
+
506
 extern int apply_dhcp_options ( struct dhcp_option_block *options );
507
 extern int apply_dhcp_options ( struct dhcp_option_block *options );
507
 extern int apply_global_dhcp_options ( void );
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
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev,
519
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev,
516
 			int (*register_options) ( struct net_device *,
520
 			int (*register_options) ( struct net_device *,
517
 						  struct dhcp_option_block * ));
521
 						  struct dhcp_option_block * ));

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

69
 PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
69
 PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
70
 				     *get_cached_info ) {
70
 				     *get_cached_info ) {
71
 	struct dhcp_packet dhcppkt;
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
 	void *data = NULL;
76
 	void *data = NULL;
73
 	size_t len;
77
 	size_t len;
74
-	int msgtype;
75
-	struct dhcp_option_block *options;
76
 	userptr_t buffer;
78
 	userptr_t buffer;
77
 	int rc;
79
 	int rc;
78
 
80
 
102
 
104
 
103
 	/* Construct DHCP packet */
105
 	/* Construct DHCP packet */
104
 	if ( get_cached_info->PacketType == PXENV_PACKET_TYPE_DHCP_DISCOVER ) {
106
 	if ( get_cached_info->PacketType == PXENV_PACKET_TYPE_DHCP_DISCOVER ) {
107
+		dhcp_packet_creator = create_dhcp_request;
105
 		msgtype = DHCPDISCOVER;
108
 		msgtype = DHCPDISCOVER;
106
-		options = &dhcp_request_options;
107
 	} else {
109
 	} else {
110
+		dhcp_packet_creator = create_dhcp_response;
108
 		msgtype = DHCPACK;
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
 		DBG ( " failed to build packet" );
115
 		DBG ( " failed to build packet" );
114
 		goto err;
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
 	/* Overwrite filename to work around Microsoft RIS bug */
119
 	/* Overwrite filename to work around Microsoft RIS bug */
122
 	if ( pxe_ris_filename ) {
120
 	if ( pxe_ris_filename ) {

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

108
 }
108
 }
109
 
109
 
110
 /** Options common to all DHCP requests */
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
 	.data = dhcp_request_options_data,
112
 	.data = dhcp_request_options_data,
113
 	.max_len = sizeof ( dhcp_request_options_data ),
113
 	.max_len = sizeof ( dhcp_request_options_data ),
114
 	.len = sizeof ( dhcp_request_options_data ),
114
 	.len = sizeof ( dhcp_request_options_data ),
270
  * @c options may specify a single options block, or be left as NULL
270
  * @c options may specify a single options block, or be left as NULL
271
  * in order to copy options from all registered options blocks.
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
 	return copy_dhcp_packet_encap_options ( dhcppkt, options, 0 );
275
 	return copy_dhcp_packet_encap_options ( dhcppkt, options, 0 );
276
 }
276
 }
277
 
277
 
289
  * dhcp_packet structure that can be passed to
289
  * dhcp_packet structure that can be passed to
290
  * set_dhcp_packet_option() or copy_dhcp_packet_options().
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
 	struct dhcphdr *dhcphdr = data;
296
 	struct dhcphdr *dhcphdr = data;
296
 	int rc;
297
 	int rc;
297
 
298
 
473
 	return options;
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
  * DHCP to UDP interface
570
  * DHCP to UDP interface
556
 	struct xfer_metadata meta = {
648
 	struct xfer_metadata meta = {
557
 		.netdev = dhcp->netdev,
649
 		.netdev = dhcp->netdev,
558
 	};
650
 	};
559
-	struct dhcp_packet dhcppkt;
560
 	struct io_buffer *iobuf;
651
 	struct io_buffer *iobuf;
652
+	struct dhcp_packet dhcppkt;
561
 	int rc;
653
 	int rc;
562
 	
654
 	
563
 	DBGC ( dhcp, "DHCP %p transmitting %s\n",
655
 	DBGC ( dhcp, "DHCP %p transmitting %s\n",
577
 		return -ENOMEM;
669
 		return -ENOMEM;
578
 
670
 
579
 	/* Create DHCP packet in temporary buffer */
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
 		       dhcp, strerror ( rc ) );
677
 		       dhcp, strerror ( rc ) );
593
 		goto done;
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
 	/* Transmit the packet */
681
 	/* Transmit the packet */
615
 	iob_put ( iobuf, dhcppkt.len );
682
 	iob_put ( iobuf, dhcppkt.len );
616
 	rc = xfer_deliver_iob_meta ( &dhcp->xfer, iobuf, &meta );
683
 	rc = xfer_deliver_iob_meta ( &dhcp->xfer, iobuf, &meta );

Loading…
Cancel
Save