What does the patch do?
It looks at all the broadcast ARP requests and checks that the source IP of the request is different from the interface's IP. This will catch a machine that is using your IP and is trying to talk to a machine on your net for the first time or the first time in a while.
The big plus of this approach is that it's passive
Why only the first time?
Once the first ARP request gets an answer, the MAC address is cached and at least some versions of linux will freshen their cache by doing a directed ARP request (not broadcast) to ask the remote machine if it's still using that IP. You will not see those ARP requests as they are not broadcast.
But you could put the interface in promiscuous mode
You don't want to force people to turn on promiscuous mode on all their interfaces. It will load up machines with interrupts, and make some buggy NICs unhappy (among other things)
Is it correct that you will also miss a machine that has your IP on let's
say eth0:0, or that just put your IP with a different MAC address in its ARP
cache and is also answering ARP queries for your IP?
Yes, that's because such a machine will typically not send packets with that IP alias, and therefore you won't see ARP queries from that IP.
Why not send ARP queries with your IP and make sure no one answers?
That's what I originally thought about doing. I wanted to send an ARP query for my IP each time I answered such a query, and make sure no one else answered that query.
This would have been a big mistake however because it will create an ARP loop between two machines using the same IP and the extra patch . Rogier also pointed out to me that he didn't like the idea of linux sending extra ARP packets when a passive solution exists.
So what else can you do?
Well, while the patch below will actually catch most of everyday conflicts, you also want to check that your IP isn't used when you bring your interface up (you can use arping or something similar).
Better yet, you can also have a small daemon that does an ARP query for your IP every so often and makes sure there is no answer. The problem with this approach is that it's intrusive and it can generate a lot of traffic if all the machines on a big net do this
Because both of these can be done trivially in user space (use arping), it shouldn't be in the kernel. That said, doing those checks only supplement my patch, they do not replace it (unless you want to be really invasive and arping your IP every 10sec or so, but I'm not sure you want the associated network overhead)
But then why not write the whole thing in user space?
Well, the line has to be drawn somewhere... The whole IP stack could be in user space if we wanted... In this case, the actual added code (I'm not talking about the existing code which I turned into a function) is about 20 lines, it's trivial and it uses much less resources on a slow machine (386) than a user space solution which forces a context switches, system calls, and memory for that user process.
Also, not that others are always right, but do you know any OS that does duplicate IP checking by inspecting ARP requests in user space?
2000/09/21 (15:23): Initial version of this page
2000/09/21 (18:21): Added info on arping
2000/09/21 (23:41): Released patch 1.1 for 2.4.x
2000/09/22 (00:54): Released patch 1.2 for 2.4.x
2000/09/22 (10:23): Released patch 1.3 for 2.4.x
2000/11/13 (17:13): Released patch 1.5 for 2.4.14
2002/09/19 (17:13): Released patch 1.6 for 2.4.19
2002/10/07 (21:54): Released patch 1.6.1 for 2.4.19
2003/11/09 (21:54): Released patch 1.6.2 for 2.4.22
2006/01/21 (16:22): Released patch 1.7 for 2.6.14