patch-2.1.68 linux/net/ipv4/rarp.c
Next file: linux/net/ipv4/raw.c
Previous file: linux/net/ipv4/protocol.c
Back to the patch index
Back to the overall index
- Lines: 255
- Date:
Sun Nov 30 14:00:39 1997
- Orig file:
v2.1.67/linux/net/ipv4/rarp.c
- Orig date:
Thu Sep 4 17:07:32 1997
diff -u --recursive --new-file v2.1.67/linux/net/ipv4/rarp.c linux/net/ipv4/rarp.c
@@ -3,6 +3,8 @@
* Copyright (C) 1994 by Ross Martin
* Based on linux/net/inet/arp.c, Copyright (C) 1994 by Florian La Roche
*
+ * $Id: rarp.c,v 1.21 1997/10/27 09:13:16 geert Exp $
+ *
* This module implements the Reverse Address Resolution Protocol
* (RARP, RFC 903), which is used to convert low level addresses such
* as ethernet addresses into high level addresses such as IP addresses.
@@ -119,20 +121,20 @@
struct rarp_table *entry;
struct rarp_table **pentry;
- cli();
+ start_bh_atomic();
pentry = &rarp_tables;
while ((entry = *pentry) != NULL)
{
if (entry->ip == ip_addr)
{
*pentry = entry->next;
- sti();
+ end_bh_atomic();
rarp_release_entry(entry);
return;
}
pentry = &entry->next;
}
- sti();
+ end_bh_atomic();
}
/*
@@ -144,7 +146,7 @@
struct rarp_table *entry;
struct rarp_table **pentry;
- cli();
+ start_bh_atomic();
pentry = &rarp_tables;
while ((entry = *pentry) != NULL)
{
@@ -156,7 +158,7 @@
else
pentry = &entry->next;
}
- sti();
+ end_bh_atomic();
}
static int rarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
@@ -176,6 +178,8 @@
NULL,
0
};
+
+static int rarp_pkt_inited=0;
static void rarp_init_pkt (void)
{
@@ -183,8 +187,19 @@
rarp_packet_type.type=htons(ETH_P_RARP);
dev_add_pack(&rarp_packet_type);
register_netdevice_notifier(&rarp_dev_notifier);
+ rarp_pkt_inited=1;
}
+static void rarp_end_pkt(void)
+{
+ if(!rarp_pkt_inited)
+ return;
+ dev_remove_pack(&rarp_packet_type);
+ unregister_netdevice_notifier(&rarp_dev_notifier);
+ rarp_pkt_inited=0;
+}
+
+
/*
* Receive an arp request by the device layer. Maybe it should be
* rewritten to use the incoming packet for the reply. The current
@@ -199,6 +214,7 @@
struct arphdr *rarp = (struct arphdr *) skb->data;
unsigned char *rarp_ptr = skb_pull(skb,sizeof(struct arphdr));
struct rarp_table *entry;
+ struct in_device *in_dev = dev->ip_ptr;
long sip,tip;
unsigned char *sha,*tha; /* s for "source", t for "target" */
@@ -207,7 +223,7 @@
*/
if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)
- || dev->flags&IFF_NOARP)
+ || dev->flags&IFF_NOARP || !in_dev || !in_dev->ifa_list)
{
kfree_skb(skb, FREE_READ);
return 0;
@@ -256,7 +272,6 @@
* Process entry. Use tha for table lookup according to RFC903.
*/
- cli();
for (entry = rarp_tables; entry != NULL; entry = entry->next)
if (!memcmp(entry->ha, tha, rarp->ar_hln))
break;
@@ -264,13 +279,10 @@
if (entry != NULL)
{
sip=entry->ip;
- sti();
- arp_send(ARPOP_RREPLY, ETH_P_RARP, sip, dev, dev->pa_addr, sha,
+ arp_send(ARPOP_RREPLY, ETH_P_RARP, sip, dev, in_dev->ifa_list->ifa_address, sha,
dev->dev_addr, sha);
}
- else
- sti();
kfree_skb(skb, FREE_READ);
return 0;
@@ -331,10 +343,10 @@
* Is it reachable directly ?
*/
- err = ip_route_output(&rt, ip, 0, 1, NULL);
+ err = ip_route_output(&rt, ip, 0, 1, 0);
if (err)
return err;
- if (rt->rt_flags&(RTF_LOCAL|RTF_BROADCAST|RTF_MULTICAST|RTF_NAT)) {
+ if (rt->rt_flags&(RTCF_LOCAL|RTCF_BROADCAST|RTCF_MULTICAST|RTCF_DNAT)) {
ip_rt_put(rt);
return -EINVAL;
}
@@ -344,7 +356,6 @@
* Is there an existing entry for this address? Find out...
*/
- cli();
for (entry = rarp_tables; entry != NULL; entry = entry->next)
if (entry->ip == ip)
break;
@@ -359,7 +370,6 @@
GFP_ATOMIC);
if (entry == NULL)
{
- sti();
return -ENOMEM;
}
if (initflag)
@@ -368,21 +378,23 @@
initflag=0;
}
+ /* Block interrupts until table modification is finished */
+
+ cli();
entry->next = rarp_tables;
rarp_tables = entry;
}
-
+ cli();
entry->ip = ip;
entry->hlen = hlen;
entry->htype = htype;
memcpy(&entry->ha, &r.arp_ha.sa_data, hlen);
entry->dev = dev;
+ sti();
/* Don't unlink if we have entries to serve. */
MOD_INC_USE_COUNT;
- sti();
-
return 0;
}
@@ -417,14 +429,12 @@
si = (struct sockaddr_in *) &r.arp_pa;
ip = si->sin_addr.s_addr;
- cli();
for (entry = rarp_tables; entry != NULL; entry = entry->next)
if (entry->ip == ip)
break;
if (entry == NULL)
{
- sti();
return -ENXIO;
}
@@ -434,7 +444,6 @@
memcpy(r.arp_ha.sa_data, &entry->ha, entry->hlen);
r.arp_ha.sa_family = entry->htype;
- sti();
/*
* Copy the information back
@@ -483,6 +492,7 @@
return 0;
}
+#ifdef CONFIG_PROC_FS
int rarp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{
int len=0;
@@ -505,7 +515,6 @@
pos+=size;
len+=size;
- cli();
for(entry=rarp_tables; entry!=NULL; entry=entry->next)
{
netip=htonl(entry->ip); /* switch to network order */
@@ -537,7 +546,6 @@
if(pos>offset+length)
break;
}
- sti();
}
*start = buffer+(offset-begin); /* Start of wanted data */
@@ -553,11 +561,14 @@
0, &proc_net_inode_operations,
rarp_get_info
};
+#endif
__initfunc(void
rarp_init(void))
{
+#ifdef CONFIG_PROC_FS
proc_net_register(&proc_net_rarp);
+#endif
rarp_ioctl_hook = rarp_ioctl;
}
@@ -572,7 +583,9 @@
void cleanup_module(void)
{
struct rarp_table *rt, *rt_next;
+#ifdef CONFIG_PROC_FS
proc_net_unregister(PROC_NET_RARP);
+#endif
rarp_ioctl_hook = NULL;
cli();
/* Destroy the RARP-table */
@@ -584,5 +597,6 @@
rt_next = rt->next;
rarp_release_entry(rt);
}
+ rarp_end_pkt();
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov