1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291 |
- /*++
- Copyright (c) 2015 Minoca Corp. All Rights Reserved
- Module Name:
- net80211.c
- Abstract:
- This module implements the 802.11 networking core library.
- Author:
- Chris Stevens 19-Oct-2015
- Environment:
- Kernel
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include "net80211.h"
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // Printed strings of ethernet addresses look something like:
- // "12:34:56:78:9A:BC". Include the null terminator.
- //
- #define NET80211_ADDRESS_STRING_LENGTH 18
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- VOID
- Net80211DriverUnload (
- PVOID Driver
- );
- KSTATUS
- Net80211pInitializeLink (
- PNET_LINK Link
- );
- VOID
- Net80211pDestroyLink (
- PNET_LINK Link
- );
- KSTATUS
- Net80211pSend (
- PVOID DataLinkContext,
- PNET_PACKET_LIST PacketList,
- PNETWORK_ADDRESS SourcePhysicalAddress,
- PNETWORK_ADDRESS DestinationPhysicalAddress,
- ULONG ProtocolNumber
- );
- VOID
- Net80211pProcessReceivedPacket (
- PVOID DataLinkContext,
- PNET_PACKET_BUFFER Packet
- );
- VOID
- Net80211pGetBroadcastAddress (
- PNETWORK_ADDRESS PhysicalNetworkAddress
- );
- ULONG
- Net80211pPrintAddress (
- PNETWORK_ADDRESS Address,
- PSTR Buffer,
- ULONG BufferLength
- );
- VOID
- Net80211pGetPacketSizeInformation (
- PVOID DataLinkContext,
- PNET_PACKET_SIZE_INFORMATION PacketSizeInformation,
- ULONG Flags
- );
- VOID
- Net80211pDestroy80211Link (
- PNET80211_LINK Net80211Link
- );
- KSTATUS
- Net80211pGetSetNetworkDeviceInformation (
- PNET80211_LINK Link,
- PNETWORK_80211_DEVICE_INFORMATION Information,
- BOOL Set
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- HANDLE Net80211DataLinkLayerHandle = INVALID_HANDLE;
- UUID Net80211NetworkDeviceInformationUuid =
- NETWORK_80211_DEVICE_INFORMATION_UUID;
- //
- // ------------------------------------------------------------------ Functions
- //
- KSTATUS
- DriverEntry (
- PDRIVER Driver
- )
- /*++
- Routine Description:
- This routine implements the initial entry point of the networking core
- library, called when the library is first loaded.
- Arguments:
- Driver - Supplies a pointer to the driver object.
- Return Value:
- Status code.
- --*/
- {
- NET_DATA_LINK_ENTRY DataLinkEntry;
- HANDLE DataLinkHandle;
- DRIVER_FUNCTION_TABLE FunctionTable;
- PNET_DATA_LINK_INTERFACE Interface;
- KSTATUS Status;
- ASSERT(Net80211DataLinkLayerHandle == INVALID_HANDLE);
- RtlZeroMemory(&FunctionTable, sizeof(DRIVER_FUNCTION_TABLE));
- FunctionTable.Version = DRIVER_FUNCTION_TABLE_VERSION;
- FunctionTable.Unload = Net80211DriverUnload;
- Status = IoRegisterDriverFunctions(Driver, &FunctionTable);
- if (!KSUCCESS(Status)) {
- goto DriverEntryEnd;
- }
- //
- // Register the 802.11 data link layer with the networking core.
- //
- DataLinkEntry.Domain = NetDomain80211;
- Interface = &(DataLinkEntry.Interface);
- Interface->InitializeLink = Net80211pInitializeLink;
- Interface->DestroyLink = Net80211pDestroyLink;
- Interface->Send = Net80211pSend;
- Interface->ProcessReceivedPacket = Net80211pProcessReceivedPacket;
- Interface->GetBroadcastAddress = Net80211pGetBroadcastAddress;
- Interface->PrintAddress = Net80211pPrintAddress;
- Interface->GetPacketSizeInformation = Net80211pGetPacketSizeInformation;
- Status = NetRegisterDataLinkLayer(&DataLinkEntry, &DataLinkHandle);
- if (!KSUCCESS(Status)) {
- goto DriverEntryEnd;
- }
- Net80211DataLinkLayerHandle = DataLinkHandle;
- //
- // Initialize any built-in networks.
- //
- Status = Net80211pEapolInitialize();
- if (!KSUCCESS(Status)) {
- goto DriverEntryEnd;
- }
- Status = Net80211pNetlinkInitialize();
- if (!KSUCCESS(Status)) {
- goto DriverEntryEnd;
- }
- DriverEntryEnd:
- if (!KSUCCESS(Status)) {
- if (Net80211DataLinkLayerHandle != INVALID_HANDLE) {
- NetUnregisterDataLinkLayer(Net80211DataLinkLayerHandle);
- Net80211DataLinkLayerHandle = INVALID_HANDLE;
- }
- }
- return Status;
- }
- VOID
- Net80211DriverUnload (
- PVOID Driver
- )
- /*++
- Routine Description:
- This routine is called before a driver is about to be unloaded from memory.
- The driver should take this opportunity to free any resources it may have
- set up in the driver entry routine.
- Arguments:
- Driver - Supplies a pointer to the driver being torn down.
- Return Value:
- None.
- --*/
- {
- //
- // Tear down built-in networks.
- //
- Net80211pNetlinkDestroy();
- Net80211pEapolDestroy();
- //
- // Unregister the 802.11 data link layer from the networking core.
- //
- if (Net80211DataLinkLayerHandle != INVALID_HANDLE) {
- NetUnregisterDataLinkLayer(Net80211DataLinkLayerHandle);
- Net80211DataLinkLayerHandle = INVALID_HANDLE;
- }
- return;
- }
- NET80211_API
- KSTATUS
- Net80211AddLink (
- PNET80211_LINK_PROPERTIES Properties,
- PNET80211_LINK *NewLink
- )
- /*++
- Routine Description:
- This routine adds the device link to the 802.11 networking core. The device
- must be ready to start sending and receiving 802.11 management frames in
- order to establish a BSS connection.
- Arguments:
- Properties - Supplies a pointer describing the properties and interface of
- the 802.11 link. This memory will not be referenced after the function
- returns, so this may be a stack allocated structure.
- NewLink - Supplies a pointer where a pointer to the new 802.11 link will be
- returned on success.
- Return Value:
- Status code.
- --*/
- {
- ULONG AllocationSize;
- PNET80211_LINK Link;
- NET_LINK_PROPERTIES NetProperties;
- PNET_LINK NetworkLink;
- PNET80211_RATE_INFORMATION Rates;
- KSTATUS Status;
- ASSERT(KeGetRunLevel() == RunLevelLow);
- Link = NULL;
- if (Properties->Version < NET80211_LINK_PROPERTIES_VERSION) {
- Status = STATUS_VERSION_MISMATCH;
- goto AddLinkEnd;
- }
- //
- // Convert the 802.11 properties to the networking core properties and
- // add the networking core link. In order for this to work like the
- // data link layers built into the networking core (e.g. Ethernet) the
- // networking core routine will call 802.11 back to have it create it's
- // private context.
- //
- RtlZeroMemory(&NetProperties, sizeof(NET_LINK_PROPERTIES));
- NetProperties.Version = NET_LINK_PROPERTIES_VERSION;
- NetProperties.TransmitAlignment = Properties->TransmitAlignment;
- NetProperties.Device = Properties->Device;
- NetProperties.DeviceContext = Properties->DeviceContext;
- NetProperties.PacketSizeInformation = Properties->PacketSizeInformation;
- NetProperties.ChecksumFlags = Properties->ChecksumFlags;
- NetProperties.DataLinkType = NetDomain80211;
- NetProperties.MaxPhysicalAddress = Properties->MaxPhysicalAddress;
- NetProperties.PhysicalAddress = Properties->PhysicalAddress;
- NetProperties.Interface.Send = Properties->Interface.Send;
- NetProperties.Interface.GetSetInformation =
- Properties->Interface.GetSetInformation;
- NetProperties.Interface.DestroyLink = Properties->Interface.DestroyLink;
- Status = NetAddLink(&NetProperties, &NetworkLink);
- if (!KSUCCESS(Status)) {
- goto AddLinkEnd;
- }
- ASSERT(NetworkLink->DataLinkContext != NULL);
- Link = (PNET80211_LINK)NetworkLink->DataLinkContext;
- //
- // Copy the properties, except the pointer to the supported rates.
- //
- RtlCopyMemory(&(Link->Properties),
- Properties,
- sizeof(NET80211_LINK_PROPERTIES));
- Link->Properties.SupportedRates = NULL;
- //
- // All supported station modes currently set the ESS capability.
- //
- Link->Properties.Capabilities |= NET80211_CAPABILITY_FLAG_ESS;
- //
- // The rate information has a dynamic length, so it needs to be reallocated
- // and copied.
- //
- AllocationSize = sizeof(NET80211_RATE_INFORMATION) +
- (Properties->SupportedRates->Count * sizeof(UCHAR));
- Rates = MmAllocatePagedPool(AllocationSize, NET80211_ALLOCATION_TAG);
- if (Rates == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto AddLinkEnd;
- }
- Rates->Count = Properties->SupportedRates->Count;
- Rates->Rate = (PUCHAR)(Rates + 1);
- RtlCopyMemory(Rates->Rate,
- Properties->SupportedRates->Rate,
- Rates->Count * sizeof(UCHAR));
- Link->Properties.SupportedRates = Rates;
- //
- // All 802.11 network devices respond to 802.11 network device information
- // requests.
- //
- Status = IoRegisterDeviceInformation(Link->Properties.Device,
- &Net80211NetworkDeviceInformationUuid,
- TRUE);
- if (!KSUCCESS(Status)) {
- goto AddLinkEnd;
- }
- NetSetLinkState(Link->NetworkLink, FALSE, 0);
- *NewLink = Link;
- Status = STATUS_SUCCESS;
- AddLinkEnd:
- if (!KSUCCESS(Status)) {
- if (Link != NULL) {
- Net80211RemoveLink(Link);
- }
- }
- return Status;
- }
- NET80211_API
- VOID
- Net80211RemoveLink (
- PNET80211_LINK Link
- )
- /*++
- Routine Description:
- This routine removes a link from the 802.11 core after its device has been
- removed. There may be outstanding references on the link, so the 802.11
- core will invoke the link destruction callback when all the references are
- released.
- Arguments:
- Link - Supplies a pointer to the link to remove.
- Return Value:
- None.
- --*/
- {
- //
- // The device has been removed, the link should no longer respond to
- // information requests.
- //
- IoRegisterDeviceInformation(Link->Properties.Device,
- &Net80211NetworkDeviceInformationUuid,
- FALSE);
- //
- // Remove the network link. When the last reference is released on the
- // network link it will call the data link destruction routine to destroy
- // the context.
- //
- Net80211pSetState(Link, Net80211StateUninitialized);
- NetRemoveLink(Link->NetworkLink);
- Net80211LinkReleaseReference(Link);
- return;
- }
- NET80211_API
- VOID
- Net80211LinkAddReference (
- PNET80211_LINK Link
- )
- /*++
- Routine Description:
- This routine increases the reference count on a 802.11 link.
- Arguments:
- Link - Supplies a pointer to the 802.11 link whose reference count
- should be incremented.
- Return Value:
- None.
- --*/
- {
- ULONG OldReferenceCount;
- OldReferenceCount = RtlAtomicAdd32(&(Link->ReferenceCount), 1);
- ASSERT((OldReferenceCount != 0) & (OldReferenceCount < 0x20000000));
- return;
- }
- NET80211_API
- VOID
- Net80211LinkReleaseReference (
- PNET80211_LINK Link
- )
- /*++
- Routine Description:
- This routine decreases the reference count of a 802.11 link, and destroys
- the link if the reference count drops to zero.
- Arguments:
- Link - Supplies a pointer to the 802.11 link whose reference count
- should be decremented.
- Return Value:
- None.
- --*/
- {
- ULONG OldReferenceCount;
- OldReferenceCount = RtlAtomicAdd32(&(Link->ReferenceCount), -1);
- ASSERT(OldReferenceCount != 0);
- //
- // Since the 802.11 link is owned by the network link. It cannot and should
- // not actually be destroyed until the network link's last reference goes
- // away. So release the initial reference taken on the network link.
- //
- if (OldReferenceCount == 1) {
- NetLinkReleaseReference(Link->NetworkLink);
- }
- return;
- }
- NET80211_API
- VOID
- Net80211ProcessReceivedPacket (
- PNET80211_LINK Link,
- PNET80211_RECEIVE_PACKET Packet
- )
- /*++
- Routine Description:
- This routine is called by the low level WiFi driver to pass received
- packets onto the 802.11 core networking library for dispatching.
- Arguments:
- Link - Supplies a pointer to the 802.11 link that received the packet.
- Packet - Supplies a pointer to a structure describing the incoming packet.
- This structure and the network packet it contains may be used as a
- scratch space while this routine executes and the packet travels up the
- stack, but will not be accessed after this routine returns.
- Return Value:
- None. When the function returns, the memory associated with the packet may
- be reclaimed and reused.
- --*/
- {
- PNET80211_BSS_ENTRY Bss;
- PNET80211_FRAME_HEADER Header;
- NetProcessReceivedPacket(Link->NetworkLink, Packet->NetPacket);
- //
- // Update the RSSI for the BSS that sent the packet. If this station is
- // associated (i.e. has an active BSS) and is not scanning, then assume the
- // packet came from the associated BSS.
- //
- KeAcquireQueuedLock(Link->Lock);
- if ((Link->ActiveBss != NULL) &&
- ((Link->Flags & NET80211_LINK_FLAG_SCANNING) == 0)) {
- Bss = Link->ActiveBss;
- //
- // Otherwise search the list of BSS's and update the one with the matching
- // ID.
- //
- } else {
- Header = Packet->NetPacket->Buffer + Packet->NetPacket->DataOffset;
- Bss = Net80211pLookupBssEntry(Link, Header->Address2);
- }
- if (Bss != NULL) {
- Bss->State.Rssi = Packet->Rssi;
- }
- KeReleaseQueuedLock(Link->Lock);
- return;
- }
- NET80211_API
- KSTATUS
- Net80211GetSetLinkDeviceInformation (
- PNET80211_LINK Link,
- PUUID Uuid,
- PVOID Data,
- PUINTN DataSize,
- BOOL Set
- )
- /*++
- Routine Description:
- This routine gets or sets device information for an 802.11 link.
- Arguments:
- Link - Supplies a pointer to the 802.11 link whose device information is
- being retrieved or set.
- Uuid - Supplies a pointer to the information identifier.
- Data - Supplies a pointer to the data buffer.
- DataSize - Supplies a pointer that on input contains the size of the data
- buffer in bytes. On output, returns the needed size of the data buffer,
- even if the supplied buffer was nonexistant or too small.
- Set - Supplies a boolean indicating whether to get the information (FALSE)
- or set the information (TRUE).
- Return Value:
- STATUS_SUCCESS on success.
- STATUS_BUFFER_TOO_SMALL if the supplied buffer was too small.
- STATUS_NOT_HANDLED if the given UUID was not recognized.
- --*/
- {
- KSTATUS Status;
- Status = STATUS_NOT_HANDLED;
- if (RtlAreUuidsEqual(Uuid, &Net80211NetworkDeviceInformationUuid)) {
- if (*DataSize < sizeof(NETWORK_80211_DEVICE_INFORMATION)) {
- *DataSize = sizeof(NETWORK_80211_DEVICE_INFORMATION);
- goto GetSetLinkDeviceInformationEnd;
- }
- *DataSize = sizeof(NETWORK_80211_DEVICE_INFORMATION);
- Status = Net80211pGetSetNetworkDeviceInformation(Link, Data, Set);
- goto GetSetLinkDeviceInformationEnd;
- } else {
- Status = NetGetSetLinkDeviceInformation(Link->NetworkLink,
- Uuid,
- Data,
- DataSize,
- Set);
- goto GetSetLinkDeviceInformationEnd;
- }
- GetSetLinkDeviceInformationEnd:
- return Status;
- }
- KSTATUS
- Net80211pInitializeLink (
- PNET_LINK Link
- )
- /*++
- Routine Description:
- This routine initializes any pieces of information needed by the data link
- layer for a new link.
- Arguments:
- Link - Supplies a pointer to the new link.
- Return Value:
- Status code.
- --*/
- {
- PNET80211_LINK Net80211Link;
- KSTATUS Status;
- Net80211Link = MmAllocatePagedPool(sizeof(NET80211_LINK),
- NET80211_ALLOCATION_TAG);
- if (Net80211Link == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto InitializeLinkEnd;
- }
- RtlZeroMemory(Net80211Link, sizeof(NET80211_LINK));
- Net80211Link->ReferenceCount = 1;
- NET_INITIALIZE_PACKET_LIST(&(Net80211Link->PausedPacketList));
- Net80211Link->Lock = KeCreateQueuedLock();
- if (Net80211Link->Lock == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto InitializeLinkEnd;
- }
- Net80211Link->ScanLock = KeCreateQueuedLock();
- if (Net80211Link->ScanLock == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto InitializeLinkEnd;
- }
- Net80211Link->StateTimer = KeCreateTimer(NET80211_ALLOCATION_TAG);
- if (Net80211Link->StateTimer == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto InitializeLinkEnd;
- }
- Net80211Link->TimeoutDpc = KeCreateDpc(Net80211pStateTimeoutDpcRoutine,
- Net80211Link);
- if (Net80211Link->TimeoutDpc == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto InitializeLinkEnd;
- }
- Net80211Link->TimeoutWorkItem = KeCreateWorkItem(
- NULL,
- WorkPriorityNormal,
- Net80211pStateTimeoutWorker,
- Net80211Link,
- NET80211_ALLOCATION_TAG);
- if (Net80211Link->TimeoutWorkItem == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto InitializeLinkEnd;
- }
- Net80211Link->State = Net80211StateUninitialized;
- INITIALIZE_LIST_HEAD(&(Net80211Link->BssList));
- NetLinkAddReference(Link);
- Net80211Link->NetworkLink = Link;
- Link->DataLinkContext = Net80211Link;
- Status = STATUS_SUCCESS;
- InitializeLinkEnd:
- if (!KSUCCESS(Status)) {
- Net80211pDestroy80211Link(Net80211Link);
- }
- return Status;
- }
- VOID
- Net80211pDestroyLink (
- PNET_LINK Link
- )
- /*++
- Routine Description:
- This routine allows the data link layer to tear down any state before a
- link is destroyed.
- Arguments:
- Link - Supplies a pointer to the dying link.
- Return Value:
- None.
- --*/
- {
- if (Link->DataLinkContext != NULL) {
- Net80211pDestroy80211Link(Link->DataLinkContext);
- Link->DataLinkContext = NULL;
- }
- return;
- }
- KSTATUS
- Net80211pSend (
- PVOID DataLinkContext,
- PNET_PACKET_LIST PacketList,
- PNETWORK_ADDRESS SourcePhysicalAddress,
- PNETWORK_ADDRESS DestinationPhysicalAddress,
- ULONG ProtocolNumber
- )
- /*++
- Routine Description:
- This routine sends data through the data link layer and out the link.
- Arguments:
- DataLinkContext - Supplies a pointer to the data link context for the
- link on which to send the data.
- PacketList - Supplies a pointer to a list of network packets to send. Data
- in these packets may be modified by this routine, but must not be used
- once this routine returns.
- SourcePhysicalAddress - Supplies a pointer to the source (local) physical
- network address.
- DestinationPhysicalAddress - Supplies the optional physical address of the
- destination, or at least the next hop. If NULL is provided, then the
- packets will be sent to the data link layer's broadcast address.
- ProtocolNumber - Supplies the protocol number of the data inside the data
- link header.
- Return Value:
- Status code.
- --*/
- {
- PNET80211_LINK Link;
- KSTATUS Status;
- Link = (PNET80211_LINK)DataLinkContext;
- Status = Net80211pSendDataFrames(Link,
- PacketList,
- SourcePhysicalAddress,
- DestinationPhysicalAddress,
- ProtocolNumber);
- return Status;
- }
- VOID
- Net80211pProcessReceivedPacket (
- PVOID DataLinkContext,
- PNET_PACKET_BUFFER Packet
- )
- /*++
- Routine Description:
- This routine is called to process a received ethernet packet.
- Arguments:
- DataLinkContext - Supplies a pointer to the data link context for the link
- that received the packet.
- Packet - Supplies a pointer to a structure describing the incoming packet.
- This structure may be used as a scratch space while this routine
- executes and the packet travels up the stack, but will not be accessed
- after this routine returns.
- Return Value:
- None. When the function returns, the memory associated with the packet may
- be reclaimed and reused.
- --*/
- {
- ULONG FrameType;
- PNET80211_FRAME_HEADER Header;
- PNET80211_LINK Link;
- //
- // Parse the the 802.11 header to determine the kind of packet.
- //
- Link = (PNET80211_LINK)DataLinkContext;
- Header = Packet->Buffer + Packet->DataOffset;
- FrameType = NET80211_GET_FRAME_TYPE(Header);
- switch (FrameType) {
- case NET80211_FRAME_TYPE_DATA:
- Net80211pProcessDataFrame(Link, Packet);
- break;
- case NET80211_FRAME_TYPE_MANAGEMENT:
- Net80211pProcessManagementFrame(Link, Packet);
- break;
- case NET80211_FRAME_TYPE_CONTROL:
- Net80211pProcessControlFrame(Link, Packet);
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- return;
- }
- VOID
- Net80211pGetBroadcastAddress (
- PNETWORK_ADDRESS PhysicalNetworkAddress
- )
- /*++
- Routine Description:
- This routine gets the 802.11 broadcast address.
- Arguments:
- PhysicalNetworkAddress - Supplies a pointer where the physical network
- broadcast address will be returned.
- Return Value:
- None.
- --*/
- {
- ULONG ByteIndex;
- PUCHAR BytePointer;
- BytePointer = (PUCHAR)(PhysicalNetworkAddress->Address);
- RtlZeroMemory(BytePointer, sizeof(PhysicalNetworkAddress->Address));
- PhysicalNetworkAddress->Domain = NetDomain80211;
- PhysicalNetworkAddress->Port = 0;
- for (ByteIndex = 0; ByteIndex < NET80211_ADDRESS_SIZE; ByteIndex += 1) {
- BytePointer[ByteIndex] = 0xFF;
- }
- return;
- }
- ULONG
- Net80211pPrintAddress (
- PNETWORK_ADDRESS Address,
- PSTR Buffer,
- ULONG BufferLength
- )
- /*++
- Routine Description:
- This routine is called to convert a network address into a string, or
- determine the length of the buffer needed to convert an address into a
- string.
- Arguments:
- Address - Supplies an optional pointer to a network address to convert to
- a string.
- Buffer - Supplies an optional pointer where the string representation of
- the address will be returned.
- BufferLength - Supplies the length of the supplied buffer, in bytes.
- Return Value:
- Returns the maximum length of any address if no network address is
- supplied.
- Returns the actual length of the network address string if a network address
- was supplied, including the null terminator.
- --*/
- {
- PUCHAR BytePointer;
- ULONG Length;
- if (Address == NULL) {
- return NET80211_ADDRESS_STRING_LENGTH;
- }
- ASSERT(Address->Domain == NetDomain80211);
- BytePointer = (PUCHAR)(Address->Address);
- Length = RtlPrintToString(Buffer,
- BufferLength,
- CharacterEncodingAscii,
- "%02X:%02X:%02X:%02X:%02X:%02X",
- BytePointer[0],
- BytePointer[1],
- BytePointer[2],
- BytePointer[3],
- BytePointer[4],
- BytePointer[5]);
- return Length;
- }
- VOID
- Net80211pGetPacketSizeInformation (
- PVOID DataLinkContext,
- PNET_PACKET_SIZE_INFORMATION PacketSizeInformation,
- ULONG Flags
- )
- /*++
- Routine Description:
- This routine gets the current packet size information for the given link.
- As the number of required headers can be different for each link, the
- packet size information is not a constant for an entire data link layer.
- Arguments:
- DataLinkContext - Supplies a pointer to the data link context of the link
- whose packet size information is being queried.
- PacketSizeInformation - Supplies a pointer to a structure that receives the
- link's data link layer packet size information.
- Flags - Supplies a bitmask of flags indicating which packet size
- information is desired. See NET_PACKET_SIZE_FLAG_* for definitions.
- Return Value:
- None.
- --*/
- {
- PNET80211_BSS_ENTRY Bss;
- PNET80211_LINK Link;
- Link = (PNET80211_LINK)DataLinkContext;
- //
- // The header size depends on whether QoS is implemented. If QoS is not
- // implemented, then the header size is always the same. If QoS is
- // implemented, it depends on whether or not the other station implements
- // QoS.
- //
- PacketSizeInformation->HeaderSize = sizeof(NET80211_DATA_FRAME_HEADER) +
- sizeof(NET8022_LLC_HEADER) +
- sizeof(NET8022_SNAP_EXTENSION);
- PacketSizeInformation->FooterSize = 0;
- //
- // If encryption is required for the current BSS, then there is an
- // additional header and an additional footer.
- //
- if ((Flags & NET_PACKET_SIZE_FLAG_UNENCRYPTED) == 0) {
- Bss = Net80211pGetBss(Link);
- if (Bss != NULL) {
- if ((Bss->Encryption.Pairwise == NetworkEncryptionWpa2Eap) ||
- (Bss->Encryption.Pairwise == NetworkEncryptionWpa2Psk)) {
- PacketSizeInformation->FooterSize += NET80211_CCMP_MIC_SIZE;
- PacketSizeInformation->HeaderSize +=
- sizeof(NET80211_CCMP_HEADER);
- }
- Net80211pBssEntryReleaseReference(Bss);
- }
- }
- PacketSizeInformation->MaxPacketSize = NET80211_MAX_DATA_FRAME_BODY_SIZE +
- PacketSizeInformation->HeaderSize +
- PacketSizeInformation->FooterSize;
- PacketSizeInformation->MinPacketSize = 0;
- return;
- }
- ULONG
- Net80211pGetSequenceNumber (
- PNET80211_LINK Link
- )
- /*++
- Routine Description:
- This routine returns the sequence number to use for the given link.
- Arguments:
- Link - Supplies a pointer to the 802.11 link whose sequence number is
- requested.
- Return Value:
- Returns the sequence number to use for the given link.
- --*/
- {
- return RtlAtomicAdd32(&(Link->SequenceNumber), 1);
- }
- KSTATUS
- Net80211pSetChannel (
- PNET80211_LINK Link,
- ULONG Channel
- )
- /*++
- Routine Description:
- This routine sets the 802.11 link's channel to the given value.
- Arguments:
- Link - Supplies a pointer to the 802.11 link whose channel is being updated.
- Channel - Supplies the channel to which the link should be set.
- Return Value:
- Status code.
- --*/
- {
- PVOID DeviceContext;
- DeviceContext = Link->Properties.DeviceContext;
- return Link->Properties.Interface.SetChannel(DeviceContext, Channel);
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- VOID
- Net80211pDestroy80211Link (
- PNET80211_LINK Net80211Link
- )
- /*++
- Routine Description:
- This routine destroys the given 802.11 link structure.
- Arguments:
- Net80211Link - Supplies a pointer to the 802.11 link to destroy.
- Return Value:
- None.
- --*/
- {
- //
- // Cancel the timer at the 802.11 layer before destroying it. This will
- // make sure that any lingering state transition worker does not actually
- // perform a state transition.
- //
- if (Net80211Link->StateTimer != NULL) {
- KeAcquireQueuedLock(Net80211Link->Lock);
- Net80211pCancelStateTransitionTimer(Net80211Link);
- KeReleaseQueuedLock(Net80211Link->Lock);
- KeDestroyTimer(Net80211Link->StateTimer);
- }
- if (Net80211Link->TimeoutDpc != NULL) {
- KeDestroyDpc(Net80211Link->TimeoutDpc);
- }
- //
- // As the timeout work item acquires the link's lock, make sure to flush
- // out any lingering run of the work item before destroying the lock.
- //
- if (Net80211Link->TimeoutWorkItem != NULL) {
- KeFlushWorkItem(Net80211Link->TimeoutWorkItem);
- KeDestroyWorkItem(Net80211Link->TimeoutWorkItem);
- }
- if (Net80211Link->Properties.SupportedRates != NULL) {
- MmFreePagedPool(Net80211Link->Properties.SupportedRates);
- }
- if (Net80211Link->Lock != NULL) {
- KeDestroyQueuedLock(Net80211Link->Lock);
- }
- if (Net80211Link->ScanLock != NULL) {
- KeDestroyQueuedLock(Net80211Link->ScanLock);
- }
- MmFreePagedPool(Net80211Link);
- return;
- }
- KSTATUS
- Net80211pGetSetNetworkDeviceInformation (
- PNET80211_LINK Link,
- PNETWORK_80211_DEVICE_INFORMATION Information,
- BOOL Set
- )
- /*++
- Routine Description:
- This routine gets or sets the 802.11 network device information for a
- particular link.
- Arguments:
- Link - Supplies a pointer to the link to work with.
- Information - Supplies a pointer that either receives the device
- information, or contains the new information to set. For set operations,
- the information buffer will contain the current settings on return.
- Set - Supplies a boolean indicating if the information should be set or
- returned.
- Return Value:
- Status code.
- --*/
- {
- ULONG SsidLength;
- ASSERT(KeGetRunLevel() == RunLevelLow);
- if (Information->Version < NETWORK_80211_DEVICE_INFORMATION_VERSION) {
- return STATUS_INVALID_PARAMETER;
- }
- if (Set != FALSE) {
- return STATUS_NOT_SUPPORTED;
- }
- Information->Flags = 0;
- RtlCopyMemory(&(Information->PhysicalAddress),
- &(Link->Properties.PhysicalAddress),
- sizeof(NETWORK_ADDRESS));
- KeAcquireQueuedLock(Link->Lock);
- if ((Link->State == Net80211StateAssociated) ||
- (Link->State == Net80211StateEncrypted)) {
- ASSERT(Link->ActiveBss != NULL);
- Information->Flags |= NETWORK_80211_DEVICE_FLAG_ASSOCIATED;
- Information->Bssid.Domain = NetDomain80211;
- Information->Bssid.Port = 0;
- RtlCopyMemory(Information->Bssid.Address,
- Link->ActiveBss->State.Bssid,
- NET80211_ADDRESS_SIZE);
- SsidLength = NET80211_GET_ELEMENT_LENGTH(Link->ActiveBss->Ssid);
- RtlCopyMemory(Information->Ssid,
- NET80211_GET_ELEMENT_DATA(Link->ActiveBss->Ssid),
- SsidLength);
- Information->Ssid[SsidLength] = STRING_TERMINATOR;
- Information->Channel = Link->ActiveBss->State.Channel;
- Information->MaxRate = Link->ActiveBss->State.MaxRate *
- NET80211_RATE_UNIT;
- Information->Rssi = Link->ActiveBss->State.Rssi;
- Information->PairwiseEncryption = Link->ActiveBss->Encryption.Pairwise;
- Information->GroupEncryption = Link->ActiveBss->Encryption.Group;
- }
- KeReleaseQueuedLock(Link->Lock);
- return STATUS_SUCCESS;
- }
|