prism2sta.c

来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 2,232 行 · 第 1/5 页

C
2,232
字号
			HFA384x_RID_CURRENTBSSID,			prism2sta_getbssid_cb, wlandev);		/* Collect the port status */		hfa384x_drvr_getconfig_async(hw, 			HFA384x_RID_PORTSTATUS,			prism2sta_getportstatus_cb, wlandev);#else /* !USB */		{		UINT16			portstatus;		int			result;		/* For non-usb devices, we can use the sync versions */		/* Collect the BSSID, and set state to allow tx */		result = hfa384x_drvr_getconfig(hw, 				HFA384x_RID_CURRENTBSSID,				wlandev->bssid, WLAN_BSSID_LEN);		if ( result ) {			WLAN_LOG_DEBUG2(1,				"getconfig(0x%02x) failed, result = %d\n",				HFA384x_RID_CURRENTBSSID, result);			goto failed;		}		/* Collect the port status */		result = hfa384x_drvr_getconfig16(hw, 				HFA384x_RID_PORTSTATUS, &portstatus);		if ( result ) {			WLAN_LOG_DEBUG2(1,				"getconfig(0x%02x) failed, result = %d\n",				HFA384x_RID_PORTSTATUS, result);			goto failed;		}		portstatus = hfa384x2host_16(portstatus);		wlandev->macmode = 			portstatus == HFA384x_PSTATUS_CONN_IBSS ?			WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;		}#endif /* WLANHOSTIF == WLAN_USB */		break;	case HFA384x_LINK_DISCONNECTED:		/* This one indicates that our association is gone.  We've		 * lost connection with the AP and/or been disassociated.  		 * This indicates that the MAC has completely cleared it's		 * associated state.  We * should send a deauth indication 		 * (implying disassoc) up * to the MLME.		 * Response:		 * Indicate Deauthentication		 * Block Transmits, Ignore receives of data frames		 */		WLAN_LOG_DEBUG0(1,"linkstatus=DISCONNECTED (unhandled)\n");		break;	case HFA384x_LINK_AP_CHANGE:		/* This one indicates that the MAC has decided to and 		 * successfully completed a change to another AP.  We		 * should probably implement a reassociation indication 		 * in response to this one.  I'm thinking that the the 		 * p80211 layer needs to be notified in case of 		 * buffering/queueing issues.  User mode also needs to be		 * notified so that any BSS dependent elements can be 		 * updated.		 * associated state.  We * should send a deauth indication 		 * (implying disassoc) up * to the MLME.		 * Response:		 * Indicate Reassociation		 * Enable Transmits, Receives and pass up data frames		 */		WLAN_LOG_DEBUG0(1,"linkstatus=AP_CHANGE (unhandled)\n");		break;	case HFA384x_LINK_AP_OUTOFRANGE:		/* This one indicates that the MAC has decided that the		 * AP is out of range, but hasn't found a better candidate		 * so the MAC maintains its "associated" state in case		 * we get back in range.  We should block transmits and 		 * receives in this state.  Do we need an indication here?		 * Probably not since a polling user-mode element would 		 * get this status from from p2PortStatus(FD40). What about		 * p80211?		 * Response:		 * Block Transmits, Ignore receives of data frames		 */		WLAN_LOG_DEBUG0(1,"linkstatus=AP_OUTOFRANGE (unhandled)\n");		break;	case HFA384x_LINK_AP_INRANGE:		/* This one indicates that the MAC has decided that the		 * AP is back in range.  We continue working with our 		 * existing association.		 * Response:		 * Enable Transmits, Receives and pass up data frames		 */		WLAN_LOG_DEBUG0(1,"linkstatus=AP_INRANGE (unhandled)\n");		break;	case HFA384x_LINK_ASSOCFAIL:		/* This one is actually a peer to CONNECTED.  We've 		 * requested a join for a given SSID and optionally BSSID.		 * We can use this one to indicate authentication and 		 * association failures.  The trick is going to be 		 * 1) identifying the failure, and 2) state management.		 * Response:		 * Disable Transmits, Ignore receives of data frames		 */		WLAN_LOG_DEBUG0(1,"linkstatus=ASSOCFAIL (unhandled)\n");		break;	default:		/* This is bad, IO port problems? */		WLAN_LOG_WARNING1( 			"unknown linkstatus=0x%02x\n", inf->info.linkstatus.linkstatus);		goto failed;		break;	}failed:	DBFEXIT;	return;}#if (WLAN_HOSTIF == WLAN_USB)/*----------------------------------------------------------------* prism2sta_getbssid_cb** Completion callback for getconfig_async() of CNFBSSID** Arguments:*	hw		hw struct*	result 		command result, 0==success*	ctlxresult	structure containing getconfig_async() results*	usercb_data	ptr that was passed into getconfig_async()** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/voidprism2sta_getbssid_cb(	hfa384x_t *hw, 	UINT result, 	void *ctlxresult, 	void *usercb_data){	wlandevice_t			*wlandev = usercb_data;	hfa384x_async_rridresult_t	*rrid = ctlxresult;	DBFENTER;	WLAN_LOG_DEBUG1(3,"result=%d\n", result);	if (result == 0) {		memcpy( wlandev->bssid, rrid->riddata, WLAN_BSSID_LEN);	}	DBFEXIT;	return;}/*----------------------------------------------------------------* prism2sta_getportstatus_cb** Completion callback for getconfig_async() of PORTSTATUS.* Sets wlandev->macmode based on the PORTSTATUS.** Arguments:*	hw		hw struct*	result 		command result, 0==success*	ctlxresult	structure containing getconfig_async() results*	usercb_data	ptr that was passed into getconfig_async()** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/void prism2sta_getportstatus_cb(	hfa384x_t *hw, 	UINT result, 	void *ctlxresult, 	void *usercb_data){	wlandevice_t			*wlandev = usercb_data;	hfa384x_async_rridresult_t	*rrid = ctlxresult;	UINT16				portstatus;	DBFENTER;	WLAN_LOG_DEBUG1(3,"result=%d\n", result);	if (result == 0) {		portstatus = hfa384x2host_16(*((UINT16*)rrid->riddata));		wlandev->macmode = 			portstatus == HFA384x_PSTATUS_CONN_IBSS ?			WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;	}	DBFEXIT;	return;}#endif /* WLANHOSTIF == WLAN_USB *//*----------------------------------------------------------------* prism2sta_inf_assocstatus** Handles the receipt of an Association Status info frame. Should * be present in APs only.** Arguments:*	wlandev		wlan device structure*	inf		ptr to info frame (contents in hfa384x order)** Returns: *	nothing** Side effects:** Call context:*	interrupt----------------------------------------------------------------*/void prism2sta_inf_assocstatus(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf){	prism2sta_priv_t	*priv = wlandev->priv;	hfa384x_AssocStatus_t	rec;	char			macbuf[WLAN_ADDR_LEN*3];	char			macbuf2[WLAN_ADDR_LEN*3];	int			i;	DBFENTER;	memcpy(&rec, &inf->info.assocstatus, sizeof(rec));	rec.assocstatus = hfa384x2host_16(rec.assocstatus);	rec.reason      = hfa384x2host_16(rec.reason);	if (priv->log) {		p802addr_to_str(macbuf, rec.sta_addr);		switch (rec.assocstatus) {			case HFA384x_ASSOCSTATUS_STAASSOC:				printk(KERN_INFO "wlan-ap: %s Associated\n",					macbuf);				break;			case HFA384x_ASSOCSTATUS_REASSOC:				p802addr_to_str(macbuf2, rec.old_ap_addr);				printk(KERN_INFO "wlan-ap: %s Reassociated from %s\n",					macbuf, macbuf2);				break;			case HFA384x_ASSOCSTATUS_DISASSOC:				printk(KERN_INFO "wlan-ap: %s Disssociated.  Reason = %d\n",					macbuf, rec.reason);				break;			case HFA384x_ASSOCSTATUS_ASSOCFAIL:				printk(KERN_INFO "wlan-ap: %s Association failed.  Reason = %d\n",					macbuf, rec.reason);				break;			case HFA384x_ASSOCSTATUS_AUTHFAIL:				printk(KERN_INFO "wlan-ap: %s Authentication failed.  Reason = %d\n",					macbuf, rec.reason);				break;			default:				printk(KERN_INFO "wlan-ap: %s Unknown failure.  Reason = %d\n",					macbuf, rec.reason);				break;		}	}	/*	** Find the address in the list of authenticated stations.  If it wasn't	** found, then this address has not been previously authenticated and	** something weird has happened if this is anything other than an	** "authentication failed" message.  If the address was found, then	** set the "associated" flag for that station, based on whether the	** station is associating or losing its association.  Something weird	** has also happened if we find the address in the list of authenticated	** stations but we are getting an "authentication failed" message.	*/	for (i = 0; i < priv->authlist.cnt; i++)		if (memcmp(rec.sta_addr, priv->authlist.addr[i], WLAN_ADDR_LEN) == 0)			break;	if (i >= priv->authlist.cnt) {		if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)			WLAN_LOG_WARNING0("assocstatus info frame received for non-authenticated station.\n");	} else {		priv->authlist.assoc[i] =			(rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||			 rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);		if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)			WLAN_LOG_WARNING0("authfail assocstatus info frame received for authenticated station.\n");	}	DBFEXIT;	return;}/*----------------------------------------------------------------* prism2sta_inf_authreq** Handles the receipt of an Authentication Request info frame. Should * be present in APs only.** Arguments:*	wlandev		wlan device structure*	inf		ptr to info frame (contents in hfa384x order)** Returns: *	nothing** Side effects:** Call context:*	interrupt** TODO: Make sure that the correct status values are returned.  Is*       "unspecified failure" correct?*----------------------------------------------------------------*/void prism2sta_inf_authreq( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf){	prism2sta_priv_t                    *priv = wlandev->priv;	hfa384x_t                           *hw = priv->hw;	hfa384x_authenticateStation_data_t  rec;	int    i, added, result, cnt;	UINT8  *addr;	char   macbuf[WLAN_ADDR_LEN*3];	DBFENTER;	/*	** Build the AuthenticateStation record.  Initialize it for denying	** authentication.	*/	memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN);	rec.status = P80211ENUM_status_unspec_failure;	/*	** Authenticate based on the access mode.	*/	switch (priv->accessmode) {		case WLAN_ACCESS_NONE:			/*			** Deny all new authentications.  However, if a station			** is ALREADY authenticated, then accept it.			*/			for (i = 0; i < priv->authlist.cnt; i++)				if (memcmp(rec.address, priv->authlist.addr[i],						WLAN_ADDR_LEN) == 0) {					rec.status = P80211ENUM_status_successful;					break;				}			break;		case WLAN_ACCESS_ALL:			/*			** Allow all authentications.			*/			rec.status = P80211ENUM_status_successful;			break;		case WLAN_ACCESS_ALLOW:			/*			** Only allow the authentication if the MAC address			** is in the list of allowed addresses.			**			** Since this is the interrupt handler, we may be here			** while the access list is in the middle of being			** updated.  Choose the list which is currently okay.			** See "prism2mib_priv_accessallow()" for details.			*/			if (priv->allow.modify == 0) {				cnt  = priv->allow.cnt;				addr = priv->allow.addr[0];			} else {				cnt  = priv->allow.cnt1;				addr = priv->allow.addr1[0];			}			for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)				if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {					rec.status = P80211ENUM_status_successful;					break;				}			break;		case WLAN_ACCESS_DENY:			/*			** Allow the authentication UNLESS the MAC address is			** in the list of denied addresses.			**			** Since this is the interrupt handler, we may be here			** while the access list is in the middle of being			** updated.  Choose the list which is currently okay.			** See "prism2mib_priv_accessdeny()" for details.			*/			if (priv->deny.modify == 0) {				cnt  = priv->deny.cnt;				addr = priv->deny.addr[0];			} else {				cnt  = priv->deny.cnt1;				addr = priv->deny.addr1[0];			}			rec.status = P80211ENUM_status_successful;			for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)				if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {					rec.status = P80211ENUM_status_unspec_failure;					break;				}			break;	}	/*	** If the authentication is okay, then add the MAC address to the list	** of authenticated stations.  Don't add the address if it is already in	** the list.  (802.11b does not seem to disallow a station from issuing	** an authentication request when the station is already authenticated.	** Does this sort of thing ever happen?  We might as well do the check	** just in case.)	*/	added = 0;	if (r

⌨️ 快捷键说明

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