Parcourir la source

Added dhcp_ipv4_option() and friends.

Added test code to configure the interface for IPv4 after DHCP.
tags/v0.9.3
Michael Brown il y a 18 ans
Parent
révision
00a1f000b1
3 fichiers modifiés avec 102 ajouts et 1 suppressions
  1. 7
    0
      src/include/gpxe/dhcp.h
  2. 55
    0
      src/net/dhcpopts.c
  3. 40
    1
      src/tests/dhcptest.c

+ 7
- 0
src/include/gpxe/dhcp.h Voir le fichier

@@ -250,6 +250,7 @@ struct dhcp_option {
250 250
 		uint8_t byte;
251 251
 		uint16_t word;
252 252
 		uint32_t dword;
253
+		struct in_addr in;
253 254
 		uint8_t bytes[0];
254 255
 	} data;
255 256
 } __attribute__ (( packed ));
@@ -429,6 +430,8 @@ struct dhcp_session {
429 430
 };
430 431
 
431 432
 extern unsigned long dhcp_num_option ( struct dhcp_option *option );
433
+extern void dhcp_ipv4_option ( struct dhcp_option *option,
434
+			       struct in_addr *inp );
432 435
 extern struct dhcp_option *
433 436
 find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
434 437
 extern void register_dhcp_options ( struct dhcp_option_block *options );
@@ -444,6 +447,10 @@ extern struct dhcp_option * find_global_dhcp_option ( unsigned int tag );
444 447
 extern unsigned long find_dhcp_num_option ( struct dhcp_option_block *options,
445 448
 					    unsigned int tag );
446 449
 extern unsigned long find_global_dhcp_num_option ( unsigned int tag );
450
+extern void find_dhcp_ipv4_option ( struct dhcp_option_block *options,
451
+				    unsigned int tag, struct in_addr *inp );
452
+extern void find_global_dhcp_ipv4_option ( unsigned int tag,
453
+					   struct in_addr *inp );
447 454
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
448 455
 				 unsigned int tag );
449 456
 

+ 55
- 0
src/net/dhcpopts.c Voir le fichier

@@ -24,6 +24,7 @@
24 24
 #include <assert.h>
25 25
 #include <vsprintf.h>
26 26
 #include <gpxe/list.h>
27
+#include <gpxe/in.h>
27 28
 #include <gpxe/dhcp.h>
28 29
 
