After completing the DORA process and getting the IP from the DHCP server, the client will perform an ARP probe to verify that no other devices are using the IP address before the probing device starts to do so.
If an ARP probe receives an ARP response for the same IP allocated by the DHCP server, the client will send a DHCP decline message to the DHCP server and request a new IP.
When FortiGate receives the DHCPDECLINE from a specific mac address for a leased IP, it will deduce that the leased IP is a duplicate IP and is used in the network. FortiGate will store the ip information as 'Removed due to conflict' in the GUI.
For example:
Consider a network where a device is configured with 10.0.0.3 as the client ip address. The same ip address falls under the DHCP IP range.
FortiGate Config:
config system dhcp server
edit 2
set dns-service default
set default-gateway 10.0.0.1 set netmask 255.255.255.248 set interface "port2"
config ip-range edit 1
set start-ip 10.0.0.2 set end-ip 10.0.0.6
next
end
next
end

When a client requests the DHCP IP, FortiGate will lease the next available IP from the IP range.
diag debug reset diag debug application dhcps -1 diagnose debug enable
0.0.0.0 255.255.255.255 ff:ff:ff:ff:ff:ff 50:1a:45:00:07:00 DHCP Discover - Transaction ID 0x2761267
Debug :
[note]DHCPDISCOVER from 50:1a:45:00:07:00 via port2(ethernet) [debug]found a new lease of ip 10.0.0.3 <<<<<<<<<<<<<<<< [debug]added ip 10.0.0.3 mac 50:1a:45:00:07:00 in vd root [debug]packet length 300 [debug]op = 1 htype = 1 hlen = 6 hops = 0 [debug]xid = 67127602 secs = 28 flags = 0 [debug]ciaddr = 0.0.0.0 [debug]yiaddr = 0.0.0.0 [debug]siaddr = 0.0.0.0 [debug]giaddr = 0.0.0.0 [debug]chaddr = 50:1a:45:00:07:00 [debug]filename = [debug]server_name = [debug] host-name = "UNL" [debug] dhcp-message-type = 1 [debug] dhcp-parameter-request-list = 1,15,3,6,44,46,47,31,33,121,249,43 [debug] dhcp-class-identifier = "MSFT 5.0" [debug] dhcp-client-identifier = 1:50:1a:45:0:7:0
A DHCP Offer is sent to the client:
10.0.0.1 10.0.0.3 50:1a:45:00:07:00 50:23:99:00:03:01 DHCP Offer - Transaction ID 0x2761267
[note]DHCPOFFER on 10.0.0.3 to 50:1a:45:00:07:00 via port2(ethernet) [debug]sending on port2(ethernet) [debug]sending using lpf_dhcpd_send_packet [debug]locate_network prhtype(1) pihtype(1) [debug]find_lease(): packet contains preferred client IP, cip.s_addr is 10.0.0.3 [debug]find_lease(): leaving function with lease set [debug]find_lease(): the lease's IP is 10.0.0.3
Followed by a DHCP request from the client and DHCP ack from FortiGate:
0.0.0.0 255.255.255.255 ff:ff:ff:ff:ff:ff 50:1a:45:00:07:00 DHCP Request - Transaction ID 0x2761267 10.0.0.1 10.0.0.3 50:1a:45:00:07:00 50:23:99:00:03:01 DHCP ACK - Transaction ID 0x2761267
[note]DHCPREQUEST for 10.0.0.3 from 50:1a:45:00:07:00 via port2(ethernet) [debug]deled ip 10.0.0.3 mac 50:1a:45:00:07:00 in vd root [debug]added ip 10.0.0.3 mac 50:1a:45:00:07:00 in vd root [debug]packet length 302 [debug]op = 1 htype = 1 hlen = 6 hops = 0 [debug]xid = 67127602 secs = 28 flags = 0 [debug]ciaddr = 0.0.0.0 [debug]yiaddr = 0.0.0.0 [debug]siaddr = 0.0.0.0 [debug]giaddr = 0.0.0.0 [debug]chaddr = 50:1a:45:00:07:00 [debug]filename = [debug]server_name = [debug] host-name = "UNL" [debug] dhcp-requested-address = 10.0.0.3 [debug] dhcp-message-type = 3 [debug] dhcp-server-identifier = 10.0.0.1 [debug] dhcp-parameter-request-list = 1,15,3,6,44,46,47,31,33,121,249,43 [debug] dhcp-class-identifier = "MSFT 5.0" [debug] dhcp-client-identifier = 1:50:1a:45:0:7:0 [debug] option-81 = 0:0:0:55:4e:4c [debug] [note]DHCPACK on 10.0.0.3 to 50:1a:45:00:07:00 via port2(ethernet) [debug]sending on port2(ethernet)
Once the client completes the DHCP DORA process, it will send an ARP probe to identify any duplicate IPs in the same broadcast network.
50:1a:45:00:07:00 Broadcast ff:ff:ff:ff:ff:ff 50:1a:45:00:07:00 Who has 10.0.0.3? (ARP Probe)
The IP will be assigned its interface if it does not receive a response. If there is an ARP response, the DHCP client will send the DHCPDECLINE message to the server, notifying it of the IP conflict.
50:fc:cf:00:0b:00 50:1a:45:00:07:00 50:1a:45:00:07:00 50:fc:cf:00:0b:00 10.0.0.3 is at 50:fc:cf:00:0b:00 (duplicate use of 10.0.0.3 detected!)
0.0.0.0 255.255.255.255 ff:ff:ff:ff:ff:ff 50:1a:45:00:07:00 DHCP Decline - Transaction ID 0x2761267

