Browse Source

Derive xid dynamically from the netdev, so that we can call

create_dhcp_packet() from pxe_preboot.c, after the dhcp_session is long
gone.

Expose the functions required by pxe_preboot.c
tags/v0.9.3
Michael Brown 19 years ago
parent
commit
e9561aafc0
2 changed files with 38 additions and 20 deletions
  1. 6
    2
      src/include/gpxe/dhcp.h
  2. 32
    18
      src/net/udp/dhcp.c

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

426
 	/** Options obtained from server */
426
 	/** Options obtained from server */
427
 	struct dhcp_option_block *options;
427
 	struct dhcp_option_block *options;
428
 
428
 
429
-	/** Transaction ID, in network-endian order */
430
-	uint32_t xid;
431
 	/** State of the session
429
 	/** State of the session
432
 	 *
430
 	 *
433
 	 * This is a value for the @c DHCP_MESSAGE_TYPE option
431
 	 * This is a value for the @c DHCP_MESSAGE_TYPE option
467
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
465
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
468
 				 unsigned int tag );
466
 				 unsigned int tag );
469
 
467
 
468
+extern struct dhcp_option_block dhcp_request_options;
469
+extern int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
470
+				void *data, size_t max_len,
471
+				struct dhcp_packet *dhcppkt );
472
+extern int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
473
+				      struct dhcp_option_block *options );
470
 extern struct async_operation * start_dhcp ( struct dhcp_session *dhcp );
474
 extern struct async_operation * start_dhcp ( struct dhcp_session *dhcp );
471
 
475
 
472
 #endif /* _GPXE_DHCP_H */
476
 #endif /* _GPXE_DHCP_H */

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

80
 	}
80
 	}
81
 }
81
 }
82
 
82
 
83
+/**
84
+ * Calculate DHCP transaction ID for a network device
85
+ *
86
+ * @v netdev		Network device
87
+ * @ret xid		DHCP XID
88
+ *
89
+ * Extract the least significant bits of the hardware address for use
90
+ * as the transaction ID.
91
+ */
92
+static uint32_t dhcp_xid ( struct net_device *netdev ) {
93
+	uint32_t xid;
94
+
95
+	memcpy ( &xid, ( netdev->ll_addr + netdev->ll_protocol->ll_addr_len
96
+			 - sizeof ( xid ) ), sizeof ( xid ) );
97
+	return xid;
98
+}
99
+
83
 /** Options common to all DHCP requests */
100
 /** Options common to all DHCP requests */
84
-static struct dhcp_option_block dhcp_request_options = {
101
+struct dhcp_option_block dhcp_request_options = {
85
 	.data = dhcp_request_options_data,
102
 	.data = dhcp_request_options_data,
86
 	.max_len = sizeof ( dhcp_request_options_data ),
103
 	.max_len = sizeof ( dhcp_request_options_data ),
87
 	.len = sizeof ( dhcp_request_options_data ),
104
 	.len = sizeof ( dhcp_request_options_data ),
245
  * @c options may specify a single options block, or be left as NULL
262
  * @c options may specify a single options block, or be left as NULL
246
  * in order to copy options from all registered options blocks.
263
  * in order to copy options from all registered options blocks.
247
  */
264
  */
248
-static int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
249
-				      struct dhcp_option_block *options ) {
265
+int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
266
+			       struct dhcp_option_block *options ) {
250
 	return copy_dhcp_packet_encap_options ( dhcppkt, options, 0 );
267
 	return copy_dhcp_packet_encap_options ( dhcppkt, options, 0 );
251
 }
268
 }
252
 
269
 
253
 /**
270
 /**
254
  * Create a DHCP packet
271
  * Create a DHCP packet
255
  *
272
  *
256
- * @v dhcp		DHCP session
273
+ * @v netdev		Network device
257
  * @v msgtype		DHCP message type
274
  * @v msgtype		DHCP message type
258
  * @v data		Buffer for DHCP packet
275
  * @v data		Buffer for DHCP packet
259
  * @v max_len		Size of DHCP packet buffer
276
  * @v max_len		Size of DHCP packet buffer
264
  * dhcp_packet structure that can be passed to
281
  * dhcp_packet structure that can be passed to
265
  * set_dhcp_packet_option() or copy_dhcp_packet_options().
282
  * set_dhcp_packet_option() or copy_dhcp_packet_options().
266
  */
283
  */
