⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
	 *	 *	net_alias_dev_get(): dev_get() with added alias naming magic.	 *	only allow alias creation/deletion if (getset==SIOCSIFADDR)	 *	 */	 #ifdef CONFIG_KERNELD	dev_load(ifr.ifr_name);#endif	#ifdef CONFIG_NET_ALIAS	if ((dev = net_alias_dev_get(ifr.ifr_name, getset == SIOCSIFADDR, &err, NULL, NULL)) == NULL)		return(err);#else	if ((dev = dev_get(ifr.ifr_name)) == NULL) 			return(-ENODEV);#endif	switch(getset) 	{		case SIOCGIFFLAGS:	/* Get interface flags */			ifr.ifr_flags = (dev->flags & ~IFF_SOFTHEADERS);			goto rarok;		case SIOCSIFFLAGS:	/* Set interface flags */			{				int old_flags = dev->flags;								if(securelevel>0)					ifr.ifr_flags&=~IFF_PROMISC;				/*				 *	We are not allowed to potentially close/unload				 *	a device until we get this lock.				 */								dev_lock_wait();								/*				 *	Set the flags on our device.				 */				 				dev->flags = (ifr.ifr_flags & (					IFF_BROADCAST | IFF_DEBUG | IFF_LOOPBACK |					IFF_POINTOPOINT | IFF_NOTRAILERS | IFF_RUNNING |					IFF_NOARP | IFF_PROMISC | IFF_ALLMULTI | IFF_SLAVE | IFF_MASTER					| IFF_MULTICAST)) | (dev->flags & (IFF_SOFTHEADERS|IFF_UP));				/*				 *	Load in the correct multicast list now the flags have changed.				 */								dev_mc_upload(dev);			  	/*			  	 *	Have we downed the interface. We handle IFF_UP ourselves			  	 *	according to user attempts to set it, rather than blindly			  	 *	setting it.			  	 */			  	 			  	if ((old_flags^ifr.ifr_flags)&IFF_UP)	/* Bit is different  ? */			  	{					if(old_flags&IFF_UP)		/* Gone down */						ret=dev_close(dev); 							else				/* Come up */					{						ret=dev_open(dev);						if(ret<0)							dev->flags&=~IFF_UP;	/* Open failed */					}				  	}			  	else			  		ret=0;				/*				 *	Load in the correct multicast list now the flags have changed.				 */								dev_mc_upload(dev);			}			break;				case SIOCGIFADDR:	/* Get interface address (and family) */			if(ifr.ifr_addr.sa_family==AF_UNSPEC)			{				memcpy(ifr.ifr_hwaddr.sa_data,dev->dev_addr, MAX_ADDR_LEN);				ifr.ifr_hwaddr.sa_family=dev->type;							goto rarok;			}			else			{				(*(struct sockaddr_in *)					  &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;				(*(struct sockaddr_in *)					  &ifr.ifr_addr).sin_family = dev->family;				(*(struct sockaddr_in *)					  &ifr.ifr_addr).sin_port = 0;			}			goto rarok;			case SIOCSIFADDR:	/* Set interface address (and family) */					/*			 *	BSDism. SIOCSIFADDR family=AF_UNSPEC sets the			 *	physical address. We can cope with this now.			 */						if(ifr.ifr_addr.sa_family==AF_UNSPEC)			{				if(dev->set_mac_address==NULL)					return -EOPNOTSUPP;				if(securelevel>0)					return -EPERM;				ret=dev->set_mac_address(dev,&ifr.ifr_addr);			}			else			{				u32 new_pa_addr = (*(struct sockaddr_in *)					 &ifr.ifr_addr).sin_addr.s_addr;				u16 new_family = ifr.ifr_addr.sa_family;				if (new_family == dev->family &&				    new_pa_addr == dev->pa_addr) {					ret =0;					break;				}				if (dev->flags & IFF_UP)					notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);				/*				 *	if dev is an alias, must rehash to update				 *	address change				 */#ifdef CONFIG_NET_ALIAS			  	if (net_alias_is(dev))				    	net_alias_dev_rehash(dev ,&ifr.ifr_addr);#endif				dev->pa_addr = new_pa_addr;				dev->family = new_family;			#ifdef CONFIG_INET					/* This is naughty. When net-032e comes out It wants moving into the net032				   code not the kernel. Till then it can sit here (SIGH) */						if (!dev->pa_mask)					dev->pa_mask = ip_get_mask(dev->pa_addr);#endif							if (!dev->pa_brdaddr)					dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;				if (dev->flags & IFF_UP)					notifier_call_chain(&netdev_chain, NETDEV_UP, dev);				ret = 0;			}			break;					case SIOCGIFBRDADDR:	/* Get the broadcast address */			(*(struct sockaddr_in *)				&ifr.ifr_broadaddr).sin_addr.s_addr = dev->pa_brdaddr;			(*(struct sockaddr_in *)				&ifr.ifr_broadaddr).sin_family = dev->family;			(*(struct sockaddr_in *)				&ifr.ifr_broadaddr).sin_port = 0;			goto rarok;		case SIOCSIFBRDADDR:	/* Set the broadcast address */			dev->pa_brdaddr = (*(struct sockaddr_in *)				&ifr.ifr_broadaddr).sin_addr.s_addr;			ret = 0;			break;					case SIOCGIFDSTADDR:	/* Get the destination address (for point-to-point links) */			(*(struct sockaddr_in *)				&ifr.ifr_dstaddr).sin_addr.s_addr = dev->pa_dstaddr;			(*(struct sockaddr_in *)				&ifr.ifr_dstaddr).sin_family = dev->family;			(*(struct sockaddr_in *)				&ifr.ifr_dstaddr).sin_port = 0;			goto rarok;			case SIOCSIFDSTADDR:	/* Set the destination address (for point-to-point links) */			dev->pa_dstaddr = (*(struct sockaddr_in *)				&ifr.ifr_dstaddr).sin_addr.s_addr;			ret = 0;			break;					case SIOCGIFNETMASK:	/* Get the netmask for the interface */			(*(struct sockaddr_in *)				&ifr.ifr_netmask).sin_addr.s_addr = dev->pa_mask;			(*(struct sockaddr_in *)				&ifr.ifr_netmask).sin_family = dev->family;			(*(struct sockaddr_in *)				&ifr.ifr_netmask).sin_port = 0;			goto rarok;		case SIOCSIFNETMASK: 	/* Set the netmask for the interface */			{				unsigned long mask = (*(struct sockaddr_in *)					&ifr.ifr_netmask).sin_addr.s_addr;				ret = -EINVAL;				/*				 *	The mask we set must be legal.				 */				if (bad_mask(mask,0))					break;				dev->pa_mask = mask;				ret = 0;			}			break;					case SIOCGIFMETRIC:	/* Get the metric on the interface (currently unused) */						ifr.ifr_metric = dev->metric;			goto  rarok;					case SIOCSIFMETRIC:	/* Set the metric on the interface (currently unused) */			dev->metric = ifr.ifr_metric;			ret=0;			break;			case SIOCGIFMTU:	/* Get the MTU of a device */			ifr.ifr_mtu = dev->mtu;			goto rarok;			case SIOCSIFMTU:	/* Set the MTU of a device */					if (dev->change_mtu)				ret = dev->change_mtu(dev, ifr.ifr_mtu);			else			{				/*				 *	MTU must be positive.				 */			 				if(ifr.ifr_mtu<68)					return -EINVAL;				dev->mtu = ifr.ifr_mtu;				ret = 0;			}			break;			case SIOCGIFMEM:	/* Get the per device memory space. We can add this but currently					   do not support it */			ret = -EINVAL;			break;				case SIOCSIFMEM:	/* Set the per device memory buffer space. Not applicable in our case */			ret = -EINVAL;			break;		case SIOCGIFHWADDR:			memcpy(ifr.ifr_hwaddr.sa_data,dev->dev_addr, MAX_ADDR_LEN);			ifr.ifr_hwaddr.sa_family=dev->type;						goto rarok;						case SIOCSIFHWADDR:			if(dev->set_mac_address==NULL)				return -EOPNOTSUPP;			if(securelevel > 0)				return -EPERM;			if(ifr.ifr_hwaddr.sa_family!=dev->type)				return -EINVAL;			ret=dev->set_mac_address(dev,&ifr.ifr_hwaddr);			break;					case SIOCGIFMAP:			ifr.ifr_map.mem_start=dev->mem_start;			ifr.ifr_map.mem_end=dev->mem_end;			ifr.ifr_map.base_addr=dev->base_addr;			ifr.ifr_map.irq=dev->irq;			ifr.ifr_map.dma=dev->dma;			ifr.ifr_map.port=dev->if_port;			goto rarok;					case SIOCSIFMAP:			if(dev->set_config==NULL)				return -EOPNOTSUPP;			return dev->set_config(dev,&ifr.ifr_map);					case SIOCADDMULTI:			if(dev->set_multicast_list==NULL)				return -EINVAL;			if(ifr.ifr_hwaddr.sa_family!=AF_UNSPEC)				return -EINVAL;			dev_mc_add(dev,ifr.ifr_hwaddr.sa_data, dev->addr_len, 1);			return 0;		case SIOCDELMULTI:			if(dev->set_multicast_list==NULL)				return -EINVAL;			if(ifr.ifr_hwaddr.sa_family!=AF_UNSPEC)				return -EINVAL;			dev_mc_delete(dev,ifr.ifr_hwaddr.sa_data,dev->addr_len, 1);			return 0;		/*		 *	Unknown or private ioctl		 */		default:			if((getset >= SIOCDEVPRIVATE) &&			   (getset <= (SIOCDEVPRIVATE + 15))) {				if(dev->do_ioctl==NULL)					return -EOPNOTSUPP;				ret=dev->do_ioctl(dev, &ifr, getset);				memcpy_tofs(arg,&ifr,sizeof(struct ifreq));				break;			}#ifdef CONFIG_NET_RADIO			if((getset >= SIOCIWFIRST) &&			   (getset <= SIOCIWLAST))			{				if(dev->do_ioctl==NULL)					return -EOPNOTSUPP;				/* Perform the ioctl */				ret=dev->do_ioctl(dev, &ifr, getset);				/* If return args... */				if(IW_IS_GET(getset))					memcpy_tofs(arg, &ifr,						    sizeof(struct ifreq));				break;			}#endif	/* CONFIG_NET_RADIO */			ret = -EINVAL;	}	return(ret);/* *	The load of calls that return an ifreq and ok (saves memory). */rarok:	memcpy_tofs(arg, &ifr, sizeof(struct ifreq));	return 0;}/* *	This function handles all "interface"-type I/O control requests. The actual *	'doing' part of this is dev_ifsioc above. */int dev_ioctl(unsigned int cmd, void *arg){	switch(cmd) 	{		case SIOCGIFCONF:			(void) dev_ifconf((char *) arg);			return 0;		/*		 *	Ioctl calls that can be done by all.		 */		 		case SIOCGIFFLAGS:		case SIOCGIFADDR:		case SIOCGIFDSTADDR:		case SIOCGIFBRDADDR:		case SIOCGIFNETMASK:		case SIOCGIFMETRIC:		case SIOCGIFMTU:		case SIOCGIFMEM:		case SIOCGIFHWADDR:		case SIOCGIFSLAVE:		case SIOCGIFMAP:			return dev_ifsioc(arg, cmd);		/*		 *	Ioctl calls requiring the power of a superuser		 */		 		case SIOCSIFFLAGS:		case SIOCSIFADDR:		case SIOCSIFDSTADDR:		case SIOCSIFBRDADDR:		case SIOCSIFNETMASK:		case SIOCSIFMETRIC:		case SIOCSIFMTU:		case SIOCSIFMEM:		case SIOCSIFHWADDR:		case SIOCSIFMAP:		case SIOCSIFSLAVE:		case SIOCADDMULTI:		case SIOCDELMULTI:			if (!suser())				return -EPERM;			return dev_ifsioc(arg, cmd);			case SIOCSIFLINK:			return -EINVAL;		/*		 *	Unknown or private ioctl.		 */			 		default:			if((cmd >= SIOCDEVPRIVATE) &&			   (cmd <= (SIOCDEVPRIVATE + 15))) {				return dev_ifsioc(arg, cmd);			}#ifdef CONFIG_NET_RADIO			if((cmd >= SIOCIWFIRST) &&			   (cmd <= SIOCIWLAST))			{				if((IW_IS_SET(cmd)) && (!suser()))					return -EPERM;				return dev_ifsioc(arg, cmd);			}#endif	/* CONFIG_NET_RADIO */			return -EINVAL;	}}/* *	Initialize the DEV module. At boot time this walks the device list and *	unhooks any devices that fail to initialise (normally hardware not  *	present) and leaves us with a valid list of present and active devices. * */extern int lance_init(void);extern int pi_init(void);extern int pt_init(void);extern int bpq_init(void);extern void sdla_setup(void);extern int dlci_setup(void);extern int sm_init(void);extern int baycom_init(void);int net_dev_init(void){	struct device *dev, **dp;	/*	 *	Initialise the packet receive queue.	 */	 	skb_queue_head_init(&backlog);		/*	 *	The bridge has to be up before the devices	 */#ifdef CONFIG_BRIDGE	 	br_init();#endif			/*	 * This is Very Ugly(tm).	 *	 * Some devices want to be initialized early..	 */#if defined(CONFIG_PI)	pi_init();#endif	#if defined(CONFIG_PT)	pt_init();#endif#if defined(CONFIG_BPQETHER)	bpq_init();#endif#if defined(CONFIG_DLCI)	dlci_setup();#endif#if defined(CONFIG_SDLA)	sdla_setup();#endif#if defined(CONFIG_BAYCOM)        baycom_init();#endif#if defined(CONFIG_SOUNDMODEM)        sm_init();#endif	/*	 *	SLHC if present needs attaching so other people see it	 *	even if not opened.	 */#if (defined(CONFIG_SLIP) && defined(CONFIG_SLIP_COMPRESSED)) \	 || defined(CONFIG_PPP) \    || (defined(CONFIG_ISDN) && defined(CONFIG_ISDN_PPP))	slhc_install();#endif		/*	 *	Add the devices.	 *	If the call to dev->init fails, the dev is removed	 *	from the chain disconnecting the device until the	 *	next reboot.	 */	dp = &dev_base;	while ((dev = *dp) != NULL)	{		int i;		for (i = 0; i < DEV_NUMBUFFS; i++)  {			skb_queue_head_init(dev->buffs + i);		}		if (dev->init && dev->init(dev)) 		{			/*			 *	It failed to come up. Unhook it.			 */			*dp = dev->next;		} 		else		{			dp = &dev->next;		}	}#ifdef CONFIG_PROC_FS	proc_net_register(&(struct proc_dir_entry) {		PROC_NET_DEV, 3, "dev",		S_IFREG | S_IRUGO, 1, 0, 0,		0, &proc_net_inode_operations,		dev_get_info	});#endif#ifdef CONFIG_NET_RADIO#ifdef CONFIG_PROC_FS	proc_net_register(&(struct proc_dir_entry) {		PROC_NET_WIRELESS, 8, "wireless",		S_IFREG | S_IRUGO, 1, 0, 0,		0, &proc_net_inode_operations,		dev_get_wireless_info	});#endif	/* CONFIG_PROC_FS */#endif	/* CONFIG_NET_RADIO */	/*		 *	Initialise net_alias engine 	 *	 *		- register net_alias device notifier	 *		- register proc entries:	/proc/net/alias_types	 *									/proc/net/aliases	 */#ifdef CONFIG_NET_ALIAS	net_alias_init();#endif	init_bh(NET_BH, net_bh);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -