Index | Thread | Search

From:
Andre S <andre.s@list.ru>
Subject:
dhcpleased: patch xid problem
To:
tech@openbsd.org
Date:
Sat, 03 Feb 2024 22:41:28 +0300
Reply-To:
Andre S <andre.s@list.ru>

Download raw body.

Thread
I am faced with the problem of receiving dhcp data from my internet
service provider. A laptop with OpenBSD cannot receive dhcp data.
However, a Windows 7 laptop receives dhcp data without problems.
I captured packets on ports 67 and 68 on an OpenBSD laptop using the
tcpdump utility. I also captured packets on ports 67 and 68 on
a Windows 7 laptop using the Wireshark utility. A comparison of the
captured packets in the Wireshark utility showed that the dhcp discover,
dhcp offer and dhcp request packets captured in Windows 7 have the
same xid. And the packets captured in OpenBSD dhcpdiscover, dhcpoffer
have the same xid, and the dhcp request packet has a different xid.
 
Link to screenshots.
Wireshark screenshot from Win 7 laptop   https://i.imgur.com/PISB64U.png
Wireshark screenshot from OpenBSD laptop https://i.imgur.com/oIsPJjj.png
 
 
According to Florian commit, a new xid is generated whenever the state
changes https://marc.info/?l=openbsd-tech&m=163939439719215 .
But according to the table in section 4.4.1 rfc2131 in the packet
dhcp request 'xid' from server DHCPOFFER message. And "The DHCPREQUEST
message contains the same 'xid' as the DHCPOFFER message." https://www.ietf.org/rfc/rfc2131.txt
 
 
I prepared a patch that when changing the dhcpleased state from
IF_INIT to IF_REQUESTING, the xid does not change. In case of my
internet service provider, the problem is gone.
 
Index: engine.c
===================================================================
RCS file: /cvs/src/sbin/dhcpleased/engine.c,v
retrieving revision 1.42
diff -u -p -u -r1.42 engine.c
--- engine.c    26 Jan 2024 21:14:08 -0000      1.42
+++ engine.c    3 Feb 2024 18:37:19 -0000
@@ -1386,7 +1386,8 @@ state_transition(struct dhcpleased_iface
 
        iface->state = new_state;
        if (new_state != old_state)
-               iface->xid = arc4random();
+               if (new_state != IF_REQUESTING || old_state != IF_INIT)
+                       iface->xid = arc4random();
 
        switch (new_state) {
        case IF_DOWN: