Просмотр исходного кода

Proof of concept: transmit a single DHCPDISCOVER and dump out any

parsed DHCP responses.
tags/v0.9.3
Michael Brown 18 лет назад
Родитель
Сommit
317b962b65
2 измененных файлов: 49 добавлений и 4 удалений
  1. 3
    0
      src/include/gpxe/dhcp.h
  2. 46
    4
      src/net/udp/dhcp.c

+ 3
- 0
src/include/gpxe/dhcp.h Просмотреть файл

@@ -11,6 +11,7 @@
11 11
 #include <gpxe/list.h>
12 12
 #include <gpxe/in.h>
13 13
 #include <gpxe/udp.h>
14
+#include <gpxe/async.h>
14 15
 
15 16
 /** Construct a tag value for an encapsulated option
16 17
  *
@@ -404,6 +405,8 @@ struct dhcp_session {
404 405
 	 * (e.g. @c DHCPDISCOVER).
405 406
 	 */
406 407
 	int state;
408
+	/** Asynchronous operation for this DHCP session */
409
+	struct async_operation aop;
407 410
 	
408 411
 	/** Network device being configured */
409 412
 	struct net_device *netdev;

+ 46
- 4
src/net/udp/dhcp.c Просмотреть файл

@@ -22,6 +22,7 @@
22 22
 #include <byteswap.h>
23 23
 #include <gpxe/if_ether.h>
24 24
 #include <gpxe/netdevice.h>
25
+#include <gpxe/udp.h>
25 26
 #include <gpxe/dhcp.h>
26 27
 
27 28
 /** @file
@@ -301,7 +302,7 @@ static void merge_dhcp_field ( struct dhcp_option_block *options,
301 302
 /**
302 303
  * Parse DHCP packet and construct DHCP options block
303 304
  *
304
- * @v data		DHCP packet
305
+ * @v dhcphdr		DHCP packet
305 306
  * @v len		Length of DHCP packet
306 307
  * @ret options		DHCP options block, or NULL
307 308
  *
@@ -320,8 +321,8 @@ static void merge_dhcp_field ( struct dhcp_option_block *options,
320 321
  * options block; it is the responsibility of the caller to eventually
321 322
  * free this memory.
322 323
  */
323
-struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
324
-	const struct dhcphdr *dhcphdr = data;
324
+static struct dhcp_option_block * dhcp_parse ( struct dhcphdr *dhcphdr,
325
+					       size_t len ) {
325 326
 	struct dhcp_option_block *options;
326 327
 	size_t options_len;
327 328
 	unsigned int overloading;
@@ -435,7 +436,8 @@ static void dhcp_senddata ( struct udp_connection *conn,
435 436
 		return;
436 437
 	}
437 438
 
438
-	
439
+	/* Transmit the packet */
440
+	udp_send ( conn, dhcppkt.dhcphdr, dhcppkt.len );
439 441
 }
440 442
 
441 443
 /**
@@ -448,6 +450,26 @@ static void dhcp_senddata ( struct udp_connection *conn,
448 450
 static void dhcp_newdata ( struct udp_connection *conn,
449 451
 			   void *data, size_t len ) {
450 452
 	struct dhcp_session *dhcp = udp_to_dhcp ( conn );
453
+	struct dhcphdr *dhcphdr = data;
454
+	struct dhcp_option_block *options;
455
+
456
+	/* Check for matching transaction ID */
457
+	if ( dhcphdr->xid != dhcp->xid ) {
458
+		DBG ( "DHCP wrong transaction ID (wanted %08x, got %08x)\n",
459
+		      ntohl ( dhcphdr->xid ), ntohl ( dhcp->xid ) );
460
+		return;
461
+	};
462
+
463
+	/* Parse packet and create options structure */
464
+	options = dhcp_parse ( dhcphdr, len );
465
+	if ( ! options ) {
466
+		DBG ( "Could not parse DHCP packet\n" );
467
+		return;
468
+	}
469
+
470
+	/* Proof of concept: just dump out the parsed options */
471
+	hex_dump ( options->data, options->len );
472
+	free_dhcp_options ( options );
451 473
 }
452 474
 
453 475
 /** DHCP UDP operations */
@@ -455,3 +477,23 @@ static struct udp_operations dhcp_udp_operations = {
455 477
 	.senddata	= dhcp_senddata,
456 478
 	.newdata	= dhcp_newdata,
457 479
 };
480
+
481
+/**
482
+ * Initiate DHCP on a network interface
483
+ *
484
+ * @v dhcp		DHCP session
485
+ * @ret aop		Asynchronous operation
486
+ */
487
+struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) {
488
+	dhcp->udp.udp_op = &dhcp_udp_operations;
489
+	dhcp->state = DHCPDISCOVER;
490
+	/* Use least significant 32 bits of link-layer address as XID */
491
+	memcpy ( &dhcp->xid, ( dhcp->netdev->ll_addr
492
+			       + dhcp->netdev->ll_protocol->ll_addr_len
493
+			       - sizeof ( dhcp->xid ) ), sizeof ( dhcp->xid ));
494
+
495
+	/* Proof of concept: just send a single DHCPDISCOVER */
496
+	udp_senddata ( &dhcp->udp );
497
+
498
+	return &dhcp->aop;
499
+}

Загрузка…
Отмена
Сохранить