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

📄 ieee80211_linux.c

📁 Linux下wifi实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (pv->rbuf)		vfree(pv->rbuf);	if (pv->wbuf)		vfree(pv->wbuf);	kfree(pv);	return 0;}static struct file_operations proc_ieee80211_ops = {        .read = proc_ieee80211_read,        .write = proc_ieee80211_write,        .open = proc_ieee80211_open,        .release = proc_ieee80211_close,};#ifdef IEEE80211_DEBUGstatic intIEEE80211_SYSCTL_DECL(ieee80211_sysctl_debug, ctl, write, filp, buffer,	lenp, ppos){	struct ieee80211vap *vap = ctl->extra1;	u_int val;	int ret;	ctl->data = &val;	ctl->maxlen = sizeof(val);	if (write) {		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);		if (ret == 0)			vap->iv_debug = val;	} else {		val = vap->iv_debug;		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);	}	return ret;}#endif /* IEEE80211_DEBUG */static intIEEE80211_SYSCTL_DECL(ieee80211_sysctl_dev_type, ctl, write, filp, buffer,	lenp, ppos){	struct ieee80211vap *vap = ctl->extra1;	u_int val;	int ret;	ctl->data = &val;	ctl->maxlen = sizeof(val);	if (write) {		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);		if (ret == 0 && vap->iv_opmode == IEEE80211_M_MONITOR) {			if (val == ARPHRD_IEEE80211_RADIOTAP ||			    val == ARPHRD_IEEE80211 ||			    val == ARPHRD_IEEE80211_PRISM ||			    val == ARPHRD_IEEE80211_ATHDESC) {				vap->iv_dev->type = val;			}		}	} else {		val = vap->iv_dev->type;		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);	}	return ret;}static intIEEE80211_SYSCTL_DECL(ieee80211_sysctl_monitor_nods_only, ctl, write, filp, buffer,	lenp, ppos){	struct ieee80211vap *vap = ctl->extra1;	u_int val;	int ret;	ctl->data = &val;	ctl->maxlen = sizeof(val);	if (write) {		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);		if (ret == 0)			vap->iv_monitor_nods_only = val;	} else {		val = vap->iv_monitor_nods_only;		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);	}	return ret;}static intIEEE80211_SYSCTL_DECL(ieee80211_sysctl_monitor_txf_len, ctl, write, filp, buffer,	lenp, ppos){	struct ieee80211vap *vap = ctl->extra1;	u_int val;	int ret;	ctl->data = &val;	ctl->maxlen = sizeof(val);	if (write) {		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);		if (ret == 0)			vap->iv_monitor_txf_len = val;	} else {		val = vap->iv_monitor_txf_len;		ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer,			lenp, ppos);	}	return ret;}#define	CTL_AUTO	-2	/* cannot be CTL_ANY or CTL_NONE */static const ctl_table ieee80211_sysctl_template[] = {#ifdef IEEE80211_DEBUG	{ .ctl_name	= CTL_AUTO,	  .procname	= "debug",	  .mode		= 0644,	  .proc_handler	= ieee80211_sysctl_debug	},#endif	{ .ctl_name	= CTL_AUTO,	  .procname	= "dev_type",	  .mode		= 0644,	  .proc_handler	= ieee80211_sysctl_dev_type	},	{ .ctl_name	= CTL_AUTO,	  .procname	= "monitor_nods_only",	  .mode		= 0644,	  .proc_handler	= ieee80211_sysctl_monitor_nods_only	},	{ .ctl_name	= CTL_AUTO,	  .procname	= "monitor_txf_len",	  .mode		= 0644,	  .proc_handler	= ieee80211_sysctl_monitor_txf_len	},	/* NB: must be last entry before NULL */	{ .ctl_name	= CTL_AUTO,	  .procname	= "%parent",	  .maxlen	= IFNAMSIZ,	  .mode		= 0444,	  .proc_handler	= proc_dostring	},	{ 0 }};voidieee80211_sysctl_vattach(struct ieee80211vap *vap){	int i, space;	char *devname = NULL;	struct ieee80211_proc_entry *tmp=NULL;		space = 5 * sizeof(struct ctl_table) + sizeof(ieee80211_sysctl_template);	vap->iv_sysctls = kmalloc(space, GFP_KERNEL);	if (vap->iv_sysctls == NULL) {		printk("%s: no memory for sysctl table!\n", __func__);		return;	}	/*	 * Reserve space for the device name outside the net_device structure	 * so that if the name changes we know what it used to be. 	 */	devname = kmalloc((strlen(vap->iv_dev->name) + 1) * sizeof(char), GFP_KERNEL);	if (devname == NULL) {		printk("%s: no memory for VAP name!\n", __func__);		return;	}	strncpy(devname, vap->iv_dev->name, strlen(vap->iv_dev->name) + 1);	/* setup the table */	memset(vap->iv_sysctls, 0, space);	vap->iv_sysctls[0].ctl_name = CTL_NET;	vap->iv_sysctls[0].procname = "net";	vap->iv_sysctls[0].mode = 0555;	vap->iv_sysctls[0].child = &vap->iv_sysctls[2];	/* [1] is NULL terminator */	vap->iv_sysctls[2].ctl_name = CTL_AUTO;	vap->iv_sysctls[2].procname = devname; /* XXX bad idea? */	vap->iv_sysctls[2].mode = 0555;	vap->iv_sysctls[2].child = &vap->iv_sysctls[4];	/* [3] is NULL terminator */	/* copy in pre-defined data */	memcpy(&vap->iv_sysctls[4], ieee80211_sysctl_template,		sizeof(ieee80211_sysctl_template));	/* add in dynamic data references */	for (i = 4; vap->iv_sysctls[i].ctl_name; i++)		if (vap->iv_sysctls[i].extra1 == NULL)			vap->iv_sysctls[i].extra1 = vap;	/* tack on back-pointer to parent device */	vap->iv_sysctls[i-1].data = vap->iv_ic->ic_dev->name;	/* XXX? */	/* and register everything */	vap->iv_sysctl_header = register_sysctl_table(vap->iv_sysctls, 1);	if (!vap->iv_sysctl_header) {		printk("%s: failed to register sysctls!\n", vap->iv_dev->name);		kfree(vap->iv_sysctls);		vap->iv_sysctls = NULL;	}	/* Ensure the base madwifi directory exists */	if (!proc_madwifi && proc_net != NULL) {		proc_madwifi = proc_mkdir("madwifi", proc_net);		if (!proc_madwifi)			printk(KERN_WARNING "Failed to mkdir /proc/net/madwifi\n");	}	/* Create a proc directory named after the VAP */	if (proc_madwifi) {		proc_madwifi_count++;		vap->iv_proc = proc_mkdir(vap->iv_dev->name, proc_madwifi);	}		/* Create a proc entry listing the associated stations */	ieee80211_proc_vcreate(vap, &proc_ieee80211_ops, "associated_sta");	/* Recreate any other proc entries that have been registered */		if (vap->iv_proc) {		tmp = vap->iv_proc_entries;		while (tmp) {			if (!tmp->entry) {				tmp->entry = create_proc_entry(tmp->name, 				PROC_IEEE80211_PERM, vap->iv_proc);				tmp->entry->data = vap;				tmp->entry->proc_fops = tmp->fileops;			}			tmp = tmp->next;		}	}}/* Frees all memory used for the list of proc entries */void ieee80211_proc_cleanup(struct ieee80211vap *vap){	struct ieee80211_proc_entry *tmp=vap->iv_proc_entries;	struct ieee80211_proc_entry *next = NULL;	while (tmp) {		next = tmp->next;		kfree(tmp);		tmp = next;	}}/* Called by other modules to register a proc entry under the vap directory */int ieee80211_proc_vcreate(struct ieee80211vap *vap, 		struct file_operations *fileops, char *name){	struct ieee80211_proc_entry *entry;	struct ieee80211_proc_entry *tmp=NULL;	/* Ignore if already in the list */	if (vap->iv_proc_entries) {		tmp = vap->iv_proc_entries;		do {			if (strcmp(tmp->name, name)==0)				return -1;			/* Check for end of list */			if (!tmp->next)				break;			/* Otherwise move on */			tmp = tmp->next;		} while (1);	}		/* Create an item in our list for the new entry */	entry = kmalloc(sizeof(struct ieee80211_proc_entry), GFP_KERNEL);	if (entry == NULL) {		printk("%s: no memory for new proc entry (%s)!\n", __func__, 				name);		return -1;	}	/* Replace null fileops pointers with our standard functions */	if (!fileops->open)		fileops->open = proc_ieee80211_open;	if (!fileops->release)		fileops->release = proc_ieee80211_close;	if (!fileops->read)		fileops->read = proc_ieee80211_read;	if (!fileops->write)		fileops->write = proc_ieee80211_write;		/* Create the entry record */	entry->name = name;	entry->fileops = fileops;	entry->next = NULL;	entry->entry = NULL;	/* Create the actual proc entry */	if (vap->iv_proc) {		entry->entry = create_proc_entry(entry->name, 				PROC_IEEE80211_PERM, vap->iv_proc);		entry->entry->data = vap;		entry->entry->proc_fops = entry->fileops;	}	/* Add it to the list */	if (!tmp) {		/* Add to the start */		vap->iv_proc_entries = entry;	} else {		/* Add to the end */		tmp->next = entry;	}	return 0;}EXPORT_SYMBOL(ieee80211_proc_vcreate);voidieee80211_sysctl_vdetach(struct ieee80211vap *vap){	struct ieee80211_proc_entry *tmp=NULL;	if (vap->iv_sysctl_header) {		unregister_sysctl_table(vap->iv_sysctl_header);		vap->iv_sysctl_header = NULL;	}	if (vap->iv_proc) {		/* Remove child proc entries but leave them in the list */		tmp = vap->iv_proc_entries;		while (tmp) {			if (tmp->entry) {				remove_proc_entry(tmp->name, vap->iv_proc);				tmp->entry = NULL;			}			tmp = tmp->next;		}		remove_proc_entry(vap->iv_proc->name, proc_madwifi);		if (proc_madwifi_count == 1) {			remove_proc_entry("madwifi", proc_net);			proc_madwifi = NULL;		}		proc_madwifi_count--;	}	if (vap->iv_sysctls[2].procname) {		kfree(vap->iv_sysctls[2].procname);		vap->iv_sysctls[2].procname = NULL;	}		if (vap->iv_sysctls) {		kfree(vap->iv_sysctls);		vap->iv_sysctls = NULL;	}}#endif /* CONFIG_SYSCTL *//* * Format an Ethernet MAC for printing. */const char*ether_sprintf(const u_int8_t *mac){	static char etherbuf[18]; 	/* XXX */	snprintf(etherbuf, sizeof(etherbuf), "%02x:%02x:%02x:%02x:%02x:%02x",		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);	return etherbuf;}EXPORT_SYMBOL(ether_sprintf);		/* XXX *//* Function to handle the device event notifications. * If the event is a NETDEV_CHANGENAME, and is for an interface * we are taking care of, then we want to remove its existing  * proc entries (which now have the wrong names) and add * new, correct, entries. */static intieee80211_rcv_dev_event(struct notifier_block *this, unsigned long event,	void *ptr){#ifdef CONFIG_SYSCTL	struct net_device *dev = (struct net_device *) ptr;	if (!dev || dev->open != &ieee80211_open)		return 0;        switch (event) {        case NETDEV_CHANGENAME:		ieee80211_sysctl_vdetach(dev->priv);		ieee80211_sysctl_vattach(dev->priv);		return NOTIFY_DONE;	default:		break;        }#endif /* CONFIG_SYSCTL */        return 0;}static struct notifier_block ieee80211_event_block = {        .notifier_call = ieee80211_rcv_dev_event};/* * Module glue. */#include "version.h"#include "release.h"static char *version = WLAN_VERSION " (" RELEASE_VERSION ")";static char *dev_info = "wlan";MODULE_AUTHOR("Errno Consulting, Sam Leffler");MODULE_DESCRIPTION("802.11 wireless LAN protocol support");#ifdef MODULE_VERSIONMODULE_VERSION(RELEASE_VERSION);#endif#ifdef MODULE_LICENSEMODULE_LICENSE("Dual BSD/GPL");#endifextern	void ieee80211_auth_setup(void);static int __initinit_wlan(void){  	register_netdevice_notifier(&ieee80211_event_block);	printk(KERN_INFO "%s: %s\n", dev_info, version);	return 0;}module_init(init_wlan);static void __exitexit_wlan(void){  	unregister_netdevice_notifier(&ieee80211_event_block);	printk(KERN_INFO "%s: driver unloaded\n", dev_info);}module_exit(exit_wlan);

⌨️ 快捷键说明

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