mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
875 lines
20 KiB
875 lines
20 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mlidsend.c
|
|
|
|
Abstract:
|
|
|
|
This file contains all routines for sending packets.
|
|
|
|
Author:
|
|
|
|
Sean Selitrennikoff (SeanSe) 3-8-93
|
|
|
|
Environment:
|
|
|
|
Kernel Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <ndis.h>
|
|
#include "lsl.h"
|
|
#include "frames.h"
|
|
#include "mlid.h"
|
|
#include "ndismlid.h"
|
|
|
|
VOID
|
|
NdisMlidBuildMediaHeader(
|
|
PMLID_STRUCT Mlid,
|
|
PMLID_RESERVED Reserved,
|
|
UINT32 FrameLength,
|
|
PUINT8 DestinationAddress,
|
|
PUINT8 ProtocolID
|
|
);
|
|
|
|
|
|
VOID
|
|
SendPackets(
|
|
PMLID_STRUCT Mlid
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called whenever there is a need to send a packet. It will
|
|
take as many Send ECBs from the Mlid as possible and convert them into NDIS_PACKETS
|
|
and submit them to the NDIS_MAC.
|
|
|
|
NOTE: This must be called with Mlid->StageOpen = TRUE;
|
|
NOTE: This must be called with Mlid->InSendPacket = FALSE;
|
|
NOTE: Called with Mlid->MlidSpinLock held!!
|
|
|
|
Arguments:
|
|
|
|
Mlid - Pointer to the MLID_STRUCT to service.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PNDIS_PACKET NdisSendPacket;
|
|
PNDIS_BUFFER NdisBuffer;
|
|
PMLID_RESERVED Reserved;
|
|
UINT32 i;
|
|
BOOLEAN HeldEvents = FALSE;
|
|
NDIS_STATUS NdisStatus;
|
|
|
|
PECB SendECB;
|
|
|
|
ASSERT(Mlid->StageOpen == TRUE);
|
|
ASSERT(Mlid->InSendPacket == FALSE);
|
|
|
|
//
|
|
// While there any sends queued
|
|
//
|
|
while (Mlid->FirstPendingSend) {
|
|
|
|
//
|
|
// If there are no NDIS_PACKETs avaiable, then close stage and exit.
|
|
//
|
|
NdisAllocatePacket(
|
|
&NdisStatus,
|
|
&NdisSendPacket,
|
|
Mlid->SendPacketPool
|
|
);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
Mlid->StageOpen = FALSE;
|
|
break;
|
|
|
|
}
|
|
|
|
Reserved = PMLID_RESERVED_FROM_PNDIS_PACKET(NdisSendPacket);
|
|
|
|
//
|
|
// Initialize NDIS_PACKET
|
|
//
|
|
NdisReinitializePacket(NdisSendPacket);
|
|
|
|
SendECB = Mlid->FirstPendingSend;
|
|
|
|
//
|
|
// Convert ECB fragment list into an MDL chain
|
|
//
|
|
for (i = 0; i < SendECB->ECB_FragmentCount; i++) {
|
|
|
|
NdisAllocateBuffer(
|
|
&NdisStatus,
|
|
&NdisBuffer,
|
|
Mlid->SendBufferPool,
|
|
SendECB->ECB_Fragment[i].FragmentAddress,
|
|
SendECB->ECB_Fragment[i].FragmentLength
|
|
);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
goto Fail1;
|
|
|
|
}
|
|
|
|
NdisChainBufferAtBack(
|
|
NdisSendPacket,
|
|
NdisBuffer
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Build the media header
|
|
//
|
|
NdisMlidBuildMediaHeader(Mlid,
|
|
Reserved,
|
|
SendECB->ECB_DataLength,
|
|
SendECB->ECB_ImmediateAddress,
|
|
SendECB->ECB_ProtocolID
|
|
);
|
|
|
|
//
|
|
// Link media header into front of MDL chain
|
|
//
|
|
NdisAllocateBuffer(
|
|
&NdisStatus,
|
|
&NdisBuffer,
|
|
Mlid->SendBufferPool,
|
|
Reserved->MediaHeader,
|
|
Reserved->MediaHeaderLength
|
|
);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
goto Fail1;
|
|
|
|
}
|
|
|
|
NdisChainBufferAtFront(
|
|
NdisSendPacket,
|
|
NdisBuffer
|
|
);
|
|
|
|
//
|
|
// Remove Send ECB from Send Queue
|
|
//
|
|
Mlid->FirstPendingSend = SendECB->ECB_NextLink;
|
|
|
|
if (Mlid->LastPendingSend == SendECB) {
|
|
|
|
Mlid->LastPendingSend = NULL;
|
|
|
|
} else {
|
|
|
|
SendECB->ECB_NextLink->ECB_PreviousLink = NULL;
|
|
|
|
}
|
|
|
|
//
|
|
// Store ECB in reserved section
|
|
//
|
|
Reserved->SendECB = SendECB;
|
|
|
|
//
|
|
// Release MlidSpinLock
|
|
//
|
|
NdisReleaseSpinLock(&(Mlid->MlidSpinLock));
|
|
|
|
//
|
|
// Submit to NDIS_MAC
|
|
//
|
|
NdisSend(
|
|
&NdisStatus,
|
|
Mlid->NdisBindingHandle,
|
|
NdisSendPacket
|
|
);
|
|
|
|
//
|
|
// Acquire MlidSpinLock
|
|
//
|
|
NdisAcquireSpinLock(&(Mlid->MlidSpinLock));
|
|
|
|
//
|
|
// If not pending, then
|
|
//
|
|
if (NdisStatus != NDIS_STATUS_PENDING) {
|
|
|
|
//
|
|
// Return resources to Mlid
|
|
//
|
|
NdisUnchainBufferAtFront(
|
|
NdisSendPacket,
|
|
&NdisBuffer
|
|
);
|
|
|
|
while (NdisBuffer != NULL) {
|
|
|
|
NdisFreeBuffer(NdisBuffer);
|
|
|
|
NdisUnchainBufferAtFront(
|
|
NdisSendPacket,
|
|
&NdisBuffer
|
|
);
|
|
|
|
}
|
|
|
|
NdisFreePacket(NdisSendPacket);
|
|
|
|
//
|
|
// Store completion status in ECB
|
|
//
|
|
|
|
if (NdisStatus == NDIS_STATUS_SUCCESS) {
|
|
|
|
SendECB->ECB_Status = (UINT16)SUCCESSFUL;
|
|
|
|
} else {
|
|
|
|
SendECB->ECB_Status = (UINT16)FAIL;
|
|
|
|
}
|
|
|
|
//
|
|
// Release MlidSpinLock
|
|
//
|
|
NdisReleaseSpinLock(&(Mlid->MlidSpinLock));
|
|
|
|
//
|
|
// put ECB on LSLEventQueue
|
|
//
|
|
(*(Mlid->LSLFunctionList->SupportAPIArray[HoldEvent_INDEX]))(
|
|
SendECB
|
|
);
|
|
|
|
//
|
|
// Acquire MlidSpinLock
|
|
//
|
|
NdisAcquireSpinLock(&(Mlid->MlidSpinLock));
|
|
|
|
//
|
|
// Set flag to service events
|
|
//
|
|
HeldEvents = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Call LSL_ServiceEvents if necessary
|
|
//
|
|
if (HeldEvents) {
|
|
(*(Mlid->LSLFunctionList->SupportAPIArray[ServiceEvents_INDEX]))(
|
|
);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
Fail1:
|
|
|
|
//
|
|
// Unchain all NDIS_BUFFERs from packet
|
|
//
|
|
|
|
NdisUnchainBufferAtFront(
|
|
NdisSendPacket,
|
|
&NdisBuffer
|
|
);
|
|
|
|
while (NdisBuffer != NULL) {
|
|
|
|
NdisFreeBuffer(NdisBuffer);
|
|
|
|
NdisUnchainBufferAtFront(
|
|
NdisSendPacket,
|
|
&NdisBuffer
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Return NDIS_PACKET
|
|
//
|
|
NdisFreePacket(NdisSendPacket);
|
|
|
|
//
|
|
// Close stage
|
|
//
|
|
Mlid->StageOpen = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
ReturnSendPacketResources(
|
|
PNDIS_PACKET Packet
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called to return the MLID resources allocated for a sent NDIS_PACKET.
|
|
This includes the entire MDL chain itself and the NDIS_PACKET.
|
|
|
|
NOTE: Called with Mlid->MlidSpinLock held!!
|
|
|
|
Arguments:
|
|
|
|
Packet - Pointer to the NDIS_PACKET to free.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PNDIS_BUFFER NdisBuffer;
|
|
|
|
//
|
|
// Unchain all NDIS_BUFFERs from packet
|
|
//
|
|
|
|
NdisUnchainBufferAtFront(
|
|
Packet,
|
|
&NdisBuffer
|
|
);
|
|
|
|
while (NdisBuffer != NULL) {
|
|
|
|
NdisFreeBuffer(NdisBuffer);
|
|
|
|
NdisUnchainBufferAtFront(
|
|
Packet,
|
|
&NdisBuffer
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Return NDIS_PACKET
|
|
//
|
|
NdisFreePacket(Packet);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
NdisMlidBuildMediaHeader(
|
|
PMLID_STRUCT Mlid,
|
|
PMLID_RESERVED Reserved,
|
|
UINT32 FrameLength,
|
|
PUINT8 DestinationAddress,
|
|
PUINT8 ProtocolID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine assembles a packet header for the MLID and ProtocolID given into
|
|
the given reserved section.
|
|
|
|
NOTE: Called with Mlid->MlidSpinLock held!!
|
|
|
|
Arguments:
|
|
|
|
Mlid - Pointer to MLID
|
|
|
|
Reserved - Pointer to a reserved section with memory to hold the header.
|
|
|
|
FrameLength - Length of the Data portion of the frame.
|
|
|
|
DestinationAddress - The address that the packet will be addresses to.
|
|
|
|
ProtocolID - The ID that has DSAP and other information in it.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PUINT8 SourceRoutingInfo;
|
|
UINT32 SourceRoutingLength;
|
|
UINT32 DataLength = FrameLength;
|
|
PUINT8 CurrentPlace = Reserved->MediaHeader;
|
|
|
|
//
|
|
// Switch on media type
|
|
//
|
|
switch (Mlid->NdisMlidMedium) {
|
|
|
|
case NdisMedium802_5:
|
|
|
|
if (Mlid->ConfigTable.MLIDCFG_SourceRouting != NULL) {
|
|
|
|
//
|
|
// Get any source routing information
|
|
//*\\ Get SR Info. Are parameters correct?
|
|
SourceRoutingInfo = (*((PLSL_SR_FUNCTION)(Mlid->ConfigTable.MLIDCFG_SourceRouting)))
|
|
( Mlid->BoardNumber,
|
|
&SourceRoutingLength,
|
|
DestinationAddress
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Set AC field
|
|
//
|
|
*CurrentPlace = 0x10;
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Set FC field
|
|
//
|
|
*CurrentPlace = 0x40;
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Set DestinationAddress
|
|
//
|
|
RtlCopyMemory(CurrentPlace, DestinationAddress, 6);
|
|
CurrentPlace += 6;
|
|
|
|
//
|
|
// Set SourceAddress
|
|
//
|
|
RtlCopyMemory(CurrentPlace, Mlid->ConfigTable.MLIDCFG_NodeAddress, 6);
|
|
CurrentPlace += 6;
|
|
|
|
//
|
|
// Copy SourceRoutingInfo
|
|
//
|
|
RtlCopyMemory(CurrentPlace, SourceRoutingInfo, SourceRoutingLength);
|
|
CurrentPlace += SourceRoutingLength;
|
|
|
|
//
|
|
// Switch on frame type
|
|
//
|
|
switch (Mlid->ConfigTable.MLIDCFG_FrameID) {
|
|
|
|
//
|
|
// TR - 802.2
|
|
//
|
|
case TOKEN_RING_802_2_FRAME_ID:
|
|
|
|
//
|
|
// Set DSAP, SSAP and Control
|
|
//
|
|
if (ProtocolID[0] < 2) {
|
|
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0x03;
|
|
CurrentPlace++;
|
|
|
|
} else if (ProtocolID[0] == 2) {
|
|
|
|
//
|
|
// Type I header
|
|
//
|
|
|
|
*CurrentPlace = ProtocolID[3];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[4];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Type II header
|
|
//
|
|
|
|
*CurrentPlace = ProtocolID[2];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[3];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[4];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
//
|
|
// TR - SNAP
|
|
//
|
|
case TOKEN_RING_SNAP_FRAME_ID:
|
|
|
|
//
|
|
// Set DSAP, SSAP and Control
|
|
//
|
|
*CurrentPlace = 0xAA;
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0xAA;
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0x03;
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Copy in ProtocolID
|
|
//
|
|
RtlCopyMemory(CurrentPlace, &(ProtocolID[1]), 5);
|
|
CurrentPlace += 5;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// Should never happen
|
|
//
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case NdisMedium802_3:
|
|
|
|
//
|
|
// Set DestinationAddress
|
|
//
|
|
RtlCopyMemory(CurrentPlace, DestinationAddress, 6);
|
|
CurrentPlace += 6;
|
|
|
|
//
|
|
// Set SourceAddress
|
|
//
|
|
RtlCopyMemory(CurrentPlace, Mlid->ConfigTable.MLIDCFG_NodeAddress, 6);
|
|
CurrentPlace += 6;
|
|
|
|
FrameLength += 12;
|
|
|
|
//
|
|
// Switch on frame type
|
|
//
|
|
switch (Mlid->ConfigTable.MLIDCFG_FrameID) {
|
|
|
|
//
|
|
// Ethernet 802.2
|
|
//
|
|
case ETHERNET_802_2_FRAME_ID:
|
|
|
|
FrameLength += 5;
|
|
|
|
//
|
|
// Set FrameLength
|
|
//
|
|
*CurrentPlace = (UINT8)((FrameLength >> 8) & 0xFF);
|
|
CurrentPlace++;
|
|
*CurrentPlace = (UINT8)(FrameLength & 0xFF);
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Set DSAP, SSAP and Control
|
|
//
|
|
if (ProtocolID[0] < 2) {
|
|
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0x03;
|
|
CurrentPlace++;
|
|
|
|
} else if (ProtocolID[0] == 2) {
|
|
|
|
//
|
|
// Type I header
|
|
//
|
|
|
|
*CurrentPlace = ProtocolID[3];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[4];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Type II header
|
|
//
|
|
|
|
*CurrentPlace = ProtocolID[2];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[3];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[4];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
//
|
|
// Ethernet SNAP
|
|
//
|
|
case ETHERNET_SNAP_FRAME_ID:
|
|
|
|
FrameLength += 10;
|
|
|
|
//
|
|
// Set FrameLength
|
|
//
|
|
*CurrentPlace = (UINT8)((FrameLength >> 8) & 0xFF);
|
|
CurrentPlace++;
|
|
*CurrentPlace = (UINT8)(FrameLength & 0xFF);
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Set DSAP, SSAP and Control
|
|
//
|
|
*CurrentPlace = 0xAA;
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0xAA;
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0x03;
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Copy in ProtocolID
|
|
//
|
|
RtlCopyMemory(CurrentPlace, &(ProtocolID[1]), 5);
|
|
CurrentPlace += 5;
|
|
|
|
break;
|
|
|
|
//
|
|
// Ethernet Raw 802.3
|
|
//
|
|
case ETHERNET_802_3_FRAME_ID:
|
|
|
|
FrameLength += 2;
|
|
|
|
//
|
|
// Set FrameLength
|
|
//
|
|
*CurrentPlace = (UINT8)((FrameLength >> 8) & 0xFF);
|
|
CurrentPlace++;
|
|
*CurrentPlace = (UINT8)(FrameLength & 0xFF);
|
|
CurrentPlace++;
|
|
|
|
break;
|
|
|
|
|
|
//
|
|
// Ethernet II
|
|
//
|
|
case ETHERNET_II_FRAME_ID:
|
|
|
|
FrameLength += 2;
|
|
|
|
//
|
|
// Set FrameType
|
|
//*\\ Is this right? - Ethernet II, where is FrameType stored in ProtocolID?
|
|
*CurrentPlace = (UINT8)ProtocolID[4];
|
|
CurrentPlace++;
|
|
*CurrentPlace = (UINT8)ProtocolID[5];
|
|
CurrentPlace++;
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
//
|
|
// Should never happen
|
|
//
|
|
ASSERT(0);
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case NdisMediumFddi:
|
|
|
|
//
|
|
// Set FCByte
|
|
//
|
|
*CurrentPlace = 0x57;
|
|
CurrentPlace ++;
|
|
|
|
//
|
|
// Set DestinationAddress
|
|
//
|
|
RtlCopyMemory(CurrentPlace, DestinationAddress, 6);
|
|
CurrentPlace += 6;
|
|
|
|
//
|
|
// Set SourceAddress
|
|
//
|
|
RtlCopyMemory(CurrentPlace, Mlid->ConfigTable.MLIDCFG_NodeAddress, 6);
|
|
CurrentPlace += 6;
|
|
|
|
FrameLength += 13;
|
|
|
|
//
|
|
// Switch on frame type
|
|
//
|
|
switch (Mlid->ConfigTable.MLIDCFG_FrameID) {
|
|
|
|
//
|
|
// FDDI 802.2
|
|
//
|
|
case FDDI_802_2_FRAME_ID:
|
|
|
|
if (ProtocolID[0] > 2) {
|
|
|
|
//
|
|
// Type II header
|
|
//
|
|
FrameLength += 6;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Type I header
|
|
//
|
|
FrameLength += 5;
|
|
}
|
|
|
|
//
|
|
// Set FrameLength
|
|
//
|
|
*CurrentPlace = (UINT8)((FrameLength >> 8) & 0xFF);
|
|
CurrentPlace++;
|
|
*CurrentPlace = (UINT8)(FrameLength & 0xFF);
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Set DSAP, SSAP and Control
|
|
//
|
|
if (ProtocolID[0] < 2) {
|
|
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0x03;
|
|
CurrentPlace++;
|
|
|
|
} else if (ProtocolID[0] == 2) {
|
|
|
|
//
|
|
// Type I header
|
|
//
|
|
|
|
*CurrentPlace = ProtocolID[3];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[4];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Type II header
|
|
//
|
|
|
|
*CurrentPlace = ProtocolID[2];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[3];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[4];
|
|
CurrentPlace++;
|
|
*CurrentPlace = ProtocolID[5];
|
|
CurrentPlace++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
//
|
|
// Fddi SNAP
|
|
//
|
|
case FDDI_SNAP_FRAME_ID:
|
|
|
|
FrameLength += 10;
|
|
|
|
//
|
|
// Set FrameLength
|
|
//
|
|
*CurrentPlace = (UINT8)((FrameLength >> 8) & 0xFF);
|
|
CurrentPlace++;
|
|
*CurrentPlace = (UINT8)(FrameLength & 0xFF);
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Set DSAP, SSAP and Control
|
|
//
|
|
*CurrentPlace = 0xAA;
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0xAA;
|
|
CurrentPlace++;
|
|
*CurrentPlace = 0x03;
|
|
CurrentPlace++;
|
|
|
|
//
|
|
// Copy in ProtocolID
|
|
//
|
|
RtlCopyMemory(CurrentPlace, &(ProtocolID[1]), 5);
|
|
CurrentPlace += 5;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// Should never happen
|
|
//
|
|
ASSERT(0);
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
//
|
|
// Should never happen
|
|
//
|
|
ASSERT(0);
|
|
break;
|
|
|
|
}
|
|
|
|
Reserved->MediaHeaderLength = FrameLength - DataLength;
|
|
|
|
}
|