/****************************************************************************** * * Name: PrepareDownloadPacket() * * Description: Prepare the DownloadPacket from packet send by upper layer * * Conditions for Use: * * Arguments: * IN PMRVDRV_ADAPTER Adapter, * IN PNDIS_PACKET Packet, * IN PSDIO_TX_PKT pDnldPacket * * Return Value: None * * Notes: * *****************************************************************************/ NDIS_STATUS PrepareDownloadPacket(PMRVDRV_ADAPTER Adapter,PNDIS_PACKET Packet, PSDIO_TX_PKT pDnldPacket) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; UINT BufferCount; UINT TotalPacketLength=0; UINT TotalBufferLength=0; UINT BytesCopied=0; UINT Length,AccumLength; PNDIS_BUFFER pBuffer, pNextBuffer; PVOID pVirtualAddr; PUCHAR pHeader = NULL; ULONG coBufferLength = 0; ULONG i; PWCB pWcb; UCHAR *pCurPtr = pDnldPacket->Buf.CmdBuf; Status = NDIS_STATUS_SUCCESS; NdisQueryPacket( Packet, NULL, &BufferCount, &pBuffer, &TotalPacketLength); if(!pBuffer || !BufferCount || !TotalPacketLength) { Status=NDIS_STATUS_FAILURE; DBGPRINT(DBG_TX|DBG_WARNING,(L"TX - NDIS buffer is not valid, return FAILURE \n")); return Status; } //RETAILMSG(1,(TEXT("[Marvell]SendSinglePacket:1 NdisQueryBuffer"))); NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length); //RETAILMSG(1,(TEXT("[Marvell]SendSinglePacket:2 NdisQueryBuffer"))); pHeader = (PUCHAR)pVirtualAddr; DBGPRINT(DBG_TX|DBG_HELP,(L"SendSinglePacket: buffers %d, packet len %d\n",BufferCount, TotalPacketLength)); pWcb = (PWCB)&(pDnldPacket->Buf.TxDataBuf.Wcb); NdisZeroMemory(pWcb,sizeof(WCB)); pWcb->Status = MRVDRV_WCB_STATUS_USED; pWcb->PktLen = (USHORT)TotalPacketLength; DBGPRINT(DBG_TX|DBG_HELP,(L"DataRate = %x\n", (ULONG)Adapter -> DataRate)); // number of retry is 3 // pWcb->TxControl = ( (3 << 12 ) | Adapter->DataRate); // pWcb->TxControl =0; pWcb->TxControl = Adapter->TX_Control_Value; pWcb->PktPtr = sizeof(WCB); // First buffer contains the MAC header // Call NdisMoveMemory() to copy DEST MAC adress to WCB //RETAILMSG(1,(TEXT("[Marvell]SendSinglePacket:1 NdisMoveMemory"))); NdisMoveMemory( (PVOID)&(pWcb->DestMACAdrHi), pVirtualAddr, MRVDRV_ETH_ADDR_LEN); //RETAILMSG(1,(TEXT("[Marvell]SendSinglePacket:2 NdisMoveMemory"))); { ULONG currenttime, packettime; currenttime = GetTickCount(); packettime = *((ULONG *)(&Packet->MacReserved[0])); // PKtdelay in driver layer , unit 2ms pWcb->Reserved[0]=(UCHAR)((currenttime - packettime) / 2); DBGPRINT(DBG_CCX_V4,(L"PktDelay%02x ",pWcb->Reserved[0])); } // Start the packet. TotalBufferLength = TotalPacketLength; TotalBufferLength += sizeof(WCB); // TotalBufferLength contains the size of the packet pDnldPacket->Len = ADD_SDIO_PKT_HDR_LENGTH(TotalBufferLength); DBGPRINT(DBG_TX,(L"TX %d bytes: packet size %d\n",(ULONG)TotalBufferLength, (ULONG)TotalPacketLength)); pCurPtr += sizeof(WCB); AccumLength = sizeof(WCB); // Query each buffer for the packet and move data to SQ for(i=0; i<BufferCount; i++) { NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length); AccumLength += Length; if( AccumLength > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE ) // PJG: accum length already counts the header... need to compare to entire buffer size break; if( pVirtualAddr ) { NdisMoveMemory(pCurPtr, (PUCHAR)pVirtualAddr, (USHORT)Length); pCurPtr += Length; } NdisGetNextBuffer(pBuffer, &pNextBuffer); if( !pNextBuffer ) break; pBuffer = pNextBuffer; }//for(i=0; i<BufferCount; i++) DBGPRINT(DBG_TX|DBG_HELP,(L"\n")); DBGPRINT(DBG_TX|DBG_HELP,(L"[Marvell]TX SendSinglePacket!\n")); pDnldPacket->Type = IF_DATA_PKT; return NDIS_STATUS_SUCCESS; }
/* ========================================================================== Description: Check sanity of unicast cipher selector in RSN IE. Return: TRUE if match FALSE otherwise ========================================================================== */ BOOLEAN RTMPCheckUcast( IN PRTMP_ADAPTER pAd, IN PEID_STRUCT eid_ptr, IN MAC_TABLE_ENTRY *pEntry) { PUCHAR pStaTmp; USHORT Count; UCHAR apidx; ASSERT(pEntry); ASSERT(pEntry->apidx < pAd->ApCfg.BssidNum); apidx = pEntry->apidx; pEntry->WepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus; if (eid_ptr->Len < 16) { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : the length is too short(%d) \n", eid_ptr->Len)); return FALSE; } /* Store STA RSN_IE capability */ pStaTmp = (PUCHAR)&eid_ptr->Octet[0]; if(eid_ptr->Eid == IE_WPA2) { /* skip Version(2),Multicast cipter(4) 2+4==6 */ /* point to number of unicast */ pStaTmp +=6; } else if (eid_ptr->Eid == IE_WPA) { /* skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */ /* point to number of unicast */ pStaTmp += 10; } else { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : invalid IE=%d\n", eid_ptr->Eid)); return FALSE; } /* Store unicast cipher count */ NdisMoveMemory(&Count, pStaTmp, sizeof(USHORT)); Count = cpu2le16(Count); /* pointer to unicast cipher */ pStaTmp += sizeof(USHORT); if (eid_ptr->Len >= 16) { if (eid_ptr->Eid == IE_WPA) { if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled) {/* multiple cipher (TKIP/CCMP) */ while (Count > 0) { /* TKIP */ if (MIX_CIPHER_WPA_TKIP_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { /* Compare if peer STA uses the TKIP as its unicast cipher */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) { pEntry->WepStatus = Ndis802_11Encryption2Enabled; return TRUE; } /* Our AP uses the AES as the secondary cipher */ /* Compare if the peer STA use AES as its unicast cipher */ if (MIX_CIPHER_WPA_AES_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][16], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } } else { /* AES */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } pStaTmp += 4; Count--; } } else {/* single cipher */ while (Count > 0) { if (RTMPEqualMemory(pStaTmp , &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) return TRUE; pStaTmp += 4; Count--; } } } else if (eid_ptr->Eid == IE_WPA2) { UCHAR IE_Idx = 0; /* When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure */ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) IE_Idx = 1; if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled) {/* multiple cipher (TKIP/CCMP) */ while (Count > 0) { /* WPA2 TKIP */ if (MIX_CIPHER_WPA2_TKIP_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { /* Compare if peer STA uses the TKIP as its unicast cipher */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) { pEntry->WepStatus = Ndis802_11Encryption2Enabled; return TRUE; } /* Our AP uses the AES as the secondary cipher */ /* Compare if the peer STA use AES as its unicast cipher */ if (MIX_CIPHER_WPA2_AES_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][12], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } } else { /* AES */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } pStaTmp += 4; Count--; } } else {/* single cipher */ while (Count > 0) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) return TRUE; pStaTmp += 4; Count--; } } } } return FALSE; }
/* ========================================================================== Description: Check validity of the received RSNIE. Return: status code ========================================================================== */ UINT APValidateRSNIE( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN PUCHAR pRsnIe, IN UCHAR rsnie_len) { UINT StatusCode = MLME_SUCCESS; PEID_STRUCT eid_ptr; int apidx; PMULTISSID_STRUCT pMbss; if (rsnie_len == 0) return MLME_SUCCESS; eid_ptr = (PEID_STRUCT)pRsnIe; if ((eid_ptr->Len + 2) != rsnie_len) { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : the len is invalid !!!\n")); return MLME_UNSPECIFY_FAIL; } apidx = pEntry->apidx; pMbss = &pAd->ApCfg.MBSSID[apidx]; #ifdef WAPI_SUPPORT if (eid_ptr->Eid == IE_WAPI) return MLME_SUCCESS; #endif /* WAPI_SUPPORT */ /* check group cipher */ if (!RTMPCheckMcast(pAd, eid_ptr, pEntry)) { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : invalid group cipher !!!\n")); StatusCode = MLME_INVALID_GROUP_CIPHER; } /* Check pairwise cipher */ else if (!RTMPCheckUcast(pAd, eid_ptr, pEntry)) { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : invalid pairwise cipher !!!\n")); StatusCode = MLME_INVALID_PAIRWISE_CIPHER; } /* Check AKM */ else if (!RTMPCheckAUTH(pAd, eid_ptr, pEntry)) { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]APValidateRSNIE : invalid AKM !!!\n")); StatusCode = MLME_INVALID_AKMP; } if (StatusCode != MLME_SUCCESS) { /* send wireless event - for RSN IE sanity check fail */ RTMPSendWirelessEvent(pAd, IW_RSNIE_SANITY_FAIL_EVENT_FLAG, pEntry->Addr, 0, 0); DBGPRINT(RT_DEBUG_ERROR, ("%s : invalid status code(%d) !!!\n", __FUNCTION__, StatusCode)); } else { UCHAR CipherAlg = CIPHER_NONE; if (pEntry->WepStatus == Ndis802_11Encryption1Enabled) CipherAlg = CIPHER_WEP64; else if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) CipherAlg = CIPHER_TKIP; else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) CipherAlg = CIPHER_AES; DBGPRINT(RT_DEBUG_TRACE, ("%s : (AID#%d WepStatus=%s)\n", __FUNCTION__, pEntry->Aid, CipherName[CipherAlg])); } return StatusCode; }
VOID ndisMOpenAdapter( OUT PNDIS_STATUS Status, OUT PNDIS_STATUS OpenErrorStatus, OUT PNDIS_HANDLE NdisBindingHandle, IN NDIS_HANDLE NdisProtocolHandle, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_STRING AdapterName, IN UINT OpenOptions, IN PSTRING AddressingInformation, IN PNDIS_MINIPORT_BLOCK Miniport, IN PNDIS_OPEN_BLOCK NewOpenP, IN PFILE_OBJECT FileObject, IN BOOLEAN UsingEncapsulation ) /*++ Routine Description: This routine handles opening a miniport either directly from NdisOpenAdapter() of from our deferred processing routine if the open had to pend. NOTE: Must be called with spin lock held. NOTE: Must be called with lock acquired flag set. Arguments: Return Value: None. --*/ { PNDIS_M_OPEN_BLOCK MiniportOpen; PNDIS_MAC_BLOCK FakeMac; BOOLEAN FilterOpen; PNDIS_PROTOCOL_BLOCK TmpProtP; BOOLEAN DerefMini = FALSE, FreeOpen = FALSE, DerefProt = FALSE; ASSERT(MINIPORT_LOCK_ACQUIRED(Miniport)); do { if (!ndisReferenceMiniport(Miniport)) { // // The adapter is closing. // *Status = NDIS_STATUS_CLOSING; break; } DerefMini = TRUE; // // Increment the protocol's reference count. // TmpProtP = (PNDIS_PROTOCOL_BLOCK)NdisProtocolHandle; if (!ndisReferenceProtocol(TmpProtP)) { // // The protocol is closing. // *Status = NDIS_STATUS_CLOSING; break; } DerefProt = TRUE; // // Now allocate a complete set of MAC structures for the protocol // and set them up to transfer to the Miniport handler routines. // if (Miniport->FakeMac == NULL) { // // Allocate a fake MAC block for the characteristics. // FakeMac = (PNDIS_MAC_BLOCK)ALLOC_FROM_POOL(sizeof(NDIS_MAC_BLOCK), NDIS_TAG_DEFAULT); if (FakeMac == NULL) { *Status = NDIS_STATUS_RESOURCES; break; } // // Initialize the fake mac block. // ZeroMemory(FakeMac, sizeof(NDIS_MAC_BLOCK)); // // Save the fake mac block with the miniport. // Miniport->FakeMac = FakeMac; // // If transfer data calls don't pend then we'll use the faster // ndisMTransferDataSync(). // if ((Miniport->MacOptions & NDIS_MAC_OPTION_TRANSFERS_NOT_PEND) != 0) { FakeMac->MacCharacteristics.TransferDataHandler = ndisMTransferDataSync; } else { FakeMac->MacCharacteristics.TransferDataHandler = ndisMTransferData; } // // Initialize the reset handler. // FakeMac->MacCharacteristics.ResetHandler = ndisMReset; // // Initialize the request handler. // FakeMac->MacCharacteristics.RequestHandler = ndisMRequest; // // Initialize the send handler. // switch (Miniport->MediaType) { case NdisMediumArcnet878_2: FakeMac->MacCharacteristics.SendHandler = ndisMArcnetSend; break; case NdisMediumWan: FakeMac->MacCharacteristics.SendHandler = (PVOID)ndisMWanSend; break; default: // // If this is a fullduplex miniport then change the reset handler. // if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX)) { FakeMac->MacCharacteristics.ResetHandler = ndisMResetFullDuplex; } // // Set up the send packet handlers miniports that support // the new NDIS 4.0 SendPackets handler. // if (MINIPORT_TEST_SEND_FLAG(Miniport, fMINIPORT_SEND_PACKET_ARRAY)) { if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX)) { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSendFullDuplexToSendPackets\n")); FakeMac->MacCharacteristics.SendHandler = ndisMSendFullDuplexToSendPackets; } else { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSendToSendPackets\n")); FakeMac->MacCharacteristics.SendHandler = ndisMSendToSendPackets; } } else { if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX)) { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSendFullDuplex\n")); FakeMac->MacCharacteristics.SendHandler = ndisMSendFullDuplex; } else { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSend\n")); FakeMac->MacCharacteristics.SendHandler = ndisMSend; } } break; } // // If the miniport indicates packets the we have a dummy // transfer data. // if (Miniport->DriverHandle->MiniportCharacteristics.ReturnPacketHandler != NULL) { // This driver supports the receive packet paradigm // Fake the transferdata handler so if any xport calls // this, we're still ok FakeMac->MacCharacteristics.TransferDataHandler = ndisMDummyTransferData; } } else { FakeMac = Miniport->FakeMac; } // // Allocate an open within the Miniport context // MiniportOpen = (PNDIS_M_OPEN_BLOCK)ALLOC_FROM_POOL(sizeof(NDIS_M_OPEN_BLOCK), NDIS_TAG_DEFAULT); if (MiniportOpen == (PNDIS_M_OPEN_BLOCK)NULL) { *Status = NDIS_STATUS_RESOURCES; break; } FreeOpen = TRUE; // // Initialize the open block. // ZeroMemory(MiniportOpen, sizeof(NDIS_M_OPEN_BLOCK)); MiniportOpen->DriverHandle = Miniport->DriverHandle; MiniportOpen->MiniportHandle = Miniport; MiniportOpen->ProtocolHandle = TmpProtP; MiniportOpen->FakeOpen = NewOpenP; MiniportOpen->ProtocolBindingContext = ProtocolBindingContext; MiniportOpen->MiniportAdapterContext = Miniport->MiniportAdapterContext; MiniportOpen->FileObject = FileObject; MiniportOpen->CurrentLookahead = Miniport->CurrentLookahead; NdisAllocateSpinLock(&(MiniportOpen->SpinLock)); DBGPRINT(DBG_COMP_OPEN, DBG_LEVEL_INFO, ("=1 0x%x\n", MiniportOpen)); MiniportOpen->References = 1; if (UsingEncapsulation) { MINIPORT_SET_FLAG(MiniportOpen, fMINIPORT_OPEN_USING_ETH_ENCAPSULATION); } // // Save the handlers with the open block. // MiniportOpen->SendHandler = Miniport->DriverHandle->MiniportCharacteristics.SendHandler; MiniportOpen->TransferDataHandler = Miniport->DriverHandle->MiniportCharacteristics.TransferDataHandler; MiniportOpen->SendCompleteHandler = TmpProtP->ProtocolCharacteristics.SendCompleteHandler; MiniportOpen->TransferDataCompleteHandler = TmpProtP->ProtocolCharacteristics.TransferDataCompleteHandler; MiniportOpen->ReceiveHandler = TmpProtP->ProtocolCharacteristics.ReceiveHandler; MiniportOpen->ReceiveCompleteHandler = TmpProtP->ProtocolCharacteristics.ReceiveCompleteHandler; // // NDIS 4.0 miniport extensions // MiniportOpen->SendPacketsHandler = Miniport->DriverHandle->MiniportCharacteristics.SendPacketsHandler; // // NDIS 4.0 protocol extensions // MiniportOpen->ReceivePacketHandler = (Miniport->DriverHandle->MiniportCharacteristics.ReturnPacketHandler == NULL) ? NULL : TmpProtP->ProtocolCharacteristics.ReceivePacketHandler; // // NDIS 4.1 miniport extensions // MiniportOpen->MiniportCoRequestHandler = Miniport->DriverHandle->MiniportCharacteristics.CoRequestHandler; MiniportOpen->MiniportCoCreateVcHandler = Miniport->DriverHandle->MiniportCharacteristics.CoCreateVcHandler; // // NDIS 4.1 protocol extensions // MiniportOpen->CoRequestCompleteHandler = TmpProtP->ProtocolCharacteristics.CoRequestCompleteHandler; // // initialize Lists // InitializeListHead(&MiniportOpen->ActiveVcHead); InitializeListHead(&MiniportOpen->InactiveVcHead); // // Set up the elements of the open structure. // INITIALIZE_SPIN_LOCK(&NewOpenP->SpinLock); NewOpenP->Closing = FALSE; NewOpenP->AdapterHandle = (NDIS_HANDLE) Miniport; NewOpenP->ProtocolHandle = TmpProtP; NewOpenP->ProtocolBindingContext = ProtocolBindingContext; NewOpenP->MacBindingHandle = (NDIS_HANDLE)MiniportOpen; // // for speed, instead of having to use AdapterHandle->MacHandle // NewOpenP->MacHandle = (NDIS_HANDLE)FakeMac; // // for even more speed... // if (NdisMediumArcnet878_2 == Miniport->MediaType) { NewOpenP->TransferDataHandler = ndisMArcTransferData; } else { NewOpenP->TransferDataHandler = FakeMac->MacCharacteristics.TransferDataHandler; } // // Set the send handler in the open block. // NewOpenP->SendHandler = FakeMac->MacCharacteristics.SendHandler; NewOpenP->RequestHandler = ndisMRequest; // // Set up the send packets handler. // if (MINIPORT_TEST_SEND_FLAG(Miniport, fMINIPORT_SEND_PACKET_ARRAY)) { if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX)) { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSendPacketsFullDuplex\n")); NewOpenP->SendPacketsHandler = ndisMSendPacketsFullDuplex; } else { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSendPackets\n")); NewOpenP->SendPacketsHandler = ndisMSendPackets; } } else { if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX)) { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSendPacketsFullDuplexToSend\n")); NewOpenP->SendPacketsHandler = ndisMSendPacketsFullDuplexToSend; } else { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Using ndisMSendPacketsToSend\n")); NewOpenP->SendPacketsHandler = ndisMSendPacketsToSend; } } // // For WAN miniports, the send handler is different. // if (NdisMediumWan == Miniport->MediaType) { NewOpenP->SendHandler = (PVOID)ndisMWanSend; } else if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IS_CO)) { // // the convential send function is not available for CO miniports // since this send function does not specify the Vc to send upon // However for components which want to use this let them. // if ((NewOpenP->SendHandler == NULL) && (NewOpenP->SendPacketsHandler == NULL)) { NewOpenP->SendHandler = ndisMRejectSend; FakeMac->MacCharacteristics.SendHandler = ndisMRejectSend; } // // Trap the conventional request handlers if they are not specified. // if ((Miniport->DriverHandle->MiniportCharacteristics.SetInformationHandler == NULL) || (Miniport->DriverHandle->MiniportCharacteristics.QueryInformationHandler == NULL)) { FakeMac->MacCharacteristics.RequestHandler = ndisMWrappedRequest; NewOpenP->RequestHandler = ndisMWrappedRequest; } } NewOpenP->SendCompleteHandler = TmpProtP->ProtocolCharacteristics.SendCompleteHandler; NewOpenP->TransferDataCompleteHandler = TmpProtP->ProtocolCharacteristics.TransferDataCompleteHandler; NewOpenP->ReceiveHandler = TmpProtP->ProtocolCharacteristics.ReceiveHandler; NewOpenP->ReceiveCompleteHandler = TmpProtP->ProtocolCharacteristics.ReceiveCompleteHandler; NewOpenP->PostNt31ReceiveHandler = TmpProtP->ProtocolCharacteristics.ReceiveHandler; NewOpenP->PostNt31ReceiveCompleteHandler = TmpProtP->ProtocolCharacteristics.ReceiveCompleteHandler; NewOpenP->ResetHandler = ndisMReset; NewOpenP->ReceivePacketHandler = (Miniport->DriverHandle->MiniportCharacteristics.ReturnPacketHandler == NULL) ? NULL : TmpProtP->ProtocolCharacteristics.ReceivePacketHandler; // // Save a pointer to the file object in the open... // NewOpenP->FileObject = FileObject; // // ...and a pointer to the open in the file object. // FileObject->FsContext = NewOpenP; *NdisBindingHandle = (NDIS_HANDLE)NewOpenP; // // Insert the open into the filter package // switch (Miniport->MediaType) { case NdisMediumArcnet878_2: if (!UsingEncapsulation) { FilterOpen = ArcNoteFilterOpenAdapter(Miniport->ArcDB, MiniportOpen, (NDIS_HANDLE)NewOpenP, &MiniportOpen->FilterHandle); break; } // // If we're using ethernet encapsulation then // we simply fall through to the ethernet stuff. // case NdisMedium802_3: FilterOpen = EthNoteFilterOpenAdapter(Miniport->EthDB, MiniportOpen, (NDIS_HANDLE)NewOpenP, &MiniportOpen->FilterHandle); break; case NdisMedium802_5: FilterOpen = TrNoteFilterOpenAdapter(Miniport->TrDB, MiniportOpen, (NDIS_HANDLE)NewOpenP, &MiniportOpen->FilterHandle); break; case NdisMediumFddi: FilterOpen = FddiNoteFilterOpenAdapter(Miniport->FddiDB, MiniportOpen, (NDIS_HANDLE)NewOpenP, &MiniportOpen->FilterHandle); break; default: // // Bogus non-NULL value // FilterOpen = 1; break; } // // Check for an open filter failure. // if (!FilterOpen) { // // Something went wrong, clean up and exit. // *Status = NDIS_STATUS_OPEN_FAILED; break; } ndisQueueOpenOnProtocol(NewOpenP, TmpProtP); // // Everything has been filled in. Synchronize access to the // adapter block and link the new open adapter in. // MiniportOpen->MiniportNextOpen = Miniport->OpenQueue; Miniport->OpenQueue = MiniportOpen; // // If this is the first open on the adapter then fire the // wake-up-dpc timer. // if (NULL == MiniportOpen->MiniportNextOpen) { // // Start wake up timer // NdisMSetPeriodicTimer((PNDIS_MINIPORT_TIMER)(&Miniport->WakeUpDpcTimer), Miniport->CheckForHangTimeout); } *Status = NDIS_STATUS_SUCCESS; } while (FALSE); // // Cleanup failure case // if (*Status != NDIS_STATUS_SUCCESS) { if (DerefMini) { ndisDereferenceMiniport(Miniport); } if (DerefProt) { ndisDereferenceProtocol(TmpProtP); } if (FreeOpen) { FREE_POOL(MiniportOpen); } ObDereferenceObject(FileObject); FREE_POOL(NewOpenP); } }
VOID RTMPGetTxTscFromAsic( IN PRTMP_ADAPTER pAd, IN UCHAR apidx, OUT PUCHAR pTxTsc) { USHORT Wcid; USHORT offset; UCHAR IvEiv[8]; int i; /* Sanity check of apidx */ if (apidx >= MAX_MBSSID_NUM(pAd)) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPGetTxTscFromAsic : invalid apidx(%d)\n", apidx)); return; } /* Initial value */ NdisZeroMemory(IvEiv, 8); NdisZeroMemory(pTxTsc, 6); /* Get apidx for this BSSID */ GET_GroupKey_WCID(pAd, Wcid, apidx); /* When the group rekey action is triggered, a count-down(3 seconds) is started. During the count-down, use the initial PN as TSC. Otherwise, get the IVEIV from ASIC. */ if (pAd->ApCfg.MBSSID[apidx].RekeyCountDown > 0) { /* In IEEE 802.11-2007 8.3.3.4.3 described : The PN shall be implemented as a 48-bit monotonically incrementing non-negative integer, initialized to 1 when the corresponding temporal key is initialized or refreshed. */ IvEiv[0] = 1; } else { UINT32 temp1, temp2; /* Read IVEIV from Asic */ offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE); /* Use Read32 to avoid endian problem */ RTMP_IO_READ32(pAd, offset, &temp1); RTMP_IO_READ32(pAd, offset+4, &temp2); for ( i=0; i<4; i++) { IvEiv[i] = (UCHAR)(temp1 >> (i*8)); IvEiv[i+4] = (UCHAR)(temp2 >> (i*8)); } } /* Record current TxTsc */ if (pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { /* AES */ *pTxTsc = IvEiv[0]; *(pTxTsc+1) = IvEiv[1]; *(pTxTsc+2) = IvEiv[4]; *(pTxTsc+3) = IvEiv[5]; *(pTxTsc+4) = IvEiv[6]; *(pTxTsc+5) = IvEiv[7]; } else { /* TKIP */ *pTxTsc = IvEiv[2]; *(pTxTsc+1) = IvEiv[0]; *(pTxTsc+2) = IvEiv[4]; *(pTxTsc+3) = IvEiv[5]; *(pTxTsc+4) = IvEiv[6]; *(pTxTsc+5) = IvEiv[7]; } DBGPRINT(RT_DEBUG_TRACE, ("RTMPGetTxTscFromAsic : WCID(%d) TxTsc 0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x \n", Wcid, *pTxTsc, *(pTxTsc+1), *(pTxTsc+2), *(pTxTsc+3), *(pTxTsc+4), *(pTxTsc+5))); }
int WirelessProtocol::sendData(byte* data, uint16_t size, uint64_t Pipe, uint16_t SendTimeout) { ProtocolMessage PM; if (size % 30 == 0) PM.AllLength = size / 30; else PM.AllLength = size / 30 + 1; radio->stopListening(); radio->openWritingPipe(Pipe); DBGPRINT("Send data size: %hu, package count: %hu", size, PM.AllLength); unsigned long lastSuccSend = millis(); for (uint8_t i = 0; i < PM.AllLength; i++) { if (millis() - lastSuccSend > SendTimeout) { DBGPRINT("All send timeout"); return ERROR_TIMEOUT; } DBGPRINT("Trying send package: %hu", i); PM.CurrentNum = i; memcpy(PM.data, &(data[i*30]), min(30, size - 30*i)); bin_dump((char *)(PM.data), 30); radio->write(&PM, sizeof(ProtocolMessage)); long wait_start = millis(); bool ackR = false; while ( !(ackR = radio->available()) && (millis() - wait_start) < PACKET_TIMEOUT) { radio->stopListening(); radio->write(&PM, sizeof(ProtocolMessage)); radio->startListening(); delay(30); } if (ackR) { uint8_t message_count; radio->read(&message_count,sizeof(message_count)); DBGPRINT("Reciving ack package %hu", message_count); if (message_count != i) { DBGPRINT("Failed send package: %hu", i); i--; } else { DBGPRINT("Packet send"); lastSuccSend = millis(); } } else { DBGPRINT("Timeout sending package: %hu", i); i--; } } DBGPRINT("Send complete"); return ERROR_SUCCESS; }
VOID NdisMDeregisterIoPortRange( IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InitialPort, IN UINT NumberOfPorts, IN PVOID PortOffset ) /*++ Routine Description: Sets up an IO port for operations. Arguments: MiniportAdapterHandle - Handle passed to Miniport Initialize. InitialPort - Physical address of the starting port number. NumberOfPorts - Number of ports to map. PortOffset - The mapped port address the Miniport uses for NdisRaw functions. Return Value: None. --*/ { PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)(MiniportAdapterHandle); PHYSICAL_ADDRESS PortAddress; PHYSICAL_ADDRESS InitialPortAddress; ULONG addressSpace; CM_PARTIAL_RESOURCE_DESCRIPTOR Resource; NDIS_STATUS Status; // // Get the system physical address for this card. The card uses // I/O space, except for "internal" Jazz devices which use // memory space. // addressSpace = (Miniport->AdapterType == NdisInterfaceInternal) ? 0 : 1; InitialPortAddress.LowPart = InitialPort; InitialPortAddress.HighPart = 0; HalTranslateBusAddress(Miniport->BusType, // InterfaceType Miniport->BusNumber, // BusNumber InitialPortAddress, // Bus Address &addressSpace, // AddressSpace &PortAddress); // Translated address if (addressSpace == 0) { // // memory space // MmUnmapIoSpace(PortOffset, NumberOfPorts); } // // Build the resource to remove. // Resource.Type = CmResourceTypePort; Resource.ShareDisposition = CmResourceShareDeviceExclusive; Resource.Flags = (Miniport->AdapterType == NdisInterfaceInternal) ? CM_RESOURCE_PORT_MEMORY : CM_RESOURCE_PORT_IO; Resource.u.Port.Start.QuadPart = InitialPort; Resource.u.Port.Length = NumberOfPorts; // // Remove the resource. // Status = ndisRemoveResource( &Miniport->Resources, &Resource, Miniport->DriverHandle->NdisDriverInfo->NdisWrapperDriver, Miniport->DeviceObject, &Miniport->MiniportName); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT(DBG_COMP_UNLOAD, DBG_LEVEL_INFO, ("NdisMDeregisterIoPortRange failed to remove the resource\n")); } }
/* ======================================================================== Routine Description: For each out-going packet, check the upper layer protocol type if need to handled by our APCLI convert engine. If yes, call corresponding handler to handle it. Arguments: pAd =>Pointer to our adapter pPkt =>pointer to the 802.11 header of outgoing packet ifIdx =>Interface Index want to dispatch to. Return Value: Success => TRUE Mapped mac address if found, else return specific default mac address depends on the upper layer protocol type. Error => FALSE. Note: 1.the pPktHdr must be a 802.3 packet. 2.Maybe we need a TxD arguments? 3.We check every packet here including group mac address becasue we need to handle DHCP packet. ======================================================================== */ PUCHAR MATEngineTxHandle( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPkt, IN UINT ifIdx, IN UCHAR OpMode) { PUCHAR pLayerHdr = NULL, pPktHdr = NULL, pMacAddr = NULL; UINT16 protoType, protoType_ori; INT i; struct _MATProtoOps *pHandle = NULL; PUCHAR retSkb = NULL; BOOLEAN bVLANPkt = FALSE; if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED) return NULL; pPktHdr = GET_OS_PKT_DATAPTR(pPkt); if (!pPktHdr) return NULL; protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12)); /* Get the upper layer protocol type of this 802.3 pkt. */ protoType = OS_NTOHS(protoType_ori); /* handle 802.1q enabled packet. Skip the VLAN tag field to get the protocol type. */ if (protoType == 0x8100) { protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12 + 4)); protoType = OS_NTOHS(protoType_ori); bVLANPkt = TRUE; } #ifdef RELEASE_EXCLUDE DBGPRINT(RT_DEBUG_INFO,("%s(): protoType=0x%04x\n", __FUNCTION__, protoType)); #endif /* RELEASE_EXCLUDE */ /* For differnet protocol, dispatch to specific handler */ for (i=0; i < MAX_MAT_SUPPORT_PROTO_NUM; i++) { if (protoType == MATProtoTb[i].protocol) { pHandle = MATProtoTb[i].pHandle; /* the pHandle must not be null! */ pLayerHdr = bVLANPkt ? (pPktHdr + MAT_VLAN_ETH_HDR_LEN) : (pPktHdr + MAT_ETHER_HDR_LEN); #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAC_REPEATER_SUPPORT UCHAR tempIdx = ifIdx; UCHAR CliIdx = 0xFF; if (tempIdx >= 64) { CliIdx = ((tempIdx - 64) % 16); tempIdx = ((tempIdx - 64) / 16); pMacAddr = &pAd->ApCfg.ApCliTab[tempIdx].RepeaterCli[CliIdx].CurrentAddress[0]; } else #endif /* MAC_REPEATER_SUPPORT */ pMacAddr = &pAd->ApCfg.ApCliTab[ifIdx].wdev.if_addr[0]; } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT #ifdef ETH_CONVERT_SUPPORT #ifdef P2P_SUPPORT if (OpMode == OPMODE_STA) pMacAddr = &pAd->CurrentAddress[0]; #ifdef APCLI_SUPPORT else pMacAddr = &pAd->ApCfg.ApCliTab[ifIdx].wdev.if_addr[0]; #endif /* APCLI_SUPPORT */ #else IF_DEV_CONFIG_OPMODE_ON_STA(pAd) pMacAddr = &pAd->CurrentAddress[0]; #endif /* P2P_SUPPORT */ #endif /* ETH_CONVERT_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ if (pHandle->tx!=NULL) retSkb = pHandle->tx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, pMacAddr); return retSkb; } }
MAC_TABLE_ENTRY *MacTableInsertEntry( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr, IN UCHAR apidx, IN UCHAR OpMode, IN BOOLEAN CleanAll) { UCHAR HashIdx; int i, FirstWcid; MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; /* USHORT offset;*/ /* ULONG addr;*/ BOOLEAN Cancelled; /* if FULL, return*/ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) return NULL; FirstWcid = 1; /* allocate one MAC entry*/ NdisAcquireSpinLock(&pAd->MacTabLock); for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) /* skip entry#0 so that "entry index == AID" for fast lookup*/ { /* pick up the first available vacancy*/ if (IS_ENTRY_NONE(&pAd->MacTab.Content[i])) { pEntry = &pAd->MacTab.Content[i]; /* ENTRY PREEMPTION: initialize the entry */ RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); if (CleanAll == TRUE) { pEntry->MaxSupportedRate = RATE_11; pEntry->CurrTxRate = RATE_11; NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; } do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_APCLI) { SET_ENTRY_APCLI(pEntry); pEntry->isCached = FALSE; break; } #endif /* APCLI_SUPPORT */ #ifdef WDS_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_WDS) { SET_ENTRY_WDS(pEntry); pEntry->isCached = FALSE; break; } #endif /* WDS_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { /* be a regular-entry*/ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && ((apidx < HW_BEACON_MAX_NUM)) && (pAd->ApCfg.MBSSID[apidx].MaxStaNum != 0) && (pAd->ApCfg.MBSSID[apidx].StaCount >= pAd->ApCfg.MBSSID[apidx].MaxStaNum)) { DBGPRINT(RT_DEBUG_WARN, ("%s: The connection table is full in ra%d.\n", __FUNCTION__, apidx)); NdisReleaseSpinLock(&pAd->MacTabLock); return NULL; } } #endif /* CONFIG_AP_SUPPORT */ SET_ENTRY_CLIENT(pEntry); } while (FALSE); pEntry->bIAmBadAtheros = FALSE; RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (IS_ENTRY_CLIENT(pEntry)) /* Only Clent entry need the retry timer.*/ { RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE); /* RTMP_OS_Init_Timer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pAd);*/ } #ifdef APCLI_SUPPORT else if (IS_ENTRY_APCLI(pEntry)) { RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) RTMPInitTimer(pAd, &pEntry->eTxBfProbeTimer, GET_TIMER_FUNCTION(eTxBfProbeTimerExec), pEntry, FALSE); #endif /* TXBF_SUPPORT */ pEntry->pAd = pAd; pEntry->CMTimerRunning = FALSE; pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; pEntry->RSNIE_Len = 0; NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter)); pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; if (IS_ENTRY_MESH(pEntry)) pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH); else if (IS_ENTRY_APCLI(pEntry)) pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI); else if (IS_ENTRY_WDS(pEntry)) pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS); else pEntry->apidx = apidx; #ifdef CONFIG_AP_SUPPORT if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM)) pEntry->pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx]; else pEntry->pMbss = NULL; #endif /* CONFIG_AP_SUPPORT */ do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (IS_ENTRY_APCLI(pEntry)) { pEntry->AuthMode = pAd->ApCfg.ApCliTab[pEntry->apidx].AuthMode; pEntry->WepStatus = pAd->ApCfg.ApCliTab[pEntry->apidx].WepStatus; if (pEntry->AuthMode < Ndis802_11AuthModeWPA) { pEntry->WpaState = AS_NOTUSE; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; } else { pEntry->WpaState = AS_PTKSTART; pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; } pEntry->MatchAPCLITabIdx = pEntry->apidx; break; } #endif /* APCLI_SUPPORT */ #ifdef WDS_SUPPORT if (IS_ENTRY_WDS(pEntry)) { pEntry->AuthMode = Ndis802_11AuthModeOpen; pEntry->WepStatus = Ndis802_11EncryptionDisabled; pEntry->MatchWDSTabIdx = pEntry->apidx; break; } #endif /* WDS_SUPPORT */ IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { MBSS_MR_APIDX_SANITY_CHECK(pAd, apidx); pEntry->AuthMode = pAd->ApCfg.MBSSID[apidx].AuthMode; pEntry->WepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus; pEntry->GroupKeyWepStatus = pAd->ApCfg.MBSSID[apidx].GroupKeyWepStatus; if (pEntry->AuthMode < Ndis802_11AuthModeWPA) pEntry->WpaState = AS_NOTUSE; else pEntry->WpaState = AS_INITIALIZE; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; pEntry->StaIdleTimeout = pAd->ApCfg.StaIdleTimeout; pAd->ApCfg.MBSSID[apidx].StaCount++; pAd->ApCfg.EntryClientCount++; break; } #endif /* CONFIG_AP_SUPPORT */ } while (FALSE); pEntry->GTKState = REKEY_NEGOTIATING; pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; COPY_MAC_ADDR(pEntry->Addr, pAddr); COPY_MAC_ADDR(pEntry->HdrAddr1, pAddr); do { #ifdef APCLI_SUPPORT if (IS_ENTRY_APCLI(pEntry)) { COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.ApCliTab[pEntry->apidx].CurrentAddress); COPY_MAC_ADDR(pEntry->HdrAddr3, pAddr); break; } #endif // APCLI_SUPPORT // #ifdef WDS_SUPPORT if (IS_ENTRY_WDS(pEntry)) { COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid); COPY_MAC_ADDR(pEntry->HdrAddr3, pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid); break; } #endif // WDS_SUPPORT // #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) { COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.MBSSID[apidx].Bssid); COPY_MAC_ADDR(pEntry->HdrAddr3, pAd->ApCfg.MBSSID[apidx].Bssid); break; } #endif // CONFIG_AP_SUPPORT // } while (FALSE); pEntry->Sst = SST_NOT_AUTH; pEntry->AuthState = AS_NOT_AUTH; pEntry->Aid = (USHORT)i; /*0;*/ pEntry->CapabilityInfo = 0; pEntry->PsMode = PWR_ACTIVE; pEntry->PsQIdleCount = 0; pEntry->NoDataIdleCount = 0; pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; pEntry->ContinueTxFailCnt = 0; #ifdef WDS_SUPPORT pEntry->LockEntryTx = FALSE; #endif /* WDS_SUPPORT */ pEntry->TimeStamp_toTxRing = 0; InitializeQueueHeader(&pEntry->PsQueue); #ifdef STREAM_MODE_SUPPORT /* Enable Stream mode for first three entries in MAC table */ #endif /* STREAM_MODE_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef UAPSD_SUPPORT if (IS_ENTRY_CLIENT(pEntry)) /* Ralink WDS doesn't support any power saving.*/ { /* init U-APSD enhancement related parameters */ UAPSD_MR_ENTRY_INIT(pEntry); } #endif /* UAPSD_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ pAd->MacTab.Size ++; /* Set the security mode of this entry as OPEN-NONE in ASIC */ RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, (UCHAR)i); /* Add this entry into ASIC RX WCID search table */ RTMP_STA_ENTRY_ADD(pAd, pEntry); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef WSC_AP_SUPPORT pEntry->bWscCapable = FALSE; pEntry->Receive_EapolStart_EapRspId = 0; #endif /* WSC_AP_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) NdisAllocateSpinLock(pAd, &pEntry->TxSndgLock); #endif /* TXBF_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size)); break; } }
//static int me2fsCreate( struct inode *inode, struct dentry *dir, // umode_t mode, bool flag ) //{ DBGPRINT( "<ME2FS>inode ops:create!\n" ); return 0; } //static int me2fsLink( struct dentry *dentry, struct inode *inode, struct dentry *d) //{ DBGPRINT( "<ME2FS>inode ops:link!\n" ); return 0; } //static int me2fsUnlink( struct inode *inode, struct dentry *d ) //{ DBGPRINT( "<ME2FS>inode ops:unlink!\n" ); return 0; } //static int me2fsSymlink( struct inode *inode, struct dentry *d, const char *name ) //{ DBGPRINT( "<ME2FS>inode ops:symlink!\n" ); return 0; } //static int me2fsMkdir( struct inode *inode, struct dentry *d, umode_t mode ) //{ DBGPRINT( "<ME2FS>inode ops:mkdir!\n" ); return 0; } //static int me2fsRmdir( struct inode *inode, struct dentry *d ) //{ DBGPRINT( "<ME2FS>inode ops:rmdir!\n" ); return 0; } //static int me2fsMknod( struct inode *inode, struct dentry *d, // umode_t mode, dev_t dev ) //{ DBGPRINT( "<ME2FS>inode ops:mknod!\n" ); return 0; } //static int me2fsRename( struct inode *inode, struct dentry *d, // struct inode *inode2, struct dentry *d2 ) //{ DBGPRINT( "<ME2FS>inode ops:rename!\n" ); return 0; } //static int me2fsSetAttr( struct dentry *dentry, struct iattr *attr ) //{ DBGPRINT( "<ME2FS>inode ops:setattr!\n" ); return 0; } static struct posix_acl* me2fsGetAcl( struct inode *inode, int flags ) { DBGPRINT( "<ME2FS>inode ops:get_acl!\n" ); return 0; }
/* ================================================================================== Function :me2fsMkdir Input :struct inode *dir < vfs inode of directory > struct dentry *dentry < dentry to be made its entry > umode_t mode < file mode > Output :void Return :int < result > Description :make a directory in *dir ================================================================================== */ static int me2fsMkdir( struct inode *dir, struct dentry *dentry, umode_t mode ) { struct inode *inode; int err; #if 0 // quota dquot_initialize( dir ); #endif DBGPRINT( "<ME2FS>mkdir : start make [%s]\n", dentry->d_name.name ); /* ------------------------------------------------------------------------ */ /* allocate a new inode for new directory */ /* ------------------------------------------------------------------------ */ inode_inc_link_count( dir ); inode = me2fsAllocNewInode( dir, S_IFDIR | mode, &dentry->d_name ); if( IS_ERR( inode ) ) { inode_dec_link_count( dir ); return( PTR_ERR( inode ) ); } inode->i_op = &me2fs_dir_inode_operations; inode->i_fop = &me2fs_dir_operations; inode->i_mapping->a_ops = &me2fs_aops; /* ------------------------------------------------------------------------ */ /* make empty directory( just make '.') */ /* ------------------------------------------------------------------------ */ inode_inc_link_count( inode ); if( ( err = me2fsMakeEmpty( inode, dir ) ) ) { goto out_fail; } /* ------------------------------------------------------------------------ */ /* insert the new directory's inode to its parent */ /* ------------------------------------------------------------------------ */ if( ( err = me2fsAddLink( dentry, inode ) ) ) { goto out_fail; } unlock_new_inode( inode ); d_instantiate( dentry, inode ); DBGPRINT( "<ME2FS>mkdir : complete [%s]\n", dentry->d_name.name ); return( err ); out_fail: DBGPRINT( "<ME2FS>failed to make dir\n" ); inode_dec_link_count( inode ); inode_dec_link_count( inode ); unlock_new_inode( inode ); iput( inode ); return( err ); }
static VOID APPeerAuthConfirmAction( IN struct rtmp_adapter *pAd, IN MLME_QUEUE_ELEM *Elem) { unsigned short Seq, Alg, Status; u8 Addr2[MAC_ADDR_LEN]; PHEADER_802_11 pRcvHdr; CHAR Chtxt[CIPHER_TEXT_LEN]; MAC_TABLE_ENTRY *pEntry; u8 Addr1[MAC_ADDR_LEN]; uint32_t apidx; if (! APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, &Alg, &Seq, &Status, Chtxt )) return; apidx = get_apidx_by_addr(pAd, Addr1); if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } if ((pAd->ApCfg.MBSSID[apidx].wdev.if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].wdev.if_dev))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } /* End of if */ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) { DBGPRINT(RT_DEBUG_ERROR, ("AUTH - Invalid wcid (%d).\n", Elem->Wcid)); return; } pEntry = &pAd->MacTab.Content[Elem->Wcid]; if (pEntry && IS_ENTRY_CLIENT(pEntry)) { if (!RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == true) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, false, false); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = false; } ASSERT(pEntry->Aid == Elem->Wcid); BASessionTearDownALL(pAd, pEntry->wcid); } } pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, Seq, Alg, Status, Elem->Wcid, PRINT_MAC(Addr2))); if (pEntry && MAC_ADDR_EQUAL(Addr2, pAd->ApMlmeAux.Addr)) { if ((pRcvHdr->FC.Wep == 1) && NdisEqualMemory(Chtxt, pAd->ApMlmeAux.Challenge, CIPHER_TEXT_LEN)) { /* Successful */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_SUCCESS); pEntry->AuthState = AS_AUTH_KEY; pEntry->Sst = SST_AUTH; } else { /* send wireless event - Authentication rejected because of challenge failure */ RTMPSendWirelessEvent(pAd, IW_AUTH_REJECT_CHALLENGE_FAILURE, pEntry->Addr, 0, 0); /* fail - wep bit is not set or challenge text is not equal */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_REJ_CHALLENGE_FAILURE); MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); /*Chtxt[127]='\0'; */ /*pAd->ApMlmeAux.Challenge[127]='\0'; */ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", ((pRcvHdr->FC.Wep == 1) ? "challenge text is not equal" : "wep bit is not set"))); /*DBGPRINT(RT_DEBUG_TRACE, ("Sent Challenge = %s\n",&pAd->ApMlmeAux.Challenge[100])); */ /*DBGPRINT(RT_DEBUG_TRACE, ("Rcv Challenge = %s\n",&Chtxt[100])); */ } } else { /* fail for unknown reason. most likely is AuthRspAux machine be overwritten by another */ /* STA also using SHARED_KEY authentication */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); } }
static VOID APPeerAuthReqAtIdleAction( IN struct rtmp_adapter *pAd, IN MLME_QUEUE_ELEM *Elem) { INT i; unsigned short Seq, Alg, RspReason, Status; u8 Addr1[MAC_ADDR_LEN]; u8 Addr2[MAC_ADDR_LEN]; CHAR Chtxt[CIPHER_TEXT_LEN]; uint32_t apidx; PHEADER_802_11 pRcvHdr; HEADER_802_11 AuthHdr; u8 *pOutBuffer = NULL; int NStatus; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; u8 ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN; MULTISSID_STRUCT *pMbss; struct rtmp_wifi_dev *wdev; CHAR rssi; if (! APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, &Alg, &Seq, &Status, Chtxt )) return; /* Find which MBSSID to be authenticate */ apidx = get_apidx_by_addr(pAd, Addr1); if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } pEntry = MacTableLookup(pAd, Addr2); if (pEntry && IS_ENTRY_CLIENT(pEntry)) { if (!RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == true) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, false, false); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = false; } BASessionTearDownALL(pAd, pEntry->wcid); ASSERT(pEntry->Aid == Elem->Wcid); } } pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, Seq, Alg, Status, Elem->Wcid, PRINT_MAC(Addr2))); /* YF@20130102: Refuse the weak signal of AuthReq */ rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, (CHAR)Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, (CHAR)Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, (CHAR)Elem->Rssi2, RSSI_2)); DBGPRINT(RT_DEBUG_TRACE, ("%s: AUTH_FAIL_REQ Threshold = %d, AUTH_NO_RSP_REQ Threshold = %d, AUTH RSSI = %d\n", wdev->if_dev->name, pMbss->AuthFailRssiThreshold, pMbss->AuthNoRspRssiThreshold, rssi)); if (((pMbss->AuthFailRssiThreshold != 0) && (rssi < pMbss->AuthFailRssiThreshold)) || ((pMbss->AuthNoRspRssiThreshold != 0) && (rssi < pMbss->AuthNoRspRssiThreshold))) { DBGPRINT(RT_DEBUG_TRACE, ("Reject this AUTH_REQ due to Weak Signal.\n")); if ((pMbss->AuthFailRssiThreshold != 0) && (rssi < pMbss->AuthFailRssiThreshold)) APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); return; } /* fail in ACL checking => send an AUTH-Fail seq#2. */ if (! ApCheckAccessControlList(pAd, Addr2, apidx)) { ASSERT(Seq == 1); ASSERT(pEntry == NULL); APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("Failed in ACL checking => send an AUTH seq#2 with " "Status code = %d\n", MLME_UNSPECIFY_FAIL)); return; } if ((Alg == AUTH_MODE_OPEN) && (pMbss->wdev.AuthMode != Ndis802_11AuthModeShared)) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, wdev, apidx, OPMODE_AP, true); if (pEntry) { { pEntry->AuthState = AS_AUTH_OPEN; pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */ } APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_SUCCESS); } else ; /* MAC table full, what should we respond ????? */ } else if ((Alg == AUTH_MODE_KEY) && ((wdev->AuthMode == Ndis802_11AuthModeShared) || (wdev->AuthMode == Ndis802_11AuthModeAutoSwitch))) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, wdev, apidx, OPMODE_AP, true); if (pEntry) { pEntry->AuthState = AS_AUTHENTICATING; pEntry->Sst = SST_NOT_AUTH; /* what if it already in SST_ASSOC ??????? */ /* log this STA in AuthRspAux machine, only one STA is stored. If two STAs using */ /* SHARED_KEY authentication mingled together, then the late comer will win. */ COPY_MAC_ADDR(&pAd->ApMlmeAux.Addr, Addr2); for(i=0; i<CIPHER_TEXT_LEN; i++) pAd->ApMlmeAux.Challenge[i] = RandomByte(pAd); RspReason = 0; Seq++; pOutBuffer = kmalloc(MGMT_DMA_BUFFER_SIZE, GFP_ATOMIC); if(pOutBuffer == NULL) return; /* if no memory, can't do anything */ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH seq#2 (Challenge)\n")); MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, wdev->if_addr, wdev->bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AuthHdr, 2, &Alg, 2, &Seq, 2, &RspReason, 1, &ChTxtIe, 1, &ChTxtLen, CIPHER_TEXT_LEN, pAd->ApMlmeAux.Challenge, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); kfree(pOutBuffer); } else ; /* MAC table full, what should we respond ???? */ } else { /* wrong algorithm */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_ALG_NOT_SUPPORT); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Alg=%d, Seq=%d, AuthMode=%d\n", Alg, Seq, pAd->ApCfg.MBSSID[apidx].wdev.AuthMode)); } }
INT RtmpChipOpsEepromHook( IN RTMP_ADAPTER *pAd, IN INT infType) { RTMP_CHIP_OP *pChipOps = &pAd->chipOps; #ifdef RT30xx #ifdef RTMP_EFUSE_SUPPORT UINT32 eFuseCtrl, MacCsr0; int index; #endif #endif #ifdef RTMP_FLASH_SUPPORT pChipOps->eeinit = rtmp_nv_init; pChipOps->eeread = rtmp_ee_flash_read; pChipOps->eewrite = rtmp_ee_flash_write; return 0; #endif /* RTMP_FLASH_SUPPORT */ #ifdef RT30xx #ifdef RTMP_EFUSE_SUPPORT index = 0; do { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return -1; RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); pAd->MACVersion = MacCsr0; if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) break; RTMPusecDelay(10); } while (index++ < 100); pAd->bUseEfuse=FALSE; #ifdef RT3290 if (IS_RT3290(pAd)) { RTMP_IO_READ32(pAd, EFUSE_CTRL_3290, &eFuseCtrl); } else #endif /* RT3290 */ { RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl); } pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0; if(pAd->bUseEfuse) { pChipOps->eeinit = eFuse_init; pChipOps->eeread = rtmp_ee_efuse_read16; pChipOps->eewrite = rtmp_ee_efuse_write16; DBGPRINT(RT_DEBUG_TRACE, ("NVM is EFUSE\n")); return 0 ; } else { pAd->bFroceEEPROMBuffer = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n")); } #endif /* RTMP_EFUSE_SUPPORT */ #endif /* RT30xx */ switch(infType) { #ifdef RTMP_USB_SUPPORT case RTMP_DEV_INF_USB: pChipOps->eeinit = NULL; pChipOps->eeread = RTUSBReadEEPROM16; pChipOps->eewrite = RTUSBWriteEEPROM16; break; #endif /* RTMP_USB_SUPPORT */ default: DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n")); break; } return 0; }
/*解析命令选项*/ static int SIPFW_ParseOpt(int opt, char *str, union sipfw_variant *var) { const struct vec *p = NULL; int chain = SIPFW_CHAIN_ALL; int action = SIPFW_ACTION_DROP; unsigned int port = 0,ip = 0; int protocol = 0, i = 0; DBGPRINT("==>SIPFW_ParseOpt\n"); switch(opt) { case SIPFW_OPT_CHAIN:/*链名称*/ if(str){ for(i = 0;i<SIPFW_CHAIN_NUM;i++){/*遍历链查找匹配项*/ if(!strncmp(str, sipfw_chain_name[i].ptr, sipfw_chain_name[i].len)){ chain = i; break; } } } var->v_uint = chain; break; case SIPFW_OPT_ACTION:/*动作名称匹配*/ if(str) { for(i = 0;i<SIPFW_ACTION_NUM;i++){/*查找动作名称并匹配*/ if(!strncmp(str, sipfw_action_name[i].ptr, sipfw_action_name[i].len)) { action = i; break; } } } var->v_uint = action; break; case SIPFW_OPT_IP:/*将字符串转为网络字节序*/ if(str) ip = inet_addr(str); var->v_uint = ip; break; case SIPFW_OPT_PORT:/*将字符串类型转为网络序*/ if(str){ port = htons(strtoul(str, NULL, 10)); } var->v_uint = port; break; case SIPFW_OPT_PROTOCOL:/*将协议的名称转为值*/ if(str){ for(p=sipfw_protocol_name + 0; p->ptr != NULL; p++){ if(!strncmp(p->ptr, str, p->len)){ protocol = p->value; break; } } } var->v_uint = protocol; break; case SIPFW_OPT_STR:/*字符串直接拷贝*/ if(str){ int len = strlen(str); memset(var->v_str, 0, sizeof(var->v_str)); if(len < 8){ memcpy(var->v_str, str, len); } } break; default: break; } DBGPRINT("<==SIPFW_ParseOpt\n"); }
INT Set_BeaconReq_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { INT Loop; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; UCHAR ifIndex = pObj->ioctl_if; UINT Aid = 1; UINT ArgIdx; PSTRING thisChar; RRM_MLME_BCN_REQ_INFO BcnReq; ArgIdx = 0; NdisZeroMemory(&BcnReq, sizeof(RRM_MLME_BCN_REQ_INFO)); while ((thisChar = strsep((char **)&arg, "-")) != NULL) { switch(ArgIdx) { case 0: /* Aid. */ Aid = (UINT8) simple_strtol(thisChar, 0, 16); if (!VALID_WCID(Aid)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid)); return TRUE; } break; case 1: /* Meausre Duration. */ BcnReq.MeasureDuration = (UINT8) simple_strtol(thisChar, 0, 10); case 2: /* Regulator Class */ BcnReq.RegulatoryClass = (UINT8) simple_strtol(thisChar, 0, 10); break; case 3: /* BSSID */ if(strlen(thisChar) != 17) { DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid value BSSID.\n", __FUNCTION__)); return TRUE; } if(strlen(thisChar) == 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */ { PSTRING value; for (Loop=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":")) { if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) ) return FALSE; /*Invalid */ AtoH(value, &BcnReq.Bssid[Loop++], 1); } if(Loop != 6) return TRUE; } break; case 4: /* SSID */ BcnReq.pSsid = (PUINT8)thisChar; BcnReq.SsidLen = strlen(thisChar); break; case 5: /* measure channel */ BcnReq.MeasureCh = (UINT8) simple_strtol(thisChar, 0, 10); break; case 6: /* measure mode. */ BcnReq.MeasureMode = (UINT8) simple_strtol(thisChar, 0, 10); if (BcnReq.MeasureMode > RRM_BCN_REQ_MODE_BCNTAB) { DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid Measure Mode. %d\n", __FUNCTION__, BcnReq.MeasureMode)); return TRUE; } case 7: /* regulatory class. */ { PSTRING RegClassString; int RegClassIdx; RegClassIdx = 0; while ((RegClassString = strsep((char **)&thisChar, "+")) != NULL) { BcnReq.ChRepRegulatoryClass[RegClassIdx] = (UINT8) simple_strtol(RegClassString, 0, 10); RegClassIdx++; } } break; } ArgIdx++; } if (ArgIdx < 7 || ArgIdx > 8) { DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid args (%d).\n", __FUNCTION__, ArgIdx)); DBGPRINT(RT_DEBUG_ERROR, ("eg: iwpriv ra0 set BcnReq=<Aid>-<Duration>-<RegulatoryClass>-<BSSID>-<SSID>-<MeasureCh>-<MeasureMode>-<ChRegClass>\n")); return TRUE; } #ifdef RELEASE_EXCLUDE DBGPRINT(RT_DEBUG_ERROR, ("%s::Aid = %d\n", __FUNCTION__, Aid)); DBGPRINT(RT_DEBUG_ERROR, ("%s::Bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, BcnReq.Bssid[0], BcnReq.Bssid[1], BcnReq.Bssid[2], BcnReq.Bssid[3], BcnReq.Bssid[4], BcnReq.Bssid[5])); DBGPRINT(RT_DEBUG_ERROR, ("%s::SsidLen = %d\n", __FUNCTION__, BcnReq.SsidLen)); DBGPRINT(RT_DEBUG_ERROR, ("%s::MeasureCh = %d\n", __FUNCTION__, BcnReq.MeasureCh)); DBGPRINT(RT_DEBUG_ERROR, ("%s::RegulatoryDuration=%d\n", __FUNCTION__, BcnReq.MeasureDuration)); DBGPRINT(RT_DEBUG_ERROR, ("%s::MeasureMode=%d\n", __FUNCTION__, BcnReq.MeasureMode)); DBGPRINT(RT_DEBUG_ERROR, ("RegulatoryClass=")); for (ArgIdx=0; ArgIdx<MAX_NUM_OF_REGULATORY_CLASS; ArgIdx++) { if (BcnReq.ChRepRegulatoryClass[ArgIdx] == 0) break; DBGPRINT(RT_DEBUG_ERROR, ("%d ", \ BcnReq.ChRepRegulatoryClass[ArgIdx])); } DBGPRINT(RT_DEBUG_ERROR, ("\n")); #endif /* RELEASE_EXCLUDE */ BcnReq.BcnReqCapFlag.field.ReportCondition = TRUE; if (BcnReq.MeasureCh == 255) BcnReq.BcnReqCapFlag.field.ChannelRep = TRUE; else BcnReq.BcnReqCapFlag.field.ChannelRep = FALSE; RRM_EnqueueBcnReq(pAd, Aid, ifIndex, &BcnReq); return TRUE; }
int WirelessProtocol::reciveData(byte* data, uint16_t MaxSize, uint16_t* size, uint64_t* Pipe, uint16_t ReciveTimeout) { for (uint8_t i = 0; i < RECIVING_PIPES_MAXCOUNT; i++) { if (reciving_pipes_state[i]) { DBGPRINT("Waiting pipe %d", i); *Pipe = reciving_pipes[i]; radio->openReadingPipe(1, *Pipe); radio->openWritingPipe(*Pipe); radio->startListening(); long startReciveTime = millis(); bool rC = false; while ( !(rC = radio->available()) && (millis() - startReciveTime) < PACKET_TIMEOUT ) ; if (rC) { DBGPRINT("Start reciving, pipe %d", i); radio->read(buf, 32); ProtocolMessage *PM = (ProtocolMessage*)buf; radio->stopListening(); radio->write(&(PM->CurrentNum), sizeof(uint8_t)); //radio->writeAckPayload(1, &(PM.CurrentNum), sizeof(uint8_t)); if (PM->CurrentNum != 0) continue; DBGPRINT("Package count %d", PM->AllLength); *size = PM->AllLength*30; if (*size > MaxSize) return ERROR_NO_ENAUGHT_MEMORY; DBGPRINT("Memory copy"); memcpy(data, PM->data, 30); DBGPRINT("Data size %d", *size); long lastSuccRecv = millis(); for (uint8_t j = 1; j < PM->AllLength; j++) { if (millis() - lastSuccRecv > ReciveTimeout) { DBGPRINT("Package %d timeout", PM->CurrentNum); return ERROR_TIMEOUT; } startReciveTime = millis(); radio->startListening(); while ( !(rC = radio->available()) && (millis() - startReciveTime) < PACKET_TIMEOUT ) ; if (rC) { radio->read(buf, 32); radio->stopListening(); PM = (ProtocolMessage*)buf; if (PM->CurrentNum < j) { bool ackres = radio->write(&(PM->CurrentNum), sizeof(uint8_t)); j--; DBGPRINT("Duplicate packet %d, ackres: %d", PM->CurrentNum, ackres); continue; } else if (PM->CurrentNum > j) { DBGPRINT("Radio transmitt error on package %d", PM->CurrentNum); return ERROR_RADIO_TRANSMITT; } radio->write(&j, sizeof(uint8_t)); memcpy(&(data[j*30]), PM->data, 30); bin_dump((char *)(PM->data), 30); lastSuccRecv = millis(); DBGPRINT("Recived packege %d", j); } } while ( !(rC = radio->available()) && (millis() - startReciveTime) < PACKET_TIMEOUT ) radio->write(&(PM->CurrentNum), sizeof(uint8_t)); DBGPRINT("Recive complete"); return ERROR_SUCCESS; } else { DBGPRINT("No data"); continue; } } } return ERROR_NO_ACTIVE_PIPE; }
INT Set_TxStreamMeasureReq_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; UCHAR ifIndex = pObj->ioctl_if; UINT Aid = 1; UINT ArgIdx; PSTRING thisChar; RRM_MLME_TRANSMIT_REQ_INFO TransmitReq; PMAC_TABLE_ENTRY pMacEntry; ArgIdx = 0; NdisZeroMemory(&TransmitReq, sizeof(RRM_MLME_TRANSMIT_REQ_INFO)); while ((thisChar = strsep((char **)&arg, "-")) != NULL) { switch(ArgIdx) { case 0: /* Aid. */ Aid = (UINT8) simple_strtol(thisChar, 0, 10); if (!VALID_WCID(Aid)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid)); return TRUE; } break; case 1: /* DurationMandotory. */ TransmitReq.bDurationMandatory = ((UINT16)simple_strtol(thisChar, 0, 10) > 0 ? TRUE : FALSE); break; case 2: /* Measure Duration */ TransmitReq.MeasureDuration = (UINT16)simple_strtol(thisChar, 0, 10); break; case 3: /* TID */ TransmitReq.Tid = (UINT8) simple_strtol(thisChar, 0, 10); break; case 4: /* Bin 0 Range */ TransmitReq.BinRange = (UINT8) simple_strtol(thisChar, 0, 10); break; case 5: /* Averange Condition */ TransmitReq.ArvCondition = ((UINT8) simple_strtol(thisChar, 0, 10)) > 0 ? 1 : 0; break; case 6: /* Consecutive Condition */ TransmitReq.ConsecutiveCondition = ((UINT8) simple_strtol(thisChar, 0, 10)) > 0 ? 1 : 0; break; case 7: /* Delay Condition */ TransmitReq.DelayCondition = ((UINT8) simple_strtol(thisChar, 0, 10)) > 0 ? 1 : 0; break; case 8: /* Averange Error Threshold */ TransmitReq.AvrErrorThreshold = (UINT8) simple_strtol(thisChar, 0, 10); break; case 9: /* Consecutive Error Threshold */ TransmitReq.ConsecutiveErrorThreshold = (UINT8) simple_strtol(thisChar, 0, 10); break; case 10: /* Delay Threshold */ TransmitReq.DelayThreshold = (UINT8) simple_strtol(thisChar, 0, 10); break; case 11: /* Measure counter */ TransmitReq.MeasureCnt = (UINT8) simple_strtol(thisChar, 0, 10); break; case 12: /* Trigger time out */ TransmitReq.TriggerTimeout = (UINT8) simple_strtol(thisChar, 0, 10); break; } ArgIdx++; } if ((ArgIdx != 13) && (ArgIdx != 5)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid args (%d).\n", __FUNCTION__, ArgIdx)); DBGPRINT(RT_DEBUG_ERROR, ("eg: iwpriv ra0 set txreq=<Aid>-<DurationMandortory>-<Duration>-<TID>-<BinRange>[-<AvrCond>-<ConsecutiveCond>-<DealyCond>-<AvrErrorThreshold>-<ConsecutiveErrorThreshold>-<DelayThreshold>-<MeasureCnt>-<TriggerTimeout>]\n")); return TRUE; } if (ArgIdx == 5) TransmitReq.bTriggerReport = 0; else TransmitReq.bTriggerReport = 1; pMacEntry = &pAd->MacTab.Content[Aid]; DBGPRINT(RT_DEBUG_ERROR, ("%s::Aid=%d, PeerMac=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, Aid, pMacEntry->Addr[0], pMacEntry->Addr[1], pMacEntry->Addr[2], pMacEntry->Addr[3], pMacEntry->Addr[4], pMacEntry->Addr[5])); DBGPRINT(RT_DEBUG_ERROR, ("Duration=%d, Tid=%d, Bin 0 Range=%d\n", TransmitReq.MeasureDuration, TransmitReq.Tid, TransmitReq.BinRange)); DBGPRINT(RT_DEBUG_ERROR, ("ArvCondition=%d, ConsecutiveCondition=%d, DelayCondition=%d\n", TransmitReq.ArvCondition, TransmitReq.ConsecutiveCondition, TransmitReq.DelayCondition)); DBGPRINT(RT_DEBUG_ERROR, ("AvrErrorThreshold=%d, ConsecutiveErrorThreshold=%d\n", TransmitReq.AvrErrorThreshold, TransmitReq.ConsecutiveErrorThreshold)); DBGPRINT(RT_DEBUG_ERROR, ("DelayThreshold=%d\n", TransmitReq.DelayThreshold)); DBGPRINT(RT_DEBUG_ERROR, ("MeasureCnt=%d, TriggerTimeout=%d\n", TransmitReq.MeasureCnt, TransmitReq.TriggerTimeout)); RRM_EnqueueTxStreamMeasureReq(pAd, Aid, ifIndex, &TransmitReq); return TRUE; }
NDIS_STATUS NdisIMRegisterLayeredMiniport( IN NDIS_HANDLE NdisWrapperHandle, IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics, IN UINT CharacteristicsLength, OUT PNDIS_HANDLE DriverHandle ) /*++ Routine Description: Used to register a layered Miniport driver with the wrapper. Arguments: Status - Status of the operation. NdisWrapperHandle - Handle returned by NdisWInitializeWrapper. MiniportCharacteritics - The NDIS_MINIPORT_CHARACTERISTICS table. CharacteristicsLength - The length of MiniportCharacteristics. DriverHandle - Returns a handle which can be used to call NdisMInitializeDeviceInstance. Return Value: None. --*/ { PNDIS_M_DRIVER_BLOCK MiniBlock; PNDIS_WRAPPER_HANDLE DriverInfo = (PNDIS_WRAPPER_HANDLE)(NdisWrapperHandle); UNICODE_STRING Us; PWSTR pWch; USHORT i, size; UINT MemNeeded; NDIS_STATUS Status; KIRQL OldIrql; DBGPRINT(DBG_COMP_CONFIG, DBG_LEVEL_INFO, ("Enter mini-port register\n")); do { if (DriverInfo == NULL) { Status = NDIS_STATUS_FAILURE; break; } // // Check version numbers and CharacteristicsLength. // size = 0; // Used to indicate bad version below if (MiniportCharacteristics->MajorNdisVersion == 3) { if (MiniportCharacteristics->MinorNdisVersion == 0) size = sizeof(NDIS30_MINIPORT_CHARACTERISTICS); } else if (MiniportCharacteristics->MajorNdisVersion == 4) { if (MiniportCharacteristics->MinorNdisVersion == 0) { size = sizeof(NDIS40_MINIPORT_CHARACTERISTICS); } else if (MiniportCharacteristics->MinorNdisVersion == 1) { size = sizeof(NDIS41_MINIPORT_CHARACTERISTICS); } } // // Check that this is an NDIS 3.0/4.0/4.1 miniport. // if (size == 0) { Status = NDIS_STATUS_BAD_VERSION; break; } // // Check that CharacteristicsLength is enough. // if (CharacteristicsLength < size) { Status = NDIS_STATUS_BAD_CHARACTERISTICS; break; } // // Allocate memory for the NDIS MINIPORT block. // MemNeeded = sizeof(NDIS_M_DRIVER_BLOCK); // // Extract the base-name, determine its length and allocate that much more // Us = *(PUNICODE_STRING)(DriverInfo->NdisWrapperConfigurationHandle); for (i = Us.Length/sizeof(WCHAR), pWch = Us.Buffer + i - 1; i > 0; pWch --, i--) { if (*pWch == L'\\') { Us.Buffer = pWch + 1; Us.Length -= i*sizeof(WCHAR); Us.MaximumLength = Us.Length + sizeof(WCHAR); break; } } MemNeeded += Us.MaximumLength; MiniBlock = (PNDIS_M_DRIVER_BLOCK)ALLOC_FROM_POOL(MemNeeded, NDIS_TAG_MINI_BLOCK); if (MiniBlock == (PNDIS_M_DRIVER_BLOCK)NULL) { return NDIS_STATUS_RESOURCES; } ZeroMemory(MiniBlock, MemNeeded); MiniBlock->Length = MemNeeded; // // Copy over the characteristics table. // CopyMemory(&MiniBlock->MiniportCharacteristics, MiniportCharacteristics, size); // // Upcase the base-name and save it in the MiniBlock // MiniBlock->BaseName.Buffer = (PWSTR)((PUCHAR)MiniBlock + sizeof(NDIS_M_DRIVER_BLOCK)); MiniBlock->BaseName.Length = MiniBlock->BaseName.MaximumLength = Us.Length; RtlUpcaseUnicodeString(&MiniBlock->BaseName, &Us, FALSE); // // No adapters yet registered for this Miniport. // MiniBlock->MiniportQueue = (PNDIS_MINIPORT_BLOCK)NULL; // // Set up unload handler // DriverInfo->NdisWrapperDriver->DriverUnload = ndisMUnload; // // Set up shutdown handler // DriverInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_SHUTDOWN] = ndisMShutdown; // // Set up the handlers for this driver (they all do nothing). // DriverInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_CREATE] = ndisCreateIrpHandler; DriverInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ndisDeviceControlIrpHandler; DriverInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_CLEANUP] = ndisSuccessIrpHandler; DriverInfo->NdisWrapperDriver->MajorFunction[IRP_MJ_CLOSE] = ndisCloseIrpHandler; // // Use this event to tell us when all adapters are removed from the mac // during an unload // INITIALIZE_EVENT(&MiniBlock->MiniportsRemovedEvent); MiniBlock->Unloading = FALSE; MiniBlock->NdisDriverInfo = DriverInfo; MiniBlock->MiniportIdField = (NDIS_HANDLE)0x1; NdisInitializeRef(&MiniBlock->Ref); // Lock the init code down now - before we take the lock below MiniportReferencePackage(); // // Put Driver on global list. // ACQUIRE_SPIN_LOCK(&ndisDriverListLock, &OldIrql); MiniBlock->NextDriver = ndisMiniDriverList; ndisMiniDriverList = MiniBlock; RELEASE_SPIN_LOCK(&ndisDriverListLock, OldIrql); MiniportDereferencePackage(); *DriverHandle = MiniBlock; Status = NDIS_STATUS_SUCCESS; } while (FALSE); return Status; }
VOID RRM_BeaconReportHandler( IN PRTMP_ADAPTER pAd, IN PRRM_BEACON_REP_INFO pBcnRepInfo, IN LONG Length) { CHAR Rssi; USHORT LenVIE = 0; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; UCHAR VarIE[MAX_VIE_LEN]; ULONG Idx = BSS_NOT_FOUND; LONG RemainLen = Length; PRRM_BEACON_REP_INFO pBcnRep; PUINT8 ptr; RRM_BEACON_REP_INFO_FIELD BcnReqInfoField; UINT32 Ptsf; BCN_IE_LIST *ie_list = NULL; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): Alloc ie_list failed!\n", __FUNCTION__)); return; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); ptr = (PUINT8)pBcnRepInfo; pBcnRep = (PRRM_BEACON_REP_INFO)ptr; Ptsf = le2cpu32(pBcnRep->ParentTSF); BcnReqInfoField.word = pBcnRep->RepFrameInfo; DBGPRINT(RT_DEBUG_TRACE, ("%s:: ReqClass=%d, Channel=%d\n", __FUNCTION__, pBcnRep->RegulatoryClass, pBcnRep->ChNumber)); DBGPRINT(RT_DEBUG_TRACE, ("Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pBcnRep->Bssid))); Rssi = pBcnRep->RCPI + pAd->BbpRssiToDbmDelta; RemainLen -= sizeof(RRM_BEACON_REP_INFO); ptr += sizeof(RRM_BEACON_REP_INFO); /* check option sub element IE. */ while (RemainLen > 0) { PRRM_SUBFRAME_INFO pRrmSubFrame; pRrmSubFrame = (PRRM_SUBFRAME_INFO)ptr; switch(pRrmSubFrame->SubId) { case 1: if (BcnReqInfoField.field.ReportFrameType == 0) { /* Init Variable IE structure */ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; PeerBeaconAndProbeRspSanity(pAd, pRrmSubFrame->Oct, pRrmSubFrame->Length, pBcnRep->ChNumber, ie_list, &LenVIE, pVIE); } break; case 221: DBGPRINT(RT_DEBUG_TRACE, ("%s:: SubIe: ID=%x, Len=%d\n", __FUNCTION__, pRrmSubFrame->SubId, pRrmSubFrame->Length)); break; } RemainLen -= (pRrmSubFrame->Length + 2); ptr += (pRrmSubFrame->Length + 2); /* avoid infinite loop. */ if (pRrmSubFrame->Length == 0) break; } if (NdisEqualMemory(pBcnRep->Bssid, ie_list->Bssid, MAC_ADDR_LEN) == FALSE) { DBGPRINT(RT_DEBUG_WARN, ("%s():BcnReq->BSSID not equal ie_list->Bssid!\n", __FUNCTION__)); } #ifdef AP_SCAN_SUPPORT Idx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, Rssi, LenVIE, pVIE); if (Idx != BSS_NOT_FOUND) { BSS_ENTRY *pBssEntry = &pAd->ScanTab.BssEntry[Idx]; NdisMoveMemory(pBssEntry->PTSF, (PUCHAR)&Ptsf, 4); pBssEntry->RegulatoryClass = pBcnRep->RegulatoryClass; pBssEntry->CondensedPhyType = BcnReqInfoField.field.CondensePhyType; pBssEntry->RSNI = pBcnRep->RSNI; } #endif /* AP_SCAN_SUPPORT */ return; }
NDIS_STATUS NdisMAllocateMapRegisters( IN NDIS_HANDLE MiniportAdapterHandle, IN UINT DmaChannel, IN BOOLEAN Dma32BitAddresses, IN ULONG PhysicalMapRegistersNeeded, IN ULONG MaximumPhysicalMapping ) /*++ Routine Description: Allocates map registers for bus mastering devices. Arguments: MiniportAdapterHandle - Handle passed to MiniportInitialize. PhysicalMapRegistersNeeded - The maximum number of map registers needed by the Miniport at any one time. MaximumPhysicalMapping - Maximum length of a buffer that will have to be mapped. Return Value: None. --*/ { // // Convert the handle to our internal structure. // PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK) MiniportAdapterHandle; // // This is needed by HalGetAdapter. // DEVICE_DESCRIPTION DeviceDescription; // // Returned by HalGetAdapter. // ULONG MapRegistersAllowed; // // Returned by HalGetAdapter. // PADAPTER_OBJECT AdapterObject; // // Map registers needed per channel. // ULONG MapRegistersPerChannel; NTSTATUS NtStatus; KIRQL OldIrql; UINT i; LARGE_INTEGER TimeoutValue; // // If the device is a busmaster, we get an adapter // object for it. // If map registers are needed, we loop, allocating an // adapter channel for each map register needed. // if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_BUS_MASTER) && (Miniport->BusType != (NDIS_INTERFACE_TYPE)-1) && (Miniport->BusNumber != (ULONG)-1)) { TimeoutValue.QuadPart = Int32x32To64(2 * 1000, -10000); Miniport->PhysicalMapRegistersNeeded = PhysicalMapRegistersNeeded; Miniport->MaximumPhysicalMapping = MaximumPhysicalMapping; // // Allocate storage for holding the appropriate // information for each map register. // Miniport->MapRegisters = (PMAP_REGISTER_ENTRY) ALLOC_FROM_POOL(sizeof(MAP_REGISTER_ENTRY) * PhysicalMapRegistersNeeded, NDIS_TAG_DEFAULT); if (Miniport->MapRegisters == (PMAP_REGISTER_ENTRY)NULL) { // // Error out // NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, 0xFFFFFFFF); return NDIS_STATUS_RESOURCES; } // // Use this event to tell us when ndisAllocationExecutionRoutine // has been called. // INITIALIZE_EVENT(&Miniport->AllocationEvent); // // Set up the device description; zero it out in case its // size changes. // ZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION)); DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; DeviceDescription.Master = TRUE; DeviceDescription.ScatterGather = TRUE; DeviceDescription.BusNumber = Miniport->BusNumber; DeviceDescription.DmaChannel = DmaChannel; DeviceDescription.InterfaceType = Miniport->AdapterType; if (DeviceDescription.InterfaceType == NdisInterfaceIsa) { // // For ISA devices, the width is based on the DMA channel: // 0-3 == 8 bits, 5-7 == 16 bits. Timing is compatibility // mode. // if (DmaChannel > 4) { DeviceDescription.DmaWidth = Width16Bits; } else { DeviceDescription.DmaWidth = Width8Bits; } DeviceDescription.DmaSpeed = Compatible; } else if ((DeviceDescription.InterfaceType == NdisInterfaceEisa) || (DeviceDescription.InterfaceType == NdisInterfacePci) || (DeviceDescription.InterfaceType == NdisInterfaceMca)) { DeviceDescription.Dma32BitAddresses = Dma32BitAddresses; } DeviceDescription.MaximumLength = MaximumPhysicalMapping; // // Get the adapter object. // AdapterObject = HalGetAdapter (&DeviceDescription, &MapRegistersAllowed); if (AdapterObject == NULL) { NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, 0xFFFFFFFF); FREE_POOL(Miniport->MapRegisters); Miniport->MapRegisters = NULL; DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_INFO, ("<==NdisRegisterAdapter\n")); return NDIS_STATUS_RESOURCES; } // // We save this to call IoFreeMapRegisters later. // Miniport->SystemAdapterObject = AdapterObject; // // Determine how many map registers we need per channel. // MapRegistersPerChannel = ((MaximumPhysicalMapping - 2) / PAGE_SIZE) + 2; ASSERT (MapRegistersAllowed >= MapRegistersPerChannel); // // Now loop, allocating an adapter channel each time, then // freeing everything but the map registers. // for (i=0; i<Miniport->PhysicalMapRegistersNeeded; i++) { Miniport->CurrentMapRegister = i; RAISE_IRQL_TO_DISPATCH(&OldIrql); NtStatus = IoAllocateAdapterChannel(AdapterObject, Miniport->DeviceObject, MapRegistersPerChannel, ndisAllocationExecutionRoutine, Miniport); if (!NT_SUCCESS(NtStatus)) { DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR, ("AllocateAdapterChannel: %lx\n", NtStatus)); for (; i != 0; i--) { IoFreeMapRegisters(Miniport->SystemAdapterObject, Miniport->MapRegisters[i-1].MapRegister, MapRegistersPerChannel); } LOWER_IRQL(OldIrql); NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, 0xFFFFFFFF); FREE_POOL(Miniport->MapRegisters); Miniport->MapRegisters = NULL; return NDIS_STATUS_RESOURCES; } LOWER_IRQL(OldIrql); TimeoutValue.QuadPart = Int32x32To64(2 * 1000, -10000); // // ndisAllocationExecutionRoutine will set this event // when it has gotten FirstTranslationEntry. // NtStatus = WAIT_FOR_OBJECT(&Miniport->AllocationEvent, &TimeoutValue); if (NtStatus != STATUS_SUCCESS) { DBGPRINT(DBG_COMP_ALL, DBG_LEVEL_ERR, ("NDIS DMA AllocateAdapterChannel: %lx\n", NtStatus)); RAISE_IRQL_TO_DISPATCH(&OldIrql); for (; i != 0; i--) { IoFreeMapRegisters(Miniport->SystemAdapterObject, Miniport->MapRegisters[i-1].MapRegister, MapRegistersPerChannel); } LOWER_IRQL(OldIrql); NdisWriteErrorLogEntry((NDIS_HANDLE)Miniport, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, 0xFFFFFFFF); FREE_POOL(Miniport->MapRegisters); Miniport->MapRegisters = NULL; return NDIS_STATUS_RESOURCES; } RESET_EVENT(&Miniport->AllocationEvent); } } return NDIS_STATUS_SUCCESS; }
VOID RRM_PeerMeasureRepAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; PUCHAR pFramePtr = pFr->Octet; ULONG MsgLen = Elem->MsgLen; PMEASURE_REQ_ENTRY pDialogEntry; PMAC_TABLE_ENTRY pEntry; UINT8 DialogToken; DBGPRINT(RT_DEBUG_TRACE, ("%s::\n", __FUNCTION__)); /* skip Category and action code. */ pFramePtr += 2; MsgLen -= 2; /* get DialogToken. */ NdisMoveMemory(&DialogToken, pFramePtr, 1); pFramePtr += 1; MsgLen -= 1; /* Not a autonomous measure report (non zero DialogToken). check the dialog token field. drop it if the dialog token doesn't match. */ pDialogEntry = NULL; if ((DialogToken != 0) && ((pDialogEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL)) return; if (pDialogEntry != NULL) MeasureReqDelete(pAd, pDialogEntry->DialogToken); do { PEID_STRUCT eid_ptr; MEASURE_REPORT_MODE ReportMode; UINT8 ReportType; PRRM_BEACON_REP_INFO pMeasureRep; /* Is the STA associated. Dorp the Measure report if it's not. */ pEntry = MacTableLookup(pAd, pFr->Hdr.Addr2); if (!pEntry || (pEntry->Sst != SST_ASSOC)) break; eid_ptr = (PEID_STRUCT)pFramePtr; while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) { switch(eid_ptr->Eid) { case IE_MEASUREMENT_REPORT: { LONG BcnRepLen = (LONG)eid_ptr->Len - 3; NdisMoveMemory(&ReportMode, eid_ptr->Octet + 1, 1); NdisMoveMemory(&ReportType, eid_ptr->Octet + 2, 1); pMeasureRep = (PVOID)(eid_ptr->Octet + 3); if (ReportType == RRM_MEASURE_SUBTYPE_BEACON) RRM_BeaconReportHandler(pAd, pMeasureRep, BcnRepLen); } break; default: break; } eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); } } while(FALSE); return; }
NDIS_STATUS NdisMRegisterMiniport( IN NDIS_HANDLE NdisWrapperHandle, IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics, IN UINT CharacteristicsLength ) /*++ Routine Description: Used to register a Miniport driver with the wrapper. Arguments: Status - Status of the operation. NdisWrapperHandle - Handle returned by NdisWInitializeWrapper. MiniportCharacteritics - The NDIS_MINIPORT_CHARACTERISTICS table. CharacteristicsLength - The length of MiniportCharacteristics. Return Value: None. --*/ { NDIS_STATUS Status; PNDIS_M_DRIVER_BLOCK MiniBlock; PNDIS_WRAPPER_HANDLE DriverInfo = (PNDIS_WRAPPER_HANDLE)(NdisWrapperHandle); Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle, MiniportCharacteristics, CharacteristicsLength, &MiniBlock); DBGPRINT(DBG_COMP_CONFIG, DBG_LEVEL_INFO, ("Exit mini-port register\n")); if (Status == NDIS_STATUS_SUCCESS) { InitReferencePackage(); if (DriverInfo->NdisWrapperConfigurationHandle) { Status = ndisInitializeAllAdapterInstances((PNDIS_MAC_BLOCK)MiniBlock, NULL); if (Status != NDIS_STATUS_SUCCESS) { ndisDereferenceDriver(MiniBlock); Status = NDIS_STATUS_FAILURE; } } else { Status = NDIS_STATUS_FAILURE; } InitDereferencePackage(); } ASSERT (CURRENT_IRQL < DISPATCH_LEVEL); return Status; }
/* ======================================================================== Routine Description: Initialize Multi-BSS function. Arguments: pAd points to our adapter pDevMain points to the main BSS network interface Return Value: None Note: 1. Only create and initialize virtual network interfaces. 2. No main network interface here. 3. If you down ra0 and modify the BssNum of RT2860AP.dat/RT2870AP.dat, it will not work! You must rmmod rt2860ap.ko and lsmod rt2860ap.ko again. ======================================================================== */ VOID MBSS_Init(RTMP_ADAPTER *pAd, RTMP_OS_NETDEV_OP_HOOK *pNetDevOps) { #define MBSS_MAX_DEV_NUM 32 PNET_DEV pDevNew; INT32 IdBss, MaxNumBss; INT status; RTMP_OS_NETDEV_OP_HOOK netDevHook; /* sanity check to avoid redundant virtual interfaces are created */ if (pAd->FlgMbssInit != FALSE) return; MaxNumBss = pAd->ApCfg.BssidNum; if (MaxNumBss > MAX_MBSSID_NUM(pAd)) MaxNumBss = MAX_MBSSID_NUM(pAd); /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ for(IdBss=FIRST_MBSSID; IdBss<MAX_MBSSID_NUM(pAd); IdBss++) pAd->ApCfg.MBSSID[IdBss].wdev.if_dev = NULL; /* create virtual network interface */ for(IdBss=FIRST_MBSSID; IdBss<MaxNumBss; IdBss++) { struct wifi_dev *wdev; UINT32 MC_RowID = 0, IoctlIF = 0; char *dev_name; #ifdef MULTIPLE_CARD_SUPPORT MC_RowID = pAd->MC_RowID; #endif /* MULTIPLE_CARD_SUPPORT */ #ifdef HOSTAPD_SUPPORT IoctlIF = pAd->IoctlIF; #endif /* HOSTAPD_SUPPORT */ BSS_STRUCT *pMbss; dev_name = get_dev_name_prefix(pAd, INT_MBSSID); pDevNew = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_MBSSID, IdBss, sizeof(struct mt_dev_priv), dev_name); #ifdef HOSTAPD_SUPPORT pAd->IoctlIF = IoctlIF; #endif /* HOSTAPD_SUPPORT */ if (pDevNew == NULL) { pAd->ApCfg.BssidNum = IdBss; /* re-assign new MBSS number */ break; } else { DBGPRINT(RT_DEBUG_TRACE, ("Register MBSSID IF (%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pDevNew))); } pMbss = &pAd->ApCfg.MBSSID[IdBss]; wdev = &pAd->ApCfg.MBSSID[IdBss].wdev; wdev->wdev_type = WDEV_TYPE_AP; wdev->func_dev = &pAd->ApCfg.MBSSID[IdBss]; wdev->func_idx = IdBss; wdev->sys_handle = (void *)pAd; wdev->if_dev = pDevNew; if (rtmp_wdev_idx_reg(pAd, wdev) < 0) { DBGPRINT(RT_DEBUG_ERROR, ("Assign wdev idx for %s failed, free net device!\n", RTMP_OS_NETDEV_GET_DEVNAME(pDevNew))); RtmpOSNetDevFree(pDevNew); break; } wdev->tx_pkt_allowed = ApAllowToSendPacket; wdev->tx_pkt_handle = APSendPacket; wdev->wdev_hard_tx = APHardTransmit; wdev->rx_pkt_allowed = ap_rx_pkt_allow; wdev->rx_ps_handle = ap_rx_ps_handle; wdev->rx_pkt_foward = ap_rx_foward_handle; RTMP_OS_NETDEV_SET_PRIV(pDevNew, pAd); RTMP_OS_NETDEV_SET_WDEV(pDevNew, wdev); /* init operation functions and flags */ NdisCopyMemory(&netDevHook, pNetDevOps, sizeof(netDevHook)); netDevHook.priv_flags = INT_MBSSID; netDevHook.needProtcted = TRUE; netDevHook.wdev = wdev; /* Init MAC address of virtual network interface */ NdisMoveMemory(&netDevHook.devAddr[0], &wdev->bssid[0], MAC_ADDR_LEN); /* register this device to OS */ status = RtmpOSNetDevAttach(pAd->OpMode, pDevNew, &netDevHook); ASSERT(pMbss); if (pMbss) { wdev_bcn_buf_init(pAd, &pMbss->bcn_buf); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s():func_dev is NULL!\n", __FUNCTION__)); return; } } pAd->FlgMbssInit = TRUE; }
VOID RTMPHandleSTAKey( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN MLME_QUEUE_ELEM *Elem) { extern UCHAR OUI_WPA2_WEP40[]; ULONG FrameLen = 0; PUCHAR pOutBuffer = NULL; UCHAR Header802_3[14]; UCHAR *mpool; PEAPOL_PACKET pOutPacket; PEAPOL_PACKET pSTAKey; PHEADER_802_11 pHeader; UCHAR Offset = 0; ULONG MICMsgLen; UCHAR DA[MAC_ADDR_LEN]; UCHAR Key_Data[512]; UCHAR key_length; UCHAR mic[LEN_KEY_DESC_MIC]; UCHAR rcv_mic[LEN_KEY_DESC_MIC]; UCHAR digest[80]; UCHAR temp[64]; PMAC_TABLE_ENTRY pDaEntry; /*Benson add for big-endian 20081016--> */ KEY_INFO peerKeyInfo; /*Benson add 20081016 <-- */ DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleSTAKey\n")); if (!pEntry) return; if ((pEntry->WpaState != AS_PTKINITDONE)) { DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here")); return; } pHeader = (PHEADER_802_11) Elem->Msg; /* QoS control field (2B) is took off */ /* if (pHeader->FC.SubType & 0x08) */ /* Offset += 2; */ pSTAKey = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset]; /*Benson add for big-endian 20081016--> */ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pSTAKey->KeyDesc.KeyInfo, sizeof(KEY_INFO)); *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo)); /*Benson add 20081016 <-- */ /* Check Replay Counter */ if (!RTMPEqualMemory(pSTAKey->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY)) { DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in STAKey handshake!! \n")); DBGPRINT(RT_DEBUG_ERROR, ("Receive : %d %d %d %d \n", pSTAKey->KeyDesc.ReplayCounter[0], pSTAKey->KeyDesc.ReplayCounter[1], pSTAKey->KeyDesc.ReplayCounter[2], pSTAKey->KeyDesc.ReplayCounter[3])); DBGPRINT(RT_DEBUG_ERROR, ("Current : %d %d %d %d \n", pEntry->R_Counter[4],pEntry->R_Counter[5], pEntry->R_Counter[6],pEntry->R_Counter[7])); return; } /* Check MIC, if not valid, discard silently */ NdisMoveMemory(DA, &pSTAKey->KeyDesc.KeyData[6], MAC_ADDR_LEN); if (peerKeyInfo.KeyMic && peerKeyInfo.Secure && peerKeyInfo.Request)/*Benson add for big-endian 20081016 --> */ { pEntry->bDlsInit = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("STAKey Initiator: %02x:%02x:%02x:%02x:%02x:%02x\n", pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); } MICMsgLen = pSTAKey->Body_Len[1] | ((pSTAKey->Body_Len[0]<<8) && 0xff00); MICMsgLen += LENGTH_EAPOL_H; if (MICMsgLen > (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H)) { DBGPRINT(RT_DEBUG_ERROR, ("Receive wrong format EAPOL packets \n")); return; } /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */ NdisZeroMemory(temp, 64); NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, sizeof(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK)); NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, temp, pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK); DBGPRINT(RT_DEBUG_TRACE, ("PTK-%x %x %x %x %x %x %x %x \n", pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7])); /* Record the received MIC for check later */ NdisMoveMemory(rcv_mic, pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); NdisZeroMemory(pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) { RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, mic, MD5_DIGEST_SIZE); } else { RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); } if (!RTMPEqualMemory(rcv_mic, mic, LEN_KEY_DESC_MIC)) { DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in STAKey handshake!! \n")); return; } else DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in STAKey handshake!! \n")); /* Receive init STA's STAKey Message-2, and terminate the handshake */ /*if (pEntry->bDlsInit && !pSTAKey->KeyDesc.KeyInfo.Request) */ if (pEntry->bDlsInit && !peerKeyInfo.Request) /*Benson add for big-endian 20081016 --> */ { pEntry->bDlsInit = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("Receive init STA's STAKey Message-2, STAKey handshake finished \n")); return; } /* Receive init STA's STAKey Message-2, and terminate the handshake */ if (RTMPEqualMemory(&pSTAKey->KeyDesc.KeyData[2], OUI_WPA2_WEP40, 3)) { DBGPRINT(RT_DEBUG_WARN, ("Receive a STAKey message which not support currently, just drop it \n")); return; } do { pDaEntry = MacTableLookup(pAd, DA); if (!pDaEntry) break; if ((pDaEntry->WpaState != AS_PTKINITDONE)) { DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here \n")); break; } MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); /* allocate memory */ if(pOutBuffer == NULL) break; MAKE_802_3_HEADER(Header802_3, pDaEntry->Addr, pAd->ApCfg.MBSSID[pDaEntry->apidx].Bssid, EAPOL); /* Increment replay counter by 1 */ ADD_ONE_To_64BIT_VAR(pDaEntry->R_Counter); /* Allocate memory for output */ os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); if (mpool == NULL) { MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); return; } pOutPacket = (PEAPOL_PACKET)mpool; NdisZeroMemory(pOutPacket, TX_EAPOL_BUFFER); /* 0. init Packet and Fill header */ pOutPacket->ProVer = EAPOL_VER; pOutPacket->ProType = EAPOLKey; pOutPacket->Body_Len[1] = 0x5f; /* 1. Fill replay counter */ /* NdisMoveMemory(pDaEntry->R_Counter, pAd->ApCfg.R_Counter, sizeof(pDaEntry->R_Counter)); */ NdisMoveMemory(pOutPacket->KeyDesc.ReplayCounter, pDaEntry->R_Counter, LEN_KEY_DESC_REPLAY); /* 2. Fill key version, keyinfo, key len */ pOutPacket->KeyDesc.KeyInfo.KeyDescVer= GROUP_KEY; pOutPacket->KeyDesc.KeyInfo.KeyType = GROUPKEY; pOutPacket->KeyDesc.KeyInfo.Install = 1; pOutPacket->KeyDesc.KeyInfo.KeyAck = 1; pOutPacket->KeyDesc.KeyInfo.KeyMic = 1; pOutPacket->KeyDesc.KeyInfo.Secure = 1; pOutPacket->KeyDesc.KeyInfo.EKD_DL = 1; DBGPRINT(RT_DEBUG_TRACE, ("STAKey handshake for peer STA %02x:%02x:%02x:%02x:%02x:%02x\n", DA[0], DA[1], DA[2], DA[3], DA[4], DA[5])); if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPAPSK)) { pOutPacket->KeyDesc.Type = WPA1_KEY_DESC; DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n")); } else if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) { pOutPacket->KeyDesc.Type = WPA2_KEY_DESC; pOutPacket->KeyDesc.KeyDataLen[1] = 0; DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n")); } pOutPacket->KeyDesc.KeyLength[1] = LEN_TKIP_TK; pOutPacket->KeyDesc.KeyDataLen[1] = LEN_TKIP_TK; pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_TKIP; if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled) { pOutPacket->KeyDesc.KeyLength[1] = LEN_AES_TK; pOutPacket->KeyDesc.KeyDataLen[1] = LEN_AES_TK; pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_AES; } /* Key Data Encapsulation format, use Ralink OUI to distinguish proprietary and standard. */ Key_Data[0] = 0xDD; Key_Data[1] = 0x00; /* Length (This field will be filled later) */ Key_Data[2] = 0x00; /* OUI */ Key_Data[3] = 0x0C; /* OUI */ Key_Data[4] = 0x43; /* OUI */ Key_Data[5] = 0x02; /* Data Type (STAKey Key Data Encryption) */ /* STAKey Data Encapsulation format */ Key_Data[6] = 0x00; /*Reserved */ Key_Data[7] = 0x00; /*Reserved */ /* STAKey MAC address */ NdisMoveMemory(&Key_Data[8], pEntry->Addr, MAC_ADDR_LEN); /* initiator MAC address */ /* STAKey (Handle the difference between TKIP and AES-CCMP) */ if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled) { Key_Data[1] = 0x1E; /* 4+2+6+16(OUI+Reserved+STAKey_MAC_Addr+STAKey) */ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_AES_TK); } else { Key_Data[1] = 0x2E; /* 4+2+6+32(OUI+Reserved+STAKey_MAC_Addr+STAKey) */ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_TK); NdisMoveMemory(&Key_Data[14+LEN_TK], pEntry->PairwiseKey.TxMic, LEN_TKIP_MIC); NdisMoveMemory(&Key_Data[14+LEN_TK+LEN_TKIP_MIC], pEntry->PairwiseKey.RxMic, LEN_TKIP_MIC); } key_length = Key_Data[1]; pOutPacket->Body_Len[1] = key_length + 0x5f; /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */ NdisZeroMemory(temp, 64); NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, temp, DA, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK); DBGPRINT(RT_DEBUG_TRACE, ("PTK-0-%x %x %x %x %x %x %x %x \n", pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7])); NdisMoveMemory(pOutPacket->KeyDesc.KeyData, Key_Data, key_length); NdisZeroMemory(mic, sizeof(mic)); *(USHORT *)(&pOutPacket->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pOutPacket->KeyDesc.KeyInfo)); MakeOutgoingFrame(pOutBuffer, &FrameLen, pOutPacket->Body_Len[1] + 4, pOutPacket, END_OF_ARGS); /* Calculate MIC */ if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled) { RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC); } else { RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, mic, MD5_DIGEST_SIZE); NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); } RTMPToWirelessSta(pAd, pDaEntry, Header802_3, LENGTH_802_3, (PUCHAR)pOutPacket, pOutPacket->Body_Len[1] + 4, FALSE); MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); os_free_mem(NULL, mpool); }while(FALSE); DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleSTAKey: FrameLen=%ld\n", FrameLen)); }
static int SIPFW_ParseCommand(int argc, char *argv[], struct sipfw_cmd_opts *cmd_opt) { DBGPRINT("==>SIPFW_ParseCommand\n"); struct option longopts[] = { /*长选项*/ {"source", required_argument, NULL, 's'}, /*源主机IP地址*/ {"dest", required_argument, NULL, 'd'}, /*目的主机IP地址*/ {"sport", required_argument, NULL, 'm'}, /*源端口地址*/ {"dport", required_argument, NULL, 'n'}, /*目的端口地址*/ {"protocol", required_argument, NULL, 'p'}, /*协议类型*/ {"list", optional_argument, NULL, 'L'}, /*规则列表*/ {"flush", optional_argument, NULL, 'F'}, /*清空规则*/ {"append", required_argument, NULL, 'A'}, /*增加规则到链尾部*/ {"insert", required_argument, NULL, 'I'}, /*向链中增加规则*/ {"delete", required_argument, NULL, 'D'}, /*删除规则*/ {"interface", required_argument, NULL, 'i'}, /*网络接口*/ {"action", required_argument, NULL, 'j'}, /*动作*/ {"syn", no_argument, NULL, 'y'}, /*syn*/ {"rst", no_argument, NULL, 'r'}, /*rst*/ {"acksyn", no_argument, NULL, 'k'}, /*acksyn*/ {"fin", no_argument, NULL, 'f'}, /*fin*/ {"number", required_argument, NULL, 'u'}, /*删除或者插入的位置*/ {0, 0, 0, 0}, }; static char opts_short[] = "s:d:m:n:p:LFA:I:D:i:j:yrkfu:"; /*短选项*/ static char *l_opt_arg = NULL;/*产选项的参数*/ cmd_opt->command.v_int = -1; /*命令默认值为-1*/ cmd_opt->source.v_int = 0; /*源地址默认值为0*/ cmd_opt->sport.v_int = 0; /*源端口默认值为0*/ cmd_opt->dest.v_int =0; /*目的地址默认值为0*/ cmd_opt->dport.v_int = 0; /*目的端口默认值为0*/ cmd_opt->protocol.v_int = -1; /*协议类型默认值为-1*/ cmd_opt->chain.v_int = -1; /*链默认值为-1*/ cmd_opt->action.v_int= -1; /*动作默认值为-1*/ memset(cmd_opt->ifname.v_str, 0, 8); char c = 0; while ((c = getopt_long(argc, argv, opts_short, longopts, NULL)) != -1) { switch(c) { case 's': /*源主机IP地址*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_IP, optarg, &cmd_opt->source); } break; case 'd':/*目的主机IP地址*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_IP, optarg, &cmd_opt->dest); } break; case 'm':/*源端口地址*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_PORT, optarg, &cmd_opt->sport); } break; case 'n':/*目的端口地址*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_PORT, optarg, &cmd_opt->dport); } break; case 'p':/*协议类型*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_PROTOCOL, optarg, &cmd_opt->protocol); } break; case 'L':/*规则列表*/ cmd_opt->command.v_uint = SIPFW_CMD_LIST; l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_CHAIN, optarg, &cmd_opt->chain); } break; case 'F':/*清空规则*/ cmd_opt->command.v_uint = SIPFW_CMD_FLUSH; l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_CHAIN, optarg, &cmd_opt->chain); } break; case 'A':/*增加规则到链尾部*/ cmd_opt->command.v_uint = SIPFW_CMD_APPEND; l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_CHAIN, optarg, &cmd_opt->chain); } break; case 'I':/*向链中增加规则*/ cmd_opt->command.v_uint = SIPFW_CMD_INSERT; l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_CHAIN, optarg, &cmd_opt->chain); } break; case 'D':/*删除规则*/ cmd_opt->command.v_uint = SIPFW_CMD_DELETE; l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_CHAIN, optarg, &cmd_opt->chain); } break; case 'i':/*网络接口*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_STR, optarg, &cmd_opt->ifname); } break; case 'j':/*动作*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_ACTION, optarg, &cmd_opt->action); } break; case 'y':/*syn*/ cmd_opt->addtion.tcp.valid = 1; cmd_opt->addtion.tcp.syn = 1; break; case 'r':/*rst*/ cmd_opt->addtion.tcp.valid = 1; cmd_opt->addtion.tcp.rst= 1; break; case 'k':/*acksyn*/ cmd_opt->addtion.tcp.valid = 1; cmd_opt->addtion.tcp.ack= 1; cmd_opt->addtion.tcp.syn= 1; break; case 'f':/*fin*/ cmd_opt->addtion.tcp.valid = 1; cmd_opt->addtion.tcp.fin= 1; break; case 'u':/*number*/ l_opt_arg = optarg; if(l_opt_arg && l_opt_arg[0]!=':') { SIPFW_ParseOpt(SIPFW_OPT_PORT, optarg, &cmd_opt->number); } break; default: break; } } DBGPRINT("<==SIPFW_ParseCommand\n"); }
/* ========================================================================== Description: Check sanity of authentication method selector in RSN IE. Return: TRUE if match FALSE otherwise ========================================================================== */ BOOLEAN RTMPCheckAUTH( IN PRTMP_ADAPTER pAd, IN PEID_STRUCT eid_ptr, IN MAC_TABLE_ENTRY *pEntry) { PUCHAR pStaTmp; USHORT Count; UCHAR apidx; ASSERT(pEntry); ASSERT(pEntry->apidx < pAd->ApCfg.BssidNum); apidx = pEntry->apidx; if (eid_ptr->Len < 16) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPCheckAUTH ==> WPAIE len is too short(%d) \n", eid_ptr->Len)); return FALSE; } /* Store STA RSN_IE capability */ pStaTmp = (PUCHAR)&eid_ptr->Octet[0]; if(eid_ptr->Eid == IE_WPA2) { /* skip Version(2),Multicast cipter(4) 2+4==6 */ /* point to number of unicast */ pStaTmp +=6; } else if (eid_ptr->Eid == IE_WPA) { /* skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */ /* point to number of unicast */ pStaTmp += 10; } else { DBGPRINT(RT_DEBUG_ERROR, ("RTMPCheckAUTH ==> Unknown WPAIE, WPAIE=%d\n", eid_ptr->Eid)); return FALSE; } /* Store unicast cipher count */ NdisMoveMemory(&Count, pStaTmp, sizeof(USHORT)); Count = cpu2le16(Count); /* pointer to unicast cipher */ pStaTmp += sizeof(USHORT); /* Skip all unicast cipher suite */ while (Count > 0) { /* Skip OUI */ pStaTmp += 4; Count--; } /* Store AKM count */ NdisMoveMemory(&Count, pStaTmp, sizeof(USHORT)); Count = cpu2le16(Count); /*pointer to AKM cipher */ pStaTmp += sizeof(USHORT); if (eid_ptr->Len >= 16) { if (eid_ptr->Eid == IE_WPA) { while (Count > 0) { if (RTMPCheckAKM(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][0],0)) return TRUE; pStaTmp += 4; Count--; } } else if (eid_ptr->Eid == IE_WPA2) { UCHAR IE_Idx = 0; /* When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure */ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) IE_Idx = 1; while (Count > 0) { if (RTMPCheckAKM(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][0],1)) return TRUE; pStaTmp += 4; Count--; } } } return FALSE; }
static void SIPFW_NLClose(void) { DBGPRINT("==>SIPFW_NLClose\n"); close(nls); DBGPRINT("<==SIPFW_NLClose\n"); }
/* ========================================================================== Description: Function to handle countermeasures active attack. Init 60-sec timer if necessary. Return: ========================================================================== */ VOID HandleCounterMeasure( IN PRTMP_ADAPTER pAd, IN MAC_TABLE_ENTRY *pEntry) { int i; BOOLEAN Cancelled; if (!pEntry) return; /* Todo by AlbertY - Not support currently in ApClient-link */ if (IS_ENTRY_APCLI(pEntry)) return; /* if entry not set key done, ignore this RX MIC ERROR */ if ((pEntry->WpaState < AS_PTKINITDONE) || (pEntry->GTKState != REKEY_ESTABLISHED)) return; DBGPRINT(RT_DEBUG_TRACE, ("HandleCounterMeasure ===> \n")); /* record which entry causes this MIC error, if this entry sends disauth/disassoc, AP doesn't need to log the CM */ pEntry->CMTimerRunning = TRUE; pAd->ApCfg.MICFailureCounter++; /* send wireless event - for MIC error */ RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pEntry->Addr, 0, 0); if (pAd->ApCfg.CMTimerRunning == TRUE) { DBGPRINT(RT_DEBUG_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>> \n")); /* send wireless event - for counter measures */ RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pEntry->Addr, 0, 0); ApLogEvent(pAd, pEntry->Addr, EVENT_COUNTER_M); /* renew GTK */ GenRandom(pAd, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, pAd->ApCfg.MBSSID[pEntry->apidx].GNonce); /* Cancel CounterMeasure Timer */ RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled); pAd->ApCfg.CMTimerRunning = FALSE; for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { /* happened twice within 60 sec, AP SENDS disaccociate all associated STAs. All STA's transition to State 2 */ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])) { MlmeDeAuthAction(pAd, &pAd->MacTab.Content[i], REASON_MIC_FAILURE, FALSE); } } /* Further, ban all Class 3 DATA transportation for a period 0f 60 sec */ /* disallow new association , too */ pAd->ApCfg.BANClass3Data = TRUE; /* check how many entry left... should be zero */ /*pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations = pAd->MacTab.Size; */ /*DBGPRINT(RT_DEBUG_TRACE, ("GKeyDoneStations=%d \n", pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations)); */ } RTMPSetTimer(&pAd->ApCfg.CounterMeasureTimer, 60 * MLME_TASK_EXEC_INTV * MLME_TASK_EXEC_MULTIPLE); pAd->ApCfg.CMTimerRunning = TRUE; pAd->ApCfg.PrevaMICFailTime = pAd->ApCfg.aMICFailTime; RTMP_GetCurrentSystemTime(&pAd->ApCfg.aMICFailTime); }
/****************************************************************************** * * Name: MrvDrvSend() * * Description: NDIS miniport serialized send packet routine * * Conditions for Use: Protocol driver will call this routine to pass Tx NDIS_PACKET * * Arguments: * IN NDIS_HANDLE MiniportAdapterContext * IN PPNDIS_PACKET Packet * IN UINT Flags * * Return Value: NDIS_STATUS_RESOURCES or NDIS_STATUS_PENDING * * Notes: * *****************************************************************************/ NDIS_STATUS MrvDrvSend( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet, IN UINT Flags) { PMRVDRV_ADAPTER Adapter; NDIS_STATUS Status; PNDIS_BUFFER pBuffer; UINT BufferCount; UINT Length; UINT TotalPacketLength = 0; PVOID pVirtualAddr; PTxCtrlNode pTxNode; PUCHAR pHeader = NULL; Status = NDIS_STATUS_SUCCESS; Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext; DBGPRINT(DBG_TX, (L"+MrvDrvSend()\n")); // printf ("+MrvDrvSend()\n"); // In Deep Sleep Mode no packet can be sent out //012207 //if (Adapter->IsDeepSleep) if( !IsThisDsState(Adapter, DS_STATE_NONE) ) { //Status = NDIS_STATUS_NO_CABLE; return NDIS_STATUS_FAILURE; } // Check device removal status if( Adapter->SurpriseRemoved == TRUE ) { DBGPRINT(DBG_TX|DBG_WARNING,(TEXT("[MrvSend]: NDIS_STATUS_FAILURE by supriseRemoved\r\n"))); return NDIS_STATUS_FAILURE; } if( Adapter->bIsPendingReset == TRUE || Adapter->ChipResetting == 1) { DBGPRINT(DBG_TX|DBG_CMD|DBG_WARNING,(L"[MrvSend]: NDIS RETURN FAILURE by bIsPendingReset or ChipReset\r\n")); return NDIS_STATUS_FAILURE; } if ( Adapter->MediaConnectStatus == NdisMediaStateDisconnected ) { DBGPRINT(DBG_TX|DBG_WARNING, (L"***WARNING: OS attempted to send packet while disconnected!\r\n")); if (IsIndicateDisconnect(Adapter) == TRUE) { Ndis_MediaStatus_Notify(Adapter,NDIS_STATUS_MEDIA_DISCONNECT); } else { NdisMSleep(100000); ///Sleep 100ms temporally } //dralee_20060712 ResetAllScanTypeAndPower(Adapter); CleanUpSingleTxBuffer(Adapter); ResetRxPDQ(Adapter); return NDIS_STATUS_FAILURE; } if( Adapter->bIsScanInProgress == TRUE ) { return NDIS_STATUS_SUCCESS; } *((ULONG *)(&Packet->MacReserved[0])) = GetTickCount(); // check if in key absent state, if so, block all packet other than // 802.1x if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )|| (Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) ) { pTxNode = &Adapter->TxNode; NdisQueryPacket( Packet, NULL, &BufferCount, &pBuffer, &TotalPacketLength ); if (!pBuffer || !BufferCount || !TotalPacketLength) { return NDIS_STATUS_FAILURE; } NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length); pHeader = (PUCHAR)pVirtualAddr; if ( TotalPacketLength < 14 ) { // malformed packet, blocked! DBGPRINT(DBG_TX|DBG_WARNING,(L"Got packet with size less than 14 bytes, reject!\n")); return NDIS_STATUS_FAILURE; } if ( (pHeader[12] != 0x88) || (pHeader[13] != 0x8E) ) { DBGPRINT(DBG_TX|DBG_WARNING,(L"Still no key and packet type(0x%x 0x%x)is not 802.1x , drop!\n", pHeader[12], pHeader[13])); return NDIS_STATUS_FAILURE; } }// if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )|| (Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) ) if(Adapter->TCloseWZCFlag==WZC_Ignore_Send_EAPOL_START) { if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2Enabled )||(Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )||(Adapter->EncryptionStatus == Ndis802_11Encryption3Enabled )||(Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) ) { pTxNode = &Adapter->TxNode; NdisQueryPacket( Packet, NULL, &BufferCount, &pBuffer, &TotalPacketLength ); if (!pBuffer || !BufferCount || !TotalPacketLength) { return NDIS_STATUS_FAILURE; } NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length); pHeader = (PUCHAR)pVirtualAddr; if ( (pHeader[12] == 0x88) && (pHeader[13] == 0x8E)&& (pHeader[14] == 0x01) &&(pHeader[15] == 0x01) ) { DBGPRINT(DBG_TX|DBG_HELP,(L"Temporary don't send EAPOL-start!!EncryptionStatus=0x%x, (0x%x, 0x%x, 0x%x, 0x%x)\n", Adapter->EncryptionStatus, pHeader[12], pHeader[13], pHeader[14], pHeader[15])); return NDIS_STATUS_SUCCESS; } } } EnterCriticalSection(&Adapter->TxCriticalSection); if(Adapter->TxPacketCount >= (MAX_TX_PACKETS-1) ) { UCHAR sts; //DBGPRINT(DBG_ERROR,(L"Tx queue is still full (count=%d), return FAILURE for this packet\r\n",Adapter->TxPacketCount)); sts = TxPacketEnQueue(Adapter, Packet); if( sts == TRUE ) //101607 { Adapter->TxPacketCount++; LeaveCriticalSection(&Adapter->TxCriticalSection); return NDIS_STATUS_SUCCESS; } else if ( sts == EQ_REPLACE_QUEUE ) { LeaveCriticalSection(&Adapter->TxCriticalSection); DBGPRINT(DBG_ERROR,(L"Replace a queued packet:%d\n\r",Adapter->TxPacketCount)); return NDIS_STATUS_SUCCESS; } else { LeaveCriticalSection(&Adapter->TxCriticalSection); //NdisMSleep(2000); DBGPRINT(DBG_ERROR,(L"Throw out current packet:%d\n\r",Adapter->TxPacketCount)); //return success otherwise the endpoint may retransmit this packet that low down the throughput. return NDIS_STATUS_SUCCESS; } } //record how many tx pkt is sent. Adapter->TxPacketSend++; DBGPRINT(DBG_TX|DBG_HELP,(L"[Marvell:MrvDrvSend] Adapter->TxPacketSend=%d\n", Adapter->TxPacketSend)); if ( TxPacketEnQueue(Adapter, Packet) != TRUE) { LeaveCriticalSection(&Adapter->TxCriticalSection); return NDIS_STATUS_SUCCESS; } Adapter->TxPacketCount++; LeaveCriticalSection(&Adapter->TxCriticalSection); if ( Adapter->SentPacket == NULL && Adapter->TxLock == 0 ) { // Fire TxThread! Adapter->SoftIntStatus |= MRVL_SOFT_INT_TxRequest; SetEvent(Adapter->hControllerInterruptEvent); } return NDIS_STATUS_SUCCESS; return Status; }