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

📄 am930llc.c

📁 Linux Wireless LAN Project 的目标是开发一个完整的
💻 C
📖 第 1 页 / 共 3 页
字号:
									(wlan_ie_ssid_t*)cmd.ssid,									cmd.beacon_int, 									cmd.atim_win);				break;			}			case WLAN_BSSJOIN:			{				wlan_bssjoin_t	cmd;				if (copy_from_user( &cmd, req->data, sizeof(cmd))) {					result = -EFAULT;					break;				} 				req->result = am930mgr_joinbss( llc->mgr, cmd.bssid );				break;			}			case WLAN_AUTHENTICATE:			{				UINT32		timeout = 2 * HZ;	/* default 2 second */								/* Call mgr to begin the authentication */				am930mgr_authen_begin_sta( llc->mgr, WLAN_AUTH_ALG_OPENSYSTEM);				/* Set a timer for (mgmt_timeout) to make sure we  return */				init_timer(&llc->cmdtimer);				llc->cmdtimer.data = (unsigned long)llc;				llc->cmdtimer.function = (timerfunc_t)am930llc_cmdtimerfunc;				llc->cmdtimer.expires = jiffies + timeout;				add_timer(&llc->cmdtimer);				/* Now, do an interruptible_sleep, we'll be awakened by: */				/*  a signal the process, cmdtimerfunc (timeout), or llc_scancomplete */				interruptible_sleep_on(&(llc->cmdwq));				llc->cmdwq = NULL;				/* If sleep return is via signal */				if ( signal_pending(current) ) {					/* stop authen and clean up */					am930mgr_authen_stop(llc->mgr);					del_timer(&llc->cmdtimer);					result = -EINTR;				} else {					/* If timeout */					if ( llc->cmdtimer.expires == 0 )					{						/* stop authen and clean up */						am930mgr_authen_stop(llc->mgr);						result = -ETIME;					} else {						/* Success */						/* clean up timer */						del_timer(&llc->cmdtimer);						llc->cmdtimer.expires=0;						req->result = llc->cmdstatus;						/* return success */						result = 0;					}				}				break;			}			case WLAN_ASSOCIATE:			{				UINT32		timeout = 2 * HZ;	/* default 2 second */								/* Call mgr to begin the association */				am930mgr_assoc_begin_sta(llc->mgr);				/* Set a timer for (mgmt_timeout) to make sure we  return */				init_timer(&llc->cmdtimer);				llc->cmdtimer.data = (unsigned long)llc;				llc->cmdtimer.function = (timerfunc_t)am930llc_cmdtimerfunc;				llc->cmdtimer.expires = jiffies + timeout;				add_timer(&llc->cmdtimer);				/* Now, do an interruptible_sleep, we'll be awakened by: */				/*  a signal the process, cmdtimerfunc (timeout), or llc_scancomplete */				interruptible_sleep_on(&(llc->cmdwq));				llc->cmdwq = NULL;				/* If sleep return is via signal */				if ( signal_pending(current) ) {					/* stop assoc and clean up */					am930mgr_assoc_stop(llc->mgr);					del_timer(&llc->cmdtimer);					result = -EINTR;				} else {					/* If timeout */					if ( llc->cmdtimer.expires == 0 )					{						/* stop assoc and clean up */						am930mgr_assoc_stop(llc->mgr);						result = -ETIME;					} else {						/* Success */						/* clean up timer */						del_timer(&llc->cmdtimer);						llc->cmdtimer.expires=0;						req->result = llc->cmdstatus;						/* return success */						result = 0;					}				}				break;			}			case WLAN_GETMIB:			{				UINT8*	p = NULL;				UINT32	size = 0;				UINT32	mibcode;								p = kmalloc(req->len, GFP_KERNEL);				if (p == NULL) {					result = -ENOMEM;					break;				}				if ( copy_from_user( &mibcode, req->data, 4 ) ) {					kfree_s(p, req->len);					result = -EFAULT;					break;				}				switch(mibcode) {					case SUMIB_LOCAL:						size = sizeof(su_mib_local_t);						break;					case SUMIB_ADDR:						size = sizeof(su_mib_mac_addr_stat_grp_t);						break;					case SUMIB_MAC:						size = sizeof(su_mib_mac_t); 						break;					case SUMIB_STAT:						size = sizeof(su_mib_mac_statistics_t); 						break;					case SUMIB_MGMT:						size = sizeof(su_mib_mac_mgmt_t); 						break;					case SUMIB_DRVR:						/* size = sizeof(su_mib_local_t); */						size = 0;						break;					case SUMIB_PHY:						size = sizeof(su_mib_phy_t); 						break;				}				am930mgr_mibget( llc->mgr, mibcode, size, p);				if ( copy_to_user( ((UINT8*)(req->data)) + 4, p, size)) {					result = -EFAULT;				}				kfree_s(p, req->len);				break;			}			case WLAN_SETMIBITEM:			case WLAN_GETMIBITEM:				result = -ENOSYS;				break;			case WLAN_PRIVACY:			{				wlan_privacy_t	cmd;				int				i;				if ( copy_from_user( &cmd, req->data, sizeof(cmd)) ) {					result = -EFAULT;					break;				}				llc->mac->wep_defkeyid = cmd.defkey;				llc->mac->exclude_unencrypted = cmd.exclude_unencrypted;				for ( i = 0; i < WLAN_WEP_NKEYS; i++)				{					memcpy( llc->mac->wep_key[i], cmd.keys[i], WLAN_WEP_KEYLEN);				}				llc->mac->privacy_invoked = 1;				WLAN_LOG_DEBUG2(2, "Wep set: defkey=%lu, exclude=%lu\n", 					(UINT32)llc->mac->wep_defkeyid,					(UINT32)llc->mac->exclude_unencrypted);				WLAN_LOG_DEBUG5(2, "Wep key0: %02x:%02x:%02x:%02x:%02x\n",					llc->mac->wep_key[0][0],					llc->mac->wep_key[0][1],					llc->mac->wep_key[0][2],					llc->mac->wep_key[0][3],					llc->mac->wep_key[0][4] );				WLAN_LOG_DEBUG5(2, "Wep key1: %02x:%02x:%02x:%02x:%02x\n",					llc->mac->wep_key[1][0],					llc->mac->wep_key[1][1],					llc->mac->wep_key[1][2],					llc->mac->wep_key[1][3],					llc->mac->wep_key[1][4] );				WLAN_LOG_DEBUG5(2, "Wep key2: %02x:%02x:%02x:%02x:%02x\n",					llc->mac->wep_key[2][0],					llc->mac->wep_key[2][1],					llc->mac->wep_key[2][2],					llc->mac->wep_key[2][3],					llc->mac->wep_key[2][4] );				WLAN_LOG_DEBUG5(2, "Wep key3: %02x:%02x:%02x:%02x:%02x\n",					llc->mac->wep_key[3][0],					llc->mac->wep_key[3][1],					llc->mac->wep_key[3][2],					llc->mac->wep_key[3][3],					llc->mac->wep_key[3][4] );				break;			}			case WLAN_ETHCONV:			{				wlan_ethconv_t	cmd;				if ( copy_from_user( &cmd, req->data, sizeof(cmd)) ) {					result = -EFAULT;					break;				}				llc->ethconv = cmd.ethconv_type;				switch( llc->ethconv )				{					case WLAN_ETHCONV_ENCAP:						WLAN_LOG_NOTICE0("ethconv=encapsulation\n");						break;					case WLAN_ETHCONV_RFC1042:						WLAN_LOG_NOTICE0("ethconv=rfc1042\n");						break;					case WLAN_ETHCONV_8021h:						WLAN_LOG_NOTICE0("ethconv=802.1h\n");						break;					default:						WLAN_LOG_NOTICE0("ethconv=UNKNOWN...this is bad.\n");						break;				}				break;			}			case WLAN_SNIFFERCMD:			{				#ifdef WLAN_INCLUDE_SNIF				wlan_sniffercmd_t	cmd;					if ( copy_from_user( &cmd, req->data, sizeof(cmd)) ) {					result = -EFAULT;					break;				}				cmd.result = 0;				if ( cmd.cmd == SNIFFERCMD_REG ) {					WLAN_LOG_DEBUG0(2, "Doing sniffer cmd reg.\n");					if ( llc->nlsk == NULL || llc->snifferpid != 0 ) {						WLAN_LOG_DEBUG1(1, "llc->nlsk=%lx\n", (UINT32)llc->nlsk);						WLAN_LOG_DEBUG1(1, "llc->snifferpid=%d\n", llc->snifferpid);						WLAN_LOG_DEBUG0(1, "Failed to reg sniffer: no netlink or sniffer already reg.\n");						cmd.result = -1;					} else {						llc->snifferpid = cmd.pid;						llc->mac->snifflags = SNIFFLAG_SNIFRX | cmd.flags;					}				} else if ( cmd.cmd == SNIFFERCMD_UNREG ) {					WLAN_LOG_DEBUG0(2, "Doing sniffer cmd unreg.\n");					llc->snifferpid = 0;					llc->mac->snifflags = 0;				}				if ( copy_to_user( req->data, &cmd, sizeof(cmd)) ) {					result = -EFAULT;				}				#else				result = -ENOSYS;				#endif				break;			}			default:				printk(KERN_DEBUG "am930_cs: Unknown or unsupported wlan ioctl!\n");				break;		}		llc->currcmd = 0;	}	clear_bit( 0, (void*)&(llc->cmdbusy));	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930llc_devgetstats*	getstats method for the linux net device. Called as a result*	of a number of user mode utilities used to check the rx/tx*	statistics of an interface.**	returns: zero----------------------------------------------------------------*/enet_stats_t* am930llc_devgetstats(device_t *dev){	DBFENTER;	DBFEXIT;	return &(V2P(dev->priv)->stats);}/*----------------------------------------------------------------*	am930llc_devhard_start_xmit*	hard_start_xmint method for the linux net device. Called by *	the higher level protocol code when it has a packet to xmit.**	returns: zero----------------------------------------------------------------*/int am930llc_devhard_start_xmit( struct sk_buff *skb, device_t *dev){	int			result = 0;	int			txresult = -1;	wlan_pb_t	*pb;	am930llc_t	*llc = V2P(dev->priv)->llc;	DBFENTER;	if ( dev->start == 1 )	{		/* If some higher layer thinks we've missed a tx-done, we are passed			NULL. Caution: dev_tint handles the cli/sti ..		*/#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,25))		if ( skb == NULL )		{			dev->tbusy = 0;			dev_tint(dev);			return 0;		}#endif		if ( test_and_set_bit(0, (void*)&(dev->tbusy)) != 0 )		{			/* TODO: add a f/w reset capability here. see skeleton.c */			WLAN_LOG_DEBUG2(1, "called when tbusy set,"			                   "txllc.len=%d txmac.len=%d\n",							   llc->mac->llcq->len,							   llc->mac->macq->len);			result = 1;		}		else		{			dev->trans_start = jiffies;			/* OK, now we setup the ether to 802.11 conversion */			pb = am930llc_pballoc();			if ( pb != NULL )			{				pb->ethhostbuf = skb;				pb->ethfree = am930llc_pbfreeskb;				pb->ethbuf = skb->data;				pb->ethbuflen = skb->len;				pb->ethfrmlen = skb->len;				pb->eth_hdr = (wlan_ethhdr_t*)pb->ethbuf;				if ( am930llc_pb_ether_to_p80211( llc, pb) != 0 )				{					/* convert failed */					result = 1;					am930llc_pbfree(pb);				}				else				{					txresult = 						am930mac_txllc( llc->mac, pb->eth_hdr->daddr,									 pb->eth_hdr->saddr, pb);							if ( txresult == 0)  /* success and more buf avail, re: hw_txdata */					{						dev->tbusy = 0;						result = 0;					}					else if ( txresult == 1 ) /* success, no more avail */					{						result = 0;					}					else if ( txresult == 2 ) /* alloc failure, drop frame */					{						result = 0;						am930llc_pbfree(pb);					}					else /* buffer full or queue busy */					{						result = 1;						pb->ethfree = NULL;					}				}			}		}	}	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930llc_devopen*	open method for the linux net device. Called when ifconfig*	is used to set up the interface.**	returns: zero----------------------------------------------------------------*/int am930llc_devopen(device_t *dev){	int result = 0;	DBFENTER;	/* set the flags in the device object */	dev->tbusy = 0;	dev->interrupt = 0;	dev->start = 1;	#ifdef WLAN_PCMCIA	MOD_INC_USE_COUNT;	#endif	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930llc_devstop*	stop method for the linux net device. Called  when ifconfig*	is used to shut down an interface.**	returns: zero----------------------------------------------------------------*/int am930llc_devstop(device_t *dev){	int result = 0;	DBFENTER;	/* set the flags in the device object */	dev->start = 0;	dev->tbusy = 1;	#ifdef WLAN_PCMCIA	MOD_DEC_USE_COUNT;	#endif	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930llc_nlfunc*	Called by netlink when an skb is ready on our netlink i/f.*	Currently does nothing since we don't expect anything to be*	coming in.*	Arguments:*		sk		- sock representing our netlink i/f*		len		- buf len*	returns: nothing----------------------------------------------------------------*/void am930llc_nlfunc(struct sock *sk, int len){	return;}/*----------------------------------------------------------------*	am930llc_pb_ether_to_p80211*	Uses the contents of the ether frame and the etherconv setting*   to build the elements of the 802.11 frame.  **	We don't actually set *	up the frame header here.  That's the MAC's job.  We're only handling*	conversion of DIXII or 802.3+LLC frames to something that works*	with 802.11.**	Assume the following are already set:*		pb->ethfree*		pb->ethhostbuf*		pb->ethbuf;*		pb->ethbuflen*		pb->eth_hdr*	returns: zero on success, non-zero on failure----------------------------------------------------------------*/int am930llc_pb_ether_to_p80211( am930llc_t *llc, wlan_pb_t *pb){	UINT16	proto;	if ( llc->ethconv == WLAN_ETHCONV_ENCAP ) /* simplest case */	{		/* here, we don't care what kind of ether frm. Just stick it */		/*  in the 80211 payload */		pb->p80211hostbuf = kmalloc( WLAN_HDR_A3_LEN, GFP_ATOMIC);		if ( pb->p80211hostbuf == NULL ) return 1;		pb->p80211buflen = WLAN_HDR_A3_LEN;		pb->p80211free = am930llc_pbkfree_s;		pb->p80211buf = (UINT8*)(pb->p80211hostbuf);		pb->p80211_hdr = (p80211_hdr_t*)pb->p80211buf;		pb->p80211_payload = pb->ethbuf;		pb->p80211_payloadlen = pb->ethbuflen;	}	else	{		/* step 1: classify ether frame, DIX or 802.3? */		proto = ntohs(pb->eth_hdr->type);		if ( proto <= 0x05DC )  /* type|len <= 1500 ? */		{			/* it's 802.3, pass ether payload unchanged,  */			/*   leave off any PAD octets.  */			pb->p80211hostbuf = kmalloc( WLAN_HDR_A3_LEN, GFP_ATOMIC);			if ( pb->p80211hostbuf == NULL ) return 1;			pb->p80211buflen = WLAN_HDR_A3_LEN;			pb->p80211free = am930llc_pbkfree_s;			pb->p80211buf = (UINT8*)(pb->p80211hostbuf);			pb->p80211_hdr = (p80211_hdr_t*)pb->p80211buf;			/* setup the payload ptrs */			pb->p80211_payload = pb->ethbuf + sizeof(wlan_ethhdr_t);			pb->p80211_payloadlen = ntohs(pb->eth_hdr->type);		}		else		{			/* it's DIXII, time for some conversion */			pb->p80211hostbuf = kmalloc( 						WLAN_HDR_A3_LEN + 						sizeof(wlan_llc_t) +						sizeof(wlan_snap_t), GFP_ATOMIC);			if ( pb->p80211hostbuf == NULL ) return 1;			pb->p80211buflen = 						WLAN_HDR_A3_LEN + 						sizeof(wlan_llc_t) +						sizeof(wlan_snap_t);			pb->p80211free = am930llc_pbkfree_s;			pb->p80211buf = (UINT8*)pb->p80211hostbuf;			pb->p80211_hdr = (p80211_hdr_t*)pb->p80211buf;			pb->p80211_llc = (wlan_llc_t*)(pb->p80211buf + WLAN_HDR_A3_LEN);			pb->p80211_snap = (wlan_snap_t*)(((UINT8*)pb->p80211_llc) + sizeof(wlan_llc_t));			/* setup the LLC header */			pb->p80211_llc->dsap = 0xAA;	/* SNAP, see IEEE 802 */			pb->p80211_llc->ssap = 0xAA;			pb->p80211_llc->ctl = 0x03;					/* setup the SNAP header */			pb->p80211_snap->type = htons(proto);			if ( llc->ethconv == WLAN_ETHCONV_8021h && 				 am930llc_stt_findproto(llc, proto) )			{				memcpy( pb->p80211_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN);			}			else			{				memcpy( pb->p80211_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN);			}			/* setup the payload ptrs */

⌨️ 快捷键说明

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