(ifa->ifa_local|~ifa->ifa_mask))) { 
(ifa->ifa_local|~old_mask))) { 
int devinet_ioctl(unsigned int cmd, void __user *arg){	struct ifreq ifr;	struct sockaddr_in sin_orig;	struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;	struct in_device *in_dev;	struct in_ifaddr **ifap = NULL;	struct in_ifaddr *ifa = NULL;	struct net_device *dev;	char *colon;	int ret = -EFAULT;	int tryaddrmatch = 0;	/*	 *	Fetch the caller's info block into kernel space	 */	if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))		goto out;	ifr.ifr_name[IFNAMSIZ - 1] = 0;	/* save original address for comparison */	memcpy(&sin_orig, sin, sizeof(*sin));	colon = strchr(ifr.ifr_name, ':');	if (colon)		*colon = 0;#ifdef CONFIG_KMOD	dev_load(ifr.ifr_name);#endif	switch(cmd) {	case SIOCGIFADDR:	/* Get interface address */	case SIOCGIFBRDADDR:	/* Get the broadcast address */	case SIOCGIFDSTADDR:	/* Get the destination address */	case SIOCGIFNETMASK:	/* Get the netmask for the interface */		/* Note that these ioctls will not sleep,		   so that we do not impose a lock.		   One day we will be forced to put shlock here (I mean SMP)		 */		tryaddrmatch = (sin_orig.sin_family == AF_INET);		memset(sin, 0, sizeof(*sin));		sin->sin_family = AF_INET;		break;	case SIOCSIFFLAGS:		ret = -EACCES;		if (!capable(CAP_NET_ADMIN))			goto out;		break;	case SIOCSIFADDR:	/* Set interface address (and family) */	case SIOCSIFBRDADDR:	/* Set the broadcast address */	case SIOCSIFDSTADDR:	/* Set the destination address */	case SIOCSIFNETMASK: 	/* Set the netmask for the interface */		ret = -EACCES;		if (!capable(CAP_NET_ADMIN))			goto out;		ret = -EINVAL;		if (sin->sin_family != AF_INET)			goto out;		break;	default:		ret = -EINVAL;		goto out;	}	rtnl_lock();	ret = -ENODEV;	if ((dev = __dev_get_by_name(ifr.ifr_name)) == NULL)		goto done;	if (colon)		*colon = ':';	if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {		if (tryaddrmatch) {			/* Matthias Andree */			/* compare label and address (4.4BSD style) */			/* note: we only do this for a limited set of ioctls			   and only if the original address family was AF_INET.			   This is checked above. */			for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;			     ifap = &ifa->ifa_next) {				if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&				    sin_orig.sin_addr.s_addr ==							ifa->ifa_address) {					break; /* found */				}			}		}		/* we didn't get a match, maybe the application is		   4.3BSD-style and passed in junk so we fall back to		   comparing just the label */		if (!ifa) {			for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;			     ifap = &ifa->ifa_next)				if (!strcmp(ifr.ifr_name, ifa->ifa_label))					break;		}	}	ret = -EADDRNOTAVAIL;	if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)		goto done;	switch(cmd) {	case SIOCGIFADDR:	/* Get interface address */		sin->sin_addr.s_addr = ifa->ifa_local;		goto rarok;	case SIOCGIFBRDADDR:	/* Get the broadcast address */		sin->sin_addr.s_addr = ifa->ifa_broadcast;		goto rarok;	case SIOCGIFDSTADDR:	/* Get the destination address */		sin->sin_addr.s_addr = ifa->ifa_address;		goto rarok;	case SIOCGIFNETMASK:	/* Get the netmask for the interface */		sin->sin_addr.s_addr = ifa->ifa_mask;		goto rarok;	case SIOCSIFFLAGS:		if (colon) {			ret = -EADDRNOTAVAIL;			if (!ifa)				break;			ret = 0;			if (!(ifr.ifr_flags & IFF_UP))				inet_del_ifa(in_dev, ifap, 1);			break;		}		ret = dev_change_flags(dev, ifr.ifr_flags);		break;	case SIOCSIFADDR:	/* Set interface address (and family) */		ret = -EINVAL;		if (inet_abc_len(sin->sin_addr.s_addr) < 0)			break;		if (!ifa) {			ret = -ENOBUFS;			if ((ifa = inet_alloc_ifa()) == NULL)				break;			if (colon)				memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);			else				memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);		} else {			ret = 0;			if (ifa->ifa_local == sin->sin_addr.s_addr)				break;			inet_del_ifa(in_dev, ifap, 0);			ifa->ifa_broadcast = 0;			ifa->ifa_anycast = 0;		}		ifa->ifa_address = ifa->ifa_local = sin->sin_addr.s_addr;		if (!(dev->flags & IFF_POINTOPOINT)) {			ifa->ifa_prefixlen = inet_abc_len(ifa->ifa_address);			ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);			if ((dev->flags & IFF_BROADCAST) &&			    ifa->ifa_prefixlen < 31)				ifa->ifa_broadcast = ifa->ifa_address |						     ~ifa->ifa_mask;		} else {			ifa->ifa_prefixlen = 32;			ifa->ifa_mask = inet_make_mask(32);		}		ret = inet_set_ifa(dev, ifa);		break;	case SIOCSIFBRDADDR:	/* Set the broadcast address */		ret = 0;		if (ifa->ifa_broadcast != sin->sin_addr.s_addr) {			inet_del_ifa(in_dev, ifap, 0);			ifa->ifa_broadcast = sin->sin_addr.s_addr;			inet_insert_ifa(ifa);		}		break;	case SIOCSIFDSTADDR:	/* Set the destination address */		ret = 0;		if (ifa->ifa_address == sin->sin_addr.s_addr)			break;		ret = -EINVAL;		if (inet_abc_len(sin->sin_addr.s_addr) < 0)			break;		ret = 0;		inet_del_ifa(in_dev, ifap, 0);		ifa->ifa_address = sin->sin_addr.s_addr;		inet_insert_ifa(ifa);		break;	case SIOCSIFNETMASK: 	/* Set the netmask for the interface */		/*		 *	The mask we set must be legal.		 */		ret = -EINVAL;		if (bad_mask(sin->sin_addr.s_addr, 0))			break;		ret = 0;		if (ifa->ifa_mask != sin->sin_addr.s_addr) {			inet_del_ifa(in_dev, ifap, 0);			ifa->ifa_mask = sin->sin_addr.s_addr;			ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);			/* See if current broadcast address matches			 * with current netmask, then recalculate			 * the broadcast address. Otherwise it's a			 * funny address, so don't touch it since			 * the user seems to know what (s)he's doing...			 */			if ((dev->flags & IFF_BROADCAST) &&			    (ifa->ifa_prefixlen < 31) &&			    (ifa->ifa_broadcast ==			     (ifa->ifa_local|~ifa->ifa_mask))) {				ifa->ifa_broadcast = (ifa->ifa_local |						      ~sin->sin_addr.s_addr);			}			inet_insert_ifa(ifa);		}		break;	}done:	rtnl_unlock();out:	return ret;rarok:	rtnl_unlock();	ret = copy_to_user(arg, &ifr, sizeof(struct ifreq)) ? -EFAULT : 0;	goto out;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/dcab5e1eeccf5e226c771ecc013631cde157435f/devinet.c/clean/net/ipv4/devinet.c