RFC2131.txt:
xid 4 Transaction ID, a random number chosen by the
client, used by the client and server to associate
messages and responses between a client and a
server.
The 'xid' field is used by the client to match incoming DHCP messages
with pending requests. A DHCP client MUST choose 'xid's in such a
way as to minimize the chance of using an 'xid' identical to one used
by another client. For example, a client may choose a different,
random initial 'xid' each time the client is rebooted, and
subsequently use sequential 'xid's until the next reboot. Selecting
a new 'xid' for each retransmission is an implementation decision. A
client may choose to reuse the same 'xid' or select a new 'xid' for
each retransmitted message.
This patch generates random id when start dhcp, and record it to
netdev struct.
Signed-off-by: Amos Kong <[email protected]>
CC: Eduardo Habkost <[email protected]>
CC: Marty Connor <[email protected]>
---
src/include/gpxe/netdevice.h | 3 +++
src/net/udp/dhcp.c | 23 ++++-------------------
2 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h
index 97bf168..7272cf8 100644
--- a/src/include/gpxe/netdevice.h
+++ b/src/include/gpxe/netdevice.h
@@ -294,6 +294,9 @@ struct net_device {
/** Link-layer broadcast address */
const uint8_t *ll_broadcast;
+ /* DHCP Transaction ID */
+ uint32_t xid;
+
/** Current device state
*
* This is the bitwise-OR of zero or more NETDEV_XXX constants.
diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c
index 4bfcb80..51b7150 100644
--- a/src/net/udp/dhcp.c
+++ b/src/net/udp/dhcp.c
@@ -136,23 +136,6 @@ static inline const char * dhcp_msgtype_name ( unsigned
int msgtype ) {
}
}
-/**
- * Calculate DHCP transaction ID for a network device
- *
- * @v netdev Network device
- * @ret xid DHCP XID
- *
- * Extract the least significant bits of the hardware address for use
- * as the transaction ID.
- */
-static uint32_t dhcp_xid ( struct net_device *netdev ) {
- uint32_t xid;
-
- memcpy ( &xid, ( netdev->ll_addr + netdev->ll_protocol->ll_addr_len
- - sizeof ( xid ) ), sizeof ( xid ) );
- return xid;
-}
-
/****************************************************************************
*
* DHCP session
@@ -1070,7 +1053,7 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
/* Initialise DHCP packet content */
memset ( dhcphdr, 0, max_len );
- dhcphdr->xid = dhcp_xid ( netdev );
+ dhcphdr->xid = netdev->xid;
dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto );
dhcphdr->op = dhcp_op[msgtype];
@@ -1313,7 +1296,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
&server_id, sizeof ( server_id ) );
/* Check for matching transaction ID */
- if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
+ if ( dhcphdr->xid != dhcp->netdev->xid ) {
+
DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
"ID\n", dhcp, dhcp_msgtype_name ( msgtype ),
inet_ntoa ( peer->sin_addr ),
@@ -1442,6 +1426,7 @@ int start_dhcp ( struct job_interface *job, struct
net_device *netdev ) {
dhcp = zalloc ( sizeof ( *dhcp ) );
if ( ! dhcp )
return -ENOMEM;
+ netdev->xid = random();
ref_init ( &dhcp->refcnt, dhcp_free );
job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt );
xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt );
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html