浏览代码

[dhcp] Verify DHCP server source port

Verifying server ID and DHCP transaction ID is insufficient to
differentiate between DHCPACK and ProxyDHCPACK when the DHCP server and
Proxy DHCP server are the same machine.
tags/v0.9.4
Michael Brown 17 年前
父节点
当前提交
6f39dfe6c0
共有 1 个文件被更改,包括 45 次插入16 次删除
  1. 45
    16
      src/net/udp/dhcp.c

+ 45
- 16
src/net/udp/dhcp.c 查看文件

865
  * Receive new data
865
  * Receive new data
866
  *
866
  *
867
  * @v xfer 		Data transfer interface
867
  * @v xfer 		Data transfer interface
868
- * @v data		Received data
869
- * @v len		Length of received data
868
+ * @v iobuf		I/O buffer
869
+ * @v meta		Transfer metadata
870
  * @ret rc		Return status code
870
  * @ret rc		Return status code
871
  */
871
  */
872
-static int dhcp_deliver_raw ( struct xfer_interface *xfer,
873
-			      const void *data, size_t len ) {
872
+static int dhcp_deliver_iob ( struct xfer_interface *xfer,
873
+			      struct io_buffer *iobuf,
874
+			      struct xfer_metadata *meta ) {
874
 	struct dhcp_session *dhcp =
875
 	struct dhcp_session *dhcp =
875
 		container_of ( xfer, struct dhcp_session, xfer );
876
 		container_of ( xfer, struct dhcp_session, xfer );
877
+	struct sockaddr_tcpip *st_src;
878
+	unsigned int src_port;
876
 	struct dhcp_settings *dhcpset;
879
 	struct dhcp_settings *dhcpset;
877
 	struct dhcphdr *dhcphdr;
880
 	struct dhcphdr *dhcphdr;
878
 	uint8_t msgtype = 0;
881
 	uint8_t msgtype = 0;
882
+	int rc = 0;
883
+
884
+	/* Sanity checks */
885
+	if ( ! meta ) {
886
+		DBGC ( dhcp, "DHCP %p received packet without metadata\n",
887
+		       dhcp );
888
+		rc = -EINVAL;
889
+		goto err_no_meta;
890
+	}
891
+	if ( ! meta->src ) {
892
+		DBGC ( dhcp, "DHCP %p received packet without source port\n",
893
+		       dhcp );
894
+		rc = -EINVAL;
895
+		goto err_no_src;
896
+	}
897
+	st_src = ( struct sockaddr_tcpip * ) meta->src;
898
+	src_port = st_src->st_port;
879
 
899
 
880
 	/* Convert packet into a DHCP settings block */
900
 	/* Convert packet into a DHCP settings block */
881
-	dhcpset = dhcpset_create ( data, len );
901
+	dhcpset = dhcpset_create ( iobuf->data, iob_len ( iobuf ) );
882
 	if ( ! dhcpset ) {
902
 	if ( ! dhcpset ) {
883
 		DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp );
903
 		DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp );
884
-		return -ENOMEM;
904
+		rc = -ENOMEM;
905
+		goto err_dhcpset_create;
885
 	}
906
 	}
886
 	dhcphdr = dhcpset->dhcppkt.dhcphdr;
907
 	dhcphdr = dhcpset->dhcppkt.dhcphdr;
887
 
908
 
888
 	/* Identify message type */
909
 	/* Identify message type */
889
 	dhcppkt_fetch ( &dhcpset->dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
910
 	dhcppkt_fetch ( &dhcpset->dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
890
 			sizeof ( msgtype ) );
911
 			sizeof ( msgtype ) );
891
-	DBGC ( dhcp, "DHCP %p received %s %p\n",
892
-	       dhcp, dhcp_msgtype_name ( msgtype ), dhcpset );
912
+	DBGC ( dhcp, "DHCP %p received %s %p from port %d\n", dhcp,
913
+	       dhcp_msgtype_name ( msgtype ), dhcpset, ntohs ( src_port ) );
893
 
914
 
894
 	/* Check for matching transaction ID */
915
 	/* Check for matching transaction ID */
895
 	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
916
 	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
896
 		DBGC ( dhcp, "DHCP %p received %s %p has bad transaction ID\n",
917
 		DBGC ( dhcp, "DHCP %p received %s %p has bad transaction ID\n",
897
 		       dhcp, dhcp_msgtype_name ( msgtype ), dhcpset );
918
 		       dhcp, dhcp_msgtype_name ( msgtype ), dhcpset );
898
-		goto out;
919
+		rc = -EINVAL;
920
+		goto err_xid;
899
 	};
921
 	};
900
 
922
 
901
 	/* Handle packet based on current state */
923
 	/* Handle packet based on current state */
902
 	switch ( dhcp->state ) {
924
 	switch ( dhcp->state ) {
903
 	case DHCP_STATE_DISCOVER:
925
 	case DHCP_STATE_DISCOVER:
904
-		if ( msgtype == DHCPOFFER )
926
+		if ( ( msgtype == DHCPOFFER ) &&
927
+		     ( src_port == htons ( BOOTPS_PORT ) ) )
905
 			dhcp_rx_dhcpoffer ( dhcp, dhcpset );
928
 			dhcp_rx_dhcpoffer ( dhcp, dhcpset );
906
 		break;
929
 		break;
907
 	case DHCP_STATE_REQUEST:
930
 	case DHCP_STATE_REQUEST:
908
-		if ( msgtype == DHCPACK )
931
+		if ( ( msgtype == DHCPACK ) &&
932
+		     ( src_port == htons ( BOOTPS_PORT ) ) )
909
 			dhcp_rx_dhcpack ( dhcp, dhcpset );
933
 			dhcp_rx_dhcpack ( dhcp, dhcpset );
910
 		break;
934
 		break;
911
 	case DHCP_STATE_PROXYREQUEST:
935
 	case DHCP_STATE_PROXYREQUEST:
912
-		if ( msgtype == DHCPACK )
936
+		if ( ( msgtype == DHCPACK ) &&
937
+		     ( src_port == htons ( PROXYDHCP_PORT ) ) )
913
 			dhcp_rx_proxydhcpack ( dhcp, dhcpset );
938
 			dhcp_rx_proxydhcpack ( dhcp, dhcpset );
914
 		break;
939
 		break;
915
 	default:
940
 	default:
917
 		break;
942
 		break;
918
 	}
943
 	}
919
 
944
 
920
- out:
945
+ err_xid:
921
 	dhcpset_put ( dhcpset );
946
 	dhcpset_put ( dhcpset );
922
-	return 0;
947
+ err_dhcpset_create:
948
+ err_no_src:
949
+ err_no_meta:
950
+	free_iob ( iobuf );
951
+	return rc;
923
 }
952
 }
924
 
953
 
925
 /** DHCP data transfer interface operations */
954
 /** DHCP data transfer interface operations */
928
 	.vredirect	= xfer_vopen,
957
 	.vredirect	= xfer_vopen,
929
 	.window		= unlimited_xfer_window,
958
 	.window		= unlimited_xfer_window,
930
 	.alloc_iob	= default_xfer_alloc_iob,
959
 	.alloc_iob	= default_xfer_alloc_iob,
931
-	.deliver_iob	= xfer_deliver_as_raw,
932
-	.deliver_raw	= dhcp_deliver_raw,
960
+	.deliver_iob	= dhcp_deliver_iob,
961
+	.deliver_raw	= xfer_deliver_as_iob,
933
 };
962
 };
934
 
963
 
935
 /**
964
 /**

正在加载...
取消
保存