Bernard CLABOTS
2018-09-18 15:59:01 UTC
Hi all,  I have been trying to replicate an issue of IP conflict on Open-WRT, the issue is randomly seen, and I expect in real life, it is related to a de-sync of the lease data base with the actual situation (in case a switch is between the client and the server and the server is rebooted e.g., so that the client acts as though it would have a fixed IP. Reported as seen as well when moving a client from one setup to another setup where the IP that it used to receive is used on the LAN).
  I tested with 2 different versions of dnsmasq (2.78 and 2.79).
  I use Scapy to forge DHCP Requests (see further).
Setup:I have a laptop with a fixed IP inside the range of the DHCP (192.168.1.0/26). I then forge a Request of that IP using scapy and I cannot explain the behavior:1. I see no ARP whatsoever to the requested IP when DNSMasq handles the request.2. When I request the fixed IP for a client with a random MAC, I instantly receive an ACK, then I see some unanswered ARP requests (*after*) as to "who has [IP just assigned]? Tell 192.168.1.1" where 192.168.1.1 is the DHCP server IP.
I end up in a situation where the dhcp.leases contains the fake MAC associated to the lease, while the ARP table contains the MAC of the fixed IP laptop (probably because I'm not sending any IP packet where the IP is associated to the fake MAC, so the switch cannot learn it).
I have observed that Windows 10 has a mechanism to prevent conflicts where, whenever a fixed IP is used/configured, after the link is up an ARP probe is sent with its own IP. In case it gets answered, the client keeps silent and start using a link local IPv4 (169....). Yet I have tested with a very old laptop running Windows 3.1 and I can replicate the issue.But basically, it is puzzling that the device is ARPing *after* the DHCP distributed the IP.
*The all issue seems to boil down to:* why does DNSMasq not check if the IP is free before assigning it?
I thought that unless option "-5" or "--no-ping" was set, DNSMasq would always ping once to the assigned IP *before* assignment (I controlled in the code and see that actually, there is a mechanism to store the positive identification as well as to blacklist IP's in case a client is constantly coming back).The only ARP I see in this case is *after* the IP is assigned. How come DNSMasq is not trying to ping before assignment? Is there an option to force this behavior (from the code I guess not)? Is DNSMasq also somehow relying on the ARP table and flags that are set on reachability? or solely on the _non_ answer to ping?
Thanks a lot for your assistance.
Regards,Bernard
Scapy forged packet (I know the source MAC does not match the client MAC, but I deem this good enough for testing, AFAIK it is a legal packet):dhcp_request = Ether(dst='ff:ff:ff:ff:ff:ff')/IP(src='0.0.0.0', dst='255.255.255.255')/UDP(dport=67, sport=68)/BOOTP(xid=RandInt())/DHCP(options=[('message-type', 'request'),("server_id","192.168.1.1"),("requested_addr","192.168.1.34"),("hostname","Scapy"), 'end'])
dhcp_ack = srp1(dhcp_request, iface='enp9s0')
  I tested with 2 different versions of dnsmasq (2.78 and 2.79).
  I use Scapy to forge DHCP Requests (see further).
Setup:I have a laptop with a fixed IP inside the range of the DHCP (192.168.1.0/26). I then forge a Request of that IP using scapy and I cannot explain the behavior:1. I see no ARP whatsoever to the requested IP when DNSMasq handles the request.2. When I request the fixed IP for a client with a random MAC, I instantly receive an ACK, then I see some unanswered ARP requests (*after*) as to "who has [IP just assigned]? Tell 192.168.1.1" where 192.168.1.1 is the DHCP server IP.
I end up in a situation where the dhcp.leases contains the fake MAC associated to the lease, while the ARP table contains the MAC of the fixed IP laptop (probably because I'm not sending any IP packet where the IP is associated to the fake MAC, so the switch cannot learn it).
I have observed that Windows 10 has a mechanism to prevent conflicts where, whenever a fixed IP is used/configured, after the link is up an ARP probe is sent with its own IP. In case it gets answered, the client keeps silent and start using a link local IPv4 (169....). Yet I have tested with a very old laptop running Windows 3.1 and I can replicate the issue.But basically, it is puzzling that the device is ARPing *after* the DHCP distributed the IP.
*The all issue seems to boil down to:* why does DNSMasq not check if the IP is free before assigning it?
I thought that unless option "-5" or "--no-ping" was set, DNSMasq would always ping once to the assigned IP *before* assignment (I controlled in the code and see that actually, there is a mechanism to store the positive identification as well as to blacklist IP's in case a client is constantly coming back).The only ARP I see in this case is *after* the IP is assigned. How come DNSMasq is not trying to ping before assignment? Is there an option to force this behavior (from the code I guess not)? Is DNSMasq also somehow relying on the ARP table and flags that are set on reachability? or solely on the _non_ answer to ping?
Thanks a lot for your assistance.
Regards,Bernard
Scapy forged packet (I know the source MAC does not match the client MAC, but I deem this good enough for testing, AFAIK it is a legal packet):dhcp_request = Ether(dst='ff:ff:ff:ff:ff:ff')/IP(src='0.0.0.0', dst='255.255.255.255')/UDP(dport=67, sport=68)/BOOTP(xid=RandInt())/DHCP(options=[('message-type', 'request'),("server_id","192.168.1.1"),("requested_addr","192.168.1.34"),("hostname","Scapy"), 'end'])
dhcp_ack = srp1(dhcp_request, iface='enp9s0')