29 30
 /** @file
@@ -85,6 +86,21 @@ unsigned long dhcp_num_option ( struct dhcp_option *option ) {
85 86
 	return value;
86 87
 }
87 88
 
89
+/**
90
+ * Obtain value of an IPv4-address DHCP option
91
+ *
92
+ * @v option		DHCP option, or NULL
93
+ * @v inp		IPv4 address to fill in
94
+ *
95
+ * Parses the IPv4 address value from a DHCP option, if present.  It
96
+ * is permitted to call dhcp_ipv4_option() with @c option set to NULL;
97
+ * in this case the address will be set to 0.0.0.0.
98
+ */
99
+void dhcp_ipv4_option ( struct dhcp_option *option, struct in_addr *inp ) {
100
+	if ( option )
101
+		*inp = option->data.in;
102
+}
103
+
88 104
 /**
89 105
  * Calculate length of a normal DHCP option
90 106
  *
@@ -460,6 +476,45 @@ unsigned long find_global_dhcp_num_option ( unsigned int tag ) {
460 476
 	return dhcp_num_option ( find_global_dhcp_option ( tag ) );
461 477
 }
462 478
 
479
+/**
480
+ * Find DHCP IPv4-address option, and return its value
481
+ *
482
+ * @v options		DHCP options block
483
+ * @v tag		DHCP option tag to search for
484
+ * @v inp		IPv4 address to fill in
485
+ * @ret value		Numerical value of the option, or 0 if not found
486
+ *
487
+ * This function exists merely as a notational shorthand for a call to
488
+ * find_dhcp_option() followed by a call to dhcp_ipv4_option().  It is
489
+ * not possible to distinguish between the cases "option not found"
490
+ * and "option has a value of 0.0.0.0" using this function; if this
491
+ * matters to you then issue the two constituent calls directly and
492
+ * check that find_dhcp_option() returns a non-NULL value.
493
+ */
494
+void find_dhcp_ipv4_option ( struct dhcp_option_block *options,
495
+			     unsigned int tag, struct in_addr *inp ) {
496
+	dhcp_ipv4_option ( find_dhcp_option ( options, tag ), inp );
497
+}
498
+
499
+/**
500
+ * Find DHCP IPv4-address option, and return its value
501
+ *
502
+ * @v options		DHCP options block
503
+ * @v tag		DHCP option tag to search for
504
+ * @v inp		IPv4 address to fill in
505
+ * @ret value		Numerical value of the option, or 0 if not found
506
+ *
507
+ * This function exists merely as a notational shorthand for a call to
508
+ * find_dhcp_option() followed by a call to dhcp_ipv4_option().  It is
509
+ * not possible to distinguish between the cases "option not found"
510
+ * and "option has a value of 0.0.0.0" using this function; if this
511
+ * matters to you then issue the two constituent calls directly and
512
+ * check that find_dhcp_option() returns a non-NULL value.
513
+ */
514
+void find_global_dhcp_ipv4_option ( unsigned int tag, struct in_addr *inp ) {
515
+	dhcp_ipv4_option ( find_global_dhcp_option ( tag ), inp );
516
+}
517
+
463 518
 /**
464 519
  * Delete DHCP option
465 520
  *

+ 40
- 1
src/tests/dhcptest.c Voir le fichier

@@ -1,10 +1,49 @@
1 1
 #include <string.h>
2
+#include <vsprintf.h>
3
+#include <byteswap.h>
4
+#include <gpxe/ip.h>
2 5
 #include <gpxe/dhcp.h>
3 6
 
4 7
 int test_dhcp ( struct net_device *netdev ) {
5 8
 	struct dhcp_session dhcp;
9
+	struct in_addr address = { htonl ( 0 ) };
10
+	struct in_addr netmask = { htonl ( 0 ) };
11
+	struct in_addr gateway = { INADDR_NONE };
12
+	int rc;
6 13
 
14
+	/* Bring IP interface up with address 0.0.0.0 */
15
+	if ( ( rc = add_ipv4_address ( netdev, address, netmask,
16
+				       gateway ) ) != 0 )
17
+		goto out_no_del_ipv4;
18
+
19
+	/* Issue DHCP request */
7 20
 	memset ( &dhcp, 0, sizeof ( dhcp ) );
8 21
 	dhcp.netdev = netdev;
9
-	return async_wait ( start_dhcp ( &dhcp ) );
22
+	if ( ( rc = async_wait ( start_dhcp ( &dhcp ) ) ) != 0 )
23
+		goto out_no_options;
24
+
25
+	/* Retrieve IP address configuration */
26
+	find_dhcp_ipv4_option ( dhcp.options, DHCP_EB_YIADDR, &address );
27
+	find_dhcp_ipv4_option ( dhcp.options, DHCP_SUBNET_MASK, &netmask );
28
+	find_dhcp_ipv4_option ( dhcp.options, DHCP_ROUTERS, &gateway );
29
+
30
+	/* Remove old IP address configuration */
31
+	del_ipv4_address ( netdev );
32
+
33
+	/* Set up new IP address configuration */
34
+	if ( ( rc = add_ipv4_address ( netdev, address, netmask,
35
+				       gateway ) ) != 0 )
36
+		goto out_no_del_ipv4;
37
+
38
+	printf ( "IP %s", inet_ntoa ( address ) );
39
+	printf ( " netmask %s", inet_ntoa ( netmask ) );
40
+	printf ( " gateway %s\n", inet_ntoa ( gateway ) );
41
+
42
+	/* Free DHCP options */
43
+	free_dhcp_options ( dhcp.options );
44
+ out_no_options:
45
+	/* Take down IP interface */
46
+	del_ipv4_address ( netdev );
47
+ out_no_del_ipv4:
48
+	return rc;
10 49
 }

Chargement…
Annuler
Enregistrer