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

Reply via email to