I updated my duplicate IP detection patch to work with 2.4.

I announced  the 2.2 version  here last  year, and several  people expr=
essed
interest in it, but it never  made it into the kernel unfortunately. I =
asked
a few times and  eventually gave up as I didn't want  to appear overly =
pushy
and it got included in the kernels that I use (kernels from VA).

I didn't receive  any negative comments, except for Alexey  who believe=
d the
check should be done in user space.

The patches (2.2/2.4) and discussion can be found here:
http://marc.merlins.org/linux/arppatch/

Here are two excerpts:
-----------------------------------------------------------------------=
-----
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 ma=
chine
that is using your IP and is trying to talk to a machine on your net fo=
r the
first time or the first time in a while.
The big plus of this approach is that it's passive=20

It will get your system to output this:=20
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:=20
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
-----------------------------------------------------------------------=
-----

-----------------------------------------------------------------------=
-----
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 abo=
ut 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 c=
alls,
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?
-----------------------------------------------------------------------=
-----

I'm attaching the 2.4  version which I'd really like to  see included i=
n the
main tree. While I don't see a good reason to disable this, if what it =
takes
is a  config option, experimental  or not, disabled  by default or  not=
 (I'd
rather  have it  non experimental  since  it's a  year old,  and enable=
d  by
default, but I'll settle), I'll do what it takes.

I'm attaching the 2.4  version and you can find the 2.2  version, as we=
ll as
more info on my page:
http://marc.merlins.org/linux/arppatch/

Thanks,
Marc

diff -urN linux-2.2.4-test5/net/ipv4/arp.c linux-2.2.4-test5-detectarpd=
upe/net/ipv4/arp.c
--- linux-2.2.4-test5/net/ipv4/arp.c    Fri Jul 21 21:54:29 2000
+++ linux-2.2.4-test5-detectarpdupe/net/ipv4/arp.c      Sun Sep 17 19:19:49 =
2000
@@ -65,6 +65,8 @@
  *                                     clean up the APFDDI & gen. FDDI bits.
  *             Alexey Kuznetsov:       new arp state machine;
  *                                     now it is in net/core/neighbour.c.
+ *             Marc Merlin     :       Added duplicate IP and MAC address
+ *                                     detection (2000/09/17)
  */
=20
 /* RFC1122 Status:
@@ -121,6 +123,8 @@
=20
 #include <asm/system.h>
 #include <asm/uaccess.h>
+=20
+#undef IDONTRECEIVEMYOWNPACKETSBACK=20
=20
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 static char *ax2asc2(ax25_address *a, char *buf);
@@ -135,6 +139,7 @@
 static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb);
 static void arp_error_report(struct neighbour *neigh, struct sk_buff *=
skb);
 static void parp_redo(struct sk_buff *skb);
+static char *mac2asc(unsigned char *sha, unsigned char addr_len);
=20
 static struct neigh_ops arp_generic_ops =3D
 {
@@ -716,6 +721,55 @@
                goto out;
        }
=20
+       if (!memcmp(sha,dev->dev_addr,dev->addr_len))
+       {
+               char ourip=3D0;
+               struct in_device *idev=3Ddev->ip_ptr;
+               struct in_ifaddr *adlist=3Didev->ifa_list;
+       =09
+               while (adlist !=3D NULL)
+               {
+                   if (adlist->ifa_address =3D=3D sip) {
+               =09
+                       ourip=3D1;
+                       break;
+                   }
+                   adlist=3Dadlist->ifa_next;
+               }
+       =09
+               if (net_ratelimit()) {
+                       if (ourip) {
+#ifdef IDONTRECEIVEMYOWNPACKETSBACK
+/* This is an attempt at detecting that someone stole your MAC and you=
r IP, but
+ * in some network configurations and with some switches, you will get=
 your
+ * own packets back, so this warning would be triggered by error for t=
oo many
+ * people.
+ * It's disabled by default but I have left it there in case it's usef=
ul to=20
+ * someone -- Marc <[EMAIL PROTECTED]> */
+                               printk(KERN_WARNING "We either got one of our ARP 
+packets back bec=
ause of a switch or the network configuration, or some machine is using=
 our MAC address %s and our IP address %s\n",mac2asc(sha,dev->addr_len)=
,in_ntoa(sip));
+#endif
+                       } else {
+                               printk(KERN_WARNING "Uh Oh, I received an ARP packet 
+claiming to b=
e from our MAC address %s, but with an IP I don't own (%s). Someone has=
 apparently stolen our MAC address\n",mac2asc(sha,dev->addr_len),in_nto=
a(sip));
+                       }
+               }
+       }
+       else if (arp->ar_op =3D=3D __constant_htons(ARPOP_REQUEST)) {
+               struct in_device *idev=3Ddev->ip_ptr;
+               struct in_ifaddr *adlist=3Didev->ifa_list;
+
+               while (adlist !=3D NULL)
+               {
+                   if (adlist->ifa_address =3D=3D sip) {
+
+                       if (net_ratelimit())
+                               printk (KERN_WARNING "Uh Oh, MAC address %s claims to 
+have our IP =
addresses (%s) (duplicate IP conflict likely)\n", mac2asc(sha,dev->addr=
_len), in_ntoa(sip));
+                       break;
+                   }
+                   adlist=3Dadlist->ifa_next;
+               }
+       }
+
+=09
        if (arp->ar_op =3D=3D __constant_htons(ARPOP_REQUEST) &&
            ip_route_input(skb, tip, sip, 0, dev) =3D=3D 0) {
=20
@@ -1009,22 +1063,51 @@
        return err;
 }
