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
 #include <gpxe/udp.h>
13
 #include <gpxe/udp.h>
14
 #include <gpxe/async.h>
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
 /** Construct a tag value for an encapsulated option
22
 /** Construct a tag value for an encapsulated option
17
  *
23
  *
18
  * This tag value can be passed to Etherboot functions when searching
24
  * This tag value can be passed to Etherboot functions when searching
345
 	uint32_t magic;
351
 	uint32_t magic;
346
 	/** DHCP options
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
 /** Opcode for a request from client to server */
361
 /** Opcode for a request from client to server */

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

233
 					     DHCP_OPTION_OVERLOAD_SNAME );
233
 					     DHCP_OPTION_OVERLOAD_SNAME );
234
 	int rc;
234
 	int rc;
235
 
235
 
236
+	/* Sanity check */
237
+	if ( max_len < sizeof ( *dhcphdr ) )
238
+		return -ENOSPC;
239
+
236
 	/* Initialise DHCP packet content */
240
 	/* Initialise DHCP packet content */
237
 	memset ( dhcphdr, 0, max_len );
241
 	memset ( dhcphdr, 0, max_len );
238
 	dhcphdr->xid = dhcp->xid;
242
 	dhcphdr->xid = dhcp->xid;
428
 	return container_of ( conn, struct dhcp_session, udp );
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
  * Transmit DHCP request
445
  * Transmit DHCP request
433
  *
446
  *
461
 	}
474
 	}
462
 
475
 
463
 	/* Transmit the packet */
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
  * @ret aop		Asynchronous operation
530
  * @ret aop		Asynchronous operation
514
  */
531
  */
515
 struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) {
532
 struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) {
533
+	int rc;
534
+
516
 	dhcp->udp.udp_op = &dhcp_udp_operations;
535
 	dhcp->udp.udp_op = &dhcp_udp_operations;
517
 	dhcp->state = DHCPDISCOVER;
536
 	dhcp->state = DHCPDISCOVER;
518
 	/* Use least significant 32 bits of link-layer address as XID */
537
 	/* Use least significant 32 bits of link-layer address as XID */
520
 			       + dhcp->netdev->ll_protocol->ll_addr_len
539
 			       + dhcp->netdev->ll_protocol->ll_addr_len
521
 			       - sizeof ( dhcp->xid ) ), sizeof ( dhcp->xid ));
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
 	/* Proof of concept: just send a single DHCPDISCOVER */
548
 	/* Proof of concept: just send a single DHCPDISCOVER */
524
 	udp_senddata ( &dhcp->udp );
549
 	udp_senddata ( &dhcp->udp );
525
 
550
 
551
+ out:
526
 	return &dhcp->aop;
552
 	return &dhcp->aop;
527
 }
553
 }

Loading…
Cancel
Save