Browse Source

Added dhcp_ipv4_option() and friends.

Added test code to configure the interface for IPv4 after DHCP.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
00a1f000b1
3 changed files with 102 additions and 1 deletions
  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 View File

250
 		uint8_t byte;
250
 		uint8_t byte;
251
 		uint16_t word;
251
 		uint16_t word;
252
 		uint32_t dword;
252
 		uint32_t dword;
253
+		struct in_addr in;
253
 		uint8_t bytes[0];
254
 		uint8_t bytes[0];
254
 	} data;
255
 	} data;
255
 } __attribute__ (( packed ));
256
 } __attribute__ (( packed ));
429
 };
430
 };
430
 
431
 
431
 extern unsigned long dhcp_num_option ( struct dhcp_option *option );
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
 extern struct dhcp_option *
435
 extern struct dhcp_option *
433
 find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
436
 find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
434
 extern void register_dhcp_options ( struct dhcp_option_block *options );
437
 extern void register_dhcp_options ( struct dhcp_option_block *options );
444
 extern unsigned long find_dhcp_num_option ( struct dhcp_option_block *options,
447
 extern unsigned long find_dhcp_num_option ( struct dhcp_option_block *options,
445
 					    unsigned int tag );
448
 					    unsigned int tag );
446
 extern unsigned long find_global_dhcp_num_option ( unsigned int tag );
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
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
454
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
448
 				 unsigned int tag );
455
 				 unsigned int tag );
449
 
456
 

+ 55
- 0
src/net/dhcpopts.c View File

24
 #include <assert.h>
24
 #include <assert.h>
25
 #include <vsprintf.h>
25
 #include <vsprintf.h>
26
 #include <gpxe/list.h>
26
 #include <gpxe/list.h>
27
+#include <gpxe/in.h>
27
 #include <gpxe/dhcp.h>
28
 #include <gpxe/dhcp.h>
28
 
29
 
29
 /** @file
30
 /** @file
85
 	return value;
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
  * Calculate length of a normal DHCP option
105
  * Calculate length of a normal DHCP option
90
  *
106
  *
460
 	return dhcp_num_option ( find_global_dhcp_option ( tag ) );
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
  * Delete DHCP option
519
  * Delete DHCP option
465
  *
520
  *

+ 40
- 1
src/tests/dhcptest.c View File

1
 #include <string.h>
1
 #include <string.h>
2
+#include <vsprintf.h>
3
+#include <byteswap.h>
4
+#include <gpxe/ip.h>
2
 #include <gpxe/dhcp.h>
5
 #include <gpxe/dhcp.h>
3
 
6
 
4
 int test_dhcp ( struct net_device *netdev ) {
7
 int test_dhcp ( struct net_device *netdev ) {
5
 	struct dhcp_session dhcp;
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
 	memset ( &dhcp, 0, sizeof ( dhcp ) );
20
 	memset ( &dhcp, 0, sizeof ( dhcp ) );
8
 	dhcp.netdev = netdev;
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
 }

Loading…
Cancel
Save