--- linux-2.2.14/net/ipv4/arp.c.arp Fri Feb 18 15:53:34 2000
+++ linux-2.2.14/net/ipv4/arp.c Fri Feb 18 15:57:28 2000
@@ -67,6 +67,8 @@
* now it is in net/core/neighbour.c.
* Julian Anastasov: "hidden" flag: hide the
* interface and don't reply for it
+ * Marc Merlin : Added duplicate IP and MAC address
+ * detection (99/10/11)
*/
/* RFC1122 Status:
@@ -128,6 +130,7 @@ static int arp_constructor(struct neighb
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);
static struct neigh_ops arp_generic_ops =
{
@@ -618,7 +621,7 @@ int arp_rcv(struct sk_buff *skb, struct
#endif
}
- /* Undertsand only these message types */
+ /* Understand only these message types */
if (arp->ar_op != __constant_htons(ARPOP_REPLY) &&
arp->ar_op != __constant_htons(ARPOP_REQUEST))
@@ -672,6 +675,45 @@ int arp_rcv(struct sk_buff *skb, struct
goto out;
}
+ if (!memcmp(sha,dev->dev_addr,dev->addr_len))
+ {
+ char ourip=0;
+ struct in_device *idev=dev->ip_ptr;
+ struct in_ifaddr *adlist=idev->ifa_list;
+
+ while (adlist != NULL)
+ {
+ if (adlist->ifa_address == sip) {
+
+ ourip=1;
+ break;
+ }
+ adlist=adlist->ifa_next;
+ }
+
+ if (net_ratelimit()) {
+ if (!ourip) {
+ printk(KERN_WARNING "Uh Oh, I received an ARP packet claiming to be 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_ntoa(sip));
+ }
+ }
+ }
+ else if (arp->ar_op == __constant_htons(ARPOP_REQUEST)) {
+ struct in_device *idev=dev->ip_ptr;
+ struct in_ifaddr *adlist=idev->ifa_list;
+
+ while (adlist != NULL)
+ {
+ if (adlist->ifa_address == 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=adlist->ifa_next;
+ }
+ }
+
+
if (arp->ar_op == __constant_htons(ARPOP_REQUEST) &&
ip_route_input(skb, tip, sip, 0, dev) == 0) {
@@ -978,21 +1020,61 @@ out:
return err;
}
+
+#define HBUFFERLEN 30
+/*
+ * Convert Mac Address to ASCII
+ */
+char *mac2asc(unsigned char *sha, unsigned char addr_len) {
+ static char hbuffer[HBUFFERLEN];
+ const char hexbuf[] = "0123456789ABCDEF";
+ int j,k;
+
+ /* I'd get great pleasure deleting
+ this ugly code. Let's output it in hexadecimal format.
+ "arp" utility will eventually repaired --ANK
+ This is also used for outputting IP/Mac conflicts, but if Alexey
+ wants to change the output in /proc, it can also be changed for
+ warning printks -- Marc
+ */
+#if 1 /* UGLY CODE */
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+ if (hatype == ARPHRD_AX25 || hatype == ARPHRD_NETROM)
+ strcpy(hbuffer,ax2asc((ax25_address *)sha));
+ else {
+#endif
+ for (k=0,j=0; k<HBUFFERLEN-3 && j<addr_len ; j++) {
+ hbuffer[k++]=hexbuf[(sha[j]>>4)&15 ];
+ hbuffer[k++]=hexbuf[sha[j]&15 ];
+ hbuffer[k++]=':';
+ }
+ hbuffer[--k]=0;
+
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+ }
+#endif
+#else
+ if (addr_len) {
+ int j;
+ for (j=0; j < addr_len; j++)
+ sprintf(hbuffer+2*j, "%02x", sha[j]);
+ } else
+ sprintf(hbuffer, "0");
+#endif
+ return hbuffer;
+}
+
/*
* Write the contents of the ARP cache to a PROCfs file.
*/
#ifdef CONFIG_PROC_FS
-#define HBUFFERLEN 30
-
int arp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{
int len=0;
off_t pos=0;
int size;
- char hbuffer[HBUFFERLEN];
- int i,j,k;
- const char hexbuf[] = "0123456789ABCDEF";
+ int i;
size = sprintf(buffer,"IP address HW type Flags HW address Mask Device\n");
@@ -1011,44 +1093,12 @@ int arp_get_info(char *buffer, char **st
if (!(n->nud_state&~NUD_NOARP))
continue;
- /* I'd get great pleasure deleting
- this ugly code. Let's output it in hexadecimal format.
- "arp" utility will eventually repaired --ANK
- */
-#if 1 /* UGLY CODE */
-/*
- * Convert hardware address to XX:XX:XX:XX ... form.
- */
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- if (hatype == ARPHRD_AX25 || hatype == ARPHRD_NETROM)
- strcpy(hbuffer,ax2asc((ax25_address *)n->ha));
- else {
-#endif
- for (k=0,j=0;k<HBUFFERLEN-3 && j<dev->addr_len;j++) {
- hbuffer[k++]=hexbuf[(n->ha[j]>>4)&15 ];
- hbuffer[k++]=hexbuf[n->ha[j]&15 ];
- hbuffer[k++]=':';
- }
- hbuffer[--k]=0;
-
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- }
-#endif
-#else
- if ((neigh->nud_state&NUD_VALID) && dev->addr_len) {
- int j;
- for (j=0; j < dev->addr_len; j++)
- sprintf(hbuffer+2*j, "%02x", neigh->ha[j]);
- } else
- sprintf(hbuffer, "0");
-#endif
-
size = sprintf(buffer+len,
"%-17s0x%-10x0x%-10x%s",
in_ntoa(*(u32*)n->primary_key),
hatype,
arp_state_to_flags(n),
- hbuffer);
+ mac2asc(n->ha,dev->addr_len));
size += sprintf(buffer+len+size,
" %-17s %s\n",
"*", dev->name);
--- linux-2.2.14/CREDITS.arp Fri Feb 18 15:53:34 2000
+++ linux-2.2.14/CREDITS Fri Feb 18 15:53:46 2000
@@ -1370,6 +1370,14 @@ S: R. Prof. Rubens Elke Braga, 558 - Par
S: 80220-320 Curitiba - Parana
S: Brazil
+N: Marc Merlin
+E:
[email protected]
+E:
[email protected]
+D: Passive duplicate IP and MAC address detection through ARP packet watching
+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