|
@@ -865,51 +865,76 @@ static void dhcp_rx_proxydhcpack ( struct dhcp_session *dhcp,
|
865
|
865
|
* Receive new data
|
866
|
866
|
*
|
867
|
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
|
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
|
875
|
struct dhcp_session *dhcp =
|
875
|
876
|
container_of ( xfer, struct dhcp_session, xfer );
|
|
877
|
+ struct sockaddr_tcpip *st_src;
|
|
878
|
+ unsigned int src_port;
|
876
|
879
|
struct dhcp_settings *dhcpset;
|
877
|
880
|
struct dhcphdr *dhcphdr;
|
878
|
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
|
900
|
/* Convert packet into a DHCP settings block */
|
881
|
|
- dhcpset = dhcpset_create ( data, len );
|
|
901
|
+ dhcpset = dhcpset_create ( iobuf->data, iob_len ( iobuf ) );
|
882
|
902
|
if ( ! dhcpset ) {
|
883
|
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
|
907
|
dhcphdr = dhcpset->dhcppkt.dhcphdr;
|
887
|
908
|
|
888
|
909
|
/* Identify message type */
|
889
|
910
|
dhcppkt_fetch ( &dhcpset->dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
|
890
|
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
|
915
|
/* Check for matching transaction ID */
|
895
|
916
|
if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
|
896
|
917
|
DBGC ( dhcp, "DHCP %p received %s %p has bad transaction ID\n",
|
897
|
918
|
dhcp, dhcp_msgtype_name ( msgtype ), dhcpset );
|
898
|
|
- goto out;
|
|
919
|
+ rc = -EINVAL;
|
|
920
|
+ goto err_xid;
|
899
|
921
|
};
|
900
|
922
|
|
901
|
923
|
/* Handle packet based on current state */
|
902
|
924
|
switch ( dhcp->state ) {
|
903
|
925
|
case DHCP_STATE_DISCOVER:
|
904
|
|
- if ( msgtype == DHCPOFFER )
|
|
926
|
+ if ( ( msgtype == DHCPOFFER ) &&
|
|
927
|
+ ( src_port == htons ( BOOTPS_PORT ) ) )
|
905
|
928
|
dhcp_rx_dhcpoffer ( dhcp, dhcpset );
|
906
|
929
|
break;
|
907
|
930
|
case DHCP_STATE_REQUEST:
|
908
|
|
- if ( msgtype == DHCPACK )
|
|
931
|
+ if ( ( msgtype == DHCPACK ) &&
|
|
932
|
+ ( src_port == htons ( BOOTPS_PORT ) ) )
|
909
|
933
|
dhcp_rx_dhcpack ( dhcp, dhcpset );
|
910
|
934
|
break;
|
911
|
935
|
case DHCP_STATE_PROXYREQUEST:
|
912
|
|
- if ( msgtype == DHCPACK )
|
|
936
|
+ if ( ( msgtype == DHCPACK ) &&
|
|
937
|
+ ( src_port == htons ( PROXYDHCP_PORT ) ) )
|
913
|
938
|
dhcp_rx_proxydhcpack ( dhcp, dhcpset );
|
914
|
939
|
break;
|
915
|
940
|
default:
|
|
@@ -917,9 +942,13 @@ static int dhcp_deliver_raw ( struct xfer_interface *xfer,
|
917
|
942
|
break;
|
918
|
943
|
}
|
919
|
944
|
|
920
|
|
- out:
|
|
945
|
+ err_xid:
|
921
|
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
|
954
|
/** DHCP data transfer interface operations */
|
|
@@ -928,8 +957,8 @@ static struct xfer_interface_operations dhcp_xfer_operations = {
|
928
|
957
|
.vredirect = xfer_vopen,
|
929
|
958
|
.window = unlimited_xfer_window,
|
930
|
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
|
/**
|