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

📄 wanmain.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 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 managenment (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/config.h>#include <linux/stddef.h>	/* offsetof(), etc. */#include <linux/errno.h>	/* return codes */#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>	/* support for loadable modules */#include <linux/slab.h>	/* kmalloc(), kfree() */#include <linux/mm.h>		/* verify_area(), etc. */#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/***********FOR DEBUGGING PURPOSES*********************************************static void * dbg_kmalloc(unsigned int size, int prio, int line) {	int i = 0;	void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);	char * c1 = v;	c1 += sizeof(unsigned int);	*((unsigned int *)v) = size;	for (i = 0; i < KMEM_SAFETYZONE; i++) {		c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';		c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';		c1 += 8;	}	c1 += size;	for (i = 0; i < KMEM_SAFETYZONE; i++) {		c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';		c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';		c1 += 8;	}	v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;	printk(KERN_INFO "line %d  kmalloc(%d,%d) = %p\n",line,size,prio,v);	return v;}static void dbg_kfree(void * v, int line) {	unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));	unsigned int size = *sp;	char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;	int i = 0;	for (i = 0; i < KMEM_SAFETYZONE; i++) {		if (   c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'		    || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {			printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v);			printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,			                c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );		}		c1 += 8;	}	c1 += size;	for (i = 0; i < KMEM_SAFETYZONE; i++) {		if (   c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'		    || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'		   ) {			printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v);			printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,			                c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );		}		c1 += 8;	}	printk(KERN_INFO "line %d  kfree(%p)\n",line,v);	v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);	kfree(v);}#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)#define kfree(x) dbg_kfree(x,__LINE__)*****************************************************************************//* * 	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);void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);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 */static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };#if 0static 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;}/* *	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;		memcpy(&skb->data[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. */unsigned short wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev){	int cnt = skb->data[0] ? 0 : 1;	/* there may be a pad present */	unsigned short 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 = *((unsigned short*)&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->mac.raw  = skb->data;	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;	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;

⌨️ 快捷键说明

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