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

📄 wanmain.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	default:		printk(KERN_INFO			"%s: unsupported NLPID 0x%02X on interface %s!\n",			modname, skb->data[cnt], dev->name);		return 0;	}	skb->protocol = ethertype;	skb->pkt_type = PACKET_HOST;	/*	Physically point to point */	skb->mac.raw  = skb->data;	skb_pull(skb, cnt);	return ethertype;}/* *	WAN device IOCTL. *	o find WAN device associated with this node *	o execute requested action or pass command to the device driver */int wanrouter_ioctl(struct inode *inode, struct file *file,		unsigned int cmd, unsigned long arg){	int err = 0;	struct proc_dir_entry *dent;	wan_device_t *wandev;	if (!capable(CAP_NET_ADMIN)){		return -EPERM;	}			if ((cmd >> 8) != ROUTER_IOCTL)		return -EINVAL;			dent = inode->u.generic_ip;	if ((dent == NULL) || (dent->data == NULL))		return -EINVAL;			wandev = dent->data;	if (wandev->magic != ROUTER_MAGIC)		return -EINVAL;			switch (cmd) {	case ROUTER_SETUP:		err = device_setup(wandev, (void*)arg);		break;	case ROUTER_DOWN:		err = device_shutdown(wandev);		break;	case ROUTER_STAT:		err = device_stat(wandev, (void*)arg);		break;	case ROUTER_IFNEW:		err = device_new_if(wandev, (void*)arg);		break;	case ROUTER_IFDEL:		err = device_del_if(wandev, (void*)arg);		break;	case ROUTER_IFSTAT:		break;	default:		if ((cmd >= ROUTER_USER) &&		    (cmd <= ROUTER_USER_MAX) &&		    wandev->ioctl)			err = wandev->ioctl(wandev, cmd, arg);		else err = -EINVAL;	}	return err;}/* *	WAN Driver IOCTL Handlers *//* *	Setup WAN link device. *	o verify user address space *	o allocate kernel memory and copy configuration data to kernel space *	o if configuration data includes extension, copy it to kernel space too *	o call driver's setup() entry point */static int device_setup (wan_device_t *wandev, wandev_conf_t *u_conf){	void *data = NULL;	wandev_conf_t *conf;	int err = -EINVAL;	if (wandev->setup == NULL)	/* Nothing to do ? */		return 0;	conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL);	if (conf == NULL)		return -ENOBUFS;	if(copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) {		kfree(conf);		return -EFAULT;	}		if (conf->magic != ROUTER_MAGIC) {		kfree(conf);	        return -EINVAL; 	}	if (conf->data_size && conf->data) {		if(conf->data_size > 128000 || conf->data_size < 0) {			kfree(conf);		        return -EINVAL;;		}		data = vmalloc(conf->data_size);		if (data) {			if(!copy_from_user(data, conf->data, conf->data_size)){				conf->data=data;				err = wandev->setup(wandev,conf);			}			else 				err = -EFAULT;		}		else 			err = -ENOBUFS;		if (data)			vfree(data);	}	kfree(conf);	return err;}/* *	Shutdown WAN device. *	o delete all not opened logical channels for this device *	o call driver's shutdown() entry point */ static int device_shutdown (wan_device_t* wandev){	struct net_device* dev;	if (wandev->state == WAN_UNCONFIGURED)		return 0;			for (dev = wandev->dev; dev;)	{		if (delete_interface(wandev, dev->name, 0))		{			struct net_device **slave = dev->priv;			dev = *slave;		}	}	if (wandev->ndev)		return -EBUSY;	/* there are opened interfaces  */			if (wandev->shutdown)		return wandev->shutdown(wandev);	return 0;}/* *	Get WAN device status & statistics. */static int device_stat (wan_device_t *wandev, wandev_stat_t *u_stat){	wandev_stat_t stat;	memset(&stat, 0, sizeof(stat));	/* Ask device driver to update device statistics */	if ((wandev->state != WAN_UNCONFIGURED) && wandev->update)		wandev->update(wandev);	/* Fill out structure */	stat.ndev  = wandev->ndev;	stat.state = wandev->state;	if(copy_to_user(u_stat, &stat, sizeof(stat)))		return -EFAULT;	return 0;}/* *	Create new WAN interface. *	o verify user address space *	o copy configuration data to kernel address space *	o allocate network interface data space *	o call driver's new_if() entry point *	o make sure there is no interface name conflict *	o register network interface */static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf){	wanif_conf_t conf;	struct net_device *dev;	int err;	if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))		return -ENODEV;			if(copy_from_user(&conf, u_conf, sizeof(wanif_conf_t)))		return -EFAULT;			if (conf.magic != ROUTER_MAGIC)		return -EINVAL;			dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);	if (dev == NULL)		return -ENOBUFS;			memset(dev, 0, sizeof(struct net_device));	err = wandev->new_if(wandev, dev, &conf);	if (!err) {		/* Register network interface. This will invoke init()		 * function supplied by the driver.  If device registered		 * successfully, add it to the interface list.		 */		if (dev->name == NULL)			err = -EINVAL;					else if (dev_get(dev->name))			err = -EEXIST;	/* name already exists */		else {#ifdef WANDEBUG					printk(KERN_INFO "%s: registering interface %s...\n",				modname, dev->name);#endif							err = register_netdev(dev);			if (!err) {				struct net_device **slave = dev->priv;				cli();	/***** critical section start *****/				*slave = wandev->dev;				wandev->dev = dev;				++wandev->ndev;				sti();	/****** critical section end ******/				return 0;	/* done !!! */			}		}		if (wandev->del_if)			wandev->del_if(wandev, dev);	}	kfree(dev);	return err;}/* *	Delete WAN logical channel. *	 o verify user address space *	 o copy configuration data to kernel address space */static int device_del_if (wan_device_t *wandev, char *u_name){	char name[WAN_IFNAME_SZ + 1];	if (wandev->state == WAN_UNCONFIGURED)		return -ENODEV;		memset(name, 0, sizeof(name));	if(copy_from_user(name, u_name, WAN_IFNAME_SZ))		return -EFAULT;	return delete_interface(wandev, name, 0);}/* *	Miscellaneous Functions *//* *	Find WAN device by name. *	Return pointer to the WAN device data space or NULL if device not found. */static wan_device_t *find_device(char *name){	wan_device_t *wandev;	for (wandev = router_devlist;wandev && strcmp(wandev->name, name);		wandev = wandev->next);	return wandev;}/* *	Delete WAN logical channel identified by its name. *	o find logical channel by its name *	o call driver's del_if() entry point *	o unregister network interface *	o unlink channel data space from linked list of channels *	o release channel data space * *	Return:	0		success *		-ENODEV		channel not found. *		-EBUSY		interface is open * *	Note: If (force != 0), then device will be destroyed even if interface *	associated with it is open. It's caller's responsibility to make *	sure that opened interfaces are not removed! */static int delete_interface (wan_device_t *wandev, char *name, int force){	struct net_device *dev, *prev;	dev = wandev->dev;	prev = NULL;	while (dev && strcmp(name, dev->name)) {		struct net_device **slave = dev->priv;		prev = dev;		dev = *slave;	}	if (dev == NULL)		return -ENODEV;	/* interface not found */	if (netif_running(dev)) {		if (force) {			printk(KERN_WARNING				"%s: deleting opened interface %s!\n",				modname, name);		}		else			return -EBUSY;	/* interface in use */	}	if (wandev->del_if)		wandev->del_if(wandev, dev);	cli();			/***** critical section start *****/	if (prev) {		struct net_device **prev_slave = prev->priv;		struct net_device **slave = dev->priv;		*prev_slave = *slave;	} else {		struct net_device **slave = dev->priv;		wandev->dev = *slave;	}	--wandev->ndev;	sti();			/****** critical section end ******/	printk("Unregistering '%s'\n", dev->name); 	unregister_netdev(dev);	kfree(dev);	return 0;}EXPORT_SYMBOL(register_wan_device);EXPORT_SYMBOL(unregister_wan_device);EXPORT_SYMBOL(wanrouter_encapsulate);EXPORT_SYMBOL(wanrouter_type_trans);/* *	End */

⌨️ 快捷键说明

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