=20
+
+
+#define HBUFFERLEN 30
+/*
+ *     Convert Mac Address to ASCII=20
+ */
+char *mac2asc(unsigned char *sha, unsigned char addr_len) {
+       static char hbuffer[HBUFFERLEN];
+       const char hexbuf[] =3D  "0123456789ABCDEF";
+       int j,k;
+
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+       if (hatype =3D=3D ARPHRD_AX25 || hatype =3D=3D ARPHRD_NETROM)
+               ax2asc2((ax25_address *)sha, hbuffer);
+       else {
+#endif
+               for (k=3D0,j=3D0;k<HBUFFERLEN-3 && j<addr_len;j++) {
+                       hbuffer[k++]=3Dhexbuf[(sha[j]>>4)&15 ];
+                       hbuffer[k++]=3Dhexbuf[sha[j]&15     ];
+                       hbuffer[k++]=3D':';
+               }
+               hbuffer[--k]=3D0;
+
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+       }
+#endif
+
+       return hbuffer;
+}
+
+
 /*
  *     Write the contents of the ARP cache to a PROCfs file.
  */
 #ifndef CONFIG_PROC_FS
 static int arp_get_info(char *buffer, char **start, off_t offset, int =
length) { return 0; }
 #else
-#define HBUFFERLEN 30
+
=20
 static int arp_get_info(char *buffer, char **start, off_t offset, int =
length)
 {
        int len=3D0;
        off_t pos=3D0;
        int size;
-       char hbuffer[HBUFFERLEN];
-       int i,j,k;
-       const char hexbuf[] =3D  "0123456789ABCDEF";
+       int i;
=20
        size =3D sprintf(buffer,"IP address       HW type     Flags       HW =
address            Mask     Device\n");
=20
@@ -1044,24 +1127,6 @@
=20
                        read_lock(&n->lock);
=20
-/*
- *     Convert hardware address to XX:XX:XX:XX ... form.
- */
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
-                       if (hatype =3D=3D ARPHRD_AX25 || hatype =3D=3D ARPHRD_NETROM)
-                               ax2asc2((ax25_address *)n->ha, hbuffer);
-                       else {
-#endif
-                       for (k=3D0,j=3D0;k<HBUFFERLEN-3 && j<dev->addr_len;j++) {
-                               hbuffer[k++]=3Dhexbuf[(n->ha[j]>>4)&15 ];
-                               hbuffer[k++]=3Dhexbuf[n->ha[j]&15     ];
-                               hbuffer[k++]=3D':';
-                       }
-                       hbuffer[--k]=3D0;
-
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
-               }
-#endif
=20
                        {
                                char tbuf[16];
@@ -1071,7 +1136,7 @@
                                        tbuf,
                                        hatype,
                                        arp_state_to_flags(n),=20
-                                       hbuffer);
+                                       mac2asc(n->ha,dev->addr_len));
=20
                                size +=3D sprintf(buffer+len+size,
                                         "     %-8s %s\n",
diff -urN linux-2.2.4-test5/CREDITS linux-2.2.4-test5-detectarpdupe/CRE=
DITS
--- linux-2.2.4-test5/CREDITS   Sat Jul 29 15:58:05 2000
+++ linux-2.2.4-test5-detectarpdupe/CREDITS     Sun Sep 17 17:17:19 2000
@@ -1730,6 +1730,14 @@
 S: 80050-430 - Curitiba - Paran=E1
 S: Brazil
=20
+N: Marc Merlin
+E: [EMAIL PROTECTED]
+E: [EMAIL PROTECTED]
+D: Passive duplicate IP and MAC address detection through ARP packet w=
atching
+W: http://marc.merlins.org/
+P: 1024/763BE901 A1 9F 94 B7 78 01 E5 21  21 E0 F1 2E A2 85 E2 77
+S: Sunnyvale, California, USA
+
 N: Michael Meskes
 E: [EMAIL PROTECTED]
 P: 1024/04B6E8F5 6C 77 33 CA CC D6 22 03  AB AB 15 A3 AE AD 39 7D
--=20
Microsoft is to software what McDonalds is to gourmet cooking
=20
Home page: http://marc.merlins.org/ (friendly to non IE browsers)
=46inger [EMAIL PROTECTED] for PGP key and other contact information
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"=
 in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to