Fixed bugs in TCP/IP driver

svn path=/trunk/; revision=1317
This commit is contained in:
Casper Hornstrup 2000-08-27 16:28:59 +00:00
parent 24d06e9f82
commit abd30f9819
11 changed files with 314 additions and 195 deletions

View file

@ -211,12 +211,16 @@ VOID ARPReceive(
Header = (PARP_HEADER)Packet->Header;
/* FIXME: Ethernet only */
if (WN2H(Header->HWType) != 1)
if (WN2H(Header->HWType) != 1) {
TI_DbgPrint(DEBUG_ARP, ("Unknown ARP hardware type (0x%X).\n", WN2H(Header->HWType)));
return;
}
/* Check protocol type */
if (Header->ProtoType != ETYPE_IPv4)
if (Header->ProtoType != ETYPE_IPv4) {
TI_DbgPrint(DEBUG_ARP, ("Unknown ARP protocol type (0x%X).\n", WN2H(Header->ProtoType)));
return;
}
SenderHWAddress = (PVOID)((ULONG_PTR)Header + sizeof(ARP_HEADER));
SenderProtoAddress = (PVOID)((ULONG_PTR)SenderHWAddress + Header->HWAddrLen);
@ -226,16 +230,16 @@ VOID ARPReceive(
TargetProtoAddress = (PVOID)((ULONG_PTR)SenderProtoAddress +
Header->ProtoAddrLen + Header->HWAddrLen);
Address = AddrBuildIPv4(*(PULONG)(TargetProtoAddress));
Address = AddrBuildIPv4(*((PULONG)TargetProtoAddress));
ADE = IPLocateADE(Address, ADE_UNICAST);
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
TI_DbgPrint(DEBUG_ARP, ("Target address (0x%X) is not mine.\n", *((PULONG)TargetProtoAddress)));
return;
}
/* Check if we know the sender */
AddrInitIPv4(Address, *(PULONG)(SenderProtoAddress));
AddrInitIPv4(Address, *((PULONG)SenderProtoAddress));
NCE = NBLocateNeighbor(Address);
if (NCE) {
DereferenceObject(Address);
@ -269,8 +273,11 @@ VOID ARPReceive(
ARP_OPCODE_REPLY); /* ARP reply */
if (NdisPacket) {
PC(NdisPacket)->DLComplete = ARPTransmitComplete;
(*Interface->Transmit)(Interface->Context, NdisPacket,
MaxLLHeaderSize, SenderHWAddress, LAN_PROTO_ARP);
(*Interface->Transmit)(Interface->Context,
NdisPacket,
MaxLLHeaderSize,
SenderHWAddress,
LAN_PROTO_ARP);
}
}

View file

@ -18,7 +18,8 @@
NDIS_HANDLE NdisProtocolHandle = (NDIS_HANDLE)NULL;
BOOLEAN ProtocolRegistered = FALSE;
PLAN_ADAPTER Adapters = NULL;
LIST_ENTRY AdapterListHead;
KSPIN_LOCK AdapterListLock;
NDIS_STATUS NDISCall(
@ -55,12 +56,17 @@ NDIS_STATUS NDISCall(
if (Adapter->State != LAN_STATE_RESETTING) {
NdisRequest(&NdisStatus, Adapter->NdisHandle, &Request);
} else
} else {
NdisStatus = NDIS_STATUS_NOT_ACCEPTED;
}
/* Wait for NDIS to complete the request */
if (NdisStatus == NDIS_STATUS_PENDING) {
KeWaitForSingleObject(&Adapter->Event, UserRequest, KernelMode, FALSE, NULL);
KeWaitForSingleObject(&Adapter->Event,
UserRequest,
KernelMode,
FALSE,
NULL);
NdisStatus = Adapter->NdisStatus;
}
@ -94,7 +100,11 @@ PNDIS_PACKET AllocateTDPacket(
return NULL;
}
NdisAllocateBuffer(&NdisStatus, &Buffer, GlobalBufferPool, Data, Adapter->MTU);
NdisAllocateBuffer(&NdisStatus,
&Buffer,
GlobalBufferPool,
Data,
Adapter->MTU);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
NdisFreePacket(NdisPacket);
ExFreePool(Data);
@ -157,7 +167,7 @@ VOID ProtocolOpenAdapterComplete(
{
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
KeSetEvent(&Adapter->Event, 0, FALSE);
}
@ -175,7 +185,7 @@ VOID ProtocolCloseAdapterComplete(
{
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
Adapter->NdisStatus = Status;
@ -211,6 +221,8 @@ VOID ProtocolRequestComplete(
{
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
/* Save status of request and signal an event */
Adapter->NdisStatus = Status;
@ -230,9 +242,9 @@ VOID ProtocolSendComplete(
* Status = Status of the operation
*/
{
PLAN_ADAPTER Adapter = BindingContext;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
AdjustPacket(Packet, Adapter->HeaderSize, PC(Packet)->DLOffset);
@ -260,13 +272,19 @@ VOID ProtocolTransferDataComplete(
UINT PacketType;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
if (Status == NDIS_STATUS_SUCCESS) {
PNDIS_BUFFER NdisBuffer;
IP_PACKET IPPacket;
NdisGetFirstBufferFromPacket(
Packet, &NdisBuffer, &IPPacket.Header,
&IPPacket.ContigSize, &IPPacket.TotalSize);
IPPacket.NdisPacket = Packet;
NdisGetFirstBufferFromPacket(Packet,
&NdisBuffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
/* Determine which upper layer protocol that should receive
this packet and pass it to the correct receive handler */
@ -318,64 +336,89 @@ NDIS_STATUS ProtocolReceive(
USHORT EType;
UINT PacketType;
IP_PACKET IPPacket;
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
PETH_HEADER EHeader = (PETH_HEADER)HeaderBuffer;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
if ((Adapter->State != LAN_STATE_STARTED) ||
HeaderBufferSize < Adapter->HeaderSize)
/* Adapter is not started or the header was too small */
if (Adapter->State != LAN_STATE_STARTED) {
TI_DbgPrint(DEBUG_DATALINK, ("Adapter is stopped.\n"));
return NDIS_STATUS_NOT_ACCEPTED;
}
if (HeaderBufferSize < Adapter->HeaderSize) {
TI_DbgPrint(DEBUG_DATALINK, ("Runt frame received.\n"));
return NDIS_STATUS_NOT_ACCEPTED;
}
if (Adapter->Media == NdisMedium802_3) {
/* Ethernet and IEEE 802.3 frames can be destinguished by
looking at the IEEE 802.3 length field. This field is
less than or equal to 1500 for a valid IEEE 802.3 frame
and larger than 1500 is it's a valid Ether-Type value.
and larger than 1500 is it's a valid EtherType value.
See RFC 1122, section 2.3.3 for more information */
if (((EType = EHeader->EType) != ETYPE_IPv4) && (EType != ETYPE_ARP))
/* FIXME: Test for Ethernet and IEEE 802.3 frame */
if (((EType = EHeader->EType) != ETYPE_IPv4) && (EType != ETYPE_ARP)) {
TI_DbgPrint(DEBUG_DATALINK, ("Not IP or ARP frame. EtherType (0x%X).\n", EType));
return NDIS_STATUS_NOT_ACCEPTED;
/* We use Ether-Type constants to destinguish packets */
}
/* We use EtherType constants to destinguish packet types */
PacketType = EType;
} else
} else {
TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
/* FIXME: Support other medias */
return NDIS_STATUS_NOT_ACCEPTED;
}
/* Get a transfer data packet */
KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
NdisPacket = Adapter->TDPackets;
if (NdisPacket == (PNDIS_PACKET)NULL) {
TI_DbgPrint(DEBUG_DATALINK, ("No available packet descriptors.\n"));
/* We don't have a free packet descriptor. Drop the packet */
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
return NDIS_STATUS_SUCCESS;
}
Adapter->TDPackets = PC(NdisPacket)->Context;
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
if (LookaheadBufferSize < PacketSize) {
NDIS_STATUS NdisStatus;
PNDIS_PACKET NdisPacket;
UINT BytesTransferred;
/* Get transfer data packet */
KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
NdisPacket = Adapter->TDPackets;
if (NdisPacket == (PNDIS_PACKET)NULL) {
/* We don't have a free packet descriptor. Drop the packet */
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
return NDIS_STATUS_SUCCESS;
}
Adapter->TDPackets = PC(NdisPacket)->Context;
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
/* Get the data */
NdisTransferData(&NdisStatus, Adapter->NdisHandle,
MacReceiveContext, 0, PacketSize,
NdisPacket, &BytesTransferred);
NdisTransferData(&NdisStatus,
Adapter->NdisHandle,
MacReceiveContext,
0,
PacketSize,
NdisPacket,
&BytesTransferred);
if (NdisStatus != NDIS_STATUS_PENDING)
ProtocolTransferDataComplete(BindingContext,
NdisPacket, NdisStatus, BytesTransferred);
NdisPacket,
NdisStatus,
BytesTransferred);
return NDIS_STATUS_SUCCESS;
}
/* We got all the data in the lookahead buffer */
RtlZeroMemory(&IPPacket, sizeof(IPPacket));
IPPacket.Header = LookaheadBuffer;
IPPacket.TotalSize = PacketSize;
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
&NdisBuffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
RtlCopyMemory(IPPacket.Header, LookaheadBuffer, PacketSize);
switch (PacketType) {
case ETYPE_IPv4:
@ -389,6 +432,14 @@ NDIS_STATUS ProtocolReceive(
break;
}
/* Release the packet descriptor */
KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
PC(NdisPacket)->Context = Adapter->TDPackets;
Adapter->TDPackets = NdisPacket;
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
return NDIS_STATUS_SUCCESS;
}
@ -401,7 +452,7 @@ VOID ProtocolReceiveComplete(
* BindingContext = Pointer to a device context (LAN_ADAPTER)
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
}
@ -419,7 +470,7 @@ VOID ProtocolStatus(
* StatusBufferSize = Number of bytes in StatusBuffer
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
}
@ -431,7 +482,7 @@ VOID ProtocolStatusComplete(
* BindingContext = Pointer to a device context (LAN_ADAPTER)
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
}
@ -456,7 +507,7 @@ VOID LANTransmit(
PVOID Data;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
/* NDIS send routines don't have an offset argument so we
must offset the data in upper layers and adjust the
@ -469,13 +520,14 @@ VOID LANTransmit(
switch (Adapter->Media) {
case NdisMedium802_3:
EHeader = (PETH_HEADER)Data;
if (LinkAddress)
if (LinkAddress) {
/* Unicast address */
RtlCopyMemory(EHeader->DstAddr, LinkAddress, IEEE_802_ADDR_LENGTH);
else
} else {
/* Broadcast address */
RtlFillMemory(EHeader->DstAddr, IEEE_802_ADDR_LENGTH, 0xFF);
}
RtlCopyMemory(EHeader->SrcAddr, Adapter->HWAddress, IEEE_802_ADDR_LENGTH);
@ -490,11 +542,13 @@ VOID LANTransmit(
EHeader->EType = ETYPE_IPv6;
break;
default:
#if DBG
#ifdef DBG
/* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown LAN protocol.\n"));
ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NDIS_STATUS_FAILURE);
ProtocolSendComplete((NDIS_HANDLE)Context,
NdisPacket,
NDIS_STATUS_FAILURE);
#endif
return;
}
@ -504,12 +558,13 @@ VOID LANTransmit(
/* FIXME: Support other medias */
break;
}
NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket);
if (NdisStatus != NDIS_STATUS_PENDING)
ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NdisStatus);
} else
} else {
ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NDIS_STATUS_CLOSED);
}
}
@ -532,12 +587,15 @@ VOID BindAdapter(
LLIP_BIND_INFO BindInfo;
ULONG Lookahead = LOOKAHEAD_SIZE;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
Adapter->State = LAN_STATE_OPENING;
NdisStatus = NDISCall(Adapter, NdisRequestSetInformation,
OID_GEN_CURRENT_LOOKAHEAD, &Lookahead, sizeof(ULONG));
NdisStatus = NDISCall(Adapter,
NdisRequestSetInformation,
OID_GEN_CURRENT_LOOKAHEAD,
&Lookahead,
sizeof(ULONG));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MID_TRACE, ("Could not set lookahead buffer size (0x%X).\n", NdisStatus));
return;
@ -551,7 +609,7 @@ VOID BindAdapter(
PC(Packet)->Context = Adapter->TDPackets;
Adapter->TDPackets = Packet;
if (!Packet) {
TI_DbgPrint(MID_TRACE, ("Could not allocate transfer data packet (out of resources).\n"));
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
FreeTDPackets(Adapter);
return;
}
@ -590,16 +648,19 @@ VOID BindAdapter(
return;
}
/* Reference the interface for the NTE. The reference for
the address is just passed on to the NTE */
/* Reference the interface for the NTE. The reference
for the address is just passed on to the NTE */
ReferenceObject(IF);
/* Register interface with IP layer */
IPRegisterInterface(IF);
/* Set packet filter so we can send and receive packets */
NdisStatus = NDISCall(Adapter, NdisRequestSetInformation,
OID_GEN_CURRENT_PACKET_FILTER, &Adapter->PacketFilter, sizeof(UINT));
NdisStatus = NDISCall(Adapter,
NdisRequestSetInformation,
OID_GEN_CURRENT_PACKET_FILTER,
&Adapter->PacketFilter,
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MID_TRACE, ("Could not set packet filter (0x%X).\n", NdisStatus));
FreeTDPackets(Adapter);
@ -621,7 +682,7 @@ VOID UnbindAdapter(
* Adapter = Pointer to LAN_ADAPTER structure
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
if (Adapter->State == LAN_STATE_STARTED) {
PIP_INTERFACE IF = Adapter->Context;
@ -656,11 +717,13 @@ NDIS_STATUS LANRegisterAdapter(
UINT AddressOID;
UINT Speed;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
IF = ExAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER));
if (!IF)
if (!IF) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES;
}
RtlZeroMemory(IF, sizeof(LAN_ADAPTER));
@ -676,8 +739,17 @@ NDIS_STATUS LANRegisterAdapter(
MediaArray[MEDIA_ETH] = NdisMedium802_3;
/* Open the adapter. */
NdisOpenAdapter(&NdisStatus, &OpenStatus, &IF->NdisHandle, &MediaIndex,
MediaArray, MAX_MEDIA, NdisProtocolHandle, IF, AdapterName, 0, NULL);
NdisOpenAdapter(&NdisStatus,
&OpenStatus,
&IF->NdisHandle,
&MediaIndex,
MediaArray,
MAX_MEDIA,
NdisProtocolHandle,
IF,
AdapterName,
0,
NULL);
/* Wait until the adapter is opened */
if (NdisStatus == NDIS_STATUS_PENDING)
@ -713,16 +785,22 @@ NDIS_STATUS LANRegisterAdapter(
}
/* Get maximum frame size */
NdisStatus = NDISCall(IF, NdisRequestQueryInformation,
OID_GEN_MAXIMUM_FRAME_SIZE, &IF->MTU, sizeof(UINT));
NdisStatus = NDISCall(IF,
NdisRequestQueryInformation,
OID_GEN_MAXIMUM_FRAME_SIZE,
&IF->MTU,
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
ExFreePool(IF);
return NdisStatus;
}
/* Get maximum packet size */
NdisStatus = NDISCall(IF, NdisRequestQueryInformation,
OID_GEN_MAXIMUM_TOTAL_SIZE, &IF->MaxPacketSize, sizeof(UINT));
NdisStatus = NDISCall(IF,
NdisRequestQueryInformation,
OID_GEN_MAXIMUM_TOTAL_SIZE,
&IF->MaxPacketSize,
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n"));
ExFreePool(IF);
@ -730,16 +808,22 @@ NDIS_STATUS LANRegisterAdapter(
}
/* Get maximum number of packets we can pass to NdisSend(Packets) at one time */
NdisStatus = NDISCall(IF, NdisRequestQueryInformation,
OID_GEN_MAXIMUM_SEND_PACKETS, &IF->MaxSendPackets, sizeof(UINT));
NdisStatus = NDISCall(IF,
NdisRequestQueryInformation,
OID_GEN_MAXIMUM_SEND_PACKETS,
&IF->MaxSendPackets,
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS)
/* Legacy NIC drivers may not support this query, if it fails we
assume it can send at least one packet per call to NdisSend(Packets) */
IF->MaxSendPackets = 1;
/* Get current hardware address */
NdisStatus = NDISCall(IF, NdisRequestQueryInformation, AddressOID,
IF->HWAddress, IF->HWAddressLength);
NdisStatus = NDISCall(IF,
NdisRequestQueryInformation,
AddressOID,
&IF->HWAddress,
IF->HWAddressLength);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n"));
ExFreePool(IF);
@ -747,8 +831,11 @@ NDIS_STATUS LANRegisterAdapter(
}
/* Get maximum link speed */
NdisStatus = NDISCall(IF, NdisRequestQueryInformation,
OID_GEN_LINK_SPEED, &Speed, sizeof(UINT));
NdisStatus = NDISCall(IF,
NdisRequestQueryInformation,
OID_GEN_LINK_SPEED,
&Speed,
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n"));
ExFreePool(IF);
@ -761,13 +848,14 @@ NDIS_STATUS LANRegisterAdapter(
*Adapter = IF;
/* Add adapter to the adapter list */
IF->Next = Adapters;
Adapters = IF;
ExInterlockedInsertTailList(&AdapterListHead,
&IF->ListEntry,
&AdapterListLock);
/* Bind adapter to IP layer */
BindAdapter(IF);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Leaving.\n"));
return NDIS_STATUS_SUCCESS;
}
@ -785,35 +873,12 @@ NDIS_STATUS LANUnregisterAdapter(
{
KIRQL OldIrql;
NDIS_HANDLE NdisHandle;
PLAN_ADAPTER IF, PrevIF;
BOOLEAN Found = FALSE;
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
/* Search the adapter list for the specified adapter and remove it */
IF = Adapters;
if (IF) {
if (Adapter != Adapters) {
PrevIF = IF;
while ((IF) && (!Found)) {
if (IF == Adapter) {
/* We've found the adapter, now remove it from the list */
PrevIF->Next = IF->Next;
Found = TRUE;
}
PrevIF = IF;
IF = IF->Next;
}
} else {
Adapters = NULL;
Found = TRUE;
}
}
if (!Found) {
TI_DbgPrint(MIN_TRACE, ("Leaving (adapter was not in list).\n"));
return NDIS_STATUS_ADAPTER_NOT_FOUND;
}
/* Unlink the adapter from the list */
RemoveEntryList(&Adapter->ListEntry);
/* Unbind adapter from IP layer */
UnbindAdapter(Adapter);
@ -827,7 +892,10 @@ NDIS_STATUS LANUnregisterAdapter(
NdisCloseAdapter(&NdisStatus, NdisHandle);
if (NdisStatus == NDIS_STATUS_PENDING) {
KeWaitForSingleObject(&Adapter->Event,
UserRequest, KernelMode, FALSE, NULL);
UserRequest,
KernelMode,
FALSE,
NULL);
NdisStatus = Adapter->NdisStatus;
}
} else
@ -852,27 +920,33 @@ NTSTATUS LANRegisterProtocol(
NDIS_STATUS NdisStatus;
NDIS_PROTOCOL_CHARACTERISTICS ProtChars;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
InitializeListHead(&AdapterListHead);
KeInitializeSpinLock(&AdapterListLock);
/* Set up protocol characteristics */
RtlZeroMemory(&ProtChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
ProtChars.MajorNdisVersion = NDIS_VERSION_MAJOR;
ProtChars.MinorNdisVersion = NDIS_VERSION_MINOR;
ProtChars.Name.Length = Name->Length;
ProtChars.Name.Buffer = (PVOID)Name->Buffer;
ProtChars.OpenAdapterCompleteHandler = ProtocolOpenAdapterComplete;
ProtChars.CloseAdapterCompleteHandler = ProtocolCloseAdapterComplete;
ProtChars.ResetCompleteHandler = ProtocolResetComplete;
ProtChars.RequestCompleteHandler = ProtocolRequestComplete;
ProtChars.MajorNdisVersion = NDIS_VERSION_MAJOR;
ProtChars.MinorNdisVersion = NDIS_VERSION_MINOR;
ProtChars.Name.Length = Name->Length;
ProtChars.Name.Buffer = (PVOID)Name->Buffer;
ProtChars.OpenAdapterCompleteHandler = ProtocolOpenAdapterComplete;
ProtChars.CloseAdapterCompleteHandler = ProtocolCloseAdapterComplete;
ProtChars.ResetCompleteHandler = ProtocolResetComplete;
ProtChars.RequestCompleteHandler = ProtocolRequestComplete;
ProtChars.u2.SendCompleteHandler = ProtocolSendComplete;
ProtChars.u3.TransferDataCompleteHandler = ProtocolTransferDataComplete;
ProtChars.u4.ReceiveHandler = ProtocolReceive;
ProtChars.ReceiveCompleteHandler = ProtocolReceiveComplete;
ProtChars.StatusHandler = ProtocolStatus;
ProtChars.StatusCompleteHandler = ProtocolStatusComplete;
ProtChars.ReceiveCompleteHandler = ProtocolReceiveComplete;
ProtChars.StatusHandler = ProtocolStatus;
ProtChars.StatusCompleteHandler = ProtocolStatusComplete;
/* Try to register protocol */
NdisRegisterProtocol(
&NdisStatus, &NdisProtocolHandle, &ProtChars,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS) + Name->Length);
NdisRegisterProtocol(&NdisStatus,
&NdisProtocolHandle,
&ProtChars,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS) + Name->Length);
if (NdisStatus != NDIS_STATUS_SUCCESS)
return (NTSTATUS)NdisStatus;
@ -889,11 +963,28 @@ VOID LANUnregisterProtocol(
* NOTES: Does not care wether we are already registered
*/
{
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
if (ProtocolRegistered) {
NDIS_STATUS NdisStatus;
PLIST_ENTRY CurrentEntry;
PLIST_ENTRY NextEntry;
PLAN_ADAPTER Current;
KIRQL OldIrql;
while (Adapters)
NdisStatus = LANUnregisterAdapter(Adapters);
KeAcquireSpinLock(&AdapterListLock, &OldIrql);
/* Search the list and remove every adapter we find */
CurrentEntry = AdapterListHead.Flink;
while (CurrentEntry != &AdapterListHead) {
NextEntry = CurrentEntry->Flink;
Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry);
/* Unregister it */
LANUnregisterAdapter(Current);
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&AdapterListLock, OldIrql);
NdisDeregisterProtocol(&NdisStatus, NdisProtocolHandle);
ProtocolRegistered = FALSE;

View file

@ -37,8 +37,8 @@ VOID RealTransmit(
{
KIRQL OldIrql;
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
IP_PACKET IPPacket;
PNDIS_BUFFER Buffer;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
@ -59,10 +59,10 @@ VOID RealTransmit(
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
&Buffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
&NdisBuffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
IPReceive(Context, &IPPacket);

View file

@ -20,10 +20,13 @@
#define DEBUG_IRP 0x00000400
#define DEBUG_REFCOUNT 0x00000800
#define DEBUG_ADDRFILE 0x00001000
#define DEBUG_IP 0x00002000
#define DEBUG_ROUTER 0x00004000
#define DEBUG_RCACHE 0x00008000
#define DEBUG_NCACHE 0x00010000
#define DEBUG_DATALINK 0x00002000
#define DEBUG_ARP 0x00004000
#define DEBUG_IP 0x00008000
#define DEBUG_ICMP 0x00010000
#define DEBUG_ROUTER 0x00020000
#define DEBUG_RCACHE 0x00040000
#define DEBUG_NCACHE 0x00080000
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG

View file

@ -35,7 +35,7 @@ typedef struct ETH_HEADER {
/* Per adapter information */
typedef struct LAN_ADAPTER {
struct LAN_ADAPTER *Next; /* Pointer to next adapter */
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Lock for this structure */
UCHAR State; /* State of the adapter */
KEVENT Event; /* Opening event */
@ -69,7 +69,7 @@ typedef struct LAN_ADAPTER {
#define LOOKAHEAD_SIZE 128
/* Ethernet types. We swap constants so we can compare values at runtime
without swapping them */
without swapping them there */
#define ETYPE_IPv4 WH2N(0x0800)
#define ETYPE_IPv6 WH2N(0x0000) /* FIXME */
#define ETYPE_ARP WH2N(0x0806)
@ -79,8 +79,6 @@ typedef struct LAN_ADAPTER {
#define LAN_PROTO_IPv6 0x0001 /* Internet Protocol version 6 */
#define LAN_PROTO_ARP 0x0002 /* Address Resolution Protocol */
extern PLAN_ADAPTER Adapters;
NDIS_STATUS LANRegisterAdapter(
PNDIS_STRING AdapterName,

View file

@ -31,14 +31,12 @@ VOID SendICMPComplete(
{
PIP_PACKET IPPacket = (PIP_PACKET)Context;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("Freeing NDIS packet (%X).\n", Packet));
TI_DbgPrint(DEBUG_ICMP, ("Freeing NDIS packet (%X).\n", Packet));
/* Free packet */
FreeNdisPacket(Packet);
TI_DbgPrint(MAX_TRACE, ("Freeing IP packet at %X.\n", IPPacket));
TI_DbgPrint(DEBUG_ICMP, ("Freeing IP packet at %X.\n", IPPacket));
PoolFreeBuffer(IPPacket);
}
@ -66,14 +64,14 @@ PIP_PACKET PrepareICMPPacket(
PVOID DataBuffer;
ULONG Size;
TI_DbgPrint(MAX_TRACE, ("Called. DataSize = %d.\n", DataSize));
TI_DbgPrint(DEBUG_ICMP, ("Called. DataSize (%d).\n", DataSize));
/* Prepare ICMP packet */
IPPacket = PoolAllocateBuffer(sizeof(IP_PACKET));
if (!IPPacket)
return NULL;
TI_DbgPrint(MAX_TRACE, ("IPPacket at %X.\n", IPPacket));
TI_DbgPrint(DEBUG_ICMP, ("IPPacket at (0x%X).\n", IPPacket));
Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) +
sizeof(ICMP_HEADER) + DataSize;
@ -83,7 +81,7 @@ PIP_PACKET PrepareICMPPacket(
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("Size = %d, Data at %X.\n", Size, DataBuffer));
TI_DbgPrint(DEBUG_ICMP, ("Size (%d). Data at (0x%X).\n", Size, DataBuffer));
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
@ -93,7 +91,7 @@ PIP_PACKET PrepareICMPPacket(
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("NdisPacket at %X.\n", NdisPacket));
TI_DbgPrint(MAX_TRACE, ("NdisPacket at (0x%X).\n", NdisPacket));
/* Allocate NDIS buffer for maximum link level header and ICMP packet */
NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
@ -105,7 +103,7 @@ PIP_PACKET PrepareICMPPacket(
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("NdisBuffer at %X.\n", NdisBuffer));
TI_DbgPrint(MAX_TRACE, ("NdisBuffer at (0x%X).\n", NdisBuffer));
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(NdisPacket, NdisBuffer);
@ -164,26 +162,24 @@ VOID ICMPReceive(
PICMP_HEADER ICMPHeader;
PIP_PACKET NewPacket;
UINT DataSize;
ULONG Checksum;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_ICMP, ("Called.\n"));
ICMPHeader = (PICMP_HEADER)IPPacket->Data;
TI_DbgPrint(MID_TRACE, ("Size = %d.\n", IPPacket->TotalSize));
TI_DbgPrint(DEBUG_ICMP, ("Size (%d).\n", IPPacket->TotalSize));
TI_DbgPrint(MID_TRACE, ("HeaderSize = %d.\n", IPPacket->HeaderSize));
TI_DbgPrint(DEBUG_ICMP, ("HeaderSize (%d).\n", IPPacket->HeaderSize));
TI_DbgPrint(MID_TRACE, ("Type = %d.\n", ICMPHeader->Type));
TI_DbgPrint(DEBUG_ICMP, ("Type (%d).\n", ICMPHeader->Type));
TI_DbgPrint(MID_TRACE, ("Code = %d.\n", ICMPHeader->Code));
TI_DbgPrint(DEBUG_ICMP, ("Code (%d).\n", ICMPHeader->Code));
TI_DbgPrint(MID_TRACE, ("Checksum = %X.\n", ICMPHeader->Checksum));
TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum));
/* Checksum ICMP header and data and compare */
Checksum = DN2H(IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0));
if (Checksum != 0xFFFF) {
TI_DbgPrint(MIN_TRACE, ("Bad ICMP checksum (0x%X).\n", Checksum));
/* Checksum ICMP header and data */
if (!CorrectChecksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize)) {
TI_DbgPrint(DEBUG_ICMP, ("Bad ICMP checksum.\n"));
/* Discard packet */
return;
}
@ -193,8 +189,10 @@ VOID ICMPReceive(
/* Reply with an ICMP echo reply message */
DataSize = IPPacket->TotalSize - IPPacket->HeaderSize - sizeof(ICMP_HEADER);
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
if (!NewPacket)
if (!NewPacket) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return;
}
/* Copy ICMP header and data into new packet */
RtlCopyMemory(NewPacket->Data, IPPacket->Data, DataSize + sizeof(ICMP_HEADER));
@ -204,11 +202,11 @@ VOID ICMPReceive(
ICMPTransmit(NTE, NewPacket);
TI_DbgPrint(MID_TRACE, ("Echo reply sent.\n"));
TI_DbgPrint(DEBUG_ICMP, ("Echo reply sent.\n"));
return;
default:
TI_DbgPrint(MID_TRACE, ("Discarded ICMP datagram of unknown type.\n"));
TI_DbgPrint(DEBUG_ICMP, ("Discarded ICMP datagram of unknown type.\n"));
/* Discard packet */
break;
}
@ -227,7 +225,7 @@ VOID ICMPTransmit(
{
PROUTE_CACHE_NODE RCN;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(DEBUG_ICMP, ("Called.\n"));
/* Calculate checksum of ICMP header and data */
((PICMP_HEADER)IPPacket->Data)->Checksum = (USHORT)
@ -243,10 +241,10 @@ VOID ICMPTransmit(
/* We're done with the RCN */
DereferenceObject(RCN);
} else {
TI_DbgPrint(MIN_TRACE, ("RCN at 0x%X.\n", RCN));
TI_DbgPrint(MIN_TRACE, ("RCN at (0x%X).\n", RCN));
/* No route to destination (or no free resources) */
TI_DbgPrint(MIN_TRACE, ("No route to destination address 0x%X.\n",
TI_DbgPrint(DEBUG_ICMP, ("No route to destination address 0x%X.\n",
IPPacket->DstAddr.Address.IPv4Address));
/* Discard packet */
FreeNdisPacket(IPPacket->NdisPacket);
@ -277,15 +275,17 @@ VOID ICMPReply(
UINT DataSize;
PIP_PACKET NewPacket;
TI_DbgPrint(MID_TRACE, ("Called (Type=%d, Code=%d).\n", Type, Code));
TI_DbgPrint(DEBUG_ICMP, ("Called. Type (%d) Code (%d).\n", Type, Code));
DataSize = IPPacket->TotalSize;
if ((DataSize) > (576 - sizeof(IPv4_HEADER) - sizeof(ICMP_HEADER)))
DataSize = 576;
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
if (!NewPacket)
if (!NewPacket) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return;
}
RtlCopyMemory((PVOID)((ULONG_PTR)NewPacket->Data + sizeof(ICMP_HEADER)),
IPPacket->Header, DataSize);

View file

@ -549,7 +549,7 @@ PADDRESS_ENTRY IPGetDefaultADE(
PLIST_ENTRY CurrentADEEntry;
PIP_INTERFACE CurrentIF;
PADDRESS_ENTRY CurrentADE;
#if 0
#if 1
BOOLEAN LoopbackIsRegistered = FALSE;
#endif
TI_DbgPrint(DEBUG_IP, ("Called. AddressType (0x%X).\n", AddressType));
@ -560,7 +560,7 @@ PADDRESS_ENTRY IPGetDefaultADE(
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
#if 0
#if 1
if (CurrentIF != Loopback) {
#endif
/* Search the address entry list and return the first appropriate ADE found */
@ -573,13 +573,13 @@ PADDRESS_ENTRY IPGetDefaultADE(
return CurrentADE;
}
CurrentADEEntry = CurrentADEEntry->Flink;
#if 0
#if 1
} else
LoopbackIsRegistered = TRUE;
#endif
CurrentIFEntry = CurrentIFEntry->Flink;
}
#if 0
#if 1
/* No address was found. Use loopback interface if available */
if (LoopbackIsRegistered) {
CurrentADEEntry = Loopback->ADEListHead.Flink;
@ -671,19 +671,27 @@ PIP_INTERFACE IPCreateInterface(
TI_DbgPrint(DEBUG_IP, ("Called. BindInfo (0x%X).\n", BindInfo));
#ifdef DBG
if (BindInfo->Address) {
PUCHAR A = BindInfo->Address;
TI_DbgPrint(DEBUG_IP, ("Interface address (%02X %02X %02X %02X %02X %02X).\n",
A[0], A[1], A[2], A[3], A[4], A[5]));
}
#endif
IF = PoolAllocateBuffer(sizeof(IP_INTERFACE));
if (!IF) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
IF->RefCount = 1;
IF->Context = BindInfo->Context;
IF->HeaderSize = BindInfo->HeaderSize;
IF->RefCount = 1;
IF->Context = BindInfo->Context;
IF->HeaderSize = BindInfo->HeaderSize;
if (IF->HeaderSize > MaxLLHeaderSize)
MaxLLHeaderSize = IF->HeaderSize;
IF->MinFrameSize = BindInfo->MinFrameSize;
IF->MinFrameSize = BindInfo->MinFrameSize;
if (IF->MinFrameSize > MinLLFrameSize)
MinLLFrameSize = IF->MinFrameSize;

View file

@ -270,8 +270,11 @@ NTSTATUS IPSendFragment(
}
PC(NdisPacket)->DLComplete = IPSendComplete;
(*NCE->Interface->Transmit)(NCE->Interface->Context, NdisPacket,
MaxLLHeaderSize, NCE->LinkAddress, LAN_PROTO_IPv4);
(*NCE->Interface->Transmit)(NCE->Interface->Context,
NdisPacket,
MaxLLHeaderSize,
NCE->LinkAddress,
LAN_PROTO_IPv4);
return STATUS_SUCCESS;
}

View file

@ -18,8 +18,10 @@
#ifdef DBG
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
#endif /* DBG */
PDEVICE_OBJECT TCPDeviceObject = NULL;
@ -525,11 +527,11 @@ VOID TiUnload(
* DriverObject = Pointer to driver object created by the system
*/
{
#ifdef BDG
#ifdef DBG
KIRQL OldIrql;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
if (!IsListEmpty(AddressFileList)) {
if (!IsListEmpty(&AddressFileListHead)) {
TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
}
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
@ -539,9 +541,7 @@ VOID TiUnload(
LoopUnregisterAdapter(NULL);
/* Unregister protocol with NDIS */
#ifdef _MSC_VER
LANUnregisterProtocol();
#endif
/* Shutdown transport level protocol subsystems */
TCPShutdown();
@ -601,13 +601,13 @@ DriverEntry(
UNICODE_STRING strDeviceName;
STRING strNdisDeviceName;
NDIS_STATUS NdisStatus;
#ifdef _MSC_VER
PLAN_ADAPTER Adapter;
NDIS_STRING DeviceName;
#endif
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* FIXME: Create symbolic links in Win32 namespace */
/* Create IP device object */
RtlInitUnicodeString(&strDeviceName, DD_IP_DEVICE_NAME);
Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
@ -700,22 +700,22 @@ DriverEntry(
TiUnload(DriverObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
#if 1
#ifdef _MSC_VER
/* Open underlying adapter(s) we are bound to */
/* FIXME: Get binding information from registry */
/* Put your own NDIS adapter device name here */
#if 0
/* ReactOS */
NdisInitUnicodeString(&DeviceName, L"\\Device\\ne2000");
/* NT4 */
NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1");
#else
//NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1");
/* NT5 */
NdisInitUnicodeString(&DeviceName,
L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}");
#endif
//NdisInitUnicodeString(&DeviceName, L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}");
NdisStatus = LANRegisterAdapter(&DeviceName, &Adapter);
if (!NT_SUCCESS(NdisStatus)) {
@ -732,7 +732,7 @@ DriverEntry(
return STATUS_DEVICE_DOES_NOT_EXIST;
}
#endif
#endif
/* Setup network layer and transport layer entities */
EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * 2);
if (!NT_SUCCESS(Status)) {

View file

@ -351,6 +351,9 @@ VOID UDPReceive(
/* FIXME: IPv6 is not supported */
return;
default:
return;
}
UDPHeader = (PUDP_HEADER)IPPacket->Data;

View file

@ -422,8 +422,14 @@ NTSTATUS TdiQueryAddress(
break;
}
/* Select the first address returned */
*Address = DN2H(IpAddress->Addr);
if (SnmpInfo.NumAddr != 1) {
/* Skip loopback address */
*Address = DN2H(((PIPADDR_ENTRY)((ULONG)IpAddress + sizeof(IPADDR_ENTRY)))->Addr);
} else {
/* Select the first address returned */
*Address = DN2H(IpAddress->Addr);
}
ExFreePool(IpAddress);
} else {
Status = STATUS_UNSUCCESSFUL;