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

📄 wanmain.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** wanmain.c	WAN Multiprotocol Router Module. Main code.**		This module is completely hardware-independent and provides*		the following common services for the WAN Link Drivers:*		 o WAN device management (registering, unregistering)*		 o Network interface management*		 o Physical connection management (dial-up, incoming calls)*		 o Logical connection management (switched virtual circuits)*		 o Protocol encapsulation/decapsulation** Author:	Gideon Hack** Copyright:	(c) 1995-1999 Sangoma Technologies Inc.**		This program is free software; you can redistribute it and/or*		modify it under the terms of the GNU General Public License*		as published by the Free Software Foundation; either version*		2 of the License, or (at your option) any later version.* ============================================================================* Nov 24, 2000  Nenad Corbic	Updated for 2.4.X kernels* Nov 07, 2000  Nenad Corbic	Fixed the Mulit-Port PPP for kernels 2.2.16 and*  				greater.* Aug 2,  2000  Nenad Corbic	Block the Multi-Port PPP from running on*  			        kernels 2.2.16 or greater.  The SyncPPP*  			        has changed.* Jul 13, 2000  Nenad Corbic	Added SyncPPP support* 				Added extra debugging in device_setup().* Oct 01, 1999  Gideon Hack     Update for s514 PCI card* Dec 27, 1996	Gene Kozin	Initial version (based on Sangoma's WANPIPE)* Jan 16, 1997	Gene Kozin	router_devlist made public* Jan 31, 1997  Alan Cox	Hacked it about a bit for 2.1* Jun 27, 1997  Alan Cox	realigned with vendor code* Oct 15, 1997  Farhan Thawar   changed wan_encapsulate to add a pad byte of 0* Apr 20, 1998	Alan Cox	Fixed 2.1 symbols* May 17, 1998  K. Baranowski	Fixed SNAP encapsulation in wan_encapsulate* Dec 15, 1998  Arnaldo Melo    support for firmwares of up to 128000 bytes*                               check wandev->setup return value* Dec 22, 1998  Arnaldo Melo    vmalloc/vfree used in device_setup to allocate*                               kernel memory and copy configuration data to*                               kernel space (for big firmwares)* Jun 02, 1999  Gideon Hack	Updates for Linux 2.0.X and 2.2.X kernels.*****************************************************************************/#include <linux/stddef.h>	/* offsetof(), etc. */#include <linux/capability.h>#include <linux/errno.h>	/* return codes */#include <linux/kernel.h>#include <linux/module.h>	/* support for loadable modules */#include <linux/slab.h>		/* kmalloc(), kfree() */#include <linux/mm.h>#include <linux/string.h>	/* inline mem*, str* functions */#include <asm/byteorder.h>	/* htons(), etc. */#include <linux/wanrouter.h>	/* WAN router API definitions */#include <linux/vmalloc.h>	/* vmalloc, vfree */#include <asm/uaccess.h>        /* copy_to/from_user */#include <linux/init.h>         /* __initfunc et al. */#include <net/syncppp.h>#define KMEM_SAFETYZONE 8/* * 	Function Prototypes *//* *	WAN device IOCTL handlers */static int wanrouter_device_setup(struct wan_device *wandev,				  wandev_conf_t __user *u_conf);static int wanrouter_device_stat(struct wan_device *wandev,				 wandev_stat_t __user *u_stat);static int wanrouter_device_shutdown(struct wan_device *wandev);static int wanrouter_device_new_if(struct wan_device *wandev,				   wanif_conf_t __user *u_conf);static int wanrouter_device_del_if(struct wan_device *wandev,				   char __user *u_name);/* *	Miscellaneous */static struct wan_device *wanrouter_find_device(char *name);static int wanrouter_delete_interface(struct wan_device *wandev, char *name);static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);/* *	Global Data */static char wanrouter_fullname[]  = "Sangoma WANPIPE Router";static char wanrouter_copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";static char wanrouter_modname[] = ROUTER_NAME; /* short module name */struct wan_device* wanrouter_router_devlist; /* list of registered devices *//* *	Organize Unique Identifiers for encapsulation/decapsulation */#if 0static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };#endifstatic int __init wanrouter_init(void){	int err;	printk(KERN_INFO "%s v%u.%u %s\n",	       wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,	       wanrouter_copyright);	err = wanrouter_proc_init();	if (err)		printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",		       wanrouter_modname);	return err;}static void __exit wanrouter_cleanup (void){	wanrouter_proc_cleanup();}/* * This is just plain dumb.  We should move the bugger to drivers/net/wan, * slap it first in directory and make it module_init().  The only reason * for subsys_initcall() here is that net goes after drivers (why, BTW?) */subsys_initcall(wanrouter_init);module_exit(wanrouter_cleanup);/* * 	Kernel APIs *//* * 	Register WAN device. * 	o verify device credentials * 	o create an entry for the device in the /proc/net/router directory * 	o initialize internally maintained fields of the wan_device structure * 	o link device data space to a singly-linked list * 	o if it's the first device, then start kernel 'thread' * 	o increment module use count * * 	Return: *	0	Ok *	< 0	error. * * 	Context:	process */int register_wan_device(struct wan_device *wandev){	int err, namelen;	if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) ||	    (wandev->name == NULL))		return -EINVAL;	namelen = strlen(wandev->name);	if (!namelen || (namelen > WAN_DRVNAME_SZ))		return -EINVAL;	if (wanrouter_find_device(wandev->name))		return -EEXIST;#ifdef WANDEBUG	printk(KERN_INFO "%s: registering WAN device %s\n",	       wanrouter_modname, wandev->name);#endif	/*	 *	Register /proc directory entry	 */	err = wanrouter_proc_add(wandev);	if (err) {		printk(KERN_INFO			"%s: can't create /proc/net/router/%s entry!\n",			wanrouter_modname, wandev->name);		return err;	}	/*	 *	Initialize fields of the wan_device structure maintained by the	 *	router and update local data.	 */	wandev->ndev = 0;	wandev->dev  = NULL;	wandev->next = wanrouter_router_devlist;	wanrouter_router_devlist = wandev;	return 0;}/* *	Unregister WAN device. *	o shut down device *	o unlink device data space from the linked list *	o delete device entry in the /proc/net/router directory *	o decrement module use count * *	Return:		0	Ok *			<0	error. *	Context:	process */int unregister_wan_device(char *name){	struct wan_device *wandev, *prev;	if (name == NULL)		return -EINVAL;	for (wandev = wanrouter_router_devlist, prev = NULL;		wandev && strcmp(wandev->name, name);		prev = wandev, wandev = wandev->next)		;	if (wandev == NULL)		return -ENODEV;#ifdef WANDEBUG	printk(KERN_INFO "%s: unregistering WAN device %s\n",	       wanrouter_modname, name);#endif	if (wandev->state != WAN_UNCONFIGURED)		wanrouter_device_shutdown(wandev);	if (prev)		prev->next = wandev->next;	else		wanrouter_router_devlist = wandev->next;	wanrouter_proc_delete(wandev);	return 0;}#if 0/* *	Encapsulate packet. * *	Return:	encapsulation header size *		< 0	- unsupported Ethertype * *	Notes: *	1. This function may be called on interrupt context. */int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,			  unsigned short type){	int hdr_len = 0;	switch (type) {	case ETH_P_IP:		/* IP datagram encapsulation */		hdr_len += 1;		skb_push(skb, 1);		skb->data[0] = NLPID_IP;		break;	case ETH_P_IPX:		/* SNAP encapsulation */	case ETH_P_ARP:		hdr_len += 7;		skb_push(skb, 7);		skb->data[0] = 0;		skb->data[1] = NLPID_SNAP;		skb_copy_to_linear_data_offset(skb, 2, wanrouter_oui_ether,					       sizeof(wanrouter_oui_ether));		*((unsigned short*)&skb->data[5]) = htons(type);		break;	default:		/* Unknown packet type */		printk(KERN_INFO			"%s: unsupported Ethertype 0x%04X on interface %s!\n",			wanrouter_modname, type, dev->name);		hdr_len = -EINVAL;	}	return hdr_len;}/* *	Decapsulate packet. * *	Return:	Ethertype (in network order) *			0	unknown encapsulation * *	Notes: *	1. This function may be called on interrupt context. */__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev){	int cnt = skb->data[0] ? 0 : 1;	/* there may be a pad present */	__be16 ethertype;	switch (skb->data[cnt]) {	case NLPID_IP:		/* IP datagramm */		ethertype = htons(ETH_P_IP);		cnt += 1;		break;	case NLPID_SNAP:	/* SNAP encapsulation */		if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether,			   sizeof(wanrouter_oui_ether))){			printk(KERN_INFO				"%s: unsupported SNAP OUI %02X-%02X-%02X "				"on interface %s!\n", wanrouter_modname,				skb->data[cnt+1], skb->data[cnt+2],				skb->data[cnt+3], dev->name);			return 0;		}		ethertype = *((__be16*)&skb->data[cnt+4]);		cnt += 6;		break;	/* add other protocols, e.g. CLNP, ESIS, ISIS, if needed */	default:		printk(KERN_INFO			"%s: unsupported NLPID 0x%02X on interface %s!\n",			wanrouter_modname, skb->data[cnt], dev->name);		return 0;	}	skb->protocol = ethertype;	skb->pkt_type = PACKET_HOST;	/*	Physically point to point */	skb_pull(skb, cnt);	skb_reset_mac_header(skb);	return ethertype;}#endif  /*  0  *//* *	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;	struct wan_device *wandev;	void __user *data = (void __user *)arg;	if (!capable(CAP_NET_ADMIN))		return -EPERM;	if ((cmd >> 8) != ROUTER_IOCTL)		return -EINVAL;	dent = PDE(inode);	if ((dent == NULL) || (dent->data == NULL))		return -EINVAL;	wandev = dent->data;	if (wandev->magic != ROUTER_MAGIC)		return -EINVAL;	switch (cmd) {	case ROUTER_SETUP:		err = wanrouter_device_setup(wandev, data);		break;	case ROUTER_DOWN:		err = wanrouter_device_shutdown(wandev);		break;	case ROUTER_STAT:		err = wanrouter_device_stat(wandev, data);		break;	case ROUTER_IFNEW:		err = wanrouter_device_new_if(wandev, data);		break;	case ROUTER_IFDEL:		err = wanrouter_device_del_if(wandev, data);		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 */

⌨️ 快捷键说明

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