auth.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1
  3. */
  4. /*! \file "auth.c"
  5. \brief This file includes the authentication-related functions.
  6. This file includes the authentication-related functions.
  7. */
  8. /*
  9. ** Log: auth.c
  10. *
  11. * 02 13 2012 cp.wu
  12. * NULL
  13. * show error message only instead of raise assertion when
  14. * received authentication frame is carrying illegal parameters.
  15. *
  16. * 11 09 2011 yuche.tsai
  17. * NULL
  18. * Fix a network index & station record index issue when TX deauth frame.
  19. *
  20. * 10 12 2011 wh.su
  21. * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
  22. * adding the 802.11w related function and define .
  23. *
  24. * 06 22 2011 yuche.tsai
  25. * NULL
  26. * Fix coding error.
  27. *
  28. * 06 20 2011 yuche.tsai
  29. * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature.
  30. * BC deauth support.
  31. *
  32. * 04 21 2011 terry.wu
  33. * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
  34. * Add network type parameter to authSendAuthFrame.
  35. *
  36. * 04 15 2011 chinghwa.yu
  37. * [WCXRP00000065] Update BoW design and settings
  38. * Add BOW short range mode.
  39. *
  40. * 02 08 2011 yuche.tsai
  41. * [WCXRP00000245] 1. Invitation Request/Response.
  42. 2. Provision Discovery Request/Response
  43. * 1. Fix Service Disocvery Logical issue.
  44. * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station.
  45. *
  46. * 01 24 2011 cp.wu
  47. * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
  48. * 1. add an extra counter for tracking pending forward frames.
  49. * 2. notify TX service thread as well when there is pending forward frame
  50. * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
  51. *
  52. * 01 21 2011 terry.wu
  53. * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode
  54. * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame.
  55. *
  56. * 10 18 2010 cp.wu
  57. * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
  58. * use definition macro to replace hard-coded constant
  59. *
  60. * 09 03 2010 kevin.huang
  61. * NULL
  62. * Refine #include sequence and solve recursive/nested #include issue
  63. *
  64. * 08 30 2010 cp.wu
  65. * NULL
  66. * eliminate klockwork errors
  67. *
  68. * 08 16 2010 cp.wu
  69. * NULL
  70. * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
  71. * There is no CFG_SUPPORT_BOW in driver domain source.
  72. *
  73. * 08 16 2010 kevin.huang
  74. * NULL
  75. * Refine AAA functions
  76. *
  77. * 08 03 2010 cp.wu
  78. * NULL
  79. * surpress compilation warning.
  80. *
  81. * 07 08 2010 cp.wu
  82. *
  83. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  84. *
  85. * 06 28 2010 cp.wu
  86. * [WPD00003833][MT6620 and MT5931] Driver migration
  87. * send MMPDU in basic rate.
  88. *
  89. * 06 21 2010 cp.wu
  90. * [WPD00003833][MT6620 and MT5931] Driver migration
  91. * specify correct value for management frames.
  92. *
  93. * 06 18 2010 cm.chang
  94. * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
  95. * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
  96. *
  97. * 06 14 2010 cp.wu
  98. * [WPD00003833][MT6620 and MT5931] Driver migration
  99. * add management dispatching function table.
  100. *
  101. * 06 11 2010 cp.wu
  102. * [WPD00003833][MT6620 and MT5931] Driver migration
  103. * auth.c is migrated.
  104. *
  105. * 05 28 2010 kevin.huang
  106. * [BORA00000794][WIFISYS][New Feature]Power Management Support
  107. * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T
  108. *
  109. * 05 24 2010 kevin.huang
  110. * [BORA00000794][WIFISYS][New Feature]Power Management Support
  111. * Check Net is active before sending Deauth frame.
  112. *
  113. * 05 24 2010 kevin.huang
  114. * [BORA00000794][WIFISYS][New Feature]Power Management Support
  115. * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval.
  116. *
  117. * 04 24 2010 cm.chang
  118. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  119. * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
  120. *
  121. * 04 19 2010 kevin.huang
  122. * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
  123. * Add Send Deauth for Class 3 Error and Leave Network Support
  124. *
  125. * 02 23 2010 kevin.huang
  126. * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
  127. * Fix compile warning
  128. *
  129. * 02 05 2010 kevin.huang
  130. * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
  131. * Add debug message for abnormal authentication frame from AP
  132. *
  133. * 02 04 2010 kevin.huang
  134. * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
  135. * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
  136. *
  137. * 01 11 2010 kevin.huang
  138. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  139. * Add Deauth and Disassoc Handler
  140. *
  141. * 01 07 2010 kevin.huang
  142. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  143. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  144. *
  145. * Fix the Debug Label
  146. *
  147. * 12 18 2009 cm.chang
  148. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  149. * .
  150. *
  151. * Dec 7 2009 mtk01461
  152. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  153. * Update the authComposeAuthFrameHeader()
  154. *
  155. * Dec 7 2009 mtk01088
  156. * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
  157. * adding the send deauth frame function
  158. *
  159. * Dec 3 2009 mtk01461
  160. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  161. * Integrate send Auth with TXM
  162. *
  163. * Nov 24 2009 mtk01461
  164. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  165. * Revise MGMT Handler with Retain Status
  166. *
  167. * Nov 23 2009 mtk01461
  168. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  169. *
  170. */
  171. /*******************************************************************************
  172. * C O M P I L E R F L A G S
  173. ********************************************************************************
  174. */
  175. /*******************************************************************************
  176. * E X T E R N A L R E F E R E N C E S
  177. ********************************************************************************
  178. */
  179. #include "precomp.h"
  180. /*******************************************************************************
  181. * C O N S T A N T S
  182. ********************************************************************************
  183. */
  184. /*******************************************************************************
  185. * D A T A T Y P E S
  186. ********************************************************************************
  187. */
  188. /*******************************************************************************
  189. * P U B L I C D A T A
  190. ********************************************************************************
  191. */
  192. APPEND_IE_ENTRY_T txAuthIETable[] = {
  193. {(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText}
  194. };
  195. HANDLE_IE_ENTRY_T rxAuthIETable[] = {
  196. {ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText}
  197. };
  198. /*******************************************************************************
  199. * P R I V A T E D A T A
  200. ********************************************************************************
  201. */
  202. /*******************************************************************************
  203. * M A C R O S
  204. ********************************************************************************
  205. */
  206. /*******************************************************************************
  207. * F U N C T I O N D E C L A R A T I O N S
  208. ********************************************************************************
  209. */
  210. /*******************************************************************************
  211. * F U N C T I O N S
  212. ********************************************************************************
  213. */
  214. /*----------------------------------------------------------------------------*/
  215. /*!
  216. * @brief This function will compose the Authentication frame header and fixed fields.
  217. *
  218. * @param[in] pucBuffer Pointer to the frame buffer.
  219. * @param[in] aucPeerMACAddress Given Peer MAC Address.
  220. * @param[in] aucMACAddress Given Our MAC Address.
  221. * @param[in] u2AuthAlgNum Authentication Algorithm Number
  222. * @param[in] u2TransactionSeqNum Transaction Sequence Number
  223. * @param[in] u2StatusCode Status Code
  224. *
  225. * \return (none)
  226. */
  227. /*----------------------------------------------------------------------------*/
  228. static inline VOID
  229. authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer,
  230. IN UINT_8 aucPeerMACAddress[],
  231. IN UINT_8 aucMACAddress[],
  232. IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode)
  233. {
  234. P_WLAN_AUTH_FRAME_T prAuthFrame;
  235. UINT_16 u2FrameCtrl;
  236. ASSERT(pucBuffer);
  237. ASSERT(aucPeerMACAddress);
  238. ASSERT(aucMACAddress);
  239. prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer;
  240. /* 4 <1> Compose the frame header of the Authentication frame. */
  241. /* Fill the Frame Control field. */
  242. u2FrameCtrl = MAC_FRAME_AUTH;
  243. /* If this frame is the third frame in the shared key authentication
  244. * sequence, it shall be encrypted.
  245. */
  246. if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3))
  247. u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */
  248. /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */
  249. prAuthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */
  250. /* Fill the DA field with Target BSSID. */
  251. COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress);
  252. /* Fill the SA field with our MAC Address. */
  253. COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress);
  254. switch (u2TransactionSeqNum) {
  255. case AUTH_TRANSACTION_SEQ_1:
  256. case AUTH_TRANSACTION_SEQ_3:
  257. /* Fill the BSSID field with Target BSSID. */
  258. COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress);
  259. break;
  260. case AUTH_TRANSACTION_SEQ_2:
  261. case AUTH_TRANSACTION_SEQ_4:
  262. /* Fill the BSSID field with Current BSSID. */
  263. COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress);
  264. break;
  265. default:
  266. ASSERT(0);
  267. }
  268. /* Clear the SEQ/FRAG_NO field. */
  269. prAuthFrame->u2SeqCtrl = 0;
  270. /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */
  271. /* Fill the Authentication Algorithm Number field. */
  272. /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */
  273. prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */
  274. /* Fill the Authentication Transaction Sequence Number field. */
  275. /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */
  276. prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; /* NOTE(Kevin): Optimized for ARM */
  277. /* Fill the Status Code field. */
  278. /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */
  279. prAuthFrame->u2StatusCode = u2StatusCode; /* NOTE(Kevin): Optimized for ARM */
  280. } /* end of authComposeAuthFrameHeaderAndFF() */
  281. /*----------------------------------------------------------------------------*/
  282. /*!
  283. * @brief This function will append Challenge Text IE to the Authentication frame
  284. *
  285. * @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T.
  286. *
  287. * @return (none)
  288. */
  289. /*----------------------------------------------------------------------------*/
  290. VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo)
  291. {
  292. P_WLAN_AUTH_FRAME_T prAuthFrame;
  293. P_STA_RECORD_T prStaRec;
  294. UINT_16 u2TransactionSeqNum;
  295. ASSERT(prMsduInfo);
  296. prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
  297. if (!prStaRec)
  298. return;
  299. ASSERT(prStaRec);
  300. /* For Management, frame header and payload are in a continuous buffer */
  301. prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket;
  302. WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum)
  303. /* Only consider SEQ_3 for Challenge Text */
  304. if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) &&
  305. (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) {
  306. COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText));
  307. prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText);
  308. }
  309. return;
  310. } /* end of authAddIEChallengeText() */
  311. #if !CFG_SUPPORT_AAA
  312. /*----------------------------------------------------------------------------*/
  313. /*!
  314. * @brief This function will send the Authenticiation frame
  315. *
  316. * @param[in] prStaRec Pointer to the STA_RECORD_T
  317. * @param[in] u2TransactionSeqNum Transaction Sequence Number
  318. *
  319. * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
  320. * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module
  321. */
  322. /*----------------------------------------------------------------------------*/
  323. WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum)
  324. {
  325. P_MSDU_INFO_T prMsduInfo;
  326. P_BSS_INFO_T prBssInfo;
  327. UINT_16 u2EstimatedFrameLen;
  328. UINT_16 u2EstimatedExtraIELen;
  329. UINT_16 u2PayloadLen;
  330. UINT_32 i;
  331. DBGLOG(SAA, LOUD, "Send Auth Frame\n");
  332. ASSERT(prStaRec);
  333. /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
  334. /* Init with MGMT Header Length + Length of Fixed Fields */
  335. u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
  336. WLAN_MAC_MGMT_HEADER_LEN +
  337. AUTH_ALGORITHM_NUM_FIELD_LEN +
  338. AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
  339. /* + Extra IE Length */
  340. u2EstimatedExtraIELen = 0;
  341. for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++)
  342. u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
  343. u2EstimatedFrameLen += u2EstimatedExtraIELen;
  344. /* Allocate a MSDU_INFO_T */
  345. prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
  346. if (prMsduInfo == NULL) {
  347. DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n");
  348. return WLAN_STATUS_RESOURCES;
  349. }
  350. /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
  351. ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
  352. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
  353. /* Compose Header and some Fixed Fields */
  354. authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
  355. prStaRec->aucMacAddr,
  356. prBssInfo->aucOwnMacAddr,
  357. prStaRec->ucAuthAlgNum, u2TransactionSeqNum, STATUS_CODE_RESERVED);
  358. u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
  359. /* 4 <3> Update information of MSDU_INFO_T */
  360. prMsduInfo->eSrc = TX_PACKET_MGMT;
  361. prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
  362. prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
  363. prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
  364. prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
  365. prMsduInfo->fgIs802_1x = FALSE;
  366. prMsduInfo->fgIs802_11 = TRUE;
  367. prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
  368. prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  369. prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone;
  370. prMsduInfo->fgIsBasicRate = TRUE;
  371. /* 4 <4> Compose IEs in MSDU_INFO_T */
  372. for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
  373. if (txAuthIETable[i].pfnAppendIE)
  374. txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
  375. }
  376. /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
  377. /* 4 <6> Inform TXM to send this Authentication frame. */
  378. nicTxEnqueueMsdu(prAdapter, prMsduInfo);
  379. return WLAN_STATUS_SUCCESS;
  380. } /* end of authSendAuthFrame() */
  381. #else
  382. /*----------------------------------------------------------------------------*/
  383. /*!
  384. * @brief This function will send the Authenticiation frame
  385. *
  386. * @param[in] prStaRec Pointer to the STA_RECORD_T
  387. * @param[in] u2TransactionSeqNum Transaction Sequence Number
  388. *
  389. * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
  390. * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module
  391. */
  392. /*----------------------------------------------------------------------------*/
  393. WLAN_STATUS
  394. authSendAuthFrame(IN P_ADAPTER_T prAdapter,
  395. IN P_STA_RECORD_T prStaRec,
  396. IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
  397. IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode)
  398. {
  399. PUINT_8 pucReceiveAddr;
  400. PUINT_8 pucTransmitAddr;
  401. P_MSDU_INFO_T prMsduInfo;
  402. P_BSS_INFO_T prBssInfo;
  403. /*get from input parameter */
  404. /* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */
  405. PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL;
  406. UINT_16 u2EstimatedFrameLen;
  407. UINT_16 u2EstimatedExtraIELen;
  408. UINT_16 u2PayloadLen;
  409. UINT_16 ucAuthAlgNum;
  410. UINT_32 i;
  411. DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode);
  412. /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */
  413. /* Init with MGMT Header Length + Length of Fixed Fields */
  414. u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD +
  415. WLAN_MAC_MGMT_HEADER_LEN +
  416. AUTH_ALGORITHM_NUM_FIELD_LEN +
  417. AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
  418. /* + Extra IE Length */
  419. u2EstimatedExtraIELen = 0;
  420. for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++)
  421. u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen;
  422. u2EstimatedFrameLen += u2EstimatedExtraIELen;
  423. /* Allocate a MSDU_INFO_T */
  424. prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
  425. if (prMsduInfo == NULL) {
  426. DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n");
  427. return WLAN_STATUS_RESOURCES;
  428. }
  429. /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */
  430. if (prStaRec) {
  431. ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
  432. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
  433. pucTransmitAddr = prBssInfo->aucOwnMacAddr;
  434. pucReceiveAddr = prStaRec->aucMacAddr;
  435. ucAuthAlgNum = prStaRec->ucAuthAlgNum;
  436. switch (u2TransactionSeqNum) {
  437. case AUTH_TRANSACTION_SEQ_1:
  438. case AUTH_TRANSACTION_SEQ_3:
  439. pfTxDoneHandler = saaFsmRunEventTxDone;
  440. break;
  441. case AUTH_TRANSACTION_SEQ_2:
  442. case AUTH_TRANSACTION_SEQ_4:
  443. pfTxDoneHandler = aaaFsmRunEventTxDone;
  444. break;
  445. }
  446. } else { /* For Error Status Code */
  447. P_WLAN_AUTH_FRAME_T prFalseAuthFrame;
  448. ASSERT(prFalseAuthSwRfb);
  449. prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader;
  450. ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL);
  451. pucTransmitAddr = prFalseAuthFrame->aucDestAddr;
  452. pucReceiveAddr = prFalseAuthFrame->aucSrcAddr;
  453. ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum;
  454. u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1);
  455. }
  456. /* Compose Header and some Fixed Fields */
  457. authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
  458. pucReceiveAddr,
  459. pucTransmitAddr, ucAuthAlgNum, u2TransactionSeqNum, u2StatusCode);
  460. u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
  461. /* 4 <3> Update information of MSDU_INFO_T */
  462. prMsduInfo->eSrc = TX_PACKET_MGMT;
  463. prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
  464. if (prStaRec)
  465. prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
  466. else
  467. prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; /* false Auth frame */
  468. prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex;
  469. prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
  470. prMsduInfo->fgIs802_1x = FALSE;
  471. prMsduInfo->fgIs802_11 = TRUE;
  472. prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
  473. prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  474. prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
  475. prMsduInfo->fgIsBasicRate = TRUE;
  476. /* 4 <4> Compose IEs in MSDU_INFO_T */
  477. for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) {
  478. if (txAuthIETable[i].pfnAppendIE)
  479. txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
  480. }
  481. /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
  482. /* 4 <6> Inform TXM to send this Authentication frame. */
  483. DBGLOG(SAA, INFO, "network: %d Send Auth Frame %d, Status Code = %d seq num %d\n",
  484. eNetTypeIndex, u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum);
  485. nicTxEnqueueMsdu(prAdapter, prMsduInfo);
  486. return WLAN_STATUS_SUCCESS;
  487. } /* end of authSendAuthFrame() */
  488. #endif /* CFG_SUPPORT_AAA */
  489. /*----------------------------------------------------------------------------*/
  490. /*!
  491. * @brief This function will strictly check the TX Authentication frame for SAA/AAA event
  492. * handling.
  493. *
  494. * @param[in] prMsduInfo Pointer of MSDU_INFO_T
  495. * @param[in] u2TransactionSeqNum Transaction Sequence Number
  496. *
  497. * @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state.
  498. * @retval WLAN_STATUS_SUCCESS This is the frame we should handle.
  499. */
  500. /*----------------------------------------------------------------------------*/
  501. WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum)
  502. {
  503. P_WLAN_AUTH_FRAME_T prAuthFrame;
  504. P_STA_RECORD_T prStaRec;
  505. UINT_16 u2TxFrameCtrl;
  506. UINT_16 u2TxAuthAlgNum;
  507. UINT_16 u2TxTransactionSeqNum;
  508. ASSERT(prMsduInfo);
  509. prAuthFrame = (P_WLAN_AUTH_FRAME_T) (prMsduInfo->prPacket);
  510. ASSERT(prAuthFrame);
  511. prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
  512. ASSERT(prStaRec);
  513. if (!prStaRec)
  514. return WLAN_STATUS_INVALID_PACKET;
  515. /* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */
  516. u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */
  517. u2TxFrameCtrl &= MASK_FRAME_TYPE;
  518. if (u2TxFrameCtrl != MAC_FRAME_AUTH)
  519. return WLAN_STATUS_FAILURE;
  520. /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */
  521. u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */
  522. if (u2TxAuthAlgNum != (UINT_16) (prStaRec->ucAuthAlgNum))
  523. return WLAN_STATUS_FAILURE;
  524. /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum) */
  525. u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */
  526. if (u2TxTransactionSeqNum != u2TransactionSeqNum)
  527. return WLAN_STATUS_FAILURE;
  528. return WLAN_STATUS_SUCCESS;
  529. } /* end of authCheckTxAuthFrame() */
  530. /*----------------------------------------------------------------------------*/
  531. /*!
  532. * @brief This function will check the incoming Auth Frame's Transaction Sequence
  533. * Number before delivering it to the corresponding SAA or AAA Module.
  534. *
  535. * @param[in] prSwRfb Pointer to the SW_RFB_T structure.
  536. *
  537. * @retval WLAN_STATUS_SUCCESS Always not retain authentication frames
  538. */
  539. /*----------------------------------------------------------------------------*/
  540. WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
  541. {
  542. P_WLAN_AUTH_FRAME_T prAuthFrame;
  543. UINT_16 u2RxTransactionSeqNum;
  544. ASSERT(prSwRfb);
  545. /* 4 <1> locate the Authentication Frame. */
  546. prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
  547. /* 4 <2> Parse the Header of Authentication Frame. */
  548. if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN +
  549. AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN +
  550. STATUS_CODE_FIELD_LEN)) {
  551. ASSERT(0);
  552. return WLAN_STATUS_SUCCESS;
  553. }
  554. /* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */
  555. /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */
  556. u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */
  557. switch (u2RxTransactionSeqNum) {
  558. case AUTH_TRANSACTION_SEQ_2:
  559. case AUTH_TRANSACTION_SEQ_4:
  560. saaFsmRunEventRxAuth(prAdapter, prSwRfb);
  561. break;
  562. case AUTH_TRANSACTION_SEQ_1:
  563. case AUTH_TRANSACTION_SEQ_3:
  564. #if CFG_SUPPORT_AAA
  565. aaaFsmRunEventRxAuth(prAdapter, prSwRfb);
  566. #endif /* CFG_SUPPORT_AAA */
  567. break;
  568. default:
  569. DBGLOG(SAA, WARN, "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n",
  570. u2RxTransactionSeqNum, prAuthFrame->u2StatusCode);
  571. break;
  572. }
  573. return WLAN_STATUS_SUCCESS;
  574. } /* end of authCheckRxAuthFrameTransSeq() */
  575. /*----------------------------------------------------------------------------*/
  576. /*!
  577. * @brief This function will validate the incoming Authentication Frame and take
  578. * the status code out.
  579. *
  580. * @param[in] prSwRfb Pointer to SW RFB data structure.
  581. * @param[in] u2TransactionSeqNum Transaction Sequence Number
  582. * @param[out] pu2StatusCode Pointer to store the Status Code from Authentication.
  583. *
  584. * @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state.
  585. * @retval WLAN_STATUS_SUCCESS This is the frame we should handle.
  586. */
  587. /*----------------------------------------------------------------------------*/
  588. WLAN_STATUS
  589. authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter,
  590. IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode)
  591. {
  592. P_STA_RECORD_T prStaRec;
  593. P_WLAN_AUTH_FRAME_T prAuthFrame;
  594. UINT_16 u2RxAuthAlgNum;
  595. UINT_16 u2RxTransactionSeqNum;
  596. /* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */
  597. ASSERT(prSwRfb);
  598. ASSERT(pu2StatusCode);
  599. prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
  600. ASSERT(prStaRec);
  601. if (!prStaRec)
  602. return WLAN_STATUS_INVALID_PACKET;
  603. /* 4 <1> locate the Authentication Frame. */
  604. prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
  605. /* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */
  606. /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */
  607. u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */
  608. if (u2RxAuthAlgNum != (UINT_16) prStaRec->ucAuthAlgNum) {
  609. DBGLOG(SAA, WARN, "Discard Auth frame with auth type = %d, current = %d\n",
  610. u2RxAuthAlgNum, prStaRec->ucAuthAlgNum);
  611. *pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED;
  612. return WLAN_STATUS_SUCCESS;
  613. }
  614. /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */
  615. u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */
  616. if (u2RxTransactionSeqNum != u2TransactionSeqNum) {
  617. DBGLOG(SAA, WARN, "Discard Auth frame with Transaction Seq No = %d\n", u2RxTransactionSeqNum);
  618. *pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ;
  619. return WLAN_STATUS_FAILURE;
  620. }
  621. /* 4 <3> Get the Status code */
  622. /* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */
  623. /* *pu2StatusCode = u2RxStatusCode; */
  624. *pu2StatusCode = prAuthFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */
  625. return WLAN_STATUS_SUCCESS;
  626. } /* end of authCheckRxAuthFrameStatus() */
  627. /*----------------------------------------------------------------------------*/
  628. /*!
  629. * @brief This function will handle the Challenge Text IE from the Authentication frame
  630. *
  631. * @param[in] prSwRfb Pointer to SW RFB data structure.
  632. * @param[in] prIEHdr Pointer to start address of IE
  633. *
  634. * @return (none)
  635. */
  636. /*----------------------------------------------------------------------------*/
  637. VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr)
  638. {
  639. P_WLAN_AUTH_FRAME_T prAuthFrame;
  640. P_STA_RECORD_T prStaRec;
  641. UINT_16 u2TransactionSeqNum;
  642. ASSERT(prSwRfb);
  643. ASSERT(prIEHdr);
  644. prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
  645. ASSERT(prStaRec);
  646. if (!prStaRec)
  647. return;
  648. /* For Management, frame header and payload are in a continuous buffer */
  649. prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
  650. /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) */
  651. u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */
  652. /* Only consider SEQ_2 for Challenge Text */
  653. if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) &&
  654. (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) {
  655. /* Free previous allocated TCM memory */
  656. if (prStaRec->prChallengeText) {
  657. ASSERT(0);
  658. cnmMemFree(prAdapter, prStaRec->prChallengeText);
  659. prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL;
  660. }
  661. prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr));
  662. if (prStaRec->prChallengeText == NULL)
  663. return;
  664. /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */
  665. COPY_IE(prStaRec->prChallengeText, prIEHdr);
  666. }
  667. return;
  668. } /* end of authAddIEChallengeText() */
  669. /*----------------------------------------------------------------------------*/
  670. /*!
  671. * @brief This function will parse and process the incoming Authentication frame.
  672. *
  673. * @param[in] prSwRfb Pointer to SW RFB data structure.
  674. *
  675. * @retval WLAN_STATUS_SUCCESS This is the frame we should handle.
  676. */
  677. /*----------------------------------------------------------------------------*/
  678. WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
  679. {
  680. P_WLAN_AUTH_FRAME_T prAuthFrame;
  681. PUINT_8 pucIEsBuffer;
  682. UINT_16 u2IEsLen;
  683. UINT_16 u2Offset;
  684. UINT_8 ucIEID;
  685. UINT_32 i;
  686. ASSERT(prSwRfb);
  687. prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
  688. pucIEsBuffer = &prAuthFrame->aucInfoElem[0];
  689. u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
  690. (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN);
  691. IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) {
  692. ucIEID = IE_ID(pucIEsBuffer);
  693. for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) {
  694. if (ucIEID == rxAuthIETable[i].ucElemID)
  695. rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIEsBuffer);
  696. }
  697. }
  698. return WLAN_STATUS_SUCCESS;
  699. } /* end of authProcessRxAuth2_Auth4Frame() */
  700. /*----------------------------------------------------------------------------*/
  701. /*!
  702. * @brief This function will compose the Deauthentication frame
  703. *
  704. * @param[in] pucBuffer Pointer to the frame buffer.
  705. * @param[in] aucPeerMACAddress Given Peer MAC Address.
  706. * @param[in] aucMACAddress Given Our MAC Address.
  707. * @param[in] u2StatusCode Status Code
  708. *
  709. * @return (none)
  710. */
  711. /*----------------------------------------------------------------------------*/
  712. static inline VOID
  713. authComposeDeauthFrameHeaderAndFF(IN PUINT_8 pucBuffer,
  714. IN UINT_8 aucPeerMACAddress[],
  715. IN UINT_8 aucMACAddress[], IN UINT_8 aucBssid[], IN UINT_16 u2ReasonCode)
  716. {
  717. P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
  718. UINT_16 u2FrameCtrl;
  719. ASSERT(pucBuffer);
  720. ASSERT(aucPeerMACAddress);
  721. ASSERT(aucMACAddress);
  722. ASSERT(aucBssid);
  723. prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) pucBuffer;
  724. /* 4 <1> Compose the frame header of the Deauthentication frame. */
  725. /* Fill the Frame Control field. */
  726. u2FrameCtrl = MAC_FRAME_DEAUTH;
  727. /* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */
  728. prDeauthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */
  729. /* Fill the DA field with Target BSSID. */
  730. COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress);
  731. /* Fill the SA field with our MAC Address. */
  732. COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress);
  733. /* Fill the BSSID field with Target BSSID. */
  734. COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid);
  735. /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
  736. prDeauthFrame->u2SeqCtrl = 0;
  737. /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */
  738. /* Fill the Status Code field. */
  739. /* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */
  740. prDeauthFrame->u2ReasonCode = u2ReasonCode; /* NOTE(Kevin): Optimized for ARM */
  741. } /* end of authComposeDeauthFrameHeaderAndFF() */
  742. /*----------------------------------------------------------------------------*/
  743. /*!
  744. * @brief This function will send the Deauthenticiation frame
  745. *
  746. * @param[in] prStaRec Pointer to the STA_RECORD_T
  747. * @param[in] prClassErrSwRfb Pointer to the SW_RFB_T which is Class Error.
  748. * @param[in] u2ReasonCode A reason code to indicate why to leave BSS.
  749. * @param[in] pfTxDoneHandler TX Done call back function
  750. *
  751. * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
  752. * @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module
  753. * @retval WLAN_STATUS_FAILURE Didn't send Deauth frame for various reasons.
  754. */
  755. /*----------------------------------------------------------------------------*/
  756. WLAN_STATUS
  757. authSendDeauthFrame(IN P_ADAPTER_T prAdapter,
  758. IN P_STA_RECORD_T prStaRec,
  759. IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
  760. {
  761. P_WLAN_MAC_HEADER_A4_T prWlanMacHeader = NULL;
  762. PUINT_8 pucReceiveAddr;
  763. PUINT_8 pucTransmitAddr;
  764. PUINT_8 pucBssid = NULL;
  765. ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
  766. P_MSDU_INFO_T prMsduInfo;
  767. UINT_16 u2EstimatedFrameLen;
  768. UINT_16 u2RxFrameCtrl;
  769. P_BSS_INFO_T prBssInfo;
  770. P_DEAUTH_INFO_T prDeauthInfo;
  771. OS_SYSTIME rCurrentTime;
  772. INT_32 i4NewEntryIndex, i;
  773. UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND;
  774. #if CFG_ENABLE_WIFI_DIRECT
  775. UINT_8 aucBMC[] = BC_MAC_ADDR;
  776. #endif
  777. /* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data
  778. * frame
  779. */
  780. /* 4 <1> Find the Receiver Address first. */
  781. if (prClassErrSwRfb) {
  782. BOOLEAN fgIsAbleToSendDeauth = FALSE;
  783. prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader;
  784. /* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl); */
  785. u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */
  786. /* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */
  787. if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0)
  788. return WLAN_STATUS_FAILURE;
  789. /* Check if corresponding BSS is able to send Deauth */
  790. for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) {
  791. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]);
  792. if (IS_NET_ACTIVE(prAdapter, i) &&
  793. (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) {
  794. {
  795. fgIsAbleToSendDeauth = TRUE;
  796. eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) i;
  797. break;
  798. }
  799. }
  800. }
  801. if (!fgIsAbleToSendDeauth)
  802. return WLAN_STATUS_FAILURE;
  803. pucReceiveAddr = prWlanMacHeader->aucAddr2;
  804. } else if (prStaRec) {
  805. pucReceiveAddr = prStaRec->aucMacAddr;
  806. } else {
  807. #if CFG_ENABLE_WIFI_DIRECT
  808. pucReceiveAddr = aucBMC;
  809. #else
  810. return WLAN_STATUS_FAILURE;
  811. #endif
  812. }
  813. /* 4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC */
  814. GET_CURRENT_SYSTIME(&rCurrentTime);
  815. i4NewEntryIndex = -1;
  816. for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) {
  817. prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]);
  818. /* For continuously sending Deauth frame, the minimum interval is
  819. * MIN_DEAUTH_INTERVAL_MSEC.
  820. */
  821. if (CHECK_FOR_TIMEOUT(rCurrentTime,
  822. prDeauthInfo->rLastSendTime, MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) {
  823. i4NewEntryIndex = i;
  824. } else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) && (!pfTxDoneHandler)) {
  825. return WLAN_STATUS_FAILURE;
  826. }
  827. }
  828. /* 4 <3> Update information. */
  829. if (i4NewEntryIndex > 0) {
  830. prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]);
  831. COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr);
  832. prDeauthInfo->rLastSendTime = rCurrentTime;
  833. } else {
  834. /* NOTE(Kevin): for the case of AP mode, we may encounter this case
  835. * if deauth all the associated clients.
  836. */
  837. DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n");
  838. }
  839. /* 4 <4> Allocate a PKT_INFO_T for Deauthentication Frame */
  840. /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */
  841. u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN);
  842. /* Allocate a MSDU_INFO_T */
  843. prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
  844. if (prMsduInfo == NULL) {
  845. DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Deauth Request.\n");
  846. return WLAN_STATUS_RESOURCES;
  847. }
  848. /* 4 <5> Find the Transmitter Address and BSSID. */
  849. if (prClassErrSwRfb) {
  850. /* The TA of Deauth is the A1 of RX frame */
  851. pucTransmitAddr = prWlanMacHeader->aucAddr1;
  852. switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) {
  853. case MASK_FC_FROM_DS:
  854. /* The BSSID of Deauth is the A2 of RX frame */
  855. pucBssid = prWlanMacHeader->aucAddr2;
  856. break;
  857. case MASK_FC_TO_DS:
  858. /* The BSSID of Deauth is the A1 of RX frame */
  859. pucBssid = prWlanMacHeader->aucAddr1;
  860. break;
  861. case MASK_TO_DS_FROM_DS:
  862. /* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth
  863. * to the A2 of RX frame for temporary solution.
  864. */
  865. pucBssid = prWlanMacHeader->aucAddr2;
  866. break;
  867. /* No Default */
  868. }
  869. } else if (prStaRec) {
  870. eNetTypeIndex = prStaRec->ucNetTypeIndex;
  871. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
  872. pucTransmitAddr = prBssInfo->aucOwnMacAddr;
  873. pucBssid = prBssInfo->aucBSSID;
  874. }
  875. #if CFG_ENABLE_WIFI_DIRECT
  876. else {
  877. if (prAdapter->fgIsP2PRegistered) {
  878. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
  879. ucStaRecIdx = STA_REC_INDEX_BMCAST;
  880. pucTransmitAddr = prBssInfo->aucOwnMacAddr;
  881. pucBssid = prBssInfo->aucBSSID;
  882. eNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
  883. } else {
  884. /* 20130122: free packet by samplin */
  885. cnmMgtPktFree(prAdapter, prMsduInfo);
  886. return WLAN_STATUS_FAILURE;
  887. }
  888. }
  889. #endif
  890. /* 4 <6> compose Deauthentication frame header and some fixed fields */
  891. authComposeDeauthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
  892. pucReceiveAddr, pucTransmitAddr, pucBssid, u2ReasonCode);
  893. #if CFG_SUPPORT_802_11W
  894. if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
  895. P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
  896. prDeauthFrame =
  897. (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
  898. prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
  899. DBGLOG(TX, WARN, "authSendDeauthFrame with protection\n");
  900. }
  901. #endif
  902. /* 4 <7> Update information of MSDU_INFO_T */
  903. prMsduInfo->eSrc = TX_PACKET_MGMT;
  904. prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
  905. prMsduInfo->ucStaRecIndex = ((prStaRec == NULL) ? ucStaRecIdx : prStaRec->ucIndex);
  906. prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex;
  907. prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
  908. prMsduInfo->fgIs802_1x = FALSE;
  909. prMsduInfo->fgIs802_11 = TRUE;
  910. prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN;
  911. prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  912. prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
  913. prMsduInfo->fgIsBasicRate = TRUE;
  914. DBGLOG(SAA, INFO, "Sending Deauth, network: %d, seqNo %d\n",
  915. eNetTypeIndex, prMsduInfo->ucTxSeqNum);
  916. /* 4 <8> Inform TXM to send this Deauthentication frame. */
  917. nicTxEnqueueMsdu(prAdapter, prMsduInfo);
  918. return WLAN_STATUS_SUCCESS;
  919. } /* end of authSendDeauthFrame() */
  920. /*----------------------------------------------------------------------------*/
  921. /*!
  922. * @brief This function will parse and process the incoming Deauthentication frame
  923. * if the given BSSID is matched.
  924. *
  925. * @param[in] prSwRfb Pointer to SW RFB data structure.
  926. * @param[in] aucBSSID Given BSSID
  927. * @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication.
  928. *
  929. * @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state.
  930. * @retval WLAN_STATUS_SUCCESS This is the frame we should handle.
  931. */
  932. /*----------------------------------------------------------------------------*/
  933. WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode)
  934. {
  935. P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
  936. UINT_16 u2RxReasonCode;
  937. ASSERT(prSwRfb);
  938. ASSERT(aucBSSID);
  939. ASSERT(pu2ReasonCode);
  940. /* 4 <1> locate the Deauthentication Frame. */
  941. prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
  942. /* 4 <2> Parse the Header of Deauthentication Frame. */
  943. #if 0 /* Kevin: Seems redundant */
  944. WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl)
  945. u2RxFrameCtrl &= MASK_FRAME_TYPE;
  946. if (u2RxFrameCtrl != MAC_FRAME_DEAUTH)
  947. return WLAN_STATUS_FAILURE;
  948. #endif
  949. if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) {
  950. ASSERT(0);
  951. return WLAN_STATUS_FAILURE;
  952. }
  953. /* Check if this Deauth Frame is coming from Target BSSID */
  954. if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) {
  955. DBGLOG(SAA, LOUD, "Ignore Deauth Frame from other BSS [ %pM ]\n",
  956. prDeauthFrame->aucSrcAddr);
  957. return WLAN_STATUS_FAILURE;
  958. }
  959. /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */
  960. WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode);
  961. *pu2ReasonCode = u2RxReasonCode;
  962. return WLAN_STATUS_SUCCESS;
  963. } /* end of authProcessRxDeauthFrame() */
  964. /*----------------------------------------------------------------------------*/
  965. /*!
  966. * @brief This function will parse and process the incoming Authentication frame.
  967. *
  968. * @param[in] prSwRfb Pointer to SW RFB data structure.
  969. * @param[in] aucExpectedBSSID Given Expected BSSID.
  970. * @param[in] u2ExpectedAuthAlgNum Given Expected Authentication Algorithm Number
  971. * @param[in] u2ExpectedTransSeqNum Given Expected Transaction Sequence Number.
  972. * @param[out] pu2ReturnStatusCode Return Status Code.
  973. *
  974. * @retval WLAN_STATUS_SUCCESS This is the frame we should handle.
  975. * @retval WLAN_STATUS_FAILURE The frame we will ignore.
  976. */
  977. /*----------------------------------------------------------------------------*/
  978. WLAN_STATUS
  979. authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter,
  980. IN P_SW_RFB_T prSwRfb,
  981. IN UINT_8 aucExpectedBSSID[],
  982. IN UINT_16 u2ExpectedAuthAlgNum,
  983. IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode)
  984. {
  985. P_WLAN_AUTH_FRAME_T prAuthFrame;
  986. UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL;
  987. ASSERT(prSwRfb);
  988. ASSERT(aucExpectedBSSID);
  989. ASSERT(pu2ReturnStatusCode);
  990. /* 4 <1> locate the Authentication Frame. */
  991. prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader;
  992. /* 4 <2> Check the BSSID */
  993. if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID))
  994. return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */
  995. /* 4 <3> Check the SA, which should not be MC/BC */
  996. if (prAuthFrame->aucSrcAddr[0] & BIT(0)) {
  997. DBGLOG(P2P, WARN, "Invalid STA MAC with MC/BC bit set: %pM\n",
  998. prAuthFrame->aucSrcAddr);
  999. return WLAN_STATUS_FAILURE;
  1000. }
  1001. /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */
  1002. if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum)
  1003. u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED;
  1004. if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum)
  1005. u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ;
  1006. *pu2ReturnStatusCode = u2ReturnStatusCode;
  1007. return WLAN_STATUS_SUCCESS;
  1008. } /* end of authProcessRxAuth1Frame() */