diff options
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 423 | 
1 files changed, 127 insertions, 296 deletions
diff --git a/net/socket.c b/net/socket.c index 0b2dad3bdf7f..7f64a6eccf63 100644 --- a/net/socket.c +++ b/net/socket.c @@ -212,6 +212,7 @@ static const char * const pf_family_names[] = {  	[PF_QIPCRTR]	= "PF_QIPCRTR",  	[PF_SMC]	= "PF_SMC",  	[PF_XDP]	= "PF_XDP", +	[PF_MCTP]	= "PF_MCTP",  };  /* @@ -1064,9 +1065,13 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)   */  static DEFINE_MUTEX(br_ioctl_mutex); -static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg); +static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br, +			    unsigned int cmd, struct ifreq *ifr, +			    void __user *uarg); -void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *)) +void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br, +			     unsigned int cmd, struct ifreq *ifr, +			     void __user *uarg))  {  	mutex_lock(&br_ioctl_mutex);  	br_ioctl_hook = hook; @@ -1074,6 +1079,22 @@ void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))  }  EXPORT_SYMBOL(brioctl_set); +int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, +		  struct ifreq *ifr, void __user *uarg) +{ +	int err = -ENOPKG; + +	if (!br_ioctl_hook) +		request_module("bridge"); + +	mutex_lock(&br_ioctl_mutex); +	if (br_ioctl_hook) +		err = br_ioctl_hook(net, br, cmd, ifr, uarg); +	mutex_unlock(&br_ioctl_mutex); + +	return err; +} +  static DEFINE_MUTEX(vlan_ioctl_mutex);  static int (*vlan_ioctl_hook) (struct net *, void __user *arg); @@ -1088,8 +1109,11 @@ EXPORT_SYMBOL(vlan_ioctl_set);  static long sock_do_ioctl(struct net *net, struct socket *sock,  			  unsigned int cmd, unsigned long arg)  { +	struct ifreq ifr; +	bool need_copyout;  	int err;  	void __user *argp = (void __user *)arg; +	void __user *data;  	err = sock->ops->ioctl(sock, cmd, arg); @@ -1100,25 +1124,16 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,  	if (err != -ENOIOCTLCMD)  		return err; -	if (cmd == SIOCGIFCONF) { -		struct ifconf ifc; -		if (copy_from_user(&ifc, argp, sizeof(struct ifconf))) -			return -EFAULT; -		rtnl_lock(); -		err = dev_ifconf(net, &ifc, sizeof(struct ifreq)); -		rtnl_unlock(); -		if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf))) -			err = -EFAULT; -	} else { -		struct ifreq ifr; -		bool need_copyout; -		if (copy_from_user(&ifr, argp, sizeof(struct ifreq))) +	if (!is_socket_ioctl_cmd(cmd)) +		return -ENOTTY; + +	if (get_user_ifreq(&ifr, &data, argp)) +		return -EFAULT; +	err = dev_ioctl(net, cmd, &ifr, data, &need_copyout); +	if (!err && need_copyout) +		if (put_user_ifreq(&ifr, argp))  			return -EFAULT; -		err = dev_ioctl(net, cmd, &ifr, &need_copyout); -		if (!err && need_copyout) -			if (copy_to_user(argp, &ifr, sizeof(struct ifreq))) -				return -EFAULT; -	} +  	return err;  } @@ -1140,12 +1155,13 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)  	net = sock_net(sk);  	if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {  		struct ifreq ifr; +		void __user *data;  		bool need_copyout; -		if (copy_from_user(&ifr, argp, sizeof(struct ifreq))) +		if (get_user_ifreq(&ifr, &data, argp))  			return -EFAULT; -		err = dev_ioctl(net, cmd, &ifr, &need_copyout); +		err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);  		if (!err && need_copyout) -			if (copy_to_user(argp, &ifr, sizeof(struct ifreq))) +			if (put_user_ifreq(&ifr, argp))  				return -EFAULT;  	} else  #ifdef CONFIG_WEXT_CORE @@ -1170,14 +1186,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)  		case SIOCSIFBR:  		case SIOCBRADDBR:  		case SIOCBRDELBR: -			err = -ENOPKG; -			if (!br_ioctl_hook) -				request_module("bridge"); - -			mutex_lock(&br_ioctl_mutex); -			if (br_ioctl_hook) -				err = br_ioctl_hook(net, cmd, argp); -			mutex_unlock(&br_ioctl_mutex); +			err = br_ioctl_call(net, NULL, cmd, NULL, argp);  			break;  		case SIOCGIFVLAN:  		case SIOCSIFVLAN: @@ -1217,6 +1226,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)  						   cmd == SIOCGSTAMP_NEW,  						   false);  			break; + +		case SIOCGIFCONF: +			err = dev_ifconf(net, argp); +			break; +  		default:  			err = sock_do_ioctl(net, sock, cmd, arg);  			break; @@ -1722,32 +1736,22 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)  	return __sys_listen(fd, backlog);  } -int __sys_accept4_file(struct file *file, unsigned file_flags, +struct file *do_accept(struct file *file, unsigned file_flags,  		       struct sockaddr __user *upeer_sockaddr, -		       int __user *upeer_addrlen, int flags, -		       unsigned long nofile) +		       int __user *upeer_addrlen, int flags)  {  	struct socket *sock, *newsock;  	struct file *newfile; -	int err, len, newfd; +	int err, len;  	struct sockaddr_storage address; -	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) -		return -EINVAL; - -	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) -		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; -  	sock = sock_from_file(file); -	if (!sock) { -		err = -ENOTSOCK; -		goto out; -	} +	if (!sock) +		return ERR_PTR(-ENOTSOCK); -	err = -ENFILE;  	newsock = sock_alloc();  	if (!newsock) -		goto out; +		return ERR_PTR(-ENFILE);  	newsock->type = sock->type;  	newsock->ops = sock->ops; @@ -1758,18 +1762,9 @@ int __sys_accept4_file(struct file *file, unsigned file_flags,  	 */  	__module_get(newsock->ops->owner); -	newfd = __get_unused_fd_flags(flags, nofile); -	if (unlikely(newfd < 0)) { -		err = newfd; -		sock_release(newsock); -		goto out; -	}  	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name); -	if (IS_ERR(newfile)) { -		err = PTR_ERR(newfile); -		put_unused_fd(newfd); -		goto out; -	} +	if (IS_ERR(newfile)) +		return newfile;  	err = security_socket_accept(sock, newsock);  	if (err) @@ -1794,16 +1789,38 @@ int __sys_accept4_file(struct file *file, unsigned file_flags,  	}  	/* File flags are not inherited via accept() unlike another OSes. */ - -	fd_install(newfd, newfile); -	err = newfd; -out: -	return err; +	return newfile;  out_fd:  	fput(newfile); -	put_unused_fd(newfd); -	goto out; +	return ERR_PTR(err); +} +int __sys_accept4_file(struct file *file, unsigned file_flags, +		       struct sockaddr __user *upeer_sockaddr, +		       int __user *upeer_addrlen, int flags, +		       unsigned long nofile) +{ +	struct file *newfile; +	int newfd; + +	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) +		return -EINVAL; + +	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) +		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; + +	newfd = __get_unused_fd_flags(flags, nofile); +	if (unlikely(newfd < 0)) +		return newfd; + +	newfile = do_accept(file, file_flags, upeer_sockaddr, upeer_addrlen, +			    flags); +	if (IS_ERR(newfile)) { +		put_unused_fd(newfd); +		return PTR_ERR(newfile); +	} +	fd_install(newfd, newfile); +	return newfd;  }  /* @@ -3126,154 +3143,55 @@ void socket_seq_show(struct seq_file *seq)  }  #endif				/* CONFIG_PROC_FS */ -#ifdef CONFIG_COMPAT -static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) +/* Handle the fact that while struct ifreq has the same *layout* on + * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data, + * which are handled elsewhere, it still has different *size* due to + * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit, + * resulting in struct ifreq being 32 and 40 bytes respectively). + * As a result, if the struct happens to be at the end of a page and + * the next page isn't readable/writable, we get a fault. To prevent + * that, copy back and forth to the full size. + */ +int get_user_ifreq(struct ifreq *ifr, void __user **ifrdata, void __user *arg)  { -	struct compat_ifconf ifc32; -	struct ifconf ifc; -	int err; +	if (in_compat_syscall()) { +		struct compat_ifreq *ifr32 = (struct compat_ifreq *)ifr; -	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf))) -		return -EFAULT; +		memset(ifr, 0, sizeof(*ifr)); +		if (copy_from_user(ifr32, arg, sizeof(*ifr32))) +			return -EFAULT; -	ifc.ifc_len = ifc32.ifc_len; -	ifc.ifc_req = compat_ptr(ifc32.ifcbuf); +		if (ifrdata) +			*ifrdata = compat_ptr(ifr32->ifr_data); -	rtnl_lock(); -	err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq)); -	rtnl_unlock(); -	if (err) -		return err; +		return 0; +	} -	ifc32.ifc_len = ifc.ifc_len; -	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf))) +	if (copy_from_user(ifr, arg, sizeof(*ifr)))  		return -EFAULT; +	if (ifrdata) +		*ifrdata = ifr->ifr_data; +  	return 0;  } +EXPORT_SYMBOL(get_user_ifreq); -static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) +int put_user_ifreq(struct ifreq *ifr, void __user *arg)  { -	struct compat_ethtool_rxnfc __user *compat_rxnfc; -	bool convert_in = false, convert_out = false; -	size_t buf_size = 0; -	struct ethtool_rxnfc __user *rxnfc = NULL; -	struct ifreq ifr; -	u32 rule_cnt = 0, actual_rule_cnt; -	u32 ethcmd; -	u32 data; -	int ret; - -	if (get_user(data, &ifr32->ifr_ifru.ifru_data)) -		return -EFAULT; - -	compat_rxnfc = compat_ptr(data); - -	if (get_user(ethcmd, &compat_rxnfc->cmd)) -		return -EFAULT; +	size_t size = sizeof(*ifr); -	/* Most ethtool structures are defined without padding. -	 * Unfortunately struct ethtool_rxnfc is an exception. -	 */ -	switch (ethcmd) { -	default: -		break; -	case ETHTOOL_GRXCLSRLALL: -		/* Buffer size is variable */ -		if (get_user(rule_cnt, &compat_rxnfc->rule_cnt)) -			return -EFAULT; -		if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32)) -			return -ENOMEM; -		buf_size += rule_cnt * sizeof(u32); -		fallthrough; -	case ETHTOOL_GRXRINGS: -	case ETHTOOL_GRXCLSRLCNT: -	case ETHTOOL_GRXCLSRULE: -	case ETHTOOL_SRXCLSRLINS: -		convert_out = true; -		fallthrough; -	case ETHTOOL_SRXCLSRLDEL: -		buf_size += sizeof(struct ethtool_rxnfc); -		convert_in = true; -		rxnfc = compat_alloc_user_space(buf_size); -		break; -	} +	if (in_compat_syscall()) +		size = sizeof(struct compat_ifreq); -	if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ)) +	if (copy_to_user(arg, ifr, size))  		return -EFAULT; -	ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc; - -	if (convert_in) { -		/* We expect there to be holes between fs.m_ext and -		 * fs.ring_cookie and at the end of fs, but nowhere else. -		 */ -		BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) + -			     sizeof(compat_rxnfc->fs.m_ext) != -			     offsetof(struct ethtool_rxnfc, fs.m_ext) + -			     sizeof(rxnfc->fs.m_ext)); -		BUILD_BUG_ON( -			offsetof(struct compat_ethtool_rxnfc, fs.location) - -			offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != -			offsetof(struct ethtool_rxnfc, fs.location) - -			offsetof(struct ethtool_rxnfc, fs.ring_cookie)); - -		if (copy_in_user(rxnfc, compat_rxnfc, -				 (void __user *)(&rxnfc->fs.m_ext + 1) - -				 (void __user *)rxnfc) || -		    copy_in_user(&rxnfc->fs.ring_cookie, -				 &compat_rxnfc->fs.ring_cookie, -				 (void __user *)(&rxnfc->fs.location + 1) - -				 (void __user *)&rxnfc->fs.ring_cookie)) -			return -EFAULT; -		if (ethcmd == ETHTOOL_GRXCLSRLALL) { -			if (put_user(rule_cnt, &rxnfc->rule_cnt)) -				return -EFAULT; -		} else if (copy_in_user(&rxnfc->rule_cnt, -					&compat_rxnfc->rule_cnt, -					sizeof(rxnfc->rule_cnt))) -			return -EFAULT; -	} - -	ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL); -	if (ret) -		return ret; - -	if (convert_out) { -		if (copy_in_user(compat_rxnfc, rxnfc, -				 (const void __user *)(&rxnfc->fs.m_ext + 1) - -				 (const void __user *)rxnfc) || -		    copy_in_user(&compat_rxnfc->fs.ring_cookie, -				 &rxnfc->fs.ring_cookie, -				 (const void __user *)(&rxnfc->fs.location + 1) - -				 (const void __user *)&rxnfc->fs.ring_cookie) || -		    copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt, -				 sizeof(rxnfc->rule_cnt))) -			return -EFAULT; - -		if (ethcmd == ETHTOOL_GRXCLSRLALL) { -			/* As an optimisation, we only copy the actual -			 * number of rules that the underlying -			 * function returned.  Since Mallory might -			 * change the rule count in user memory, we -			 * check that it is less than the rule count -			 * originally given (as the user buffer size), -			 * which has been range-checked. -			 */ -			if (get_user(actual_rule_cnt, &rxnfc->rule_cnt)) -				return -EFAULT; -			if (actual_rule_cnt < rule_cnt) -				rule_cnt = actual_rule_cnt; -			if (copy_in_user(&compat_rxnfc->rule_locs[0], -					 &rxnfc->rule_locs[0], -					 rule_cnt * sizeof(u32))) -				return -EFAULT; -		} -	} -  	return 0;  } +EXPORT_SYMBOL(put_user_ifreq); +#ifdef CONFIG_COMPAT  static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)  {  	compat_uptr_t uptr32; @@ -3281,7 +3199,7 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32  	void __user *saved;  	int err; -	if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq))) +	if (get_user_ifreq(&ifr, NULL, uifr32))  		return -EFAULT;  	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu)) @@ -3290,10 +3208,10 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32  	saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;  	ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32); -	err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL); +	err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL, NULL);  	if (!err) {  		ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved; -		if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq))) +		if (put_user_ifreq(&ifr, uifr32))  			err = -EFAULT;  	}  	return err; @@ -3304,97 +3222,15 @@ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,  				 struct compat_ifreq __user *u_ifreq32)  {  	struct ifreq ifreq; -	u32 data32; - -	if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ)) -		return -EFAULT; -	if (get_user(data32, &u_ifreq32->ifr_data)) -		return -EFAULT; -	ifreq.ifr_data = compat_ptr(data32); - -	return dev_ioctl(net, cmd, &ifreq, NULL); -} - -static int compat_ifreq_ioctl(struct net *net, struct socket *sock, -			      unsigned int cmd, -			      struct compat_ifreq __user *uifr32) -{ -	struct ifreq __user *uifr; -	int err; - -	/* Handle the fact that while struct ifreq has the same *layout* on -	 * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data, -	 * which are handled elsewhere, it still has different *size* due to -	 * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit, -	 * resulting in struct ifreq being 32 and 40 bytes respectively). -	 * As a result, if the struct happens to be at the end of a page and -	 * the next page isn't readable/writable, we get a fault. To prevent -	 * that, copy back and forth to the full size. -	 */ +	void __user *data; -	uifr = compat_alloc_user_space(sizeof(*uifr)); -	if (copy_in_user(uifr, uifr32, sizeof(*uifr32))) +	if (!is_socket_ioctl_cmd(cmd)) +		return -ENOTTY; +	if (get_user_ifreq(&ifreq, &data, u_ifreq32))  		return -EFAULT; +	ifreq.ifr_data = data; -	err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr); - -	if (!err) { -		switch (cmd) { -		case SIOCGIFFLAGS: -		case SIOCGIFMETRIC: -		case SIOCGIFMTU: -		case SIOCGIFMEM: -		case SIOCGIFHWADDR: -		case SIOCGIFINDEX: -		case SIOCGIFADDR: -		case SIOCGIFBRDADDR: -		case SIOCGIFDSTADDR: -		case SIOCGIFNETMASK: -		case SIOCGIFPFLAGS: -		case SIOCGIFTXQLEN: -		case SIOCGMIIPHY: -		case SIOCGMIIREG: -		case SIOCGIFNAME: -			if (copy_in_user(uifr32, uifr, sizeof(*uifr32))) -				err = -EFAULT; -			break; -		} -	} -	return err; -} - -static int compat_sioc_ifmap(struct net *net, unsigned int cmd, -			struct compat_ifreq __user *uifr32) -{ -	struct ifreq ifr; -	struct compat_ifmap __user *uifmap32; -	int err; - -	uifmap32 = &uifr32->ifr_ifru.ifru_map; -	err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name)); -	err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); -	err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); -	err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); -	err |= get_user(ifr.ifr_map.irq, &uifmap32->irq); -	err |= get_user(ifr.ifr_map.dma, &uifmap32->dma); -	err |= get_user(ifr.ifr_map.port, &uifmap32->port); -	if (err) -		return -EFAULT; - -	err = dev_ioctl(net, cmd, &ifr, NULL); - -	if (cmd == SIOCGIFMAP && !err) { -		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); -		err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); -		err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); -		err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); -		err |= put_user(ifr.ifr_map.irq, &uifmap32->irq); -		err |= put_user(ifr.ifr_map.dma, &uifmap32->dma); -		err |= put_user(ifr.ifr_map.port, &uifmap32->port); -		if (err) -			err = -EFAULT; -	} -	return err; +	return dev_ioctl(net, cmd, &ifreq, data, NULL);  }  /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE @@ -3420,21 +3256,14 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,  	struct net *net = sock_net(sk);  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) -		return compat_ifr_data_ioctl(net, cmd, argp); +		return sock_ioctl(file, cmd, (unsigned long)argp);  	switch (cmd) {  	case SIOCSIFBR:  	case SIOCGIFBR:  		return old_bridge_ioctl(argp); -	case SIOCGIFCONF: -		return compat_dev_ifconf(net, argp); -	case SIOCETHTOOL: -		return ethtool_ioctl(net, argp);  	case SIOCWANDEV:  		return compat_siocwandev(net, argp); -	case SIOCGIFMAP: -	case SIOCSIFMAP: -		return compat_sioc_ifmap(net, cmd, argp);  	case SIOCGSTAMP_OLD:  	case SIOCGSTAMPNS_OLD:  		if (!sock->ops->gettstamp) @@ -3442,6 +3271,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,  		return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,  					    !COMPAT_USE_64BIT_TIME); +	case SIOCETHTOOL:  	case SIOCBONDSLAVEINFOQUERY:  	case SIOCBONDINFOQUERY:  	case SIOCSHWTSTAMP: @@ -3459,10 +3289,13 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,  	case SIOCGSKNS:  	case SIOCGSTAMP_NEW:  	case SIOCGSTAMPNS_NEW: +	case SIOCGIFCONF:  		return sock_ioctl(file, cmd, arg);  	case SIOCGIFFLAGS:  	case SIOCSIFFLAGS: +	case SIOCGIFMAP: +	case SIOCSIFMAP:  	case SIOCGIFMETRIC:  	case SIOCSIFMETRIC:  	case SIOCGIFMTU: @@ -3499,8 +3332,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,  	case SIOCBONDRELEASE:  	case SIOCBONDSETHWADDR:  	case SIOCBONDCHANGEACTIVE: -		return compat_ifreq_ioctl(net, sock, cmd, argp); -  	case SIOCSARP:  	case SIOCGARP:  	case SIOCDARP:  | 
