--- linux/include/linux/inetdevice.h.orig Tue Jan 5 01:31:35 1999 +++ linux/include/linux/inetdevice.h Tue Nov 23 10:11:32 1999 @@ -16,6 +16,7 @@ int log_martians; int forwarding; int mc_forwarding; + int arp_invisible; void *sysctl; }; @@ -40,6 +41,7 @@ #define IN_DEV_LOG_MARTIANS(in_dev) (ipv4_devconf.log_martians || (in_dev)->cnf.log_martians) #define IN_DEV_PROXY_ARP(in_dev) (ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp) +#define IN_DEV_ARP_INVISIBLE(in_dev) (ipv4_devconf.arp_invisible && (in_dev)->cnf.arp_invisible) #define IN_DEV_SHARED_MEDIA(in_dev) (ipv4_devconf.shared_media || (in_dev)->cnf.shared_media) #define IN_DEV_TX_REDIRECTS(in_dev) (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects) #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) --- linux/include/linux/sysctl.h.orig Tue Nov 23 10:10:42 1999 +++ linux/include/linux/sysctl.h Tue Nov 23 10:11:32 1999 @@ -267,7 +267,8 @@ NET_IPV4_CONF_RP_FILTER=8, NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE=9, NET_IPV4_CONF_BOOTP_RELAY=10, - NET_IPV4_CONF_LOG_MARTIANS=11 + NET_IPV4_CONF_LOG_MARTIANS=11, + NET_IPV4_CONF_ARP_INVISIBLE=12 }; /* /proc/sys/net/ipv6 */ --- linux/net/ipv4/arp.c.orig Tue Nov 23 09:47:26 1999 +++ linux/net/ipv4/arp.c Tue Nov 23 12:38:09 1999 @@ -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. + * Julian Anastasov: arp_invisible flag: hide the + * interface and don't reply for it */ /* RFC1122 Status: @@ -305,16 +307,31 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) { - u32 saddr; + u32 saddr, saddr2; u8 *dst_ha = NULL; struct device *dev = neigh->dev; + struct device *dev2; + struct in_device *in_dev = NULL; u32 target = *(u32*)neigh->primary_key; int probes = neigh->probes; - if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL) + if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL) { saddr = skb->nh.iph->saddr; - else - saddr = inet_select_addr(dev, target, RT_SCOPE_LINK); + dev2 = ip_dev_find(saddr); + if (dev2) in_dev = dev2->ip_ptr; + } + if (!in_dev || IN_DEV_ARP_INVISIBLE(in_dev)) { + saddr2 = inet_select_addr(dev, target, RT_SCOPE_LINK); + if (!in_dev) saddr = saddr2; + in_dev = dev->ip_ptr; + if (!in_dev || IN_DEV_ARP_INVISIBLE(in_dev)) { + saddr2 = 0; + } + if ((saddr != saddr2) && net_ratelimit()) { + printk(KERN_INFO "%s: src ip=%d.%d.%d.%d is hidden, selecting %d.%d.%d.%d\n", __FUNCTION__, NIPQUAD(saddr), NIPQUAD(saddr2)); + } + saddr = saddr2; + } if ((probes -= neigh->parms->ucast_probes) < 0) { if (!(neigh->nud_state&NUD_VALID)) @@ -542,6 +559,8 @@ u16 dev_type = dev->type; int addr_type; struct in_device *in_dev = dev->ip_ptr; + struct in_device *in_dev2; + struct device *tdev; struct neighbour *n; /* @@ -654,8 +673,17 @@ /* Special case: IPv4 duplicate address detection packet (RFC2131) */ if (sip == 0) { if (arp->ar_op == __constant_htons(ARPOP_REQUEST) && - inet_addr_type(tip) == RTN_LOCAL) - arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr); + inet_addr_type(tip) == RTN_LOCAL) { + in_dev2 = NULL; + tdev = ip_dev_find(tip); + if (tdev) in_dev2 = (struct in_device *) tdev->ip_ptr; + /* + * In fact, we allow remote host to use this IP + * if our interface is "hidden" + */ + if (in_dev2 && !IN_DEV_ARP_INVISIBLE(in_dev2)) + arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr); + } goto out; } @@ -668,7 +696,15 @@ if (addr_type == RTN_LOCAL) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) { - arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); + in_dev2 = NULL; + tdev = ip_dev_find(tip); + if (tdev) in_dev2 = tdev->ip_ptr; + if (in_dev2 && IN_DEV_ARP_INVISIBLE(in_dev2) && + net_ratelimit()) { + printk(KERN_INFO "%s: Skipping reply to %d.%d.%d.%d for hidden IP %d.%d.%d.%d\n", __FUNCTION__, NIPQUAD(sip), NIPQUAD(tip)); + } + if (in_dev2 && !IN_DEV_ARP_INVISIBLE(in_dev2)) + arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); neigh_release(n); } goto out; --- linux/net/ipv4/devinet.c.orig Tue Nov 23 09:46:40 1999 +++ linux/net/ipv4/devinet.c Tue Nov 23 10:11:32 1999 @@ -923,7 +923,7 @@ static struct devinet_sysctl_table { struct ctl_table_header *sysctl_header; - ctl_table devinet_vars[12]; + ctl_table devinet_vars[13]; ctl_table devinet_dev[2]; ctl_table devinet_conf_dir[2]; ctl_table devinet_proto_dir[2]; @@ -956,6 +956,9 @@ &proc_dointvec}, {NET_IPV4_CONF_PROXY_ARP, "proxy_arp", &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_CONF_ARP_INVISIBLE, "arp_invisible", + &ipv4_devconf.arp_invisible, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay", &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL, --- linux/Documentation/networking/ip-sysctl.txt.orig Tue Nov 23 09:45:08 1999 +++ linux/Documentation/networking/ip-sysctl.txt Tue Nov 23 10:11:32 1999 @@ -156,6 +156,9 @@ proxy_arp - BOOLEAN Do proxy arp. +arp_invisible - BOOLEAN + Hide this interface and don't send ARP replies for it. + shared_media - BOOLEAN undocumented. --- linux/Documentation/proc.txt.orig Tue Nov 23 09:43:28 1999 +++ linux/Documentation/proc.txt Tue Nov 23 10:11:32 1999 @@ -1163,6 +1163,9 @@ proxy_arp Do (1) or don't (0) do proxy ARP. +arp_invisible + Hide this interface and don't send ARP replies for it. + rp_filter Integer value deciding if source validation should be made. 1 means yes, 0 means no. Disabled by default, but