@@ -116,6 +116,14 @@ struct setting use_cached_setting __setting ( SETTING_MISC ) = {
116
116
.type = & setting_type_uint8 ,
117
117
};
118
118
119
+ /**
120
+ * Most recent DHCP transaction ID
121
+ *
122
+ * This is exposed for use by the fakedhcp code when reconstructing
123
+ * DHCP packets for PXE NBPs.
124
+ */
125
+ uint32_t dhcp_last_xid ;
126
+
119
127
/**
120
128
* Name a DHCP packet type
121
129
*
@@ -137,23 +145,6 @@ static inline const char * dhcp_msgtype_name ( unsigned int msgtype ) {
137
145
}
138
146
}
139
147
140
- /**
141
- * Calculate DHCP transaction ID for a network device
142
- *
143
- * @v netdev Network device
144
- * @ret xid DHCP XID
145
- *
146
- * Extract the least significant bits of the hardware address for use
147
- * as the transaction ID.
148
- */
149
- static uint32_t dhcp_xid ( struct net_device * netdev ) {
150
- uint32_t xid ;
151
-
152
- memcpy ( & xid , ( netdev -> ll_addr + netdev -> ll_protocol -> ll_addr_len
153
- - sizeof ( xid ) ), sizeof ( xid ) );
154
- return xid ;
155
- }
156
-
157
148
/****************************************************************************
158
149
*
159
150
* DHCP session
@@ -219,6 +210,8 @@ struct dhcp_session {
219
210
struct sockaddr_in local ;
220
211
/** State of the session */
221
212
struct dhcp_session_state * state ;
213
+ /** Transaction ID (in network-endian order) */
214
+ uint32_t xid ;
222
215
223
216
/** Offered IP address */
224
217
struct in_addr offer ;
@@ -916,6 +909,7 @@ unsigned int dhcp_chaddr ( struct net_device *netdev, void *chaddr,
916
909
* @v dhcppkt DHCP packet structure to fill in
917
910
* @v netdev Network device
918
911
* @v msgtype DHCP message type
912
+ * @v xid Transaction ID (in network-endian order)
919
913
* @v options Initial options to include (or NULL)
920
914
* @v options_len Length of initial options
921
915
* @v data Buffer for DHCP packet
@@ -927,7 +921,7 @@ unsigned int dhcp_chaddr ( struct net_device *netdev, void *chaddr,
927
921
*/
928
922
int dhcp_create_packet ( struct dhcp_packet * dhcppkt ,
929
923
struct net_device * netdev , uint8_t msgtype ,
930
- const void * options , size_t options_len ,
924
+ uint32_t xid , const void * options , size_t options_len ,
931
925
void * data , size_t max_len ) {
932
926
struct dhcphdr * dhcphdr = data ;
933
927
int rc ;
@@ -938,7 +932,7 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
938
932
939
933
/* Initialise DHCP packet content */
940
934
memset ( dhcphdr , 0 , max_len );
941
- dhcphdr -> xid = dhcp_xid ( netdev ) ;
935
+ dhcphdr -> xid = xid ;
942
936
dhcphdr -> magic = htonl ( DHCP_MAGIC_COOKIE );
943
937
dhcphdr -> htype = ntohs ( netdev -> ll_protocol -> ll_proto );
944
938
dhcphdr -> op = dhcp_op [msgtype ];
@@ -964,6 +958,7 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
964
958
* @v dhcppkt DHCP packet structure to fill in
965
959
* @v netdev Network device
966
960
* @v msgtype DHCP message type
961
+ * @v xid Transaction ID (in network-endian order)
967
962
* @v ciaddr Client IP address
968
963
* @v data Buffer for DHCP packet
969
964
* @v max_len Size of DHCP packet buffer
@@ -974,7 +969,8 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
974
969
*/
975
970
int dhcp_create_request ( struct dhcp_packet * dhcppkt ,
976
971
struct net_device * netdev , unsigned int msgtype ,
977
- struct in_addr ciaddr , void * data , size_t max_len ) {
972
+ uint32_t xid , struct in_addr ciaddr ,
973
+ void * data , size_t max_len ) {
978
974
struct dhcp_netdev_desc dhcp_desc ;
979
975
struct dhcp_client_id client_id ;
980
976
struct dhcp_client_uuid client_uuid ;
@@ -985,7 +981,7 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt,
985
981
int rc ;
986
982
987
983
/* Create DHCP packet */
988
- if ( ( rc = dhcp_create_packet ( dhcppkt , netdev , msgtype ,
984
+ if ( ( rc = dhcp_create_packet ( dhcppkt , netdev , msgtype , xid ,
989
985
dhcp_request_options_data ,
990
986
sizeof ( dhcp_request_options_data ),
991
987
data , max_len ) ) != 0 ) {
@@ -1099,7 +1095,8 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
1099
1095
1100
1096
/* Create basic DHCP packet in temporary buffer */
1101
1097
if ( ( rc = dhcp_create_request ( & dhcppkt , dhcp -> netdev , msgtype ,
1102
- dhcp -> local .sin_addr , iobuf -> data ,
1098
+ dhcp -> xid , dhcp -> local .sin_addr ,
1099
+ iobuf -> data ,
1103
1100
iob_tailroom ( iobuf ) ) ) != 0 ) {
1104
1101
DBGC ( dhcp , "DHCP %p could not construct DHCP request: %s\n" ,
1105
1102
dhcp , strerror ( rc ) );
@@ -1187,7 +1184,7 @@ static int dhcp_deliver ( struct dhcp_session *dhcp,
1187
1184
& server_id , sizeof ( server_id ) );
1188
1185
1189
1186
/* Check for matching transaction ID */
1190
- if ( dhcphdr -> xid != dhcp_xid ( dhcp -> netdev ) ) {
1187
+ if ( dhcphdr -> xid != dhcp -> xid ) {
1191
1188
DBGC ( dhcp , "DHCP %p %s from %s:%d has bad transaction "
1192
1189
"ID\n" , dhcp , dhcp_msgtype_name ( msgtype ),
1193
1190
inet_ntoa ( peer -> sin_addr ),
@@ -1311,6 +1308,10 @@ int start_dhcp ( struct interface *job, struct net_device *netdev ) {
1311
1308
dhcp -> netdev = netdev_get ( netdev );
1312
1309
dhcp -> local .sin_family = AF_INET ;
1313
1310
dhcp -> local .sin_port = htons ( BOOTPC_PORT );
1311
+ dhcp -> xid = random ();
1312
+
1313
+ /* Store DHCP transaction ID for fakedhcp code */
1314
+ dhcp_last_xid = dhcp -> xid ;
1314
1315
1315
1316
/* Instantiate child objects and attach to our interfaces */
1316
1317
if ( ( rc = xfer_open_socket ( & dhcp -> xfer , SOCK_DGRAM , & dhcp_peer ,
0 commit comments