Browse Source

Now capable of sending what, to me, looks like a valid DHCPDISCOVER

(apart from the bad UDP checksum).
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
224529d8dd
2 changed files with 37 additions and 3 deletions
  1. 10
    2
      src/include/gpxe/dhcp.h
  2. 27
    1
      src/net/udp/dhcp.c

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

@@ -13,6 +13,12 @@
13 13
 #include <gpxe/udp.h>
14 14
 #include <gpxe/async.h>
15 15
 
16
+/** BOOTP/DHCP server port */
17
+#define BOOTPS_PORT 67
18
+
19
+/** BOOTP/DHCP client port */
20
+#define BOOTPC_PORT 68
21
+
16 22
 /** Construct a tag value for an encapsulated option
17 23
  *
18 24
  * This tag value can be passed to Etherboot functions when searching
@@ -345,9 +351,11 @@ struct dhcphdr {
345 351
 	uint32_t magic;
346 352
 	/** DHCP options
347 353
 	 *
348
-	 * Variable length; extends to the end of the packet.
354
+	 * Variable length; extends to the end of the packet.  Minimum
355
+	 * length (for the sake of sanity) is 1, to allow for a single
356
+	 * @c DHCP_END tag.
349 357
 	 */
350
-	uint8_t options[0];
358
+	uint8_t options[1];
351 359
 };
352 360
 
353 361
 /** Opcode for a request from client to server */

+ 27
- 1
src/net/udp/dhcp.c View File

@@ -233,6 +233,10 @@ static int create_dhcp_packet ( struct dhcp_session *dhcp, uint8_t msgtype,
233 233
 					     DHCP_OPTION_OVERLOAD_SNAME );
234 234
 	int rc;
235 235
 
236
+	/* Sanity check */
237
+	if ( max_len < sizeof ( *dhcphdr ) )
238
+		return -ENOSPC;
239
+
236 240
 	/* Initialise DHCP packet content */
237 241
 	memset ( dhcphdr, 0, max_len );
238 242
 	dhcphdr->xid = dhcp->xid;
@@ -428,6 +432,15 @@ udp_to_dhcp ( struct udp_connection *conn ) {
428 432
 	return container_of ( conn, struct dhcp_session, udp );
429 433
 }
430 434
 
435
+/** Address for transmitting DHCP requests */
436
+static struct sockaddr sa_dhcp_server = {
437
+	.sa_family = AF_INET,
438
+	.sin = {
439
+		.sin_addr.s_addr = INADDR_BROADCAST,
440
+		.sin_port = htons ( BOOTPS_PORT ),
441
+	},
442
+};
443
+
431 444
 /**
432 445
  * Transmit DHCP request
433 446
  *
@@ -461,7 +474,11 @@ static void dhcp_senddata ( struct udp_connection *conn,
461 474
 	}
462 475
 
463 476
 	/* Transmit the packet */
464
-	udp_send ( conn, dhcppkt.dhcphdr, dhcppkt.len );
477
+	if ( ( rc = udp_sendto ( conn, &sa_dhcp_server,
478
+				 dhcppkt.dhcphdr, dhcppkt.len ) ) != 0 ) {
479
+		DBG ( "Could not transmit UDP packet\n" );
480
+		return;
481
+	}
465 482
 }
466 483
 
467 484
 /**
@@ -513,6 +530,8 @@ static struct udp_operations dhcp_udp_operations = {
513 530
  * @ret aop		Asynchronous operation
514 531
  */
515 532
 struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) {
533
+	int rc;
534
+
516 535
 	dhcp->udp.udp_op = &dhcp_udp_operations;
517 536
 	dhcp->state = DHCPDISCOVER;
518 537
 	/* Use least significant 32 bits of link-layer address as XID */
@@ -520,8 +539,15 @@ struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) {
520 539
 			       + dhcp->netdev->ll_protocol->ll_addr_len
521 540
 			       - sizeof ( dhcp->xid ) ), sizeof ( dhcp->xid ));
522 541
 
542
+	/* Bind to local port */
543
+	if ( ( rc = udp_open ( &dhcp->udp, BOOTPC_PORT ) ) != 0 ) {
544
+		async_done ( &dhcp->aop, rc );
545
+		goto out;
546
+	}
547
+
523 548
 	/* Proof of concept: just send a single DHCPDISCOVER */
524 549
 	udp_senddata ( &dhcp->udp );
525 550
 
551
+ out:
526 552
 	return &dhcp->aop;
527 553
 }

Loading…
Cancel
Save