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.
1959 lines
42 KiB
1959 lines
42 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dependnt.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the routines interacting with the mac for ethernet
|
|
tokenring, localtalk and fddi written for NT.
|
|
|
|
It will also contain any other routines that need to be supplied per
|
|
os.
|
|
|
|
Author:
|
|
|
|
Nikhil Kamkolkar (NikhilK) 8-July-1992
|
|
|
|
Notes:
|
|
|
|
Hardware specific routines for access the various kinds of physical ports
|
|
that we support.
|
|
|
|
Xxxxx is a port type and may be:
|
|
|
|
Ethernet
|
|
LocalTalk
|
|
TokenRing
|
|
Fddi
|
|
HalfPort
|
|
|
|
For each port type, the following four routines must be filled in:
|
|
|
|
BOOLEAN InitializeXxxxxController(port, controllerInfo)
|
|
int port;
|
|
char *controllerInfo;
|
|
|
|
port - Index into "portDescriptors" for the port
|
|
we're interested in.
|
|
controllerInfo - Hardware (or driver) specific information
|
|
as passed to "Initialize" to identify the
|
|
port we're supposed to query.
|
|
|
|
For HalfPort this guy is called: InitializeHalfPort.
|
|
|
|
BOOLEAN AddXxxxxMulticastAddresses(port, numberOfAddresses,
|
|
addressList)
|
|
int port;
|
|
int numberOfAddresses;
|
|
char *addressList;
|
|
|
|
port - Index into "portDescriptors" for the port
|
|
we're interested in.
|
|
numberOfAddreses
|
|
- How many hardware addresses (packed) are
|
|
in the addressList.
|
|
addressList - List of hardware multicast addresses.
|
|
|
|
Not used for HalfPort.
|
|
|
|
BOOLEAN RemoveXxxxxMulticastAddresses(port, numberOfAddresses,
|
|
addressList)
|
|
int port;
|
|
int numberOfAddresses;
|
|
char *addressList;
|
|
|
|
port - Index into "portDescriptors" for the port
|
|
we're interested in.
|
|
numberOfAddreses
|
|
- How many hardware addresses (packed) are
|
|
in the addressList.
|
|
addressList - List of hardware multicast addresses.
|
|
|
|
Not used for HalfPort.
|
|
|
|
BOOLEAN FindMyXxxxxAddress(port, controllerInfo, address)
|
|
int port;
|
|
char *controllerInfo;
|
|
char *address;
|
|
|
|
port - Index into "portDescriptors" for the port
|
|
we're interested in.
|
|
controllerInfo - Hardware (or driver) specific information
|
|
as passed to "Initialize" to identify the
|
|
port we're supposed to query.
|
|
address - Filled in with host hardware address.
|
|
|
|
Not used for HalfPort.
|
|
|
|
BOOLEAN XxxxxPacketOut(port, chain, length,
|
|
transmitCompleteHandler, userData)
|
|
int port;
|
|
BufferDescriptor chain;
|
|
int length;
|
|
|
|
port - Index into "portDescriptors" for the port
|
|
we're sending the packet out on.
|
|
packet - A descriptor chain of a full, on-the-wire, packet.
|
|
length - Length, in bytes, of the packet.
|
|
transmitCompleteHandler
|
|
- Optional pointer to routine to be called on
|
|
transmit completion.
|
|
userData
|
|
- User data for the above routine.
|
|
|
|
void BuildXxxxHeader(lapPacket, port, destination, protocol)
|
|
char *lapPacket;
|
|
int port;
|
|
char *destination;
|
|
int routingInfoLength;
|
|
char *routingInfo;
|
|
LogicalProtocol protocol;
|
|
|
|
ddpPacket - Address of the start of the LAP packet,
|
|
we'll put the header IN FRONT of this
|
|
address.
|
|
port - Index into "portDescriptors" for the port
|
|
we're interested in.
|
|
destination - Destination hardware address (if "empty"
|
|
the broadcast address will be used).
|
|
routingInfoLength
|
|
- For links with routing info (e.g. TokenRing)
|
|
number of bytes in next field.
|
|
routingInfo - Optional bytes of routing info.
|
|
protocol - Logical protocol type (AppleTalk or
|
|
AddressResolution).
|
|
|
|
void XxxxPacketInAT(port, packet, length)
|
|
void XxxxPacketInAARP(port, packet, length)
|
|
int port;
|
|
char *packet;
|
|
int length;
|
|
|
|
port - Index into "portDescriptors" for the port
|
|
the packet arrived from.
|
|
packet - A full on-the-wire packet.
|
|
length - Length, in bytes, of the packet.
|
|
|
|
AARP is not used for HalfPorts or AppleTalkRemoteAccess.
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#include "atalk.h"
|
|
|
|
//
|
|
// Local routines
|
|
//
|
|
|
|
LOCAL
|
|
VOID NTAddMulticastAddressesComplete(NDIS_STATUS Status, PVOID Context);
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NTTransmitComplete(
|
|
BufferDescriptor Chain
|
|
)
|
|
{
|
|
if (Chain->transmitCompleteHandler != NULL)
|
|
(*Chain->transmitCompleteHandler)(ATnoError, Chain->userData, Chain);
|
|
|
|
FreeBufferChain(Chain);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NTAddMulticastAddressesComplete(
|
|
NDIS_STATUS Status,
|
|
PVOID Context
|
|
)
|
|
{
|
|
int Port=(int)Context;
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_IMPOSSIBLE,
|
|
("INFO1: NTAddMulticastAddrComplete - added port %lx status %lx\n",
|
|
Port, Status));
|
|
|
|
//
|
|
// BUGBUG:
|
|
// If failure, then shutdown port
|
|
//
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// ETHERNET 802.3 MEDIA ROUTINES
|
|
//
|
|
//
|
|
|
|
|
|
BOOLEAN
|
|
NTInitializeEthernetController(
|
|
int Port,
|
|
PCHAR ControllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to intialize the ethernet
|
|
controller on a port
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
ULONG atalkFilter;
|
|
BOOLEAN result = TRUE;
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTInitializeEthernetController - port #%d\n", Port));
|
|
|
|
do {
|
|
|
|
//
|
|
// Set the lookahead size.
|
|
// ****IMPORTANT**** this must be atleast the size of the max
|
|
// link + ddp + aarp data size (= MaximumAarpPacketSize)
|
|
//
|
|
// All MACs are required to support *atleast* 256 bytes of lookahead data
|
|
// by NDIS 3.0
|
|
//
|
|
|
|
if (!AtalkNdisSetLookaheadSize(
|
|
Port,
|
|
MAX_AARPPACKETSIZE,
|
|
NdisMedium802_3,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeEthernetController - Set lookahead size failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set the broadcast address in the multicast list
|
|
//
|
|
|
|
if (!NTAddEthernetMulticastAddresses(
|
|
Port,
|
|
1, // Number of addresses
|
|
ethernetBroadcastAddress)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeEthernetController - Add broadcast failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Initialize the adapter to start receiving packets
|
|
//
|
|
|
|
atalkFilter = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST;
|
|
|
|
if (!AtalkNdisSetPacketFilter(
|
|
Port,
|
|
atalkFilter,
|
|
NdisMedium802_3,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeEthernetController - Set filter failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
} while (FALSE);
|
|
|
|
return(result);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTAddEthernetMulticastAddresses(
|
|
int Port,
|
|
int NumberOfAddresses,
|
|
PCHAR AddressList
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to add an ethernet
|
|
address. This routine will preserve whatever previous addresses were
|
|
added
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
NumberOfAddress- The number of addresses in the list
|
|
AddressList- The list of addresses
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS1,
|
|
("NTAddEthernetMulticastAddresses: PORT #%d NumAddr %d\n",
|
|
Port, NumberOfAddresses));
|
|
|
|
if (NumberOfAddresses != 1) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
return (AtalkNdisMulticastAddressList(
|
|
Port,
|
|
ADD_ADDRESSTOLIST,
|
|
AddressList,
|
|
NdisMedium802_3,
|
|
SYNC_IF_POSSIBLE,
|
|
NTAddMulticastAddressesComplete,
|
|
(PVOID)Port)); // Context value passed in above
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTRemoveEthernetMulticastAddrs(
|
|
INT Port,
|
|
INT NumberOfAddresses,
|
|
PCHAR AddressList
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to remove a list of ethernet
|
|
addresses.
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
NumberOfAddress- The number of addresses in the list
|
|
AddressList- The list of addresses to be removed
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS0,
|
|
("INFO0: NTRemoveEthernetMulticastAddrs - called\n"));
|
|
|
|
if (NumberOfAddresses != 1) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
return (AtalkNdisMulticastAddressList(
|
|
Port,
|
|
REMOVE_ADDRESSFROMLIST,
|
|
AddressList,
|
|
NdisMedium802_3,
|
|
SYNC_IF_POSSIBLE,
|
|
NULL,
|
|
NULL));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTFindMyEthernetAddress(
|
|
int Port,
|
|
PCHAR ControllerInfo,
|
|
PCHAR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to add a list of ethernet
|
|
addresses. This routine will preserve whatever previous addresses were
|
|
added
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL (use global NdisPortDesc)
|
|
Address- The buffer for the address to be returned (atleast MAX_ETHERNETADDRLEN bytes)
|
|
|
|
Return Value:
|
|
|
|
TRUE- If obtained, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS0,
|
|
("INFO0: NTFindMyEthernetAddresses: PORT #%d\n", Port));
|
|
|
|
return(AtalkNdisGetCurrentStationAddress(
|
|
Port,
|
|
Address,
|
|
EthernetAddressLength,
|
|
NdisMedium802_3,
|
|
SYNC,
|
|
NULL,
|
|
NULL));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTEthernetPacketOut(
|
|
int Port,
|
|
BufferDescriptor Chain,
|
|
int Length,
|
|
TRANSMIT_COMPLETION *TransmitCompleteRoutine,
|
|
ULONG UserData
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to send a packet out on
|
|
ethernet
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
Chain- The portable stacks buffer descriptor chain
|
|
Length- The cumulative length to send
|
|
|
|
Return Value:
|
|
|
|
TRUE- If sent/pending, FALSE otherwise
|
|
TransmitComplete is called if this call pended by completion code
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Create an NDIS Packet descriptor for all the buffer descriptor and
|
|
// send the packet
|
|
//
|
|
|
|
Chain->transmitCompleteHandler = TransmitCompleteRoutine;
|
|
Chain->userData = UserData;
|
|
|
|
return(AtalkNdisPacketOut(Port, Chain, Length));
|
|
}
|
|
|
|
|
|
|
|
PCHAR
|
|
NTBuildEthernetHeader(
|
|
PUCHAR DdpPacket,
|
|
int DdpLength,
|
|
int Port,
|
|
PUCHAR Destination,
|
|
PUCHAR RoutingInfo,
|
|
int RoutingInfoLength,
|
|
LOGICAL_PROTOCOL Protocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PUCHAR packet = DdpPacket - EthernetLinkHeaderLength - Ieee802dot2headerLength;
|
|
USHORT trueLength = (USHORT)(DdpLength + Ieee802dot2headerLength);
|
|
|
|
UNREFERENCED_PARAMETER(RoutingInfoLength);
|
|
UNREFERENCED_PARAMETER(RoutingInfo);
|
|
|
|
|
|
// Set destination address.
|
|
if (Destination isnt empty) {
|
|
MoveMem(
|
|
packet + EthernetDestinationOffset,
|
|
Destination,
|
|
EthernetAddressLength);
|
|
} else {
|
|
MoveMem(
|
|
packet + EthernetDestinationOffset,
|
|
ethernetBroadcastAddress,
|
|
EthernetAddressLength);
|
|
}
|
|
|
|
// Set source address.
|
|
MoveMem(
|
|
packet + EthernetSourceOffset,
|
|
GET_PORTDESCRIPTOR(Port)->MyAddress,
|
|
EthernetAddressLength);
|
|
|
|
// Set length, excluding Ethernet hardware header.
|
|
packet[EthernetLengthOffset] = (UCHAR)(trueLength >> 8);
|
|
packet[EthernetLengthOffset + 1] = (UCHAR)(trueLength & 0xFF);
|
|
|
|
// Build the 802.2 header.
|
|
Build802dot2header(packet + EthernetLinkHeaderLength, Protocol);
|
|
|
|
return(packet);
|
|
|
|
} // NTBuildEthernetHeader
|
|
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// TOKENRING 802.5 MEDIA ROUTINES
|
|
//
|
|
//
|
|
|
|
|
|
BOOLEAN
|
|
NTInitializeTokenRingController(
|
|
int Port,
|
|
PCHAR ControllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to intialize the ethernet
|
|
controller on a port
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL (use global NdisPortDesc)
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
ULONG atalkFilter;
|
|
BOOLEAN result = TRUE;
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTInitializeTokenRingController - PORT #%d\n", Port));
|
|
|
|
do {
|
|
|
|
//
|
|
// Set the lookahead size- this must be atleast the size of the max
|
|
// link + ddp + aarp data size (= MaximumAarpPacketSize in portable code base)
|
|
// All MACs are required to support *atleast* 256 bytes of lookahead data
|
|
// by NDIS 3.0
|
|
//
|
|
|
|
if (!AtalkNdisSetLookaheadSize(
|
|
Port,
|
|
MAX_AARPPACKETSIZE,
|
|
NdisMedium802_5,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeTokenRing - Set loolahead failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
// Set the broadcast address in the multicast list
|
|
if (!NTAddTokenRingFunctionalAddresses(
|
|
Port,
|
|
1, // Number of addresses
|
|
tokenRingBroadcastAddress)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeTokenRing - Set functional failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
// Initialize the adapter to start receiving packets
|
|
atalkFilter = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_FUNCTIONAL;
|
|
|
|
if (!AtalkNdisSetPacketFilter(
|
|
Port,
|
|
atalkFilter,
|
|
NdisMedium802_5,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeTokenRing - Set filter failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
return(result);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTAddTokenRingFunctionalAddresses(
|
|
int Port,
|
|
int NumberOfAddresses,
|
|
PCHAR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to add an ethernet
|
|
address. This routine will preserve whatever previous addresses were
|
|
added
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
NumberOfAddress- The number of addresses in the list
|
|
AddressList- The list of addresses
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
|
|
//
|
|
// The caller could have passed the address of list which could
|
|
// be on the stack. since the stack is swappable and since we
|
|
// block, we make a copy of the passed in list after allocating
|
|
// required amount of space. We assume address list is of the form
|
|
// ARRAY[X] where each element is (CHAR [6])
|
|
//
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS0,
|
|
("INFO0: NTAddTokenRingMulticastAddresses: PORT #%d NumAddr %d\n",
|
|
Port, NumberOfAddresses));
|
|
|
|
if (NumberOfAddresses != 1) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
return (AtalkNdisFunctionalAddress(
|
|
Port,
|
|
ADD_ADDRESSTOLIST,
|
|
Address,
|
|
NdisMedium802_5,
|
|
SYNC_IF_POSSIBLE,
|
|
NTAddMulticastAddressesComplete,
|
|
(PVOID)Port)); // Context value passed in above
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTRemoveTokenRingFunctionalAddresses(
|
|
INT Port,
|
|
INT NumberOfAddresses,
|
|
PCHAR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to remove a list of ethernet
|
|
addresses.
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
NumberOfAddress- The number of addresses in the list
|
|
AddressList- The list of addresses to be removed
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
if (NumberOfAddresses != 1) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
return (AtalkNdisFunctionalAddress(
|
|
Port,
|
|
REMOVE_ADDRESSFROMLIST,
|
|
Address,
|
|
NdisMedium802_5,
|
|
SYNC_IF_POSSIBLE,
|
|
NULL,
|
|
NULL));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTFindMyTokenRingAddress(
|
|
int Port,
|
|
PCHAR ControllerInfo,
|
|
PCHAR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to add a list of ethernet
|
|
addresses. This routine will preserve whatever previous addresses were
|
|
added
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL (use global NdisPortDesc)
|
|
Address- The buffer for the address to be returned (atleast MAX_yyTOKENRINGADDRLEN bytes)
|
|
|
|
Return Value:
|
|
|
|
TRUE- If obtained, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
return(AtalkNdisGetCurrentStationAddress(
|
|
Port,
|
|
Address,
|
|
TOKRING_ADDRESSLENGTH,
|
|
NdisMedium802_5,
|
|
SYNC,
|
|
NULL,
|
|
NULL));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTTokenRingPacketOut(
|
|
int Port,
|
|
BufferDescriptor Chain,
|
|
int Length,
|
|
TRANSMIT_COMPLETION *TransmitCompleteRoutine,
|
|
ULONG UserData
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to send a packet out on
|
|
ethernet
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
Chain- The portable stacks buffer descriptor chain
|
|
Length- The cumulative length to send
|
|
|
|
Return Value:
|
|
|
|
TRUE- If sent/pending, FALSE otherwise
|
|
TransmitComplete is called if this call pended by completion code
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Create an NDIS Packet descriptor for all the buffer descriptor and
|
|
// send the packet
|
|
//
|
|
|
|
Chain->transmitCompleteHandler = TransmitCompleteRoutine;
|
|
Chain->userData = UserData;
|
|
|
|
return(AtalkNdisPacketOut(Port, Chain, Length));
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Used by TokenRingHeader routine
|
|
//
|
|
|
|
static UCHAR broadcastRoutingInfo[TokenRingMinRoutingBytes] =
|
|
TokenRingBroadcastRoutingInfo;
|
|
static UCHAR simpleRoutingInfo[TokenRingMinRoutingBytes] =
|
|
TokenRingSimpleRoutingInfo;
|
|
static UCHAR broadcastDestinationHeader[TokenRingBroadcastDestLength] =
|
|
TokenRingBroadcastDestHeader;
|
|
PCHAR
|
|
NTBuildTokenRingHeader(
|
|
PCHAR DdpPacket,
|
|
int DdpLength,
|
|
int port,
|
|
PCHAR Destination,
|
|
PCHAR RoutingInfo,
|
|
int RoutingInfoLength,
|
|
LOGICAL_PROTOCOL Protocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PCHAR packet;
|
|
|
|
UNREFERENCED_PARAMETER(DdpLength);
|
|
|
|
//
|
|
// Move the "start of packet" back preceeding any headers we'll
|
|
// prepend.
|
|
//
|
|
|
|
if (Destination == NULL) { // Broadcast?
|
|
packet = DdpPacket - TokenRingRoutingInfoOffset -
|
|
TokenRingMinRoutingBytes -
|
|
Ieee802dot2headerLength;
|
|
RoutingInfo = broadcastRoutingInfo;
|
|
RoutingInfoLength = TokenRingMinRoutingBytes;
|
|
|
|
} else if (RoutingInfoLength isnt 0) { // Known route?
|
|
packet = DdpPacket - TokenRingRoutingInfoOffset -
|
|
RoutingInfoLength -
|
|
Ieee802dot2headerLength;
|
|
|
|
} else if (FixedCompareCaseSensitive(
|
|
Destination,
|
|
TokenRingBroadcastDestLength,
|
|
broadcastDestinationHeader,
|
|
TokenRingBroadcastDestLength)) { // Multicast?
|
|
|
|
packet = DdpPacket - TokenRingRoutingInfoOffset -
|
|
TokenRingMinRoutingBytes -
|
|
Ieee802dot2headerLength;
|
|
RoutingInfo = broadcastRoutingInfo;
|
|
RoutingInfoLength = TokenRingMinRoutingBytes;
|
|
|
|
} else { // No routing know; use simple non-broadcast
|
|
packet = DdpPacket - TokenRingRoutingInfoOffset -
|
|
TokenRingMinRoutingBytes -
|
|
Ieee802dot2headerLength;
|
|
RoutingInfo = simpleRoutingInfo;
|
|
RoutingInfoLength = TokenRingMinRoutingBytes;
|
|
}
|
|
|
|
// Set funny header byte values.
|
|
packet[TokenRingAccessControlOffset] = TokenRingAccessControlValue;
|
|
packet[TokenRingFrameControlOffset] = TokenRingFrameControlValue;
|
|
|
|
// Set detination address.
|
|
if (Destination != NULL)
|
|
MoveMem(
|
|
packet + TokenRingDestinationOffset,
|
|
Destination,
|
|
TokenRingAddressLength);
|
|
|
|
else
|
|
MoveMem(
|
|
packet + TokenRingDestinationOffset,
|
|
tokenRingBroadcastAddress,
|
|
TokenRingAddressLength);
|
|
|
|
// Set source address.
|
|
MoveMem(
|
|
packet + TokenRingSourceOffset,
|
|
GET_PORTDESCRIPTOR(port)->MyAddress,
|
|
TokenRingAddressLength);
|
|
|
|
// Move in routing info.
|
|
MoveMem(
|
|
packet + TokenRingRoutingInfoOffset,
|
|
RoutingInfo,
|
|
RoutingInfoLength);
|
|
|
|
packet[TokenRingSourceOffset] |= TokenRingSourceRoutingMask;
|
|
|
|
// Build the 802.2 header.
|
|
Build802dot2header(
|
|
(PUCHAR)(packet + TokenRingRoutingInfoOffset + RoutingInfoLength),
|
|
Protocol);
|
|
|
|
|
|
// All set!
|
|
return(packet);
|
|
|
|
} // NTBuildTokenRingHeader
|
|
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// LOCALTALK MEDIA ROUTINES
|
|
//
|
|
//
|
|
|
|
|
|
BOOLEAN
|
|
NTInitializeLocalTalkController(
|
|
int Port,
|
|
PCHAR ControllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to intialize the LOCALTALK
|
|
controller on a port
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL (use global NdisPortDesc)
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
ULONG atalkFilter;
|
|
BOOLEAN result = TRUE;
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTInitializeLocaltalkController: PORT #%d\n", Port));
|
|
|
|
do {
|
|
|
|
//
|
|
// Set the lookahead size- this must be atleast the size of the max
|
|
// link + ddp + aarp data size (= MaximumAarpPacketSize in portable code base)
|
|
// All MACs are required to support *atleast* 256 bytes of lookahead data
|
|
// by NDIS 3.0
|
|
//
|
|
|
|
if (!AtalkNdisSetLookaheadSize(
|
|
Port,
|
|
MAX_AARPPACKETSIZE,
|
|
NdisMediumLocalTalk,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeLocalTalk - Set loolahead failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
// Initialize the adapter to start receiving packets
|
|
atalkFilter = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_BROADCAST;
|
|
|
|
if (!AtalkNdisSetPacketFilter(
|
|
Port,
|
|
atalkFilter,
|
|
NdisMediumLocalTalk,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeLocalTalk - Set filter failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
result=TRUE;
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
return(result);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTFindMyLocalTalkAddress(
|
|
int Port,
|
|
PCHAR ControllerInfo,
|
|
PCHAR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL (use global NdisPortDesc)
|
|
Address- The buffer for the address to be returned (atleast LOCALTALKNODEID bytes)
|
|
|
|
Return Value:
|
|
|
|
TRUE- If obtained, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
return (AtalkNdisGetCurrentStationAddress(
|
|
Port,
|
|
(PCHAR)Address,
|
|
LOCALTALK_NODEIDLENGTH,
|
|
NdisMediumLocalTalk,
|
|
SYNC,
|
|
NULL,
|
|
NULL));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTLocalTalkPacketOut(
|
|
int Port,
|
|
BufferDescriptor Chain,
|
|
int Length,
|
|
TRANSMIT_COMPLETION *TransmitCompleteRoutine,
|
|
ULONG UserData
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to send a packet out on
|
|
ethernet
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
Chain- The portable stacks buffer descriptor chain
|
|
Length- The cumulative length to send
|
|
|
|
Return Value:
|
|
|
|
TRUE- If sent/pending, FALSE otherwise
|
|
TransmitComplete is called if this call pended by completion code
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Create an NDIS Packet descriptor for all the buffer descriptor and
|
|
// send the packet
|
|
//
|
|
|
|
Chain->transmitCompleteHandler = TransmitCompleteRoutine;
|
|
Chain->userData = UserData;
|
|
|
|
return(AtalkNdisPacketOut(Port, Chain, Length));
|
|
}
|
|
|
|
|
|
|
|
|
|
PCHAR
|
|
NTBuildLocalTalkHeader(
|
|
PCHAR DdpPacket,
|
|
int ExtendedDdpHeaderFlag,
|
|
int Port,
|
|
PCHAR Destination,
|
|
PCHAR RoutingInfo,
|
|
int RoutingInfoLength,
|
|
LOGICAL_PROTOCOL Protocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PCHAR packet = DdpPacket - LapHeaderLength;
|
|
|
|
// Touch unused formals.
|
|
UNREFERENCED_PARAMETER(RoutingInfoLength);
|
|
UNREFERENCED_PARAMETER(RoutingInfo);
|
|
UNREFERENCED_PARAMETER(Protocol);
|
|
|
|
// Fill in LAP header.
|
|
if (Destination != NULL)
|
|
packet[AlapDestinationOffset] = *Destination;
|
|
else
|
|
packet[AlapDestinationOffset] = AppleTalkBroadcastNodeNumber;
|
|
|
|
ASSERT(GET_PORTDESCRIPTOR(Port)->ActiveNodes != NULL);
|
|
|
|
packet[AlapSourceOffset] =
|
|
GET_PORTDESCRIPTOR(Port)->ActiveNodes->extendedNode.nodeNumber;
|
|
packet[AlapTypeOffset] = (UCHAR)(ExtendedDdpHeaderFlag ?
|
|
AlapLongDdpHeaderType :
|
|
AlapShortDdpHeaderType);
|
|
return(packet);
|
|
|
|
} // NTBuildLocalTalkHeader
|
|
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// FDDI MEDIA ROUTINES
|
|
//
|
|
//
|
|
|
|
|
|
BOOLEAN
|
|
NTInitializeFddiController(
|
|
int Port,
|
|
PCHAR ControllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to intialize the fddi
|
|
controller on a port
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
ULONG atalkFilter;
|
|
BOOLEAN result = TRUE;
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS1,
|
|
("INFO1: NTInitializeFddiController - port #%d\n", Port));
|
|
|
|
do {
|
|
|
|
//
|
|
// Set the lookahead size- this must be atleast the size of the max
|
|
// link + ddp + aarp data size (= MaximumAarpPacketSize in portable code
|
|
// base)
|
|
//
|
|
// All MACs are required to support *atleast* 256 bytes of lookahead data
|
|
// by NDIS 3.0
|
|
//
|
|
|
|
if (!AtalkNdisSetLookaheadSize(
|
|
Port,
|
|
MAX_AARPPACKETSIZE,
|
|
NdisMediumFddi,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeFddiController - Set lookahead size failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set the broadcast address in the multicast list
|
|
//
|
|
|
|
if (!NTAddFddiMulticastAddresses(
|
|
Port,
|
|
1, // Number of addresses
|
|
ethernetBroadcastAddress)) { // use ethernet multicast address
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeFddiController - Add broadcast failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Initialize the adapter to start receiving packets
|
|
//
|
|
|
|
atalkFilter = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST;
|
|
|
|
if (!AtalkNdisSetPacketFilter(
|
|
Port,
|
|
atalkFilter,
|
|
NdisMediumFddi,
|
|
SYNC,
|
|
NULL,
|
|
NULL)) {
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_ERROR,
|
|
("ERROR: NTInitializeFddiController - Set filter failed!\n"));
|
|
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
} while (FALSE);
|
|
|
|
return(result);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTAddFddiMulticastAddresses(
|
|
int Port,
|
|
int NumberOfAddresses,
|
|
PCHAR AddressList
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to add an ethernet
|
|
address. This routine will preserve whatever previous addresses were
|
|
added
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
NumberOfAddress- The number of addresses in the list
|
|
AddressList- The list of addresses
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS0,
|
|
("INFO0: NTRemoveFddiMulticastAddrs: PORT #%d NumAddr %d\n",
|
|
Port, NumberOfAddresses));
|
|
|
|
if (NumberOfAddresses != 1) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
return (AtalkNdisMulticastAddressList(
|
|
Port,
|
|
ADD_ADDRESSTOLIST,
|
|
AddressList,
|
|
NdisMediumFddi,
|
|
SYNC_IF_POSSIBLE,
|
|
NTAddMulticastAddressesComplete,
|
|
(PVOID)Port)); // Context value passed in above
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTRemoveFddiMulticastAddrs(
|
|
INT Port,
|
|
INT NumberOfAddresses,
|
|
PCHAR AddressList
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to remove a list of ethernet
|
|
addresses.
|
|
|
|
N.B The portable code never passes in more than one address though. Both
|
|
for Add and Remove
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
NumberOfAddress- The number of addresses in the list
|
|
AddressList- The list of addresses to be removed
|
|
|
|
Return Value:
|
|
|
|
TRUE- If initialized, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
PCHAR currentList;
|
|
INT numberInList, noAddr;
|
|
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS0,
|
|
("INFO0: NTRemoveFddiMulticastAddrs - called\n"));
|
|
|
|
if (NumberOfAddresses != 1) {
|
|
KeBugCheck(0);
|
|
}
|
|
|
|
return (AtalkNdisMulticastAddressList(
|
|
Port,
|
|
REMOVE_ADDRESSFROMLIST,
|
|
AddressList,
|
|
NdisMediumFddi,
|
|
SYNC_IF_POSSIBLE,
|
|
NULL,
|
|
NULL));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTFindMyFddiAddress(
|
|
int Port,
|
|
PCHAR ControllerInfo,
|
|
PCHAR Address
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
ControllerInfo- Pointer currently always NULL (use global NdisPortDesc)
|
|
Address- The buffer for the address to be returned (atleast MAX_ETHERNETADDRLEN bytes)
|
|
|
|
Return Value:
|
|
|
|
TRUE- If obtained, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
DBGPRINT(ATALK_DEBUG_DEPEND, DEBUG_LEVEL_INFOCLASS0,
|
|
("INFO0: NTFindMyFddiAddresses: PORT #%d\n", Port));
|
|
|
|
return(AtalkNdisGetCurrentStationAddress(
|
|
Port,
|
|
Address,
|
|
FddiAddressLength,
|
|
NdisMediumFddi,
|
|
SYNC,
|
|
NULL,
|
|
NULL));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTFddiPacketOut(
|
|
int Port,
|
|
BufferDescriptor Chain,
|
|
int Length,
|
|
TRANSMIT_COMPLETION *TransmitCompleteRoutine,
|
|
ULONG UserData
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the portable code to send a packet out on
|
|
fddi
|
|
|
|
Arguments:
|
|
|
|
Port- The port number associated with the adapter to be initialized
|
|
Chain- The portable stacks buffer descriptor chain
|
|
Length- The cumulative length to send
|
|
|
|
Return Value:
|
|
|
|
TRUE- If sent/pending, FALSE otherwise
|
|
TransmitComplete is called if this call pended by completion code
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Create an NDIS Packet descriptor for all the buffer descriptor and
|
|
// send the packet
|
|
//
|
|
|
|
Chain->transmitCompleteHandler = TransmitCompleteRoutine;
|
|
Chain->userData = UserData;
|
|
|
|
return(AtalkNdisPacketOut(Port, Chain, Length));
|
|
}
|
|
|
|
|
|
|
|
|
|
PCHAR
|
|
NTBuildFddiHeader(
|
|
PCHAR DdpPacket,
|
|
int DdpLength,
|
|
int port,
|
|
PCHAR Destination,
|
|
PCHAR RoutingInfo,
|
|
int RoutingInfoLength,
|
|
LOGICAL_PROTOCOL Protocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PCHAR packet = DdpPacket -
|
|
FddiLinkHeaderLength -
|
|
Ieee802dot2headerLength;
|
|
|
|
UNREFERENCED_PARAMETER(RoutingInfoLength);
|
|
UNREFERENCED_PARAMETER(RoutingInfo);
|
|
|
|
// Set Destination address. Use Fddi boardcast address, as needed.
|
|
if (Destination isnt empty)
|
|
MoveMem(
|
|
packet + FddiDestinationOffset,
|
|
Destination,
|
|
FddiAddressLength);
|
|
else
|
|
MoveMem(
|
|
packet + FddiDestinationOffset,
|
|
ethernetBroadcastAddress,
|
|
FddiAddressLength);
|
|
|
|
// Set source address.
|
|
MoveMem(
|
|
packet + FddiSourceOffset,
|
|
GET_PORTDESCRIPTOR(port)->MyAddress,
|
|
FddiAddressLength);
|
|
|
|
// Build the 802.2 header.
|
|
Build802dot2header(
|
|
packet + FddiLinkHeaderLength,
|
|
Protocol);
|
|
|
|
// All set!
|
|
return(packet);
|
|
|
|
} // NTBuildFddiHeader
|
|
|
|
|
|
|
|
|
|
//
|
|
// HALF-PORT SPECIFIC ROUTINES
|
|
//
|
|
|
|
|
|
BOOLEAN
|
|
NTInitializeHalfPort(
|
|
int Port,
|
|
PCHAR controllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
return(TRUE);
|
|
|
|
} // InitializeHalfPort
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTHalfPortPacketOut(
|
|
int Port,
|
|
BufferDescriptor Chain,
|
|
int Length,
|
|
TRANSMIT_COMPLETION
|
|
*TransmitCompleteHandler,
|
|
ULONG UserData
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
return(TRUE);
|
|
|
|
} // HalfPortPacketOut
|
|
|
|
|
|
|
|
|
|
PCHAR
|
|
NTBuildHalfPortHeader(
|
|
PCHAR DdpPacket,
|
|
int DdpLength,
|
|
int port,
|
|
PCHAR Destination,
|
|
PCHAR RoutingInfo,
|
|
int RoutingInfoLength,
|
|
LOGICAL_PROTOCOL Protocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// If this HalfPort has a loginal Destination address, it can be found
|
|
// in "portDescriptors[port].controllerInfo".
|
|
//
|
|
|
|
return(DdpPacket);
|
|
|
|
} // BuildHalfPortHeader
|
|
|
|
|
|
|
|
|
|
//
|
|
// ARAP SPECIFIC ROUTINES
|
|
//
|
|
|
|
|
|
#if ArapIncluded
|
|
|
|
|
|
BOOLEAN
|
|
NTInitializeRemoteAccess(
|
|
int Port,
|
|
PCHAR controllerInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
return(TRUE);
|
|
|
|
} // InitializeRemoteAccess
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
NTRemoteAccessPacketOut(
|
|
int Port,
|
|
BufferDescriptor Chain,
|
|
int Length,
|
|
TRANSMIT_COMPLETION
|
|
*TransmitCompleteHandler,
|
|
ULONG UserData)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
|
|
//
|
|
// Always coalesce remote access packets, we have some preprocessing to
|
|
// do.
|
|
//
|
|
|
|
if ((chain = CoalesceBufferChain(chain)) is Empty) {
|
|
ErrorLog("RemoteAccessPacketOut", ISevError, __LINE__, port,
|
|
IErrDependSourceNotKnown, IMsgDependSourceNotKnown,
|
|
Insert0());
|
|
return(False);
|
|
}
|
|
|
|
//
|
|
// There are some packets that we should be hiding from our client (packets
|
|
// sent by the client, RTMP boardcasts, NBP lookups from the client). Check
|
|
// this here.
|
|
//
|
|
|
|
if (ArapCensorPacket(port, chain->data, length)) {
|
|
chain->transmitCompleteHandler = transmitCompleteHandler;
|
|
chain->userData = userData;
|
|
TransmitComplete(chain);
|
|
return(True);
|
|
}
|
|
|
|
//
|
|
// Do whatever is needed to actually transmit the packet! Note that if
|
|
// "length" is less than the computed length of the buffer chain, the
|
|
// LAST buffer chunk should be truncated accordingly.
|
|
//
|
|
|
|
chain->transmitCompleteHandler = transmitCompleteHandler;
|
|
chain->userData = userData;
|
|
|
|
// DoTheTransmit(chain);
|
|
|
|
//
|
|
// If we don't have asynchronous transmit completion... free up the buffer
|
|
// now.
|
|
//
|
|
|
|
#if IncludeVirtualClient
|
|
VirtualClientPacketIn(port, chain->data);
|
|
#endif
|
|
|
|
if (portSpecificInfo[GET_PORTDESCRIPTOR(port)->PortType].synchronousTransmits)
|
|
TransmitComplete(chain);
|
|
|
|
return(True);
|
|
|
|
} // RemoteAccessPacketOut
|
|
|
|
|
|
|
|
|
|
VOID
|
|
NTRemoteAccessPacketInAT(
|
|
int Port,
|
|
PCHAR Packet,
|
|
int Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
// Handle the packet.
|
|
|
|
ArapIncomingPacket(Port, Packet, Length);
|
|
|
|
} // RemoteAccessPacketInAT
|
|
|
|
|
|
|
|
|
|
PCHAR
|
|
NTBuildRemoteAccessHeader(
|
|
PCHAR DdpPacket,
|
|
int DdpLength,
|
|
int port,
|
|
PCHAR Destination,
|
|
PCHAR RoutingInfo,
|
|
int RoutingInfoLength,
|
|
LOGICAL_PROTOCOL Protocol
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
|
|
PCHAR packet;
|
|
int headerLength;
|
|
short checksum;
|
|
|
|
// Touch unused formals.
|
|
|
|
Destination, RoutingInfoLength, RoutingInfo;
|
|
|
|
//
|
|
// Complete the length of the header based on what packet type; internal
|
|
// or data?
|
|
//
|
|
|
|
if (arapFlags is ArapInternalMessageFlagValue)
|
|
headerLength = ArapInternalMessageHeaderLength;
|
|
else
|
|
headerLength = ArapDataHeaderLength;
|
|
packet = DdpPacket - headerLength;
|
|
|
|
// Fill in the ARAP header (modem link tool) common to both.
|
|
|
|
MoveShortMachineToWire(packet + ModemLinkToolLengthOffset,
|
|
headerLength - sizeof(short) + packetLength);
|
|
packet[ArapFlagsOffset] = (char)arapFlags;
|
|
|
|
// For an internal add int he sequence number, and we're set.
|
|
|
|
if (arapFlags is ArapInternalMessageFlagValue) {
|
|
packet[ArapSequenceNumberOffset] =
|
|
portDescriptors[port].remoteAccessInfo->nextOutgoingSequenceNumber;
|
|
return(packet);
|
|
}
|
|
|
|
// Otherwise, fill in the LAP header for ARAP.
|
|
|
|
packet[ArapLapHeaderOffset + AlapDestinationOffset] = 0;
|
|
packet[ArapLapHeaderOffset + AlapSourceOffset] = 0;
|
|
packet[ArapLapHeaderOffset + AlapTypeOffset] = (char)AlapLongDdpHeaderType;
|
|
|
|
//
|
|
// Also, set the Ddp length field to zero (don't alter the hop-count), and
|
|
// if there is a checksum set, reset it to 1.
|
|
//
|
|
|
|
#if 0
|
|
packet[ArapDdpHeaderOffset + LongDdpLengthOffset] |= LongDdpHopCountMask;
|
|
#else
|
|
packet[ArapDdpHeaderOffset + LongDdpLengthOffset] &= LongDdpHopCountMask;
|
|
#endif
|
|
packet[ArapDdpHeaderOffset + LongDdpLengthOffset + 1] = 0;
|
|
MoveShortWireToMachine(packet + ArapDdpHeaderOffset + LongDdpChecksumOffset,
|
|
checksum);
|
|
if (checksum isnt 0)
|
|
MoveShortMachineToWire(packet + ArapDdpHeaderOffset +
|
|
LongDdpChecksumOffset, 1);
|
|
|
|
return(packet);
|
|
|
|
} // BuildRemoteAccessHeader
|
|
|
|
|
|
|
|
|
|
void
|
|
RemoteAccessIncomingCall(
|
|
int port
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
// Handle the call.
|
|
|
|
ArapHandleIncomingConnection(port);
|
|
|
|
} // RemoteAccessIncomingCall
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
RemoteAccessOutgoingCall(
|
|
int port,
|
|
PCHAR modemString
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
port, modemString;
|
|
|
|
// Do whatever we need to do to place the outgoing call.
|
|
|
|
return(True);
|
|
|
|
} // RemoteAccessOutgoingCall
|
|
|
|
|
|
|
|
|
|
void
|
|
RemoteAccessCallDisconnected(
|
|
int port
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
// Handle the disconnect.
|
|
|
|
ArapHandleConnectionDisconnect(port);
|
|
|
|
} // RemoteAccessCallDisconnected
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
RemoteAccessDisconnectCall(
|
|
int port
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
port;
|
|
|
|
// Do whatever is needed to disconnect the connection.
|
|
|
|
return(True);
|
|
|
|
} // RemoteAccessCallDisconnected
|
|
|
|
#endif
|
|
|
|
|