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