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.
2947 lines
75 KiB
2947 lines
75 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
atknpro.c
|
|
|
|
Abstract:
|
|
|
|
This module contains code related to ndis-interaction during pre-initialization.
|
|
|
|
Author:
|
|
|
|
Nikhil Kamkolkar (NikhilK) 8-Jun-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "atalknt.h"
|
|
|
|
//
|
|
// Local routines
|
|
//
|
|
|
|
|
|
NTSTATUS
|
|
AtalkNdisBind(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT PortNumber);
|
|
|
|
UINT
|
|
AtalkNdisGetNoBufferDescriptors(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts);
|
|
|
|
UINT
|
|
AtalkNdisGetNoPacketDescriptors(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts);
|
|
|
|
VOID
|
|
AtalkOpenAdapterComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS Status,
|
|
IN NDIS_STATUS OpenErrorStatus);
|
|
|
|
VOID
|
|
AtalkCloseAdapterComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS Status);
|
|
|
|
VOID
|
|
AtalkResetComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS Status);
|
|
|
|
VOID
|
|
AtalkRequestComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN PNDIS_REQUEST NdisRequest,
|
|
IN NDIS_STATUS Status);
|
|
|
|
VOID
|
|
AtalkStatusIndication (
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS GeneralStatus,
|
|
IN PVOID StatusBuffer,
|
|
IN UINT StatusBufferLength);
|
|
|
|
VOID
|
|
AtalkStatusComplete (
|
|
IN NDIS_HANDLE ProtocolBindingContext);
|
|
|
|
VOID
|
|
AtalkReceiveComplete (
|
|
IN NDIS_HANDLE BindingContext);
|
|
|
|
VOID
|
|
AtalkTransferDataComplete(
|
|
IN NDIS_HANDLE BindingContext,
|
|
IN PNDIS_PACKET NdisPacket,
|
|
IN NDIS_STATUS Status,
|
|
IN UINT BytesTransferred);
|
|
|
|
VOID
|
|
AtalkSendCompletionHandler(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN PNDIS_PACKET NdisPacket,
|
|
IN NDIS_STATUS NdisStatus);
|
|
|
|
NDIS_STATUS
|
|
AtalkReceiveIndication(
|
|
IN NDIS_HANDLE BindingContext,
|
|
IN NDIS_HANDLE ReceiveContext,
|
|
IN PVOID HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PVOID LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize);
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptEthernetPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc);
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptFddiPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc);
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptTokenringPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc);
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptLocaltalkPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
OUT PUCHAR LlapType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc);
|
|
|
|
#if DBG
|
|
VOID
|
|
DumpPacket(
|
|
PUCHAR Packet);
|
|
#endif
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
AtalkNdisRegisterProtocol(
|
|
IN PUNICODE_STRING NameString
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called during initialization time to register the protocol
|
|
with NDIS.
|
|
|
|
Arguments:
|
|
|
|
NameString- The name to be registered for this protocol- human-readable form
|
|
|
|
Return Value:
|
|
|
|
Status - TRUE if register went ok, FALSE otherwise.
|
|
--*/
|
|
{
|
|
NDIS_STATUS ndisStatus;
|
|
NDIS_PROTOCOL_CHARACTERISTICS protocolInfo;
|
|
|
|
//
|
|
// Set up the characteristics for the protocol for registering
|
|
// with NDIS
|
|
//
|
|
|
|
protocolInfo.MajorNdisVersion = PROTOCOL_MAJORNDIS_VERSION;
|
|
protocolInfo.MinorNdisVersion = PROTOCOL_MINORNDIS_VERSION;
|
|
|
|
protocolInfo.Name.Length = NameString->Length;
|
|
protocolInfo.Name.Buffer = (PVOID)NameString->Buffer;
|
|
|
|
protocolInfo.OpenAdapterCompleteHandler = AtalkOpenAdapterComplete;
|
|
protocolInfo.CloseAdapterCompleteHandler = AtalkCloseAdapterComplete;
|
|
protocolInfo.ResetCompleteHandler = AtalkResetComplete;
|
|
protocolInfo.RequestCompleteHandler = AtalkRequestComplete;
|
|
|
|
protocolInfo.SendCompleteHandler = AtalkSendCompletionHandler;
|
|
protocolInfo.TransferDataCompleteHandler = AtalkTransferDataComplete;
|
|
|
|
protocolInfo.ReceiveHandler = AtalkReceiveIndication;
|
|
protocolInfo.ReceiveCompleteHandler = AtalkReceiveComplete;
|
|
protocolInfo.StatusHandler = AtalkStatusIndication;
|
|
protocolInfo.StatusCompleteHandler = AtalkStatusComplete;
|
|
|
|
NdisRegisterProtocol(
|
|
&ndisStatus,
|
|
&AtalkNdisProtocolHandle,
|
|
&protocolInfo,
|
|
(UINT)sizeof(NDIS_PROTOCOL_CHARACTERISTICS)+NameString->Length);
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_REGISTERPROTOCOL,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
}
|
|
|
|
return(ndisStatus == NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkNdisDeregisterProtocol(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called to deregister the protocol
|
|
|
|
Arguments:
|
|
|
|
NONE
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
--*/
|
|
{
|
|
NDIS_STATUS ndisStatus;
|
|
|
|
NdisDeregisterProtocol(
|
|
&ndisStatus,
|
|
AtalkNdisProtocolHandle);
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_DEREGISTERPROTOCOL,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
INT
|
|
AtalkNdisBindToMacs(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called during initialization time to bind to all the macs
|
|
specified
|
|
|
|
Arguments:
|
|
|
|
NdisPortDesc- Pointer to beginning of the array of port descriptors
|
|
NumberOfPorts- Number of elements in this array
|
|
|
|
Return Value:
|
|
|
|
Number of successful bindings
|
|
--*/
|
|
{
|
|
NDIS_STATUS ndisStatus, openStatus;
|
|
UINT selectedMediumIndex;
|
|
INT i, noSuccessfulBinds = 0;
|
|
|
|
|
|
for (i=0; i<NumberOfPorts; i++) {
|
|
if (NdisPortDesc[i].PortState == STATE_ADAPTER_SPECIFIED) {
|
|
|
|
//
|
|
// We use the event in the Ndis port descriptor to block in case this
|
|
// request pends.
|
|
//
|
|
|
|
KeInitializeEvent(
|
|
&NdisPortDesc[i].RequestEvent,
|
|
NotificationEvent,
|
|
FALSE);
|
|
|
|
NdisOpenAdapter(
|
|
&ndisStatus, // open status
|
|
&openStatus, // more info not used
|
|
&NdisPortDesc[i].NdisBindingHandle,
|
|
&selectedMediumIndex,
|
|
AtalkSupportedMedia,
|
|
sizeof(AtalkSupportedMedia)/sizeof(NDIS_MEDIUM),
|
|
AtalkNdisProtocolHandle,
|
|
(NDIS_HANDLE)&NdisPortDesc[i],
|
|
(PNDIS_STRING)&NdisPortDesc[i].AdapterName,
|
|
0, // Open options
|
|
NULL); // Addressing information
|
|
|
|
|
|
if (ndisStatus == NDIS_STATUS_PENDING) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISREQ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: AtalkNdisBindToMacs - OpenAdapter is pending for %d\n", i));
|
|
|
|
//
|
|
// Make sure we are not at or above dispatch level
|
|
//
|
|
|
|
if (KeGetCurrentIrql() >= DISPATCH_LEVEL) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
//
|
|
// Wait on event, completion routine will set NdisRequestEvent
|
|
//
|
|
|
|
KeWaitForSingleObject(
|
|
&NdisPortDesc[i].RequestEvent,
|
|
Executive,
|
|
KernelMode,
|
|
TRUE,
|
|
(PLARGE_INTEGER)NULL);
|
|
|
|
ndisStatus = NdisPortDesc[i].RequestStatus;
|
|
|
|
KeResetEvent(
|
|
&NdisPortDesc[i].RequestEvent);
|
|
}
|
|
|
|
if (ndisStatus == NDIS_STATUS_SUCCESS) {
|
|
|
|
NdisPortDesc[i].PortState = STATE_BOUND;
|
|
NdisPortDesc[i].PortNumber = noSuccessfulBinds;
|
|
NdisPortDesc[i].NdisPortType =
|
|
AtalkSupportedMedia[selectedMediumIndex];
|
|
|
|
noSuccessfulBinds++;
|
|
|
|
} else {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_OPENADAPTER,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
1,
|
|
&NdisPortDesc[i].AdapterName);
|
|
}
|
|
}
|
|
}
|
|
|
|
return(noSuccessfulBinds);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkNdisUnbindFromMacs(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called during to unbind from all the macs currently bound to
|
|
|
|
Arguments:
|
|
|
|
NdisPortDesc- Pointer to beginning of the array of port descriptors
|
|
NumberOfPorts- Number of elements in this array
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
--*/
|
|
{
|
|
NDIS_STATUS ndisStatus;
|
|
BOOLEAN unbind;
|
|
INT i;
|
|
|
|
for (i = 0; i < NumberOfPorts; i++) {
|
|
|
|
//
|
|
// Grab the perport lock
|
|
//
|
|
|
|
unbind = FALSE;
|
|
ACQUIRE_SPIN_LOCK(&NdisPortDesc[i].PerPortLock);
|
|
if (NdisPortDesc[i].PortState == STATE_BOUND) {
|
|
NdisPortDesc[i].PortState = STATE_UNBINDING;
|
|
unbind = TRUE;
|
|
}
|
|
RELEASE_SPIN_LOCK(&NdisPortDesc[i].PerPortLock);
|
|
|
|
if (unbind) {
|
|
|
|
NdisCloseAdapter(
|
|
&ndisStatus,
|
|
NdisPortDesc[i].NdisBindingHandle);
|
|
|
|
if (ndisStatus == NDIS_STATUS_PENDING) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISREQ, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: AtalkNdisUnbindFromMacs - pending for %d!\n", i));
|
|
|
|
//
|
|
// Make sure we are not at or above dispatch level
|
|
//
|
|
|
|
if (KeGetCurrentIrql() >= DISPATCH_LEVEL) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
//
|
|
// Wait on event, completion routine will set NdisRequestEvent
|
|
//
|
|
|
|
KeWaitForSingleObject(
|
|
&NdisPortDesc->RequestEvent,
|
|
Executive,
|
|
KernelMode,
|
|
TRUE,
|
|
(PLARGE_INTEGER)NULL);
|
|
|
|
ndisStatus = NdisPortDesc->RequestStatus;
|
|
|
|
KeResetEvent(
|
|
&NdisPortDesc->RequestEvent);
|
|
|
|
} else if (ndisStatus == NDIS_STATUS_SUCCESS) {
|
|
|
|
//
|
|
// Call the completion routine
|
|
//
|
|
|
|
AtalkCloseAdapterComplete(
|
|
&NdisPortDesc[i],
|
|
ndisStatus);
|
|
|
|
} else {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_CLOSEADAPTER,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
1,
|
|
&NdisPortDesc[i].AdapterName);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT
|
|
AtalkNdisGetNoPacketDescriptors(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns the number of packet descriptors to allocate for this
|
|
protocol globally. It will determine some values based on number of ports
|
|
bound to.
|
|
|
|
Arguments:
|
|
|
|
NdisPortDesc- Pointer to a port descriptor
|
|
NumberOfPorts- Number of ports.
|
|
|
|
Return Value:
|
|
|
|
Number of packet descriptors to allocate
|
|
--*/
|
|
{
|
|
INT i;
|
|
INT noBindings = 0;
|
|
|
|
|
|
for (i = 0; i < NumberOfPorts; i++) {
|
|
if (NdisPortDesc[i].PortState == STATE_BOUND) {
|
|
noBindings++;
|
|
}
|
|
}
|
|
|
|
return(noBindings*PACKETDESCRIPTORS_PERPORT);
|
|
}
|
|
|
|
|
|
|
|
|
|
UINT
|
|
AtalkNdisGetNoBufferDescriptors(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns the number of buffer descriptors to allocate for this
|
|
protocol globally. It will determine some values based on number of ports
|
|
bound to.
|
|
|
|
Arguments:
|
|
|
|
NdisPortDesc- Pointer to a port descriptor
|
|
NumberOfPorts- Number of ports.
|
|
|
|
Return Value:
|
|
|
|
Number of buffer descriptors to allocate
|
|
--*/
|
|
{
|
|
INT i;
|
|
INT noBindings = 0;
|
|
|
|
|
|
for (i = 0; i < NumberOfPorts; i++) {
|
|
if (NdisPortDesc[i].PortState == STATE_BOUND) {
|
|
noBindings++;
|
|
}
|
|
}
|
|
|
|
return(noBindings*BUFFERDESCRIPTORS_PERPORT);
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
AtalkNdisInitializeResources(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called during initialization time to initialize any
|
|
Ndis resources for the bound macs. It will be aware enough to use
|
|
all information provided in the port descriptors to allocate proper
|
|
amount and type of resources. It will also allocate the global packet
|
|
and buffer descriptor pools.
|
|
|
|
Arguments:
|
|
|
|
NdisPortDesc- Pointer to a port descriptor
|
|
NumberOfPorts- Number of ports available
|
|
|
|
Return Value:
|
|
|
|
Status - STATUS_SUCCESS if all resources were allocated
|
|
STATUS_INSUFFICIENT_RESOURCES otherwise.
|
|
--*/
|
|
{
|
|
NDIS_STATUS ndisStatus;
|
|
INT portNumber;
|
|
|
|
//
|
|
// Setup the global ndis packet descriptor pools
|
|
//
|
|
|
|
NdisAllocatePacketPool(
|
|
&ndisStatus,
|
|
&AtalkNdisPacketPoolHandle,
|
|
AtalkNdisGetNoPacketDescriptors(NdisPortDesc, NumberOfPorts),
|
|
sizeof(PROTOCOL_RESD));
|
|
|
|
if ((ndisStatus != NDIS_STATUS_SUCCESS) &&
|
|
(ndisStatus != NDIS_STATUS_PENDING)) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
//
|
|
// Setup the global ndis buffer descriptor pools
|
|
//
|
|
|
|
NdisAllocateBufferPool(
|
|
&ndisStatus,
|
|
&AtalkNdisBufferPoolHandle,
|
|
AtalkNdisGetNoBufferDescriptors(NdisPortDesc, NumberOfPorts));
|
|
|
|
if ((ndisStatus != NDIS_STATUS_SUCCESS) &&
|
|
(ndisStatus != NDIS_STATUS_PENDING)) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
NdisFreePacketPool(AtalkNdisPacketPoolHandle);
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
for (portNumber = 0; portNumber < NumberOfPorts; portNumber++) {
|
|
if (NdisPortDesc[portNumber].PortState == STATE_BOUND) {
|
|
|
|
//
|
|
// Do all the work
|
|
//
|
|
|
|
NdisAllocateSpinLock(&NdisPortDesc[portNumber].ReceiveLock);
|
|
NdisAllocateSpinLock(&NdisPortDesc[portNumber].PerPortLock);
|
|
|
|
//
|
|
// Initialize the list heads
|
|
//
|
|
|
|
InitializeListHead(&NdisPortDesc[portNumber].ReceiveQueue);
|
|
}
|
|
}
|
|
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkNdisReleaseResources(
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc,
|
|
INT NumberOfPorts
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine releases all resources allocated during NdisAllocateResources.
|
|
|
|
Arguments:
|
|
|
|
NdisPortDesc- Pointer to a port descriptor
|
|
NumberOfPorts- Number of ports available
|
|
|
|
Return Value:
|
|
|
|
None
|
|
--*/
|
|
{
|
|
INT portNumber;
|
|
|
|
NdisFreePacketPool(AtalkNdisPacketPoolHandle);
|
|
NdisFreeBufferPool(AtalkNdisBufferPoolHandle);
|
|
|
|
for (portNumber = 0; portNumber < NumberOfPorts; portNumber++) {
|
|
if (NdisPortDesc[portNumber].PortState == STATE_BOUND) {
|
|
NdisFreeSpinLock(&NdisPortDesc[portNumber].ReceiveLock);
|
|
NdisFreeSpinLock(&NdisPortDesc[portNumber].PerPortLock);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Protocol/NDIS interaction code
|
|
//
|
|
|
|
VOID
|
|
AtalkOpenAdapterComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS Status,
|
|
IN NDIS_STATUS OpenErrorStatus
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called during by NDIS to indicate that an open adapter
|
|
is complete. This happens only during initialization and single-file. Clear
|
|
the event, so the blocked init thread can go on to the next adapter. Set the
|
|
status in the ndis port descriptor for this adapter.
|
|
|
|
Arguments:
|
|
|
|
NdisBindingContext- Pointer to a port descriptor for this port
|
|
Status- completion status of open adapter
|
|
OpenErrorStatus- Extra status information
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PNDIS_PORTDESCRIPTORS ndisPortDesc;
|
|
|
|
ndisPortDesc = (PNDIS_PORTDESCRIPTORS) NdisBindingContext;
|
|
ndisPortDesc->RequestStatus = Status;
|
|
|
|
KeSetEvent(
|
|
&ndisPortDesc->RequestEvent,
|
|
0L,
|
|
FALSE);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkCloseAdapterComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS Status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to indicate that a close adapter is complete.
|
|
|
|
Arguments:
|
|
|
|
NdisBindingContext- Pointer to a port descriptor for this port
|
|
Status- completion status of close adapter
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PNDIS_PORTDESCRIPTORS ndisPortDesc;
|
|
|
|
ndisPortDesc = (PNDIS_PORTDESCRIPTORS) NdisBindingContext;
|
|
ndisPortDesc->RequestStatus = Status;
|
|
|
|
ACQUIRE_SPIN_LOCK(&ndisPortDesc->PerPortLock);
|
|
ndisPortDesc->PortState == STATE_UNBOUND;
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->PerPortLock);
|
|
|
|
KeSetEvent(
|
|
&ndisPortDesc->RequestEvent,
|
|
0L,
|
|
FALSE);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkResetComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS Status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to indicate that a reset is complete.
|
|
|
|
Arguments:
|
|
|
|
NdisBindingContext- Pointer to a port descriptor for this port
|
|
Status- completion status of close adapter
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
|
|
PNDIS_PORTDESCRIPTORS ndisPortDesc;
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISREQ, DEBUG_LEVEL_ERROR,
|
|
("AtalkResetCOMPLETE called... TO BE IMPLEMENTED\n"));
|
|
|
|
ndisPortDesc = (PNDIS_PORTDESCRIPTORS) NdisBindingContext;
|
|
ndisPortDesc->RequestStatus = Status;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkRequestComplete(
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN PNDIS_REQUEST NdisRequest,
|
|
IN NDIS_STATUS Status
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to indicate that a NdisRequest is complete.
|
|
|
|
Arguments:
|
|
|
|
NdisBindingContext- Pointer to a port descriptor for this port
|
|
NdisRequest- Block identifying the request
|
|
Status- completion status of close adapter
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PNDIS_PORTDESCRIPTORS ndisPortDesc;
|
|
PATALK_NDIS_REQUEST atalkRequest;
|
|
|
|
ndisPortDesc = (PNDIS_PORTDESCRIPTORS) NdisBindingContext;
|
|
|
|
//
|
|
// Get the AtalkRequest block
|
|
//
|
|
|
|
atalkRequest = CONTAINING_RECORD(NdisRequest, ATALK_NDIS_REQUEST, Request);
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISREQ, DEBUG_LEVEL_INFOCLASS0,
|
|
("INFO0: AtalkRequestComplete - %lx status %lx ReqMet %d\n",
|
|
atalkRequest, Status, atalkRequest->RequestMethod));
|
|
|
|
switch (atalkRequest->RequestMethod) {
|
|
case SYNC:
|
|
|
|
//
|
|
// Set status and clear event
|
|
//
|
|
|
|
atalkRequest->RequestStatus = Status;
|
|
KeSetEvent(
|
|
&atalkRequest->RequestEvent,
|
|
0L,
|
|
FALSE);
|
|
|
|
break;
|
|
|
|
case ASYNC :
|
|
|
|
//
|
|
// Call the completion routine if specified
|
|
//
|
|
|
|
if (atalkRequest->CompletionRoutine != NULL) {
|
|
(*atalkRequest->CompletionRoutine)(
|
|
Status,
|
|
atalkRequest->CompletionContext);
|
|
}
|
|
|
|
//
|
|
// Dereference the request
|
|
//
|
|
|
|
AtalkDereferenceNdisRequest ("RequestComplete", atalkRequest, NREF_MAKEREQ);
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkStatusIndication (
|
|
IN NDIS_HANDLE NdisBindingContext,
|
|
IN NDIS_STATUS GeneralStatus,
|
|
IN PVOID StatusBuffer,
|
|
IN UINT StatusBufferLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to indicate a status change.
|
|
|
|
Arguments:
|
|
|
|
NdisBindingContext- Pointer to a port descriptor for this port
|
|
GeneralStatus- A general status value
|
|
StatusBuffer - A more specific status value
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
DBGPRINT(ATALK_DEBUG_NDISREQ, DEBUG_LEVEL_IMPOSSIBLE,
|
|
("ERROR: Status indication called %lx\n", GeneralStatus));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkStatusComplete (
|
|
IN NDIS_HANDLE ProtocolBindingContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to allow postprocessing after a status event.
|
|
|
|
Arguments:
|
|
|
|
ProtocolBindingContext- Value associated with the binding with the adapter
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
DBGPRINT(ATALK_DEBUG_NDISREQ, DEBUG_LEVEL_IMPOSSIBLE,
|
|
("ERROR: Status complete called\n"));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
PINFO_BUFFER
|
|
AtalkNdisAllocateInfoBuffer(VOID)
|
|
{
|
|
return((PINFO_BUFFER)AtalkAllocNonPagedMemory(sizeof(INFO_BUFFER)));
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
AtalkNdisFreeInfoBuffer(
|
|
PINFO_BUFFER InfoBuffer
|
|
)
|
|
{
|
|
AtalkFreeNonPagedMemory(InfoBuffer);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkReceiveComplete (
|
|
IN NDIS_HANDLE BindingContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to allow postprocessing after receive indications
|
|
This routine will directly call DdpPacketIn.
|
|
|
|
Arguments:
|
|
|
|
BindingContext- Pointer to a port descriptor for this port
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PNDIS_PORTDESCRIPTORS ndisPortDesc;
|
|
PPROTOCOL_RESD protocolResd;
|
|
PNDIS_PACKET ndisPacket;
|
|
PNDIS_BUFFER ndisBuffer;
|
|
UINT ndisBufferCount;
|
|
PLIST_ENTRY p;
|
|
|
|
PCHAR packet = NULL;
|
|
UINT packetLength = 0;
|
|
|
|
PINFO_BUFFER infoBuffer;
|
|
|
|
ndisPortDesc = (PNDIS_PORTDESCRIPTORS)BindingContext;
|
|
|
|
//
|
|
// Get the stuff off the receive queue for the port and send it up
|
|
//
|
|
|
|
while (TRUE) {
|
|
|
|
PACKET_TYPE packetType;
|
|
|
|
ACQUIRE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
|
|
//
|
|
// Check if the first queued receive is done processing. If not,
|
|
// then return, there should be one more ReceiveComplete coming
|
|
// our ways since a pending TransferData is implied by that condition.
|
|
//
|
|
|
|
p = ndisPortDesc->ReceiveQueue.Flink;
|
|
if (p == &ndisPortDesc->ReceiveQueue) {
|
|
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
break;
|
|
}
|
|
|
|
ndisPacket = CONTAINING_RECORD(p, NDIS_PACKET, ProtocolReserved);
|
|
protocolResd = (PPROTOCOL_RESD)ndisPacket->ProtocolReserved;
|
|
if (protocolResd->Receive.ReceiveState != RECEIVE_STATE_PROCESSED) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISREQ, DEBUG_LEVEL_WARNING,
|
|
("WARNING: AtalkReceiveComplete - First packet processing!\n"));
|
|
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Dequeue this received packet and indicate it to the ddp layer
|
|
//
|
|
|
|
p = RemoveHeadList(&ndisPortDesc->ReceiveQueue);
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
|
|
|
|
//
|
|
// IMPORTANT:
|
|
// We know that the buffer is virtually contiguous since we allocated
|
|
// it. And we also know that only one buffer is allocated. So we use
|
|
// that knowledge to get the actual address and pass that onto the
|
|
// higher level routines.
|
|
//
|
|
|
|
NdisQueryPacket(
|
|
ndisPacket,
|
|
NULL,
|
|
&ndisBufferCount,
|
|
&ndisBuffer,
|
|
NULL
|
|
);
|
|
|
|
ASSERT((ndisBufferCount == 0) || (ndisBufferCount == 1));
|
|
|
|
if (ndisBufferCount == 1) {
|
|
NdisQueryBuffer(
|
|
ndisBuffer,
|
|
(PVOID *)&packet,
|
|
&packetLength);
|
|
}
|
|
|
|
infoBuffer = protocolResd->Receive.InfoBuffer;
|
|
ASSERT(infoBuffer != NULL);
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Received Packet %lx Length %lx\n",
|
|
packet, packetLength));
|
|
|
|
//
|
|
// Check the receive status- accept only if ok
|
|
//
|
|
|
|
if (protocolResd->Receive.ReceiveStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_ERROR,
|
|
("ERROR: AtalkReceiveComplete - ReceiveStatus FAILURE %lx!\n",
|
|
protocolResd->Receive.ReceiveStatus ));
|
|
|
|
AtalkNdisFreeInfoBuffer(infoBuffer);
|
|
AtalkDestroyNdisPacket(ndisPacket);
|
|
AtalkFreeNonPagedMemory(packet);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Free up the packet descriptor before indicating the packet to
|
|
// the higher levels
|
|
//
|
|
|
|
packetType = protocolResd->Receive.PacketType;
|
|
|
|
// Free up the ndis packet and any chained buffers
|
|
AtalkDestroyNdisPacket(ndisPacket);
|
|
|
|
switch (ndisPortDesc->NdisPortType) {
|
|
case NdisMedium802_3 :
|
|
|
|
if (packetType == APPLETALK_PACKET) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Indicating DDP Ethernet "));
|
|
|
|
DdpPacketIn(
|
|
ndisPortDesc->PortNumber,
|
|
infoBuffer->DdpHeader,
|
|
infoBuffer->DdpHeaderLength,
|
|
packet,
|
|
(INT)packetLength,
|
|
TRUE,
|
|
TRUE,
|
|
0,
|
|
0);
|
|
|
|
} else {
|
|
|
|
//
|
|
// AARP Packet
|
|
//
|
|
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Indicating AARP Ethernet "));
|
|
|
|
AarpPacketIn(
|
|
ndisPortDesc->PortNumber,
|
|
NULL,
|
|
0,
|
|
infoBuffer->AarpPacket,
|
|
infoBuffer->AarpPacketLength);
|
|
}
|
|
|
|
break;
|
|
|
|
case NdisMediumFddi :
|
|
|
|
if (packetType == APPLETALK_PACKET) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Indicating DDP fddi "));
|
|
|
|
DdpPacketIn(
|
|
ndisPortDesc->PortNumber,
|
|
infoBuffer->DdpHeader,
|
|
infoBuffer->DdpHeaderLength,
|
|
packet,
|
|
(INT)packetLength,
|
|
TRUE,
|
|
TRUE,
|
|
0,
|
|
0);
|
|
|
|
} else {
|
|
|
|
//
|
|
// AARP Packet
|
|
//
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Indicating AARP fddi "));
|
|
|
|
AarpPacketIn(
|
|
ndisPortDesc->PortNumber,
|
|
NULL,
|
|
0,
|
|
infoBuffer->AarpPacket,
|
|
infoBuffer->AarpPacketLength);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NdisMedium802_5 :
|
|
|
|
if (packetType == APPLETALK_PACKET) {
|
|
|
|
DdpPacketIn(
|
|
ndisPortDesc->PortNumber,
|
|
infoBuffer->DdpHeader,
|
|
infoBuffer->DdpHeaderLength,
|
|
packet,
|
|
(INT)packetLength,
|
|
TRUE,
|
|
TRUE,
|
|
0,
|
|
0);
|
|
|
|
} else {
|
|
|
|
//
|
|
// AARP Packet
|
|
//
|
|
|
|
AarpPacketIn(
|
|
ndisPortDesc->PortNumber,
|
|
infoBuffer->RoutingInfo,
|
|
infoBuffer->RoutingInfoLength,
|
|
infoBuffer->AarpPacket,
|
|
infoBuffer->AarpPacketLength);
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case NdisMediumLocalTalk :
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Localtalk Packet Received!\n"));
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Source %lx Dest %lx LlapType %lx\n",
|
|
infoBuffer->SourceNode,
|
|
infoBuffer->DestinationNode,
|
|
infoBuffer->LlapType));
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_TEMP_DEBUG,
|
|
("TDBG: AtalkReceiveComplete - Packet %lx Length %lx\n",
|
|
packet, packetLength));
|
|
|
|
if (packetType == APPLETALK_PACKET) {
|
|
|
|
//
|
|
// BUGBUG: Set the alap constants to have UCHAR casts
|
|
//
|
|
|
|
DdpPacketIn(
|
|
ndisPortDesc->PortNumber,
|
|
infoBuffer->DdpHeader,
|
|
infoBuffer->DdpHeaderLength,
|
|
packet,
|
|
(INT)packetLength,
|
|
TRUE,
|
|
(BOOLEAN)(infoBuffer->LlapType == ALAP_LONGDDPHEADERTYPE),
|
|
(INT)infoBuffer->SourceNode,
|
|
(INT)infoBuffer->DestinationNode);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
AtalkNdisFreeInfoBuffer(infoBuffer);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkTransferDataComplete(
|
|
IN NDIS_HANDLE BindingContext,
|
|
IN PNDIS_PACKET NdisPacket,
|
|
IN NDIS_STATUS Status,
|
|
IN UINT BytesTransferred
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to indicate completion of a TransferData
|
|
|
|
Arguments:
|
|
|
|
BindingContext- Pointer to a port descriptor for this port
|
|
NdisPacket- Ndis packet into which data was transferred
|
|
Status- Status of request
|
|
bytesTransferred- Actual number of bytes transferred
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PNDIS_PORTDESCRIPTORS ndisPortDesc;
|
|
PPROTOCOL_RESD protocolResd;
|
|
|
|
ndisPortDesc = (PNDIS_PORTDESCRIPTORS)BindingContext;
|
|
protocolResd = (PPROTOCOL_RESD)&NdisPacket->ProtocolReserved;
|
|
|
|
ACQUIRE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
protocolResd->Receive.ReceiveState = RECEIVE_STATE_PROCESSED;
|
|
protocolResd->Receive.ReceiveStatus = Status;
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
#define RECEIVEIND_PACKET 0x0001
|
|
#define RECEIVEIND_NDISBUFFER 0x0002
|
|
#define RECEIVEIND_NDISPACKET 0x0004
|
|
#define RECEIVEIND_INFOBUFFER 0x0008
|
|
|
|
NDIS_STATUS
|
|
AtalkReceiveIndication(
|
|
IN NDIS_HANDLE BindingContext,
|
|
IN NDIS_HANDLE ReceiveContext,
|
|
IN PVOID HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PVOID LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by NDIS to indicate a receive
|
|
|
|
Arguments:
|
|
|
|
BindingContext- Pointer to a port descriptor for this port
|
|
ReceiveContext- To be used in a transfer data if necessary
|
|
LookaheadBuffer- buffer with lookahead data
|
|
LookaheadBufferSize- Size of the above buffer
|
|
PacketSize- Size of whole packet
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS- Packet accepted
|
|
STATUS_NOT_RECOGNIZED- Not our packet
|
|
Other
|
|
|
|
--*/
|
|
{
|
|
PNDIS_PACKET ndisPacket;
|
|
PNDIS_BUFFER ndisBuffer;
|
|
PINFO_BUFFER infoBuffer;
|
|
|
|
PCHAR packet; // Where we will copy the packet
|
|
PPROTOCOL_RESD protocolResd; // Protocolresd field in ndisPacket
|
|
|
|
UINT actualPacketSize; // Size of data to copy
|
|
UINT xferDataOffset; // Offset in lookahead from where to copy
|
|
UINT bytesTransferred; // Number of bytes transferred in XferData
|
|
UINT routingInfoLength; // length of routing info if present (802.5)
|
|
|
|
PNDIS_PORTDESCRIPTORS ndisPortDesc;
|
|
UCHAR llapType; // For localtalk only
|
|
|
|
ULONG resources = 0;
|
|
NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
|
|
PACKET_TYPE packetType = UNKNOWN_PACKET;
|
|
|
|
PUCHAR headerBuffer = (PUCHAR)HeaderBuffer;
|
|
PUCHAR lookaheadBuffer = (PUCHAR)lookaheadBuffer;
|
|
|
|
//
|
|
// Receive algorithm
|
|
//
|
|
// Grab the port spinlock
|
|
// For each port type, verify if packet is to be accepted,
|
|
// if yes, then allocate ndis packet,
|
|
// set state to being processed
|
|
// put in queue
|
|
// if no, release spinlock return;
|
|
// release spin lock
|
|
//
|
|
// Go ahead with allocating the memory etc.,
|
|
// and starting off the transferData call.
|
|
//
|
|
// if status_pending on xfer data, return;
|
|
// else grap port spinlock- set flag in receivestate to done.
|
|
//
|
|
// do actual indication to portable stack in a receivedone routine.
|
|
//
|
|
// IMPORTANT:
|
|
// It is possible that the MAC can make multiple receive indications
|
|
// sequentially for the packets received. To minimize mis-ordering on
|
|
// our part due to blocked indication threads, this routine is shielded
|
|
// by a spinlock. This does not eliminate mis-ordering as the indication
|
|
// thread could block even before the spinlock is acquired. So the higher
|
|
// level protocols will deal with that case
|
|
//
|
|
|
|
ndisPortDesc = (PNDIS_PORTDESCRIPTORS)BindingContext;
|
|
|
|
ACQUIRE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
|
|
switch (ndisPortDesc->NdisPortType) {
|
|
case NdisMedium802_3:
|
|
|
|
if (AtalkNdisAcceptEthernetPacket(
|
|
headerBuffer,
|
|
HeaderBufferSize,
|
|
lookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
PacketSize,
|
|
&packetType,
|
|
ndisPortDesc)) {
|
|
|
|
actualPacketSize = PacketSize;
|
|
if (packetType == APPLETALK_PACKET) {
|
|
actualPacketSize -= IEEE8022_HEADERLENGTH;
|
|
lookaheadBuffer += IEEE8022_HEADERLENGTH;
|
|
}
|
|
|
|
} else {
|
|
|
|
ndisStatus = NDIS_STATUS_NOT_RECOGNIZED;
|
|
}
|
|
|
|
break;
|
|
|
|
case NdisMediumFddi:
|
|
|
|
if (AtalkNdisAcceptFddiPacket(
|
|
headerBuffer,
|
|
HeaderBufferSize,
|
|
lookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
PacketSize,
|
|
&packetType,
|
|
ndisPortDesc)) {
|
|
|
|
actualPacketSize = PacketSize;
|
|
if (packetType == APPLETALK_PACKET) {
|
|
actualPacketSize -= IEEE8022_HEADERLENGTH;
|
|
lookaheadBuffer += IEEE8022_HEADERLENGTH;
|
|
}
|
|
|
|
} else {
|
|
|
|
ndisStatus = NDIS_STATUS_NOT_RECOGNIZED;
|
|
}
|
|
|
|
break;
|
|
|
|
case NdisMedium802_5:
|
|
|
|
if (AtalkNdisAcceptTokenringPacket(
|
|
headerBuffer,
|
|
HeaderBufferSize,
|
|
lookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
PacketSize,
|
|
&packetType,
|
|
ndisPortDesc)) {
|
|
|
|
actualPacketSize = PacketSize;
|
|
if (packetType == APPLETALK_PACKET) {
|
|
actualPacketSize -= IEEE8022_HEADERLENGTH;
|
|
lookaheadBuffer += IEEE8022_HEADERLENGTH;
|
|
}
|
|
|
|
} else {
|
|
|
|
ndisStatus = NDIS_STATUS_NOT_RECOGNIZED;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case NdisMediumLocalTalk:
|
|
|
|
|
|
if (AtalkNdisAcceptLocaltalkPacket(
|
|
headerBuffer,
|
|
HeaderBufferSize,
|
|
lookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
PacketSize,
|
|
&packetType,
|
|
&llapType,
|
|
ndisPortDesc)) {
|
|
|
|
// No 802.2 header on localtalk
|
|
actualPacketSize = PacketSize;
|
|
|
|
} else {
|
|
|
|
ndisStatus = NDIS_STATUS_NOT_RECOGNIZED;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
//
|
|
// Should never happen!
|
|
//
|
|
|
|
KeBugCheck(0);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// For AARP packets, we expect the whole packet to be in the
|
|
// lookahead data! It could be less, as we might have adjusted
|
|
// for any padding on ethernet/fddi
|
|
//
|
|
|
|
if ((packetType == AARP_PACKET) &&
|
|
(actualPacketSize > LookaheadBufferSize)) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_AARPPACKET,
|
|
(__ATKNPRO__ | __LINE__),
|
|
actualPacketSize,
|
|
HeaderBuffer,
|
|
HeaderBufferSize,
|
|
1,
|
|
&ndisPortDesc->AdapterName);
|
|
|
|
ndisStatus = NDIS_STATUS_NOT_RECOGNIZED;
|
|
}
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
return(ndisStatus);
|
|
}
|
|
|
|
do {
|
|
|
|
//
|
|
// Packet is to be accepted!
|
|
// Allocate an NDIS packet descriptor from the global packet pool
|
|
//
|
|
|
|
NdisAllocatePacket(
|
|
&ndisStatus,
|
|
&ndisPacket,
|
|
AtalkNdisPacketPoolHandle);
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Store the information needed in the packet descriptor
|
|
//
|
|
|
|
protocolResd = (PPROTOCOL_RESD)&ndisPacket->ProtocolReserved;
|
|
protocolResd->Receive.Port = ndisPortDesc->PortNumber;
|
|
protocolResd->Receive.PacketType = packetType;
|
|
protocolResd->Receive.ReceiveState = RECEIVE_STATE_PROCESSING;
|
|
|
|
//
|
|
// Queue up the packet in the receive queue on this port
|
|
// Release the spinlock
|
|
// Then, go ahead with the transfer data etc.
|
|
//
|
|
// NOTE:
|
|
// NdisAllocatePacket ZEROES out the protocol reserved area. We depend
|
|
// on that and don't initialize ReceiveEntry.
|
|
//
|
|
|
|
InsertTailList(
|
|
&ndisPortDesc->ReceiveQueue,
|
|
&protocolResd->Receive.ReceiveEntry);
|
|
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
|
|
resources |= RECEIVEIND_NDISPACKET;
|
|
|
|
//
|
|
// Now allocate the INFO_BUFFER
|
|
//
|
|
|
|
infoBuffer = AtalkNdisAllocateInfoBuffer();
|
|
if (infoBuffer == NULL) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_MEMORYRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
STATUS_INSUFFICIENT_RESOURCES,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
break;
|
|
}
|
|
protocolResd->Receive.InfoBuffer = infoBuffer;
|
|
resources |= RECEIVEIND_INFOBUFFER;
|
|
|
|
|
|
//
|
|
// AT THIS POINT:
|
|
// Spinlock is released, and the packet is to be accepted. We need to
|
|
// Copy/TransferData the packet into our buffer and then leave the
|
|
// major work for the ReceiveComplete indication
|
|
//
|
|
// We first need the ddp header for Appletalk packets for tokenring,
|
|
// ethernet and fddi. we copy the routing info for aarp packets for
|
|
// tokenring, and we copy the localtalk info for ltalk.
|
|
//
|
|
|
|
|
|
if (packetType == APPLETALK_PACKET) {
|
|
|
|
switch (ndisPortDesc->NdisPortType) {
|
|
case NdisMedium802_3:
|
|
case NdisMedium802_5:
|
|
case NdisMediumFddi :
|
|
|
|
// Copy the ddp header
|
|
RtlMoveMemory(
|
|
infoBuffer->DdpHeader,
|
|
lookaheadBuffer,
|
|
LONGDDP_HEADERLENGTH);
|
|
|
|
infoBuffer->DdpHeaderLength = LONGDDP_HEADERLENGTH;
|
|
actualPacketSize -= LONGDDP_HEADERLENGTH;
|
|
lookaheadBuffer += LONGDDP_HEADERLENGTH;
|
|
xferDataOffset = IEEE8022_HEADERLENGTH+LONGDDP_HEADERLENGTH;
|
|
break;
|
|
|
|
case NdisMediumLocalTalk:
|
|
|
|
//
|
|
// For localtalk we check the llap type to determine if the packet
|
|
// has a long or a short form header
|
|
//
|
|
|
|
if (llapType == DDP_EXTENDEDFORMHEADER) {
|
|
|
|
// Copy the ddp header
|
|
RtlMoveMemory(
|
|
infoBuffer->DdpHeader,
|
|
lookaheadBuffer,
|
|
LONGDDP_HEADERLENGTH);
|
|
|
|
infoBuffer->DdpHeaderLength = SHORTDDP_HEADERLENGTH;
|
|
actualPacketSize -= LONGDDP_HEADERLENGTH;
|
|
lookaheadBuffer += LONGDDP_HEADERLENGTH;
|
|
xferDataOffset = IEEE8022_HEADERLENGTH+LONGDDP_HEADERLENGTH;
|
|
|
|
} else {
|
|
|
|
// Copy the ddp header
|
|
RtlMoveMemory(
|
|
infoBuffer->DdpHeader,
|
|
lookaheadBuffer,
|
|
SHORTDDP_HEADERLENGTH);
|
|
|
|
infoBuffer->DdpHeaderLength = SHORTDDP_HEADERLENGTH;
|
|
actualPacketSize -= SHORTDDP_HEADERLENGTH;
|
|
lookaheadBuffer += SHORTDDP_HEADERLENGTH;
|
|
xferDataOffset = IEEE8022_HEADERLENGTH+SHORTDDP_HEADERLENGTH;
|
|
}
|
|
|
|
infoBuffer->DestinationNode = *(headerBuffer+ALAP_DESTINATIONOFFSET);
|
|
infoBuffer->SourceNode = *(headerBuffer + ALAP_SOURCEOFFSET);
|
|
infoBuffer->LlapType = llapType;
|
|
break;
|
|
|
|
default:
|
|
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
|
|
//
|
|
// Allocate space for the packet excluding the link & 802.2 header
|
|
// and the ddp header. actualPacketSize will have been adjusted for all
|
|
// of the above. !!!!!It could now also be 0!!!!!
|
|
//
|
|
// If complete packet in lookahead, make a copy and queue else
|
|
// call Transfer data
|
|
//
|
|
|
|
ASSERT(actualPacketSize >= 0);
|
|
|
|
if (actualPacketSize > 0) {
|
|
|
|
packet = (PCHAR)AtalkAllocNonPagedMemory(actualPacketSize);
|
|
if (packet == NULL) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_MEMORYRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
STATUS_INSUFFICIENT_RESOURCES,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
ndisStatus = NDIS_STATUS_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
resources |= RECEIVEIND_PACKET;
|
|
|
|
//
|
|
// Make a NDIS buffer descriptor for this data
|
|
//
|
|
|
|
NdisAllocateBuffer(
|
|
&ndisStatus,
|
|
&ndisBuffer,
|
|
AtalkNdisBufferPoolHandle,
|
|
(PVOID)packet,
|
|
(UINT)actualPacketSize);
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
ndisStatus = NDIS_STATUS_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
resources |= RECEIVEIND_NDISBUFFER;
|
|
|
|
//
|
|
// Link the buffer descriptor into the packet descriptor
|
|
//
|
|
|
|
NdisChainBufferAtBack(
|
|
ndisPacket,
|
|
ndisBuffer);
|
|
|
|
|
|
if (PacketSize <= LookaheadBufferSize) {
|
|
|
|
//
|
|
// Copy the data into the buffer we allocated, make an ndis
|
|
// buffer descriptor to describe it and then queue the packet
|
|
// into the receive queue for this port
|
|
//
|
|
|
|
RtlMoveMemory(
|
|
packet,
|
|
lookaheadBuffer,
|
|
actualPacketSize);
|
|
|
|
AtalkTransferDataComplete(
|
|
BindingContext,
|
|
ndisPacket,
|
|
NDIS_STATUS_SUCCESS,
|
|
actualPacketSize);
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Need to do TransferData
|
|
//
|
|
|
|
NdisTransferData(
|
|
&ndisStatus,
|
|
ndisPortDesc->NdisBindingHandle,
|
|
ReceiveContext,
|
|
xferDataOffset,
|
|
actualPacketSize,
|
|
ndisPacket,
|
|
&bytesTransferred);
|
|
|
|
|
|
if (ndisStatus == NDIS_STATUS_PENDING) {
|
|
|
|
ndisStatus = NDIS_STATUS_SUCCESS;
|
|
break;
|
|
|
|
} else if (ndisStatus == NDIS_STATUS_SUCCESS) {
|
|
|
|
//
|
|
// Transfer data completed, call the transfer data completion
|
|
// routine to do rest of the work
|
|
//
|
|
|
|
|
|
AtalkTransferDataComplete(
|
|
BindingContext,
|
|
ndisPacket,
|
|
ndisStatus,
|
|
bytesTransferred);
|
|
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
ndisStatus = NDIS_STATUS_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
} else {
|
|
|
|
// Packet contains 0 data bytes. Just call TransferData
|
|
AtalkTransferDataComplete(
|
|
BindingContext,
|
|
ndisPacket,
|
|
ndisStatus,
|
|
0); // bytesTransferred
|
|
}
|
|
|
|
} else { // AARP Packet
|
|
|
|
switch (ndisPortDesc->NdisPortType) {
|
|
case NdisMedium802_5:
|
|
|
|
// Copy the routing info
|
|
if (routingInfoLength > 0) {
|
|
RtlMoveMemory(
|
|
infoBuffer->RoutingInfo,
|
|
headerBuffer+TOKRING_ROUTINGINFOOFFSET,
|
|
routingInfoLength);
|
|
}
|
|
|
|
infoBuffer->RoutingInfoLength = routingInfoLength;
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Now just copy the aarp packet from lookahead into the
|
|
// aarp data part of the infobuffer
|
|
//
|
|
|
|
RtlMoveMemory(
|
|
infoBuffer->AarpPacket,
|
|
lookaheadBuffer,
|
|
actualPacketSize);
|
|
|
|
AtalkTransferDataComplete(
|
|
BindingContext,
|
|
ndisPacket,
|
|
NDIS_STATUS_SUCCESS,
|
|
actualPacketSize);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// In case of failures, we need to deallocate the resources
|
|
//
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISRECEIVE, DEBUG_LEVEL_ERROR,
|
|
("ERROR: AtalkReceiveIndication- FAILURE %lx\n", ndisStatus));
|
|
|
|
// Free up the allocated resources
|
|
if (resources & RECEIVEIND_INFOBUFFER) {
|
|
AtalkNdisFreeInfoBuffer(infoBuffer);
|
|
}
|
|
|
|
// If this is true, then ndis packet is queued in already
|
|
if (resources & RECEIVEIND_NDISPACKET) {
|
|
|
|
// Dequeue the packet and free it, this should free ndis buffers also
|
|
ACQUIRE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
RemoveEntryList(&protocolResd->Receive.ReceiveEntry);
|
|
RELEASE_SPIN_LOCK(&ndisPortDesc->ReceiveLock);
|
|
|
|
AtalkDestroyNdisPacket(ndisPacket);
|
|
}
|
|
|
|
if (resources & RECEIVEIND_PACKET) {
|
|
AtalkFreeNonPagedMemory(packet);
|
|
}
|
|
}
|
|
|
|
return(ndisStatus);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
AtalkNdisPacketOut(
|
|
int Port,
|
|
BufferDescriptor Chain,
|
|
int Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to send a packet out on
|
|
ethernet. It will build the NDIS packet descriptor for the passed in
|
|
chain and then send the packet on the specified port.
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter on which to send
|
|
Chain- The portable stacks buffer descriptor chain
|
|
Length- The length to send from chain
|
|
|
|
Return Value:
|
|
|
|
TRUE- If sent/pending, FALSE otherwise
|
|
TransmitComplete is called if this call pended by completion code
|
|
|
|
--*/
|
|
{
|
|
PNDIS_PACKET ndisPacket;
|
|
PNDIS_BUFFER ndisBuffer;
|
|
NDIS_STATUS ndisStatus;
|
|
PPROTOCOL_RESD protocolResd;
|
|
INT currentSizeOfData = 0;
|
|
|
|
BufferDescriptor currentDescriptor;
|
|
|
|
//
|
|
// Allocate an NDIS packet descriptor from the global packet pool
|
|
//
|
|
|
|
NdisAllocatePacket(
|
|
&ndisStatus,
|
|
&ndisPacket,
|
|
AtalkNdisPacketPoolHandle);
|
|
|
|
if (ndisStatus == NDIS_STATUS_SUCCESS) {
|
|
|
|
//
|
|
// Store the information needed in the packet descriptor
|
|
//
|
|
|
|
protocolResd = (PPROTOCOL_RESD)&ndisPacket->ProtocolReserved;
|
|
protocolResd->Send.Port = Port;
|
|
protocolResd->Send.Chain = Chain;
|
|
|
|
for ( currentDescriptor = Chain;
|
|
currentDescriptor != NULL;
|
|
currentDescriptor = currentDescriptor->next) {
|
|
|
|
//
|
|
// First get the onBoard data, as that is always to be prepended to
|
|
// the outBoard data
|
|
//
|
|
|
|
if (currentDescriptor->onBoardDataValid) {
|
|
|
|
//
|
|
// Make a NDIS buffer descriptor for this data
|
|
// This assumes that the buffer descriptor was allocated using
|
|
// one of our allocate routines, and so is in the non-paged pool.
|
|
//
|
|
|
|
currentSizeOfData = MIN(currentDescriptor->onBoardSize, Length);
|
|
|
|
if (currentSizeOfData > 0) {
|
|
|
|
NdisAllocateBuffer(
|
|
&ndisStatus,
|
|
&ndisBuffer,
|
|
AtalkNdisBufferPoolHandle,
|
|
(PVOID)currentDescriptor->onBoardData,
|
|
(UINT)currentSizeOfData);
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Link the buffer descriptor into the packet descriptor
|
|
//
|
|
|
|
NdisChainBufferAtBack(
|
|
ndisPacket,
|
|
ndisBuffer);
|
|
|
|
Length -= currentSizeOfData;
|
|
if (Length == 0) {
|
|
|
|
//
|
|
// Done with all the data that we need to get
|
|
// Both onBoard and outBoard
|
|
//
|
|
|
|
//
|
|
// Better not be another null buffer descriptor attached
|
|
//
|
|
|
|
ASSERT(currentDescriptor->next == NULL);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check for outboard data- could be char * or an MDL
|
|
//
|
|
|
|
if (currentDescriptor->outBoardDataValid) {
|
|
|
|
currentSizeOfData = MIN(currentDescriptor->outBoardSize, Length);
|
|
if (currentSizeOfData > 0) {
|
|
if (currentDescriptor->opaqueData) {
|
|
|
|
//
|
|
// It is an MDL
|
|
//
|
|
|
|
NdisCopyBuffer(
|
|
&ndisStatus,
|
|
&ndisBuffer,
|
|
AtalkNdisBufferPoolHandle,
|
|
(PVOID)currentDescriptor->outBoardData,
|
|
0, //offset
|
|
(UINT)currentSizeOfData);
|
|
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
//
|
|
// Cleanup
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
} else {
|
|
|
|
NdisAllocateBuffer(
|
|
&ndisStatus,
|
|
&ndisBuffer,
|
|
AtalkNdisBufferPoolHandle,
|
|
(PVOID)currentDescriptor->outBoardData,
|
|
(UINT)currentSizeOfData);
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
NdisChainBufferAtBack(
|
|
ndisPacket,
|
|
ndisBuffer);
|
|
}
|
|
|
|
Length -= currentSizeOfData;
|
|
if (Length == 0) {
|
|
|
|
//
|
|
// Done with all the data that we need to get
|
|
//
|
|
//
|
|
// Better not be another null buffer descriptor attached
|
|
//
|
|
|
|
ASSERT(currentDescriptor->next == NULL);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ndisStatus == NDIS_STATUS_SUCCESS) {
|
|
|
|
if (Length > 0) {
|
|
DBGPRINT(ATALK_DEBUG_NDISSEND, DEBUG_LEVEL_IMPOSSIBLE,
|
|
("IMPOS: AtalkNdisSend - Length greater than data available %d\n",
|
|
Length));
|
|
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
//
|
|
// Now send the built packet descriptor
|
|
//
|
|
|
|
|
|
NdisSend(
|
|
&ndisStatus,
|
|
NdisPortDesc[Port].NdisBindingHandle,
|
|
ndisPacket);
|
|
|
|
if (ndisStatus == NDIS_STATUS_PENDING) {
|
|
ndisStatus = NDIS_STATUS_SUCCESS;
|
|
} else if (ndisStatus == NDIS_STATUS_SUCCESS) {
|
|
|
|
//
|
|
// Call the completion handler
|
|
//
|
|
|
|
AtalkSendCompletionHandler(
|
|
NdisPortDesc[Port].NdisBindingHandle,
|
|
ndisPacket,
|
|
NDIS_STATUS_SUCCESS);
|
|
|
|
}
|
|
}
|
|
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
|
|
DBGPRINT(ATALK_DEBUG_NDISSEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: AtalkNdisSend - stat %lx ndisPkt %lx Chain %lx Length %lx\n",
|
|
ndisStatus, ndisPacket, Chain, Length));
|
|
|
|
// Free up the packet
|
|
AtalkDestroyNdisPacket(ndisPacket);
|
|
}
|
|
} else {
|
|
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_NDISRESOURCES,
|
|
(__ATKNPRO__ | __LINE__),
|
|
ndisStatus,
|
|
NULL,
|
|
0,
|
|
0,
|
|
NULL);
|
|
}
|
|
|
|
return(ndisStatus == NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkSendCompletionHandler(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN PNDIS_PACKET NdisPacket,
|
|
IN NDIS_STATUS NdisStatus
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called when an aarp packet is received. The whole packet
|
|
must fit in the lookahead buffer
|
|
|
|
Arguments:
|
|
|
|
ProtocolBindingContext- Binding associated with mac
|
|
NdisPacket- Packet which was sent
|
|
NdisStatus- Final status of send
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PPROTOCOL_RESD protocolResd;
|
|
|
|
//
|
|
// Call the completion routine, we don't care about status now
|
|
//
|
|
|
|
protocolResd = (PPROTOCOL_RESD)&(NdisPacket->ProtocolReserved);
|
|
|
|
ASSERT(protocolResd != NULL);
|
|
|
|
NTTransmitComplete(protocolResd->Send.Chain);
|
|
|
|
//
|
|
// Free the packet
|
|
//
|
|
|
|
AtalkDestroyNdisPacket(NdisPacket);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
AtalkDestroyNdisPacket(
|
|
IN PNDIS_PACKET NdisPacket
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called to release a ndis packet
|
|
|
|
Arguments:
|
|
|
|
NdisPacket- Packet and associated buffer descriptors to be freed
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PNDIS_BUFFER freeBuffer, nextBuffer;
|
|
UINT bufferCount;
|
|
|
|
NdisQueryPacket(
|
|
NdisPacket,
|
|
NULL,
|
|
&bufferCount,
|
|
&freeBuffer,
|
|
NULL);
|
|
|
|
while (freeBuffer != NULL) {
|
|
NdisGetNextBuffer(freeBuffer, &nextBuffer);
|
|
NdisFreeBuffer(freeBuffer);
|
|
freeBuffer = nextBuffer;
|
|
}
|
|
|
|
//
|
|
// Now free the packet itself
|
|
//
|
|
|
|
NdisFreePacket(NdisPacket);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptEthernetPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc
|
|
)
|
|
{
|
|
BOOLEAN accept = TRUE;
|
|
UINT ddpLength; // Length of packet from ddp header
|
|
UINT aarpDataLength; // Check aarp data length
|
|
|
|
do {
|
|
|
|
//
|
|
// Check length for atleast the minimum amount of space
|
|
// Also, Check if the 802.2 header is ok
|
|
//
|
|
|
|
if ( (LookaheadBufferSize <
|
|
(IEEE8022_PROTOCOLOFFSET+IEEE8022_PROTOCOLTYPELENGTH))
|
|
|
|
||
|
|
|
|
((*(LookaheadBuffer + IEEE8022_DSAPOFFSET) != SNAP_SAP) ||
|
|
(*(LookaheadBuffer + IEEE8022_SSAPOFFSET) != SNAP_SAP) ||
|
|
(*(LookaheadBuffer + IEEE8022_CONTROLOFFSET) !=
|
|
UNNUMBEREDINFORMATION)) ) {
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (RtlCompareMemory(LookaheadBuffer+IEEE8022_PROTOCOLOFFSET,
|
|
appleTalkProtocolType,
|
|
IEEE8022_PROTOCOLTYPELENGTH) ==
|
|
IEEE8022_PROTOCOLTYPELENGTH) {
|
|
|
|
//
|
|
// Use GleanAarpInfo to determine whether or not we accept this
|
|
// packet.
|
|
//
|
|
|
|
if (GleanAarpInfo(
|
|
NdisPortDesc->PortNumber,
|
|
HeaderBuffer + ETHERNET_SOURCE_OFFSET,
|
|
ETHERNET_ADDRESSLENGTH,
|
|
NULL,
|
|
0,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize))
|
|
{
|
|
|
|
// Check the ddp length
|
|
ddpLength =
|
|
(LONG)((*(LookaheadBuffer + IEEE8022_HEADERLENGTH +
|
|
LONGDDP_LENGTHOFFSET) & DDPLENGTH_MASK1)
|
|
<< 8);
|
|
|
|
ddpLength +=
|
|
(LONG)(*(LookaheadBuffer + IEEE8022_HEADERLENGTH +
|
|
LONGDDP_LENGTHOFFSET + 1) & DDPLENGTH_MASK2);
|
|
|
|
if ((ddpLength < LONGDDP_HEADERLENGTH) ||
|
|
(ddpLength > MAX_LONGDDPPACKETSIZE)) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Is the DDP length more than we really got?
|
|
//
|
|
|
|
if (ddpLength + IEEE8022_HEADERLENGTH > PacketSize)
|
|
{
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Our packet- successfully verified
|
|
//
|
|
|
|
*PacketType = APPLETALK_PACKET;
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (RtlCompareMemory(LookaheadBuffer+IEEE8022_PROTOCOLOFFSET,
|
|
aarpProtocolType,
|
|
IEEE8022_PROTOCOLTYPELENGTH) ==
|
|
IEEE8022_PROTOCOLTYPELENGTH) {
|
|
|
|
|
|
//
|
|
// For ethernet, there could be padding included in the packet.
|
|
// Shrink the length if so. Note header length is not included in
|
|
// packetlength.
|
|
//
|
|
|
|
if (PacketSize == (MIN_ETHERNETPACKETLENGTH - ETHERNET_LINKLENGTH)) {
|
|
PacketSize = IEEE8022_HEADERLENGTH + MAX_AARPDATASIZE;
|
|
}
|
|
|
|
aarpDataLength = PacketSize - IEEE8022_HEADERLENGTH;
|
|
if ((aarpDataLength > MAX_AARPDATASIZE) ||
|
|
(aarpDataLength < MIN_AARPDATASIZE))
|
|
{
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Our packet- successfully verified
|
|
//
|
|
|
|
*PacketType = AARP_PACKET;
|
|
break;
|
|
}
|
|
|
|
} while ( FALSE );
|
|
|
|
return(accept);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptFddiPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc
|
|
)
|
|
{
|
|
BOOLEAN accept = TRUE;
|
|
UINT ddpLength; // Length of packet from ddp header
|
|
UINT aarpDataLength; // Check aarp data length
|
|
|
|
do {
|
|
|
|
//
|
|
// Check length for atleast the minimum amount of space
|
|
// Also, Check if the 802.2 header is ok
|
|
//
|
|
|
|
if ( (LookaheadBufferSize <
|
|
(IEEE8022_PROTOCOLOFFSET+IEEE8022_PROTOCOLTYPELENGTH))
|
|
|
|
||
|
|
|
|
((*(LookaheadBuffer + IEEE8022_DSAPOFFSET) != SNAP_SAP) ||
|
|
(*(LookaheadBuffer + IEEE8022_SSAPOFFSET) != SNAP_SAP) ||
|
|
(*(LookaheadBuffer + IEEE8022_CONTROLOFFSET) !=
|
|
UNNUMBEREDINFORMATION)) ) {
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (RtlCompareMemory(LookaheadBuffer+IEEE8022_PROTOCOLOFFSET,
|
|
appleTalkProtocolType,
|
|
IEEE8022_PROTOCOLTYPELENGTH) ==
|
|
IEEE8022_PROTOCOLTYPELENGTH) {
|
|
|
|
//
|
|
// Use GleanAarpInfo to determine whether or not we accept this
|
|
// packet.
|
|
//
|
|
|
|
if (GleanAarpInfo(
|
|
NdisPortDesc->PortNumber,
|
|
HeaderBuffer + FddiSourceOffset,
|
|
FddiAddressLength,
|
|
NULL,
|
|
0,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize))
|
|
{
|
|
|
|
// Check the ddp length
|
|
ddpLength =
|
|
(LONG)((*(LookaheadBuffer + IEEE8022_HEADERLENGTH +
|
|
LONGDDP_LENGTHOFFSET) & DDPLENGTH_MASK1)
|
|
<< 8);
|
|
|
|
ddpLength +=
|
|
(LONG)(*(LookaheadBuffer + IEEE8022_HEADERLENGTH +
|
|
LONGDDP_LENGTHOFFSET + 1) & DDPLENGTH_MASK2);
|
|
|
|
if ((ddpLength < LONGDDP_HEADERLENGTH) ||
|
|
(ddpLength > MAX_LONGDDPPACKETSIZE)) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Is the DDP length more than we really got?
|
|
//
|
|
|
|
if (ddpLength + IEEE8022_HEADERLENGTH > PacketSize)
|
|
{
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Our packet- successfully verified
|
|
//
|
|
|
|
*PacketType = APPLETALK_PACKET;
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (RtlCompareMemory(LookaheadBuffer+IEEE8022_PROTOCOLOFFSET,
|
|
aarpProtocolType,
|
|
IEEE8022_PROTOCOLTYPELENGTH) ==
|
|
IEEE8022_PROTOCOLTYPELENGTH) {
|
|
|
|
//
|
|
// BUGBUG: is this true?
|
|
// For fddi, there could be padding included in the packet.
|
|
// Shrink the length if so. Note header length is not included in
|
|
// packetlength.
|
|
//
|
|
|
|
if (PacketSize == (MinimumFddiPacketLength - FddiLinkHeaderLength)) {
|
|
PacketSize = IEEE8022_HEADERLENGTH + MAX_AARPDATASIZE;
|
|
}
|
|
|
|
aarpDataLength = PacketSize - IEEE8022_HEADERLENGTH;
|
|
if ((aarpDataLength > MAX_AARPDATASIZE) ||
|
|
(aarpDataLength < MIN_AARPDATASIZE))
|
|
{
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Our packet- successfully verified
|
|
//
|
|
|
|
*PacketType = AARP_PACKET;
|
|
break;
|
|
}
|
|
|
|
} while ( FALSE );
|
|
|
|
return(accept);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptTokenringPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc
|
|
)
|
|
{
|
|
BOOLEAN accept = TRUE;
|
|
UINT ddpLength; // Length of packet from ddp header
|
|
UINT routingInfoLength; // length of routing info if present (802.5)
|
|
|
|
do {
|
|
|
|
//
|
|
// The tokenring code changes the source-routing bit in the
|
|
// source address and also tunes the routing info. We need
|
|
// to make copies of these before passing them onto the portable
|
|
// code. Allocate for routingInfo (since it is accessed in receive
|
|
// complete, but use a buffer on the stack for the source address
|
|
//
|
|
|
|
//
|
|
// Check length for atleast the minimum amount of space
|
|
// Also, Check if the 802.2 header is ok
|
|
//
|
|
|
|
if ( (LookaheadBufferSize <
|
|
(IEEE8022_PROTOCOLOFFSET+IEEE8022_PROTOCOLTYPELENGTH))
|
|
|
|
||
|
|
|
|
((*(LookaheadBuffer + IEEE8022_DSAPOFFSET) != SNAP_SAP) ||
|
|
(*(LookaheadBuffer + IEEE8022_SSAPOFFSET) != SNAP_SAP) ||
|
|
(*(LookaheadBuffer + IEEE8022_CONTROLOFFSET) !=
|
|
UNNUMBEREDINFORMATION)) ) {
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check the packet to see if we are to accept it
|
|
// If so, we'll need to allocate the routing info
|
|
//
|
|
|
|
if (RtlCompareMemory(LookaheadBuffer+IEEE8022_PROTOCOLOFFSET,
|
|
appleTalkProtocolType,IEEE8022_PROTOCOLTYPELENGTH)
|
|
== IEEE8022_PROTOCOLTYPELENGTH) {
|
|
|
|
*PacketType = APPLETALK_PACKET;
|
|
|
|
//
|
|
// Remember- routing info is in the header buffer
|
|
//
|
|
|
|
} else if (RtlCompareMemory(LookaheadBuffer+IEEE8022_PROTOCOLOFFSET,
|
|
aarpProtocolType, IEEE8022_PROTOCOLTYPELENGTH) ==
|
|
IEEE8022_PROTOCOLTYPELENGTH) {
|
|
|
|
*PacketType = AARP_PACKET;
|
|
|
|
} else {
|
|
|
|
accept = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Packet is either Appletalk or Aarp.
|
|
//
|
|
|
|
if (*(HeaderBuffer + TOKRING_SOURCEOFFSET) & TOKRING_SOURCEROUTINGMASK) {
|
|
|
|
routingInfoLength =
|
|
(*(HeaderBuffer + TOKRING_ROUTINGINFOOFFSET) &
|
|
TOKRING_ROUTINGINFOSIZEMASK);
|
|
|
|
ASSERT(routingInfoLength != 0);
|
|
|
|
//
|
|
// Routing info must be of reasonable size, and not odd.
|
|
//
|
|
|
|
if ((routingInfoLength & 1) ||
|
|
(routingInfoLength > TOKRING_MAXROUTINGBYTES))
|
|
{
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
HeaderBuffer,
|
|
HeaderBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept=FALSE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if (*PacketType == APPLETALK_PACKET) {
|
|
|
|
do {
|
|
|
|
UCHAR localSourceAddress[TOKRING_ADDRESSLENGTH];
|
|
UCHAR routingInfo[TOKRING_MAXROUTINGBYTES];
|
|
|
|
//
|
|
// Do we at least have a 802.2 and DDP header in the indicated
|
|
// packet?
|
|
//
|
|
|
|
if ((PacketSize < (IEEE8022_HEADERLENGTH + LONGDDP_HEADERLENGTH)) ||
|
|
(PacketSize > (IEEE8022_HEADERLENGTH + MAX_LONGDDPPACKETSIZE)))
|
|
{
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept=FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// First, glean any AARP information that we can, then handle the DDP
|
|
// packet. This guy also makes sure we have a good 802.2 header...
|
|
//
|
|
// Need to make a localcopy of the source address and then turn
|
|
// the source routing bit off before calling GleanAarpInfo
|
|
//
|
|
// (HeaderBuffer)[TOKRING_SOURCEOFFSET] =
|
|
// ((HeaderBuffer)[TOKRING_SOURCEOFFSET] &
|
|
// ~TOKRING_SOURCEROUTINGMASK);
|
|
//
|
|
|
|
//
|
|
// BUGBUG: Use RtlCopyMemory
|
|
//
|
|
|
|
RtlMoveMemory(
|
|
localSourceAddress,
|
|
HeaderBuffer+TOKRING_SOURCEOFFSET,
|
|
TOKRING_ADDRESSLENGTH);
|
|
|
|
if (routingInfoLength > 0) {
|
|
RtlMoveMemory(
|
|
routingInfo,
|
|
HeaderBuffer+TOKRING_ROUTINGINFOOFFSET,
|
|
routingInfoLength);
|
|
}
|
|
|
|
(*(PUCHAR)localSourceAddress) &= ~TOKRING_SOURCEROUTINGMASK;
|
|
|
|
if (GleanAarpInfo(
|
|
NdisPortDesc->PortNumber,
|
|
localSourceAddress,
|
|
TOKRING_ADDRESSLENGTH,
|
|
routingInfo,
|
|
routingInfoLength,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize)) {
|
|
|
|
//
|
|
// Pull out the DDP length.
|
|
//
|
|
|
|
ddpLength =
|
|
(LONG)((*(LookaheadBuffer + IEEE8022_HEADERLENGTH +
|
|
LONGDDP_LENGTHOFFSET) & DDPLENGTH_MASK1)
|
|
<< 8);
|
|
|
|
ddpLength +=
|
|
(LONG)(*(LookaheadBuffer + IEEE8022_HEADERLENGTH +
|
|
LONGDDP_LENGTHOFFSET + 1) & DDPLENGTH_MASK2);
|
|
|
|
if ((ddpLength < LONGDDP_HEADERLENGTH) ||
|
|
(ddpLength > MAX_LONGDDPPACKETSIZE)) {
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept=FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Is the DDP length more than we really got?
|
|
//
|
|
|
|
if (ddpLength + IEEE8022_HEADERLENGTH > PacketSize)
|
|
{
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
NDIS_STATUS_NOT_RECOGNIZED,
|
|
LookaheadBuffer,
|
|
LookaheadBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept=FALSE;
|
|
break;
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// GleanAarpInfo returned FALSE
|
|
//
|
|
|
|
accept=FALSE;
|
|
}
|
|
|
|
break;
|
|
|
|
} while (FALSE);
|
|
|
|
break;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
return(accept);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
AtalkNdisAcceptLocaltalkPacket(
|
|
IN PUCHAR HeaderBuffer,
|
|
IN UINT HeaderBufferSize,
|
|
IN PUCHAR LookaheadBuffer,
|
|
IN UINT LookaheadBufferSize,
|
|
IN UINT PacketSize,
|
|
OUT PACKET_TYPE *PacketType,
|
|
OUT PUCHAR LlapType,
|
|
PNDIS_PORTDESCRIPTORS NdisPortDesc
|
|
)
|
|
{
|
|
BOOLEAN accept = TRUE;
|
|
|
|
//
|
|
// No AARP/802.2 header on localtalk
|
|
//
|
|
|
|
*PacketType = APPLETALK_PACKET;
|
|
|
|
*LlapType = *(HeaderBuffer + ALAP_TYPEOFFSET);
|
|
if ((*LlapType != DDP_EXTENDEDFORMHEADER) && (*LlapType != DDP_SHORTFORMHEADER)){
|
|
|
|
LOG_ERROR(
|
|
EVENT_ATALK_PACKETINVALID,
|
|
(__ATKNPRO__ | __LINE__),
|
|
(ULONG)*LlapType,
|
|
HeaderBuffer,
|
|
HeaderBufferSize,
|
|
1,
|
|
&NdisPortDesc->AdapterName);
|
|
|
|
accept = FALSE;
|
|
}
|
|
|
|
return(accept);
|
|
}
|
|
|
|
|
|
|
|
|
|
#if DBG
|
|
|
|
VOID
|
|
DumpPacket(
|
|
PUCHAR Packet
|
|
)
|
|
{
|
|
DbgPrint("\nPACKET DUMP\n");
|
|
DbgPrint("Destination %lx\n", *(ULONG *)&Packet[2]);
|
|
DbgPrint("Source %lx\n", *(ULONG *)&Packet[8]);
|
|
DbgPrint("Protocol Disc %lx\n", *(ULONG *)&Packet[18]);
|
|
|
|
DbgPrint("DDP Source node %d\n", (UCHAR)Packet[32]);
|
|
DbgPrint("DDP Src Socket %d\n", (UCHAR)Packet[34]);
|
|
|
|
DbgPrint("DDP Dest node %d\n", (UCHAR)Packet[31]);
|
|
DbgPrint("DDP Dest Socket %d\n", (UCHAR)Packet[33]);
|
|
|
|
DbgPrint("DDP Type %d\n", (UCHAR)Packet[35]);
|
|
|
|
return;
|
|
|
|
}
|
|
#endif
|