Browse Source

[dhcp] Verify server identifier on ProxyDHCPACKs

Perform the same test for a matching DHCP_SERVER_IDENTIFIER on
ProxyDHCPACKs as we do for DHCPACKs.  Otherwise, a retransmitted
DHCPACK can end up being treated as the ProxyDHCPACK.

I have a vague and unsettling memory that this test was deliberately
omitted, but I can't remember why, and can't find anything in the VC
logs.
tags/v0.9.4
Michael Brown 16 years ago
parent
commit
fdb8481de1
1 changed files with 25 additions and 7 deletions
  1. 25
    7
      src/net/udp/dhcp.c

+ 25
- 7
src/net/udp/dhcp.c View File

685
  */
685
  */
686
 static void dhcp_rx_dhcpoffer ( struct dhcp_session *dhcp,
686
 static void dhcp_rx_dhcpoffer ( struct dhcp_session *dhcp,
687
 				struct dhcp_settings *dhcpoffer ) {
687
 				struct dhcp_settings *dhcpoffer ) {
688
+	struct in_addr server_id;
688
 	char vci[9]; /* "PXEClient" */
689
 	char vci[9]; /* "PXEClient" */
689
 	int len;
690
 	int len;
690
 	uint8_t ignore_proxy = 0;
691
 	uint8_t ignore_proxy = 0;
692
 
693
 
693
 	/* Check for presence of DHCP server ID */
694
 	/* Check for presence of DHCP server ID */
694
 	if ( dhcppkt_fetch ( &dhcpoffer->dhcppkt, DHCP_SERVER_IDENTIFIER,
695
 	if ( dhcppkt_fetch ( &dhcpoffer->dhcppkt, DHCP_SERVER_IDENTIFIER,
695
-			     NULL, 0 ) != sizeof ( struct in_addr ) ) {
696
+			     &server_id, sizeof ( server_id ) )
697
+	     != sizeof ( server_id ) ) {
696
 		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p missing server "
698
 		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p missing server "
697
 		       "identifier\n", dhcp, dhcpoffer );
699
 		       "identifier\n", dhcp, dhcpoffer );
698
 		return;
700
 		return;
700
 
702
 
701
 	/* If there is an IP address, it's a normal DHCPOFFER */
703
 	/* If there is an IP address, it's a normal DHCPOFFER */
702
 	if ( dhcpoffer->dhcppkt.dhcphdr->yiaddr.s_addr != 0 ) {
704
 	if ( dhcpoffer->dhcppkt.dhcphdr->yiaddr.s_addr != 0 ) {
703
-		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p has IP address\n",
704
-		       dhcp, dhcpoffer );
705
+		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p from %s has IP "
706
+		       "address\n",
707
+		       dhcp, dhcpoffer, inet_ntoa ( server_id ) );
705
 		dhcp_store_dhcpoffer ( dhcp, dhcpoffer, &dhcp->dhcpoffer );
708
 		dhcp_store_dhcpoffer ( dhcp, dhcpoffer, &dhcp->dhcpoffer );
706
 	}
709
 	}
707
 
710
 
713
 			      vci, sizeof ( vci ) );
716
 			      vci, sizeof ( vci ) );
714
 	if ( ( len >= ( int ) sizeof ( vci ) ) &&
717
 	if ( ( len >= ( int ) sizeof ( vci ) ) &&
715
 	     ( strncmp ( "PXEClient", vci, sizeof ( vci ) ) == 0 ) ) {
718
 	     ( strncmp ( "PXEClient", vci, sizeof ( vci ) ) == 0 ) ) {
716
-		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p is a "
717
-		       "ProxyDHCPOFFER\n", dhcp, dhcpoffer );
719
+		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p from %s is a "
720
+		       "ProxyDHCPOFFER\n",
721
+		       dhcp, dhcpoffer, inet_ntoa ( server_id ) );
718
 		dhcp_store_dhcpoffer ( dhcp, dhcpoffer,
722
 		dhcp_store_dhcpoffer ( dhcp, dhcpoffer,
719
 				       &dhcp->proxydhcpoffer );
723
 				       &dhcp->proxydhcpoffer );
720
 	}
724
 	}
802
 	dhcppkt_fetch ( &dhcpack->dhcppkt, DHCP_SERVER_IDENTIFIER,
806
 	dhcppkt_fetch ( &dhcpack->dhcppkt, DHCP_SERVER_IDENTIFIER,
803
 			&ack_server_id, sizeof ( ack_server_id ) );
807
 			&ack_server_id, sizeof ( ack_server_id ) );
804
 	if ( offer_server_id.s_addr != ack_server_id.s_addr ) {
808
 	if ( offer_server_id.s_addr != ack_server_id.s_addr ) {
805
-		DBGC ( dhcp, "DHCP %p ignoring DHCPACK with wrong server ID\n",
806
-		       dhcp );
809
+		DBGC ( dhcp, "DHCP %p ignoring DHCPACK with wrong server ID "
810
+		       "%s\n", dhcp, inet_ntoa ( ack_server_id ) );
807
 		return;
811
 		return;
808
 	}
812
 	}
809
 
813
 
830
  */
834
  */
831
 static void dhcp_rx_proxydhcpack ( struct dhcp_session *dhcp,
835
 static void dhcp_rx_proxydhcpack ( struct dhcp_session *dhcp,
832
 				   struct dhcp_settings *proxydhcpack ) {
836
 				   struct dhcp_settings *proxydhcpack ) {
837
+	struct in_addr offer_server_id = { 0 };
838
+	struct in_addr ack_server_id = { 0 };
833
 	int rc;
839
 	int rc;
834
 
840
 
841
+	/* Verify server ID matches */
842
+	assert ( dhcp->proxydhcpoffer != NULL );
843
+	dhcppkt_fetch ( &dhcp->proxydhcpoffer->dhcppkt, DHCP_SERVER_IDENTIFIER,
844
+			&offer_server_id, sizeof ( offer_server_id ) );
845
+	dhcppkt_fetch ( &proxydhcpack->dhcppkt, DHCP_SERVER_IDENTIFIER,
846
+			&ack_server_id, sizeof ( ack_server_id ) );
847
+	if ( offer_server_id.s_addr != ack_server_id.s_addr ) {
848
+		DBGC ( dhcp, "DHCP %p ignoring ProxyDHCPACK with wrong server "
849
+		       "ID %s\n", dhcp, inet_ntoa ( ack_server_id ) );
850
+		return;
851
+	}
852
+
835
 	/* Rename settings */
853
 	/* Rename settings */
836
 	proxydhcpack->settings.name = PROXYDHCP_SETTINGS_NAME;
854
 	proxydhcpack->settings.name = PROXYDHCP_SETTINGS_NAME;
837
 
855
 

Loading…
Cancel
Save