267
-static int create_dhcp_packet ( struct dhcp_session *dhcp, uint8_t msgtype,
268
-				void *data, size_t max_len,
269
-				struct dhcp_packet *dhcppkt ) {
284
+int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
285
+			 void *data, size_t max_len,
286
+			 struct dhcp_packet *dhcppkt ) {
270
 	struct dhcphdr *dhcphdr = data;
287
 	struct dhcphdr *dhcphdr = data;
271
 	static const uint8_t overloading = ( DHCP_OPTION_OVERLOAD_FILE |
288
 	static const uint8_t overloading = ( DHCP_OPTION_OVERLOAD_FILE |
272
 					     DHCP_OPTION_OVERLOAD_SNAME );
289
 					     DHCP_OPTION_OVERLOAD_SNAME );
278
 
295
 
279
 	/* Initialise DHCP packet content */
296
 	/* Initialise DHCP packet content */
280
 	memset ( dhcphdr, 0, max_len );
297
 	memset ( dhcphdr, 0, max_len );
281
-	dhcphdr->xid = dhcp->xid;
298
+	dhcphdr->xid = dhcp_xid ( netdev );
282
 	dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
299
 	dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
283
-	dhcphdr->htype = ntohs ( dhcp->netdev->ll_protocol->ll_proto );
284
-	dhcphdr->hlen = dhcp->netdev->ll_protocol->ll_addr_len;
285
-	memcpy ( dhcphdr->chaddr, dhcp->netdev->ll_addr, dhcphdr->hlen );
300
+	dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto );
301
+	dhcphdr->hlen = netdev->ll_protocol->ll_addr_len;
302
+	memcpy ( dhcphdr->chaddr, netdev->ll_addr, dhcphdr->hlen );
286
 	dhcphdr->op = dhcp_op[msgtype];
303
 	dhcphdr->op = dhcp_op[msgtype];
287
 
304
 
288
 	/* Initialise DHCP packet structure */
305
 	/* Initialise DHCP packet structure */
522
 		 ( dhcp->state == DHCPREQUEST ) );
539
 		 ( dhcp->state == DHCPREQUEST ) );
523
 
540
 
524
 	/* Create DHCP packet in temporary buffer */
541
 	/* Create DHCP packet in temporary buffer */
525
-	if ( ( rc = create_dhcp_packet ( dhcp, dhcp->state, buf, len,
542
+	if ( ( rc = create_dhcp_packet ( dhcp->netdev, dhcp->state, buf, len,
526
 					 &dhcppkt ) ) != 0 ) {
543
 					 &dhcppkt ) ) != 0 ) {
527
 		DBG ( "Could not create DHCP packet\n" );
544
 		DBG ( "Could not create DHCP packet\n" );
528
 		return rc;
545
 		return rc;
606
 	unsigned int msgtype;
623
 	unsigned int msgtype;
607
 
624
 
608
 	/* Check for matching transaction ID */
625
 	/* Check for matching transaction ID */
609
-	if ( dhcphdr->xid != dhcp->xid ) {
626
+	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
610
 		DBG ( "DHCP wrong transaction ID (wanted %08lx, got %08lx)\n",
627
 		DBG ( "DHCP wrong transaction ID (wanted %08lx, got %08lx)\n",
611
-		      ntohl ( dhcphdr->xid ), ntohl ( dhcp->xid ) );
628
+		      ntohl ( dhcphdr->xid ),
629
+		      ntohl ( dhcp_xid ( dhcp->netdev ) ) );
612
 		return 0;
630
 		return 0;
613
 	};
631
 	};
614
 
632
 
683
 	dhcp->udp.udp_op = &dhcp_udp_operations;
701
 	dhcp->udp.udp_op = &dhcp_udp_operations;
684
 	dhcp->timer.expired = dhcp_timer_expired;
702
 	dhcp->timer.expired = dhcp_timer_expired;
685
 	dhcp->state = DHCPDISCOVER;
703
 	dhcp->state = DHCPDISCOVER;
686
-	/* Use least significant 32 bits of link-layer address as XID */
687
-	memcpy ( &dhcp->xid, ( dhcp->netdev->ll_addr
688
-			       + dhcp->netdev->ll_protocol->ll_addr_len
689
-			       - sizeof ( dhcp->xid ) ), sizeof ( dhcp->xid ));
690
 
704
 
691
 	/* Bind to local port */
705
 	/* Bind to local port */
692
 	if ( ( rc = udp_open ( &dhcp->udp, htons ( BOOTPC_PORT ) ) ) != 0 ) {
706
 	if ( ( rc = udp_open ( &dhcp->udp, htons ( BOOTPC_PORT ) ) ) != 0 ) {

Loading…
Cancel
Save