Duplicate IP and MAC address ARP patch

Note, Jaroslav Imrich, wrote a userland version of this patch, see the ipwatchd sf.net page

What does this patch do?

Basically, it will get your system to output this:
Uh Oh, MAC address 00:A0:C9:EE:9C:8A claims to have our IP addresses (192.168.205.9) (duplicate IP conflict likely)
or this:
Uh Oh, I received an ARP packet claiming to be from our MAC address 00:80:C8:47:37:72, but with an IP I don't own (192.168.205.1). Someone has apparently stolen our MAC address

Ok, I'd like more info

After wondering why linux doesn't detect when someone steals its IP, just like Solaris, Irix, and windows to name only a few, do, I decided to write a kernel patch to fix this.

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?

Can you explain more about arp, layer2, and this patch

Sure, I have given a talk at linux.conf.au: the Layer2 & ARP talk

Is this stable? Does it work?

Well, I first wrote the 2.2 patch almost a year ago, and VA Linux Systems has been including it in its kernels for about as long too.
After announcing it on the linux-kernel list, I got some feedback and added net_ratelimit to prevent log floods, and I added a IDONTRECEIVEMYOWNPACKETSBACK define after confirming that you could receive your own packets back in some setups (which would trigger the "someone stole my IP and my MAC" messages).
After that, I left it alone and only recently ported it to 2.4 (simple port with no new code or features)

Ok, where are the patches?


[ms free site] Email
Link to Home Page

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