FortiGate debug:
[note]DHCPDECLINE on 10.0.0.3 from 50:1a:45:00:07:00 via port2(ethernet) <<<<<< [warn]Abandoning IP address 10.0.0.3: declined. [debug]deled ip 10.0.0.3 mac 50:1a:45:00:07:00 in vd root [debug]locate_network prhtype(1) pihtype(1) [debug]find_lease(): leaving function WITHOUT a lease [note]DHCPDISCOVER from 50:1a:45:00:07:00 via port2(ethernet) [debug]found a new lease of ip 10.0.0.4 [debug]added ip 10.0.0.4 mac 50:1a:45:00:07:00 in vd root
At this point, FortiGate learns that the leased IP 10.0.0.3 has a conflict and adds the IP to the list of conflicted leases.
The same IP will not be leased to any other client until the expiry time.
exe dhcp lease-list port2 IP MAC-Address Hostname VCI SSID AP SERVER-ID Expiry 10.0.0.4 50:1a:45:00:07:00 UNL MSFT 5.0 2 Mon Jun 19 07:19:45 2023
port2 [Conflicted leases] IP Expiry 10.0.0.2 Mon Jun 12 07:49:15 2023 10.0.0.3 Mon Jun 12 07:49:33 2023

Another scenario:
FortiGate can send an ICMP echo-request to the IP address before it provides the DHCPOFFER to the client. If FortiGate receives an ICMP echo-reply from the IP address, it will abandon that IP address, and then store the IP information as 'Removed due to conflict' in the GUI.
Below FortiGate debug shows when the client behind FortiGate port1 requests an IP address. FortiGate enables the DHCP server in port1 interface 192.168.180.1/24.
FortiGate debug:
[note]DHCPDISCOVER from 00:45:6e:64:52:02 via port1(ethernet) [debug]found a new lease of ip 192.168.180.4 [debug]added ip 192.168.180.4 mac 00:45:6e:64:52:02 in vd root [debug]packet length 302 [debug]op = 1 htype = 1 hlen = 6 hops = 0 [debug]xid = afd7d97d secs = 0 flags = 0 [debug]ciaddr = 0.0.0.0 [debug]yiaddr = 0.0.0.0 [debug]siaddr = 0.0.0.0 [debug]giaddr = 0.0.0.0 [debug]chaddr = 00:45:6e:64:52:02 [debug]filename = [debug]server_name = [debug] host-name = "DESKTOP-OLGFQ84" [debug] dhcp-requested-address = 192.168.180.6 [debug] dhcp-message-type = 1 [debug] dhcp-parameter-request-list = 1,3,6,15,31,33,43,44,46,47,119,121,249,252 [debug] dhcp-class-identifier = "MSFT 5.0" [debug] dhcp-client-identifier = 1:0:45:6e:64:52:2 [debug] [pkt]000: 01 01 06 00 7d d9 d7 af 00 00 00 00 00 00 00 00 [pkt]010: 00 00 00 00 00 00 00 00 00 00 00 00 00 45 6e 64 [pkt]020: 52 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]0a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]0d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [pkt]0e0: 00 00 00 00 00 00 00 00 00 00 00 00 63 82 53 63 [pkt]0f0: 35 01 01 3d 07 01 00 45 6e 64 52 02 32 04 c0 a8 [pkt]100: b4 06 0c 0f 44 45 53 4b 54 4f 50 2d 4f 4c 47 46 [pkt]110: 51 38 34 3c 08 4d 53 46 54 20 35 2e 30 37 0e 01 [pkt]120: 03 06 0f 1f 21 2b 2c 2e 2f 77 79 f9 fc ff [debug]Sending ICMP echo-request to 192.168.180.4 [debug]Received ICMP echo-reply from 192.168.180.4 [warn]Abandoning IP address 192.168.180.4: pinged before offer [debug]deled ip 192.168.180.4 mac 00:45:6e:64:52:02 in vd root
Related article:
Technical Tip: Understanding DHCP Server and DHCP Relay functionality on FortiGate
|