Index: oldkernel/linux/CREDITS diff -u linux/CREDITS:1.1.1.1 linux/CREDITS:1.2 --- linux/CREDITS:1.1.1.1 Wed May 31 12:33:48 2000 +++ linux/CREDITS Wed May 31 14:50:06 2000 @@ -1370,6 +1370,14 @@ S: 80220-320 Curitiba - Parana S: Brazil +N: Marc Merlin +E: marcsoft@merlins.org +E: merlin_bts@valinux.com +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: meskes@debian.org P: 1024/04B6E8F5 6C 77 33 CA CC D6 22 03 AB AB 15 A3 AE AD 39 7D Index: oldkernel/linux/net/ipv4/arp.c diff -u linux/net/ipv4/arp.c:1.1.1.1 linux/net/ipv4/arp.c:1.2 --- linux/net/ipv4/arp.c:1.1.1.1 Wed May 31 12:33:49 2000 +++ linux/net/ipv4/arp.c Wed May 31 14:50:06 2000 @@ -1,6 +1,6 @@ /* linux/net/inet/arp.c * - * Version: $Id: arp.c,v 1.77.2.4 1999/09/23 19:03:36 davem Exp $ + * Version: $Id: arp.c,v 1.1.1.1 2000/05/31 19:33:49 ccr Exp $ * * Copyright (C) 1994 by Florian La Roche * @@ -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 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 @@ #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 @@ 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 @@ 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>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 @@ 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;kaddr_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);