diff -cr linux/include/linux/sock_ioctl.h linux-rpb/include/linux/sock_ioctl.h
*** linux/include/linux/sock_ioctl.h	Tue Nov 10 12:54:56 1992
--- linux-rpb/include/linux/sock_ioctl.h	Wed Jan 13 14:54:06 1993
***************
*** 18,21 ****
--- 18,40 ----
     unsigned long net;
     unsigned long up:1;
  };
+ 
+ #define SIOCSARP	0x2501
+ #define SIOCGARP	0x2502
+ #define SIOCDARP	0x2503
+ 
+ /*
+  * ARP ioctl request
+  */
+ struct arpreq {
+ 	struct	sockaddr arp_pa;		/* protocol address */
+ 	struct	sockaddr arp_ha;		/* hardware address */
+ 	int	arp_flags;			/* flags */
+ };
+ 
+ #define ATF_COM		0x02
+ #define ATF_PERM	0x04
+ #define ATF_PUBL	0x08
+ #define ATF_USETRAILERS	0x10
+ 
  #endif
diff -cr linux/net/tcp/arp.c linux-rpb/net/tcp/arp.c
*** linux/net/tcp/arp.c	Mon Dec 21 17:36:40 1992
--- linux-rpb/net/tcp/arp.c	Wed Jan 13 15:16:36 1993
***************
*** 50,55 ****
--- 50,58 ----
  
  #include <linux/socket.h>
  #include <netinet/in.h>
+ #include <linux/sock_ioctl.h>
+ #include <linux/errno.h>
+ #include <asm/segment.h>
  #include <asm/system.h>
  
  #include "timer.h"
***************
*** 556,559 ****
--- 559,625 ----
       }
    skb->magic = ARP_QUEUE_MAGIC;
     sti();
+ }
+ 
+ static int arpreq_check(struct arpreq *req)
+ {
+ 	/* Check protocol familys */
+ 	if (req->arp_pa.sa_family != AF_INET) return -1;
+ 
+ 	if (req->arp_ha.sa_family != AF_UNSPEC) return -1;
+ 
+ 	return 0;
+ }
+ 
+ int arp_ioctl_set(struct arpreq *req)
+ {
+ 	struct arpreq		r;
+ 	struct arp_table	*apt;
+ 
+ 	memcpy_fromfs(&r, req, sizeof(r));
+ 	if (arpreq_check(&r) != 0) return -EPFNOSUPPORT;
+ 
+ 	apt = arp_lookup(*(unsigned long *)r.arp_pa.sa_data);
+ 	if (apt) {
+ 		apt->last_used = timer_seq;
+ 		memcpy(apt->hard, r.arp_ha.sa_data , 6);
+ 	} else {
+ 		if (!create_arp(*(unsigned long *)r.arp_pa.sa_data,
+ 				r.arp_ha.sa_data, 6)) {
+ 			return -ENOMEM;
+ 		}
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ int arp_ioctl_get(struct arpreq *req)
+ {
+ 	struct arpreq		r;
+ 	struct arp_table	*apt;
+ 
+ 	memcpy_fromfs(&r, req, sizeof(r));
+ 	if (arpreq_check(&r) != 0) return -EPFNOSUPPORT;
+ 	apt = arp_lookup(*(unsigned long *)r.arp_pa.sa_data);
+ 	if (apt) {
+ 		memcpy(r.arp_ha.sa_data, apt->hard, apt->hlen);
+ 	} else {
+ 		return -ENXIO;
+ 	}
+ 
+ 	/* Copy the information back */
+ 	memcpy_tofs(req, &r, sizeof(r));
+ 	return 0;
+ }
+ 
+ int arp_ioctl_del(struct arpreq *req)
+ {
+ 	struct arpreq		r;
+ 
+ 	memcpy_fromfs(&r, req, sizeof(r));
+ 	if (arpreq_check(&r) != 0) return -EPFNOSUPPORT;
+ 
+ 	arp_destroy(*(unsigned long *)r.arp_pa.sa_data);
+ 
+ 	return 0;
  }
diff -cr linux/net/tcp/arp.h linux-rpb/net/tcp/arp.h
*** linux/net/tcp/arp.h	Fri Dec  4 20:07:28 1992
--- linux-rpb/net/tcp/arp.h	Wed Jan 13 14:54:06 1993
***************
*** 76,81 ****
--- 76,85 ----
  void arp_add (unsigned long addr, unsigned char *haddr, struct device *dev);
  void arp_queue (struct sk_buff *skb);
  
+ int arp_ioctl_set(struct arpreq *req);
+ int arp_ioctl_get(struct arpreq *req);
+ int arp_ioctl_del(struct arpreq *req);
+ 
  #define ARP_TABLE_SIZE 16
  #define ARP_IP_PROT ETHERTYPE_IP
  #define ARP_REQUEST 1
diff -cr linux/net/tcp/sock.c linux-rpb/net/tcp/sock.c
*** linux/net/tcp/sock.c	Mon Dec 21 15:23:43 1992
--- linux-rpb/net/tcp/sock.c	Wed Jan 13 14:54:06 1993
***************
*** 1625,1630 ****
--- 1625,1643 ----
  	 return (-EPERM);
         return (ip_set_dev((struct ip_config *)arg));
  
+      case SIOCSARP:
+        if (!suser())
+          return (-EPERM);
+        return (arp_ioctl_set((struct arpreq *)arg));
+ 
+      case SIOCGARP:
+        return (arp_ioctl_get((struct arpreq *)arg));
+ 
+      case SIOCDARP:
+        if (!suser())
+          return (-EPERM);
+        return (arp_ioctl_del((struct arpreq *)arg));
+ 
       case FIOSETOWN:
       case SIOCSPGRP:
          {
