Messages in this thread Patch in this message | | | Date | Sat, 2 Oct 1999 01:32:11 -0700 | From | Marc Merlin <> | Subject | PATCH: detect IP conflicts from ARP packets |
| |
On ven, oct 01, 1999 at 09:29:53 +0200, Rogier Wolff wrote: > Peter Benie wrote: > > Marc Merlin writes ("Re: Why no printk for duplicate IPs?"): > > > On mer, sep 29, 1999 at 11:47:29 +0100, Alan Cox wrote: > > > > > So, is it correct that for IPv4, linux won't report the fact that > > > > > another machine is answering ARP requests for one of its IPs? > > > > ARP Replies are unicast > > > > > > good point. > > > > > > However, at least Solaris, Irix and 95/NT give you a warning when > > > someone steals your IP (at runtime, not ifconfig time). I suppose > > > they do an ARP request on their own IP after answering an ARP request > > > themselves, and watch for an answer. > > > > > > Any reason we can't do that? > > > > An alternative approach is to log when we receive a broadcast IP from an > > external interface which is apparently from one of our own addresses. > > Yes, THAT's it. > > You use the ARP REQUESTS of the double to detect that it's using your > IP. That's the "runtime" check.
I hadn't considered this initially. It does have the advantage of being "stealth". I wrote up an initial patch for it (against 2.2.12, but I'm guessing it should easily apply to other kernels), but I intentionally didn't put the dots on the i yet, because I do not believe this approach is enough.
The problems here are that:
1) If you plug your network onto an active network, if someone is already using your IP, you won't necessarly notice. The reason is that if host A (linux) knows the MAC address of host B, it will send arp queries about B's mac address from time to time, but those ARP queries aren't broadcast, they're sent directly to B's MAC address. This means that if you plug your laptop C into the net, and if A happens to be using your IP, you will never know because A sends its ARP packets directly to B.
2) A host can have your IP for its eth0:0, or it can have it as a public entry in its ARP table, but yet you will never know by just watching ARP traffic, until you send an ARP packet yourself, ask if anyone knows what MAC address is linked to your IP, and and make sure the MAC you get back is indeed yours. The way you do this is you wait for someone to ask for your MAC address, and when you answer, you send a ARP request yourself, also asking for your IP, and watch the answers.
Dave, Alan, do you agree with this? Would you accept a patch that sends an ARP query when just having answered one (and I can make this a user configurable option), or would you simply prefer a cleaned up version of the patch below (initial version that just assumes you're sitting on ethernet (and that therefore the MAC address is 6 bytes long))?
--- linux.orig/net/ipv4/arp.c Mon Aug 9 12:04:41 1999 +++ linux/net/ipv4/arp.c Sat Oct 2 00:54:36 1999 @@ -654,6 +654,30 @@ goto out; } + if (arp->ar_op == __constant_htons(ARPOP_REQUEST)) + { + struct in_device *idev=dev->ip_ptr; + struct in_ifaddr *adlist=idev->ifa_list; + + // printk("Got arp request %.8X (%.4X%.8X) -> %.8X\n", be32_to_cpu(sip), be16_to_cpu(*hadb16), be32_to_cpu(*hade32), be32_to_cpu(tip)); + + while (adlist != NULL) + { + if (adlist->ifa_address == sip) { + u16 *hadb16; + u32 *hade32; + + hadb16 = (u16 *)sha; + hade32 = (u32 *)(sha+2); + + printk (KERN_WARNING "Uh Oh, MAC address %.4X%.8X claims to have our IP %.8X\n(duplicate IP conflict likely)\n", be16_to_cpu(*hadb16), be32_to_cpu(*hade32), be32_to_cpu(sip)); + break; + } + adlist=adlist->ifa_next; + } + } + + if (arp->ar_op == __constant_htons(ARPOP_REQUEST) && ip_route_input(skb, tip, sip, 0, dev) == 0) { > As I was the original one to suggest doing the gratuitous ARP in the > first place, and people have convinced me that not ifconfiging the > interface is NOT a good idea, I've done some more thinking:
Actually I suggested that the kernel do this, and you suggested that ifconfig do this :-)
While it doesn't hurt to have ifconfig put a warning message if someone else claims to use the IP that you're ifconfiging up, it really doesn't help for networks where laptops come and go, and machines are turned on and off.
Several other TCP/IP stacks already actively check while they're running that no one is using their IP, and I believe we should do the same (although I'll make that a configurable option in the patch)
As for what you do when you see the conflict, I do not intend to do anything more than printk KERN_WARNING, as taking the interface down would be yielding to the person who's stealing your IP. I much prefer getting their MAC address, have my machine try to continue communications, and track the rogue user with a LART (aka baseball bat :-D)
Marc
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |