bool Encapsulate80211Frame ( struct PACKETxID* ptid, DOT11RFC1042ENCAP& wheader, UCHAR * addr, int len ) { bool bRet = true; // DOT11RFC1042ENCAP wheader = { 0 }; PETHERNET_HEADER eheader; eheader = (PETHERNET_HEADER)addr; // Three address format with ap mode if ( OpMode == CLIENT_MODE ) { wheader.MacHeader.Address1 = bssid; wheader.MacHeader.Address2 = eheader->srcAddr; wheader.MacHeader.Address3 = eheader->destAddr; wheader.MacHeader.FrameControl.Type = FRAME_DATA; wheader.MacHeader.FrameControl.Subtype = SUBT_DATA; wheader.MacHeader.FrameControl.ToDS = 1; // to DS wheader.MacHeader.FrameControl.Retry = 1; } else { wheader.MacHeader.Address1 = eheader->destAddr; wheader.MacHeader.Address2 = eheader->srcAddr; wheader.MacHeader.Address3 = adhoc_bssid; wheader.MacHeader.FrameControl.Type = FRAME_DATA; wheader.MacHeader.FrameControl.Subtype = SUBT_DATA; wheader.MacHeader.FrameControl.Retry = 1; } // wheader.MacHeader.DurationID = 20 + (8*(len + 4)*1000 / gDataRateK); // Kun: SequenceControl includes fragment seq // wheader.MacHeader.SequenceControl.usValue = (SendSeQ << 4); wheader.SNAP.DSAP = 0xAA; wheader.SNAP.SSAP = 0xAA; wheader.SNAP.Control = 0x03; wheader.Type = eheader->Type; SendSeQ++; ptid->m_status = PACKET_NOT_MOD; ptid->m_needack = !(ETH_IS_BROADCAST(eheader->destAddr.Address) || ETH_IS_MULTICAST(eheader->destAddr.Address)); return bRet; }
void CTXVirtQueue::UpdateTXStats(const CNB &NB, CTXDescriptor &Descriptor) { auto &HeadersArea = Descriptor.HeadersAreaAccessor(); PVOID EthHeader = HeadersArea.EthHeader(); //TODO: Statistics must be atomic auto BytesSent = NB.GetDataLength(); auto NBL = NB.GetParentNBL(); m_Context->Statistics.ifHCOutOctets += BytesSent; if (ETH_IS_BROADCAST(EthHeader)) { m_Context->Statistics.ifHCOutBroadcastOctets += BytesSent; m_Context->Statistics.ifHCOutBroadcastPkts++; } else if (ETH_IS_MULTICAST(EthHeader)) { m_Context->Statistics.ifHCOutMulticastOctets += BytesSent; m_Context->Statistics.ifHCOutMulticastPkts++; } else { m_Context->Statistics.ifHCOutUcastOctets += BytesSent; m_Context->Statistics.ifHCOutUcastPkts++; } if (NBL->IsLSO()) { m_Context->extraStatistics.framesLSO++; auto EthHeaders = Descriptor.HeadersAreaAccessor().EthHeadersAreaVA(); auto TCPHdr = reinterpret_cast<TCPHeader *>(RtlOffsetToPointer(EthHeaders, NBL->TCPHeaderOffset())); NBL->UpdateLSOTxStats(NB.GetDataLength() - NBL->TCPHeaderOffset() - TCP_HEADER_LENGTH(TCPHdr)); } else if (NBL->IsTcpCSO() || NBL->IsUdpCSO()) { m_Context->extraStatistics.framesCSOffload++; } }
ULONG tapGetNetBufferFrameType(__in PNET_BUFFER NetBuffer) /*++ Routine Description: Reads the network frame's destination address to determine the type (broadcast, multicast, etc) Runs at IRQL <= DISPATCH_LEVEL. Arguments: NetBuffer The NB to examine Return Value: NDIS_PACKET_TYPE_BROADCAST NDIS_PACKET_TYPE_MULTICAST NDIS_PACKET_TYPE_DIRECTED --*/ { PETH_HEADER ethernetHeader; ethernetHeader = (PETH_HEADER)NdisGetDataBuffer(NetBuffer, sizeof(ETH_HEADER), NULL, 1, 0); ASSERT(ethernetHeader); if (ETH_IS_BROADCAST(ethernetHeader->dest)) { return NDIS_PACKET_TYPE_BROADCAST; } else if (ETH_IS_MULTICAST(ethernetHeader->dest)) { return NDIS_PACKET_TYPE_MULTICAST; } else { return NDIS_PACKET_TYPE_DIRECTED; } }
bool ProcessDot11Frame(UCHAR *frameBuf, ULONG frameBufSize ) { PDOT11RFC1042ENCAP pWlanHeader = (PDOT11RFC1042ENCAP)frameBuf; if (pWlanHeader->MacHeader.FrameControl.Type == FRAME_DATA && pWlanHeader->MacHeader.FrameControl.Subtype == SUBT_DATA ) { static USHORT CurRecvSeqNo = 0xffff; int fTargetFrame = 0; // Try to send some ACK if ( (memcmp( MACAddress.Address, pWlanHeader->MacHeader.Address1.Address, MAC_ADDRESS_LENGTH) == 0) ) { DataFrameAck11(pWlanHeader, frameBufSize); UpdateLastRate(); PlotText ( "mac event", "receive a packet - seq (%d) size (%d) rate (%u).................................", pWlanHeader->MacHeader.SequenceControl.SequenceNumber, frameBufSize, lastRate ); fTargetFrame = 1; } if ( fTargetFrame || ETH_IS_BROADCAST (pWlanHeader->MacHeader.Address1.Address) ) { UpdateLastRate(); nDataPacketRcvCnt ++; if (CurRecvSeqNo != pWlanHeader->MacHeader.SequenceControl.SequenceNumber && pWlanHeader->MacHeader.SequenceControl.FragmentNumber == 0 ) { if ( frameBufSize < sizeof(DOT11RFC1042ENCAP)) { return S_OK; } CurRecvSeqNo = pWlanHeader->MacHeader.SequenceControl.SequenceNumber; MAC_ADDRESS destAddr; MAC_ADDRESS srcAddr; UINT16 Type; ULONG Offset; PETHERNET_HEADER pEthernetHeader; /* ad hoc mode destAddr = pWlanHeader->MacHeader.Address1; srcAddr = pWlanHeader->MacHeader.Address2; lastMACDst = pWlanHeader->MacHeader.Address1; lastMACSrc = pWlanHeader->MacHeader.Address2; lastMACBssid = pWlanHeader->MacHeader.Address3; */ /* AP mode */ if ( OpMode == CLIENT_MODE ) { destAddr = pWlanHeader->MacHeader.Address1; srcAddr = pWlanHeader->MacHeader.Address3; Type = pWlanHeader->Type; lastMACDst = pWlanHeader->MacHeader.Address1; lastMACSrc = pWlanHeader->MacHeader.Address3; lastMACBssid = pWlanHeader->MacHeader.Address2; } else { destAddr = pWlanHeader->MacHeader.Address1; srcAddr = pWlanHeader->MacHeader.Address2; Type = pWlanHeader->Type; lastMACDst = pWlanHeader->MacHeader.Address1; lastMACSrc = pWlanHeader->MacHeader.Address2; lastMACBssid = pWlanHeader->MacHeader.Address3; } Offset = sizeof(DOT11RFC1042ENCAP) - sizeof(ETHERNET_HEADER); pEthernetHeader = (PETHERNET_HEADER)(frameBuf + Offset); pEthernetHeader->destAddr = destAddr; pEthernetHeader->srcAddr = srcAddr; pEthernetHeader->Type = Type; PlotText ( "mac event", "Indicate packet seq (%d)", CurRecvSeqNo ); HRESULT hr; hr = SoraUIndicateRxPacket(frameBuf + Offset, frameBufSize - Offset - 4 ); // remove FCS UpdateEnergy (); return SUCCEEDED(hr); } } else { nInterferenceCnt ++; } } else if (pWlanHeader->MacHeader.FrameControl.Type == FRAME_CTRL && pWlanHeader->MacHeader.FrameControl.Subtype == SUBT_ACK) { if (LastPACKETxID) { if (memcmp(MACAddress.Address, pWlanHeader->MacHeader.Address1.Address, MAC_ADDRESS_LENGTH)) return true; struct PACKETxID* ptid; ptid = LastPACKETxID; LastPACKETxID = NULL; nAckRcvCnt ++; if ( ptid->m_packet ) { SoraUCompleteTxPacket(ptid->m_packet, STATUS_SUCCESS); } debug_printf("Complete Send Packet: [%08x], TxID: [%d], TX succeed\n", ptid->m_packet, ptid->m_tid.m_txid[0]); switch(ptid->m_status) { case PACKET_CAN_TX: FreeTxResource(&ptid->m_tid); break; default: break; } free(ptid); } } else if (pWlanHeader->MacHeader.FrameControl.Type == FRAME_MAN && pWlanHeader->MacHeader.FrameControl.Subtype == SUBT_BEACON) { ProcessBeacon ((PDOT11_MAC_BEACON)pWlanHeader); } else if (pWlanHeader->MacHeader.FrameControl.Type == FRAME_MAN ) { if ( memcmp( MACAddress.Address, pWlanHeader->MacHeader.Address1.Address, MAC_ADDRESS_LENGTH) == 0 ) { if ( pWlanHeader->MacHeader.FrameControl.Subtype == SUBT_AUTH ) // auth { DataFrameAck11 ( pWlanHeader, frameBufSize ); if ( assoState == ASSO_NONE ) { assoState = ASSO_AUTH; } } else if ( pWlanHeader->MacHeader.FrameControl.Subtype == SUBT_ASSO ) // asso { DataFrameAck11 ( pWlanHeader, frameBufSize ); if ( assoState == ASSO_AUTH || assoState == ASSO_NONE ) { assoState = ASSO_DONE; } } else if ( pWlanHeader->MacHeader.FrameControl.Subtype == SUBT_DEASSO || // deassociate pWlanHeader->MacHeader.FrameControl.Subtype == SUBT_DEAUTH ) // deauth { assoState = ASSO_NONE; } } } return true; }
BOOLEAN NICIsPacketAcceptable( IN PMP_ADAPTER Adapter, IN PUCHAR pDstMac ) /*++ Routine Description: Check if the destination address of a received packet matches the receive criteria of our adapter. Arguments: Adapter - pointer to the adapter structure pDstMac - Destination MAC address to compare Return Value: True or False --*/ { UINT AddrCompareResult; ULONG PacketFilter; BOOLEAN bPacketMatch; BOOLEAN bIsMulticast, bIsBroadcast; PacketFilter = Adapter->PacketFilter; bIsMulticast = ETH_IS_MULTICAST(pDstMac); bIsBroadcast = ETH_IS_BROADCAST(pDstMac); // // Handle the directed packet case first. // if (!bIsMulticast) { // // If the Adapter is not in promisc. mode, check if // the destination MAC address matches the local // address. // if ((PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == 0) { ETH_COMPARE_NETWORK_ADDRESSES_EQ(Adapter->CurrentAddress, pDstMac, &AddrCompareResult); bPacketMatch = ((AddrCompareResult == 0) && ((PacketFilter & NDIS_PACKET_TYPE_DIRECTED) != 0)); } else { bPacketMatch = TRUE; } } else { // // Multicast or broadcast packet. // // // Indicate if the filter is set to promisc mode ... // if ((PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) || // // or if this is a broadcast packet and the filter // is set to receive all broadcast packets... // (bIsBroadcast && (PacketFilter & NDIS_PACKET_TYPE_BROADCAST)) || // // or if this is a multicast packet, and the filter is // either set to receive all multicast packets, or // set to receive specific multicast packets. In the // latter case, indicate receive only if the destn // MAC address is present in the list of multicast // addresses set on the Adapter. // (!bIsBroadcast && ((PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) || ((PacketFilter & NDIS_PACKET_TYPE_MULTICAST) && NICIsMulticastMatch(Adapter, pDstMac)))) ) { bPacketMatch = TRUE; } else { // // No protocols above are interested in this // multicast/broadcast packet. // bPacketMatch = FALSE; } } return (bPacketMatch); }
/* SdrLLSendPacket transforms NDIS packet and enqueue it in MAC send queue. History: 3/Nov/2009: Created by senxiang */ VOID SdrLLSendPacket(PSDR_CONTEXT SDRContext, PNDIS_PACKET_OR_NBL pNBSPacket) { PMDL pEthBuffer = NULL; PMDL pWlanBuffer = NULL; PDLCB pDLCB = NULL; ULONG Dot11HeaderSize = 0; PUCHAR pDot11HeaderVa = NULL; PMAC pMac = (PMAC)SDRContext->Mac; PLL lnk = (PLL)SDRContext->LinkLayer; PSEND_QUEUE_MANAGER pSendQueueManager = GET_SEND_QUEUE_MANAGER(pMac); PNET_BUFFER pCurrentNB = NET_BUFFER_LIST_FIRST_NB(pNBSPacket); ULONG NetBufferCount = GetNetBufferCount(pNBSPacket); LIST_ENTRY DLCBList; BOOL fSufficientDLCBs = GetNFreeDLCB(&DLCBList, pSendQueueManager, NetBufferCount); DbgPrint("[LL_Send] %d net buffer in the NBL\n", NetBufferCount); if(pCurrentNB == NULL || !fSufficientDLCBs) { DbgPrint("[Error] Get NetBuffer failed, PACKET DROPPED\n"); NicDropPacket((PMP_ADAPTER)SDRContext->Nic, pNBSPacket); return; } NET_BUFFER_LIST_STATUS(pNBSPacket) = NDIS_STATUS_SUCCESS; //init its status to success while(pCurrentNB) { //Get MDL ASSERT(!IsListEmpty(&DLCBList)); pDLCB = CONTAINING_RECORD(RemoveHeadList(&DLCBList), DLCB, List); pDLCB->pNdisPktOrNBL = (PVOID)pNBSPacket; pDLCB->bLastNB = !(NET_BUFFER_NEXT_NB(pCurrentNB)); lnk->CurSendSeqNo.SequenceNumber++; pEthBuffer = NET_BUFFER_CURRENT_MDL(pCurrentNB); if(pEthBuffer == NULL) { pDLCB->PacketBase.pMdl = NULL; DbgPrint("[Error] Get MDL failed, PACKET DROPPED\n"); } else { EthToWlan(pEthBuffer, &pWlanBuffer, &Dot11HeaderSize, &pDot11HeaderVa, lnk->CurSendSeqNo.usValue, NET_BUFFER_CURRENT_MDL_OFFSET(pCurrentNB)); pDLCB->PacketType = PACKET_NEED_ACK; if(pDot11HeaderVa && (ETH_IS_BROADCAST(&((PDOT11RFC1042ENCAP)pDot11HeaderVa)->MacHeader.Address1) || ETH_IS_MULTICAST(&((PDOT11RFC1042ENCAP)pDot11HeaderVa)->MacHeader.Address1))) { pDLCB->PacketType = PACKET_NOT_NEED_ACK; } //Config DLCB pDLCB->Dot11HeaderSize = Dot11HeaderSize; pDLCB->pDot11HeaderVa = pDot11HeaderVa; pDLCB->PacketBase.pMdl = pWlanBuffer; pDLCB->PacketBase.PacketSize = NET_BUFFER_DATA_LENGTH(pCurrentNB) + sizeof(DOT11RFC1042ENCAP) - sizeof(ETHERNET_HEADER); { // we update the copied mdl length to packet length for baseband ULONG len = pDLCB->PacketBase.PacketSize; PMDL mdl = pDLCB->PacketBase.pMdl; while(mdl) { if (mdl->ByteCount > len) { mdl->ByteCount = len; break; } else if (mdl->ByteCount < len) { len-= mdl->ByteCount; mdl = mdl->Next; continue; } else break; } } pDLCB->PacketBase.Reserved1 = CalcMDLChainCRC32(pWlanBuffer); pDLCB->RetryCount = 0; pDLCB->bSendOK = FALSE; } SafeEnqueue(pSendQueueManager, SendSrcWaitList, pDLCB); InterlockedIncrement(&pSendQueueManager->nSrcPacket); //Notify send thread NIC_NOTIFY_SEND_THREAD(pMac); //Get next NetBuffer pCurrentNB = NET_BUFFER_NEXT_NB(pCurrentNB); } }
VOID Hw11ReadRegistryConfiguration( __in PHW Hw, __in NDIS_HANDLE ConfigurationHandle ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; PUCHAR NetworkAddress; UINT Length; // TODO: These should be read from the registry Hw->RegInfo.RTSThreshold = 2347; Hw->RegInfo.FragmentationThreshold = 2346; Hw->RegInfo.BeaconPeriod = 100; Hw->RegInfo.NumRXBuffersUpperLimit = HW11_MAX_RX_MSDUS; Hw->RegInfo.NumRXBuffersLowerBase = HW11_MIN_RX_MSDUS; // // read all the non-hardware specific registry values // MpReadRegistry((PVOID)Hw, ConfigurationHandle, HWRegTable, HW_NUM_REG_PARAMS); // // Read NetworkAddress registry value. Use it as the current address if any. // if (ConfigurationHandle != NULL) { NdisReadNetworkAddress(&ndisStatus, (void **)&NetworkAddress, &Length, ConfigurationHandle); // // If there is a valid NetworkAddress override in registry,use it // if ((ndisStatus == NDIS_STATUS_SUCCESS) && (Length == sizeof(DOT11_MAC_ADDRESS))) { // Dont use multicast/broadcast or 00* addresses if (!ETH_IS_MULTICAST(NetworkAddress) && !ETH_IS_BROADCAST(NetworkAddress)) { if ((NetworkAddress[0] == 0x00) && (NetworkAddress[1] == 0x00) && (NetworkAddress[2] == 0x00) && (NetworkAddress[3] == 0x00) && (NetworkAddress[4] == 0x00) && (NetworkAddress[5] == 0x00)) { // Network addr = 00 00 00 00 00 00 Hw->RegInfo.AddressOverrideEnabled = FALSE; } else if ((NetworkAddress[0] & 0x02) != 0x02) { // Not a locally administered address Hw->RegInfo.AddressOverrideEnabled = FALSE; } else { ETH_COPY_NETWORK_ADDRESS(Hw->RegInfo.OverrideAddress,NetworkAddress); Hw->RegInfo.AddressOverrideEnabled = TRUE; } } } ndisStatus = NDIS_STATUS_SUCCESS; } }