Browse Source

Add dhcp_configure_netdev()

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
1ec7bb789d
2 changed files with 65 additions and 4 deletions
  1. 4
    1
      src/include/gpxe/dhcp.h
  2. 61
    3
      src/net/udp/dhcp.c

+ 4
- 1
src/include/gpxe/dhcp.h View File

@@ -513,6 +513,9 @@ extern int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
513 513
 extern int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
514 514
 				      struct dhcp_option_block *options );
515 515
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev,
516
-			int (*register_options) ( struct dhcp_option_block * ));
516
+			int (*register_options) ( struct net_device *,
517
+						  struct dhcp_option_block * ));
518
+extern int dhcp_configure_netdev ( struct net_device *netdev,
519
+				   struct dhcp_option_block *options );
517 520
 
518 521
 #endif /* _GPXE_DHCP_H */

+ 61
- 3
src/net/udp/dhcp.c View File

@@ -27,6 +27,8 @@
27 27
 #include <gpxe/open.h>
28 28
 #include <gpxe/job.h>
29 29
 #include <gpxe/retry.h>
30
+#include <gpxe/tcpip.h>
31
+#include <gpxe/ip.h>
30 32
 #include <gpxe/dhcp.h>
31 33
 
32 34
 /** @file
@@ -502,7 +504,8 @@ struct dhcp_session {
502 504
 	/** Network device being configured */
503 505
 	struct net_device *netdev;
504 506
 	/** Option block registration routine */
505
-	int ( * register_options ) ( struct dhcp_option_block *options );
507
+	int ( * register_options ) ( struct net_device *netdev,
508
+				     struct dhcp_option_block *options );
506 509
 
507 510
 	/** State of the session
508 511
 	 *
@@ -717,7 +720,7 @@ static int dhcp_deliver_raw ( struct xfer_interface *xfer,
717 720
 	if ( dhcp->state < DHCPACK ) {
718 721
 		dhcp_send_request ( dhcp );
719 722
 	} else {
720
-		dhcp->register_options ( dhcp->options );
723
+		dhcp->register_options ( dhcp->netdev, dhcp->options );
721 724
 		dhcp_finished ( dhcp, 0 );
722 725
 	}
723 726
 	return 0;
@@ -782,7 +785,8 @@ static struct job_interface_operations dhcp_job_operations = {
782 785
  * options.
783 786
  */
784 787
 int start_dhcp ( struct job_interface *job, struct net_device *netdev,
785
-		 int ( * register_options ) ( struct dhcp_option_block * ) ) {
788
+		 int ( * register_options ) ( struct net_device *netdev,
789
+					      struct dhcp_option_block * ) ) {
786 790
 	static struct sockaddr_in server = {
787 791
 		.sin_family = AF_INET,
788 792
 		.sin_addr.s_addr = INADDR_BROADCAST,
@@ -827,3 +831,57 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev,
827 831
 	ref_put ( &dhcp->refcnt );
828 832
 	return rc;
829 833
 }
834
+
835
+/****************************************************************************
836
+ *
837
+ * Network device configurator
838
+ *
839
+ */
840
+
841
+/* Avoid dragging in dns.o */
842
+struct sockaddr_tcpip nameserver;
843
+
844
+/* Avoid dragging in syslog.o */
845
+struct in_addr syslogserver;
846
+
847
+/**
848
+ * Configure network device from DHCP options
849
+ *
850
+ * @v netdev		Network device
851
+ * @v options		DHCP options block
852
+ * @ret rc		Return status code
853
+ */
854
+int dhcp_configure_netdev ( struct net_device *netdev,
855
+			    struct dhcp_option_block *options ) {
856
+	struct in_addr address = { 0 };
857
+	struct in_addr netmask = { 0 };
858
+	struct in_addr gateway = { INADDR_NONE };
859
+	struct sockaddr_in *sin_nameserver;
860
+	int rc;
861
+
862
+	/* Clear any existing routing table entry */
863
+	del_ipv4_address ( netdev );
864
+
865
+	/* Retrieve IP address configuration */
866
+	find_dhcp_ipv4_option ( options, DHCP_EB_YIADDR, &address );
867
+	find_dhcp_ipv4_option ( options, DHCP_SUBNET_MASK, &netmask );
868
+	find_dhcp_ipv4_option ( options, DHCP_ROUTERS, &gateway );
869
+
870
+	/* Set up new IP address configuration */
871
+	if ( ( rc = add_ipv4_address ( netdev, address, netmask,
872
+				       gateway ) ) != 0 ) {
873
+		DBG ( "Could not configure %s with DHCP results: %s\n",
874
+		      netdev->name, strerror ( rc ) );
875
+		return rc;
876
+	}
877
+
878
+	/* Retrieve other DHCP options that we care about */
879
+	sin_nameserver = ( struct sockaddr_in * ) &nameserver;
880
+	sin_nameserver->sin_family = AF_INET;
881
+	find_dhcp_ipv4_option ( options, DHCP_DNS_SERVERS,
882
+				&sin_nameserver->sin_addr );
883
+	find_dhcp_ipv4_option ( options, DHCP_LOG_SERVERS,
884
+				&syslogserver );
885
+
886
+	return 0;
887
+}

Loading…
Cancel
Save