summaryrefslogtreecommitdiffstats
path: root/net/ipv4/arp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r--net/ipv4/arp.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index e6e272b0e..1ce69028f 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1,6 +1,6 @@
/* linux/net/inet/arp.c
*
- * Version: $Id: arp.c,v 1.67 1998/06/19 13:22:31 davem Exp $
+ * Version: $Id: arp.c,v 1.70 1998/08/26 12:03:18 davem Exp $
*
* Copyright (C) 1994 by Florian La Roche
*
@@ -760,7 +760,7 @@ int arp_req_set(struct arpreq *r, struct device * dev)
r->arp_flags |= ATF_COM;
if (dev == NULL) {
struct rtable * rt;
- if ((err = ip_route_output(&rt, ip, 0, 1, 0)) != 0)
+ if ((err = ip_route_output(&rt, ip, 0, RTO_ONLINK, 0)) != 0)
return err;
dev = rt->u.dst.dev;
ip_rt_put(rt);
@@ -843,11 +843,21 @@ int arp_req_delete(struct arpreq *r, struct device * dev)
return -EINVAL;
}
+ if (dev == NULL) {
+ struct rtable * rt;
+ if ((err = ip_route_output(&rt, ip, 0, RTO_ONLINK, 0)) != 0)
+ return err;
+ dev = rt->u.dst.dev;
+ ip_rt_put(rt);
+ if (!dev)
+ return -EINVAL;
+ }
err = -ENXIO;
start_bh_atomic();
neigh = __neigh_lookup(&arp_tbl, &ip, dev, 0);
if (neigh) {
- err = neigh_update(neigh, NULL, NUD_FAILED, 1, 0);
+ if (neigh->nud_state&~NUD_NOARP)
+ err = neigh_update(neigh, NULL, NUD_FAILED, 1, 0);
neigh_release(neigh);
}
end_bh_atomic();
@@ -867,7 +877,7 @@ int arp_ioctl(unsigned int cmd, void *arg)
switch(cmd) {
case SIOCDARP:
case SIOCSARP:
- if (!suser())
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
case SIOCGARP:
err = copy_from_user(&r, arg, sizeof(struct arpreq));
@@ -899,10 +909,8 @@ int arp_ioctl(unsigned int cmd, void *arg)
err = -EINVAL;
if ((r.arp_flags & ATF_COM) && r.arp_ha.sa_family != dev->type)
goto out;
- } else if (cmd != SIOCSARP) {
- /* dev has not been set ... */
- printk(KERN_ERR "arp_ioctl: invalid, null device\n");
- err = -EINVAL;
+ } else if (cmd == SIOCGARP) {
+ err = -ENODEV;
goto out;
}
@@ -911,7 +919,6 @@ int arp_ioctl(unsigned int cmd, void *arg)
err = arp_req_delete(&r, dev);
break;
case SIOCSARP:
- /* This checks for dev == NULL */
err = arp_req_set(&r, dev);
break;
case SIOCGARP: