|
@@ -867,20 +867,24 @@ static struct dhcp_session_state dhcp_state_pxebs = {
|
867
|
867
|
* Construct DHCP client hardware address field and broadcast flag
|
868
|
868
|
*
|
869
|
869
|
* @v netdev Network device
|
870
|
|
- * @v hlen DHCP hardware address length to fill in
|
871
|
|
- * @v flags DHCP flags to fill in
|
872
|
|
- * @ret chaddr DHCP client hardware address
|
|
870
|
+ * @v chaddr Hardware address buffer
|
|
871
|
+ * @v flags Flags to set (or NULL)
|
|
872
|
+ * @ret hlen Hardware address length
|
873
|
873
|
*/
|
874
|
|
-void * dhcp_chaddr ( struct net_device *netdev, uint8_t *hlen,
|
875
|
|
- uint16_t *flags ) {
|
|
874
|
+unsigned int dhcp_chaddr ( struct net_device *netdev, void *chaddr,
|
|
875
|
+ uint16_t *flags ) {
|
876
|
876
|
struct ll_protocol *ll_protocol = netdev->ll_protocol;
|
877
|
|
- typeof ( ( ( struct dhcphdr * ) NULL )->chaddr ) chaddr;
|
|
877
|
+ struct dhcphdr *dhcphdr;
|
|
878
|
+ int rc;
|
878
|
879
|
|
879
|
880
|
/* If the link-layer address cannot fit into the chaddr field
|
880
|
|
- * (as is the case for IPoIB) then try using the hardware
|
881
|
|
- * address instead. If we do this, set the broadcast flag,
|
882
|
|
- * since chaddr then does not represent a valid link-layer
|
883
|
|
- * address for the return path.
|
|
881
|
+ * (as is the case for IPoIB) then try using the Ethernet-
|
|
882
|
+ * compatible link-layer address. If we do this, set the
|
|
883
|
+ * broadcast flag, since chaddr then does not represent a
|
|
884
|
+ * valid link-layer address for the return path.
|
|
885
|
+ *
|
|
886
|
+ * If we cannot produce an Ethernet-compatible link-layer
|
|
887
|
+ * address, try using the hardware address.
|
884
|
888
|
*
|
885
|
889
|
* If even the hardware address is too large, use an empty
|
886
|
890
|
* chaddr field and set the broadcast flag.
|
|
@@ -891,16 +895,19 @@ void * dhcp_chaddr ( struct net_device *netdev, uint8_t *hlen,
|
891
|
895
|
* storage, or by eliminating the hardware address completely
|
892
|
896
|
* from the DHCP packet, which seems unfriendly to users.
|
893
|
897
|
*/
|
894
|
|
- if ( ( *hlen = ll_protocol->ll_addr_len ) <= sizeof ( chaddr ) ) {
|
895
|
|
- return netdev->ll_addr;
|
|
898
|
+ if ( ll_protocol->ll_addr_len <= sizeof ( dhcphdr->chaddr ) ) {
|
|
899
|
+ memcpy ( chaddr, netdev->ll_addr, ll_protocol->ll_addr_len );
|
|
900
|
+ return ll_protocol->ll_addr_len;
|
896
|
901
|
}
|
897
|
|
- *flags = htons ( BOOTP_FL_BROADCAST );
|
898
|
|
- if ( ( *hlen = ll_protocol->hw_addr_len ) <= sizeof ( chaddr ) ) {
|
899
|
|
- return netdev->hw_addr;
|
900
|
|
- } else {
|
901
|
|
- *hlen = 0;
|
902
|
|
- return NULL;
|
|
902
|
+ if ( flags )
|
|
903
|
+ *flags |= htons ( BOOTP_FL_BROADCAST );
|
|
904
|
+ if ( ( rc = ll_protocol->eth_addr ( netdev->ll_addr, chaddr ) ) == 0 )
|
|
905
|
+ return ETH_ALEN;
|
|
906
|
+ if ( ll_protocol->hw_addr_len <= sizeof ( dhcphdr->chaddr ) ) {
|
|
907
|
+ memcpy ( chaddr, netdev->hw_addr, ll_protocol->hw_addr_len );
|
|
908
|
+ return ll_protocol->hw_addr_len;
|
903
|
909
|
}
|
|
910
|
+ return 0;
|
904
|
911
|
}
|
905
|
912
|
|
906
|
913
|
/**
|
|
@@ -923,7 +930,6 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
|
923
|
930
|
const void *options, size_t options_len,
|
924
|
931
|
void *data, size_t max_len ) {
|
925
|
932
|
struct dhcphdr *dhcphdr = data;
|
926
|
|
- void *chaddr;
|
927
|
933
|
int rc;
|
928
|
934
|
|
929
|
935
|
/* Sanity check */
|
|
@@ -936,8 +942,8 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
|
936
|
942
|
dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
|
937
|
943
|
dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto );
|
938
|
944
|
dhcphdr->op = dhcp_op[msgtype];
|
939
|
|
- chaddr = dhcp_chaddr ( netdev, &dhcphdr->hlen, &dhcphdr->flags );
|
940
|
|
- memcpy ( dhcphdr->chaddr, chaddr, dhcphdr->hlen );
|
|
945
|
+ dhcphdr->hlen = dhcp_chaddr ( netdev, dhcphdr->chaddr,
|
|
946
|
+ &dhcphdr->flags );
|
941
|
947
|
memcpy ( dhcphdr->options, options, options_len );
|
942
|
948
|
|
943
|
949
|
/* Initialise DHCP packet structure */
|