#endif  
#endif  
int sock_setsockopt(struct socket *sock, int level, int optname,		    char __user *optval, int optlen){	struct sock *sk=sock->sk;	struct sk_filter *filter;	int val;	int valbool;	struct linger ling;	int ret = 0;		/*	 *	Options without arguments	 */#ifdef SO_DONTLINGER		/* Compatibility item... */	switch (optname) {		case SO_DONTLINGER:			sock_reset_flag(sk, SOCK_LINGER);			return 0;	}#endif			  	if(optlen<sizeof(int))  		return(-EINVAL);  		if (get_user(val, (int __user *)optval))		return -EFAULT;	  	valbool = val?1:0;	lock_sock(sk);  	switch(optname)   	{		case SO_DEBUG:				if(val && !capable(CAP_NET_ADMIN))			{				ret = -EACCES;			}			else if (valbool)				sock_set_flag(sk, SOCK_DBG);			else				sock_reset_flag(sk, SOCK_DBG);			break;		case SO_REUSEADDR:			sk->sk_reuse = valbool;			break;		case SO_TYPE:		case SO_ERROR:			ret = -ENOPROTOOPT;		  	break;		case SO_DONTROUTE:			if (valbool)				sock_set_flag(sk, SOCK_LOCALROUTE);			else				sock_reset_flag(sk, SOCK_LOCALROUTE);			break;		case SO_BROADCAST:			sock_valbool_flag(sk, SOCK_BROADCAST, valbool);			break;		case SO_SNDBUF:			/* Don't error on this BSD doesn't and if you think			   about it this is right. Otherwise apps have to			   play 'guess the biggest size' games. RCVBUF/SNDBUF			   are treated in BSD as hints */			   			if (val > sysctl_wmem_max)				val = sysctl_wmem_max;			sk->sk_userlocks |= SOCK_SNDBUF_LOCK;			if ((val * 2) < SOCK_MIN_SNDBUF)				sk->sk_sndbuf = SOCK_MIN_SNDBUF;			else				sk->sk_sndbuf = val * 2;			/*			 *	Wake up sending tasks if we			 *	upped the value.			 */			sk->sk_write_space(sk);			break;		case SO_RCVBUF:			/* Don't error on this BSD doesn't and if you think			   about it this is right. Otherwise apps have to			   play 'guess the biggest size' games. RCVBUF/SNDBUF			   are treated in BSD as hints */			  			if (val > sysctl_rmem_max)				val = sysctl_rmem_max;			sk->sk_userlocks |= SOCK_RCVBUF_LOCK;			/* FIXME: is this lower bound the right one? */			if ((val * 2) < SOCK_MIN_RCVBUF)				sk->sk_rcvbuf = SOCK_MIN_RCVBUF;			else				sk->sk_rcvbuf = val * 2;			break;		case SO_KEEPALIVE:#ifdef CONFIG_INET			if (sk->sk_protocol == IPPROTO_TCP)				tcp_set_keepalive(sk, valbool);#endif			sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);			break;	 	case SO_OOBINLINE:			sock_valbool_flag(sk, SOCK_URGINLINE, valbool);			break;	 	case SO_NO_CHECK:			sk->sk_no_check = valbool;			break;		case SO_PRIORITY:			if ((val >= 0 && val <= 6) || capable(CAP_NET_ADMIN)) 				sk->sk_priority = val;			else				ret = -EPERM;			break;		case SO_LINGER:			if(optlen<sizeof(ling)) {				ret = -EINVAL;	/* 1003.1g */				break;			}			if (copy_from_user(&ling,optval,sizeof(ling))) {				ret = -EFAULT;				break;			}			if (!ling.l_onoff)				sock_reset_flag(sk, SOCK_LINGER);			else {#if (BITS_PER_LONG == 32)				if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)					sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;				else#endif					sk->sk_lingertime = ling.l_linger * HZ;				sock_set_flag(sk, SOCK_LINGER);			}			break;		case SO_BSDCOMPAT:			sock_warn_obsolete_bsdism("setsockopt");			break;		case SO_PASSCRED:			if (valbool)				set_bit(SOCK_PASSCRED, &sock->flags);			else				clear_bit(SOCK_PASSCRED, &sock->flags);			break;		case SO_TIMESTAMP:			if (valbool)  {				sock_set_flag(sk, SOCK_RCVTSTAMP);				sock_enable_timestamp(sk);			} else				sock_reset_flag(sk, SOCK_RCVTSTAMP);			break;		case SO_RCVLOWAT:			if (val < 0)				val = INT_MAX;			sk->sk_rcvlowat = val ? : 1;			break;		case SO_RCVTIMEO:			ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen);			break;		case SO_SNDTIMEO:			ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen);			break;#ifdef CONFIG_NETDEVICES		case SO_BINDTODEVICE:		{			char devname[IFNAMSIZ]; 			/* Sorry... */ 			if (!capable(CAP_NET_RAW)) {				ret = -EPERM;				break;			}			/* Bind this socket to a particular device like "eth0",			 * as specified in the passed interface name. If the			 * name is "" or the option length is zero the socket 			 * is not bound. 			 */ 			if (!valbool) {				sk->sk_bound_dev_if = 0;			} else {				if (optlen > IFNAMSIZ) 					optlen = IFNAMSIZ; 				if (copy_from_user(devname, optval, optlen)) {					ret = -EFAULT;					break;				}				/* Remove any cached route for this socket. */				sk_dst_reset(sk);				if (devname[0] == '\0') {					sk->sk_bound_dev_if = 0;				} else {					struct net_device *dev = dev_get_by_name(devname);					if (!dev) {						ret = -ENODEV;						break;					}					sk->sk_bound_dev_if = dev->ifindex;					dev_put(dev);				}			}			break;		}#endif		case SO_ATTACH_FILTER:			ret = -EINVAL;			if (optlen == sizeof(struct sock_fprog)) {				struct sock_fprog fprog;				ret = -EFAULT;				if (copy_from_user(&fprog, optval, sizeof(fprog)))					break;				ret = sk_attach_filter(&fprog, sk);			}			break;		case SO_DETACH_FILTER:			spin_lock_bh(&sk->sk_lock.slock);			filter = sk->sk_filter;                        if (filter) {				sk->sk_filter = NULL;				spin_unlock_bh(&sk->sk_lock.slock);				sk_filter_release(sk, filter);				break;			}			spin_unlock_bh(&sk->sk_lock.slock);			ret = -ENONET;			break;		/* We implement the SO_SNDLOWAT etc to		   not be settable (1003.1g 5.3) */		default:		  	ret = -ENOPROTOOPT;			break;  	}	release_sock(sk);	return ret;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/a77be819f94fc55627ee257f496198ad703aaad4/sock.c/buggy/net/core/sock.c