*/
#include <tcpip.h>
#include <ip.h>
+#include <tcp.h>
#include <loopback.h>
#include <neighbor.h>
#include <receive.h>
UINT MaxLLHeaderSize; /* Largest maximum header size */
UINT MinLLFrameSize; /* Largest minimum frame size */
BOOLEAN IPInitialized = FALSE;
+NPAGED_LOOKASIDE_LIST IPPacketList;
IP_PROTOCOL_HANDLER ProtocolTable[IP_PROTOCOL_TABLE_SIZE];
+VOID FreePacket(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an IP packet object
+ * ARGUMENTS:
+ * Object = Pointer to an IP packet structure
+ */
+{
+ ExFreeToNPagedLookasideList(&IPPacketList, Object);
+}
+
+
+VOID FreeADE(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an address entry object
+ * ARGUMENTS:
+ * Object = Pointer to an address entry structure
+ */
+{
+ ExFreePool(Object);
+}
+
+
+VOID FreeNTE(
+ PVOID Object)
+/*
+ * FUNCTION: Frees a net table entry object
+ * ARGUMENTS:
+ * Object = Pointer to an net table entry structure
+ */
+{
+ ExFreePool(Object);
+}
+
+
+VOID FreeIF(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an interface object
+ * ARGUMENTS:
+ * Object = Pointer to an interface structure
+ */
+{
+ ExFreePool(Object);
+}
+
+
PADDRESS_ENTRY CreateADE(
- PIP_INTERFACE IF,
- PIP_ADDRESS Address,
+ PIP_INTERFACE IF, PIP_ADDRESS Address,
UCHAR Type,
PNET_TABLE_ENTRY NTE)
/*
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) Type (0x%X) NTE (0x%X).\n",
IF, Address, Type, NTE));
+ TI_DbgPrint(DEBUG_IP, ("Address (%s) NTE (%s).\n",
+ A2S(Address), A2S(NTE->Address)));
+
/* Allocate space for an ADE and set it up */
- ADE = PoolAllocateBuffer(sizeof(ADDRESS_ENTRY));
+ ADE = ExAllocatePool(NonPagedPool, sizeof(ADDRESS_ENTRY));
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(ADE, TAG('A','D','E',' '));
+ ADE->Free = FreeADE;
ADE->RefCount = 1;
ADE->NTE = NTE;
ADE->Type = Type;
{
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) ADE (0x%X).\n", IF, ADE));
+ TI_DbgPrint(DEBUG_IP, ("ADE (%s).\n", ADE->Address));
+
/* Unlink the address entry from the list */
RemoveEntryList(&ADE->ListEntry);
#endif
/* And free the ADE */
- PoolFreeBuffer(ADE);
- TI_DbgPrint(MIN_TRACE, ("Check.\n"));
+ FreeADE(ADE);
}
CurrentEntry = IF->ADEListHead.Flink;
while (CurrentEntry != &IF->ADEListHead) {
NextEntry = CurrentEntry->Flink;
- Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
/* Destroy the ADE */
DestroyADE(IF, Current);
CurrentEntry = NextEntry;
}
+PIP_PACKET IPCreatePacket(
+ ULONG Type)
+/*
+ * FUNCTION: Creates an IP packet object
+ * ARGUMENTS:
+ * Type = Type of IP packet
+ * RETURNS:
+ * Pointer to the created IP packet. NULL if there was not enough free resources.
+ */
+{
+ PIP_PACKET IPPacket;
+
+ IPPacket = ExAllocateFromNPagedLookasideList(&IPPacketList);
+ if (!IPPacket)
+ return NULL;
+
+ /* FIXME: Is this needed? */
+ RtlZeroMemory(IPPacket, sizeof(IP_PACKET));
+
+ INIT_TAG(IPPacket, TAG('I','P','K','T'));
+
+ IPPacket->Free = FreePacket;
+ IPPacket->RefCount = 1;
+ IPPacket->Type = Type;
+
+ return IPPacket;
+}
+
+
PPREFIX_LIST_ENTRY CreatePLE(
PIP_INTERFACE IF,
PIP_ADDRESS Prefix,
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Prefix (0x%X) Length (%d).\n", IF, Prefix, Length));
+ TI_DbgPrint(DEBUG_IP, ("Prefix (%s).\n", A2S(Prefix)));
+
/* Allocate space for an PLE and set it up */
- PLE = PoolAllocateBuffer(sizeof(PREFIX_LIST_ENTRY));
+ PLE = ExAllocatePool(NonPagedPool, sizeof(PREFIX_LIST_ENTRY));
if (!PLE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(PLE, TAG('P','L','E',' '));
PLE->RefCount = 1;
PLE->Interface = IF;
PLE->Prefix = Prefix;
{
TI_DbgPrint(DEBUG_IP, ("Called. PLE (0x%X).\n", PLE));
+ TI_DbgPrint(DEBUG_IP, ("PLE (%s).\n", PLE->Prefix));
+
/* Unlink the prefix list entry from the list */
RemoveEntryList(&PLE->ListEntry);
#endif
/* And free the PLE */
- PoolFreeBuffer(PLE);
+ ExFreePool(PLE);
}
CurrentEntry = PrefixListHead.Flink;
while (CurrentEntry != &PrefixListHead) {
NextEntry = CurrentEntry->Flink;
- Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
/* Destroy the PLE */
DestroyPLE(Current);
CurrentEntry = NextEntry;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) PrefixLength (%d).\n", IF, Address, PrefixLength));
+ TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
+
/* Allocate room for an NTE */
- NTE = PoolAllocateBuffer(sizeof(NET_TABLE_ENTRY));
+ NTE = ExAllocatePool(NonPagedPool, sizeof(NET_TABLE_ENTRY));
if (!NTE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(NTE, TAG('N','T','E',' '));
+ INIT_TAG(Address, TAG('A','D','R','S'));
+
+ NTE->Free = FreeNTE;
+
NTE->Interface = IF;
/* One reference is for beeing alive and one reference is for the ADE */
ADE = CreateADE(IF, NTE->Address, ADE_UNICAST, NTE);
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- PoolFreeBuffer(NTE);
+ ExFreePool(NTE);
return NULL;
}
NTE->PLE = CreatePLE(IF, NTE->Address, PrefixLength);
if (!NTE->PLE) {
DestroyADE(IF, ADE);
- PoolFreeBuffer(NTE);
+ ExFreePool(NTE);
return NULL;
}
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) NTE (0x%X).\n", IF, NTE));
+ TI_DbgPrint(DEBUG_IP, ("NTE (%s).\n", NTE->Address));
+
/* Invalidate the prefix list entry for this NTE */
KeAcquireSpinLock(&PrefixListLock, &OldIrql);
DestroyPLE(NTE->PLE);
/* Remove NTE from the interface list */
RemoveEntryList(&NTE->IFListEntry);
/* Remove NTE from the net table list */
+
+/* TODO: DEBUG: removed by RobD to prevent failure when testing under bochs 6 sept 2002.
+
RemoveEntryList(&NTE->NTListEntry);
+
+ */
+
/* Dereference the objects that are referenced */
DereferenceObject(NTE->Address);
DereferenceObject(NTE->Interface);
}
#endif
/* And free the NTE */
- PoolFreeBuffer(NTE);
+ ExFreePool(NTE);
}
CurrentEntry = IF->NTEListHead.Flink;
while (CurrentEntry != &IF->NTEListHead) {
NextEntry = CurrentEntry->Flink;
- Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
/* Destroy the NTE */
DestroyNTE(IF, Current);
CurrentEntry = NextEntry;
PLIST_ENTRY CurrentEntry;
PADDRESS_ENTRY Current;
- TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) AddressType (0x%X).\n",
- IF, Address, AddressType));
+// TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) AddressType (0x%X).\n",
+// IF, Address, AddressType));
+
+// TI_DbgPrint(DEBUG_IP, ("Address (%s) AddressType (0x%X).\n", A2S(Address)));
KeAcquireSpinLock(&IF->Lock, &OldIrql);
/* Search the list and return the NTE if found */
CurrentEntry = IF->ADEListHead.Flink;
+
+ if (CurrentEntry == &IF->ADEListHead) {
+ TI_DbgPrint(DEBUG_IP, ("NTE list is empty!!!\n"));
+ }
+
while (CurrentEntry != &IF->ADEListHead) {
- Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
if (AddrIsEqual(Address, Current->Address)) {
ReferenceObject(Current->NTE);
*AddressType = Current->Type;
KeReleaseSpinLock(&IF->Lock, OldIrql);
return Current->NTE;
}
+ else {
+ TI_DbgPrint(DEBUG_IP, ("CurrentEntry = 0x%X != &IF->ADEListHead = 0x%X.\n", CurrentEntry, &IF->ADEListHead));
+ }
CurrentEntry = CurrentEntry->Flink;
}
PNET_TABLE_ENTRY Current;
PNET_TABLE_ENTRY NTE;
- TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n",
- Address, AddressType));
-
+// TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n",
+// Address, AddressType));
+
+// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
+
KeAcquireSpinLock(&NetTableListLock, &OldIrql);
/* Search the list and return the NTE if found */
CurrentEntry = NetTableListHead.Flink;
while (CurrentEntry != &NetTableListHead) {
- Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, NTListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, NTListEntry);
NTE = IPLocateNTEOnInterface(Current->Interface, Address, AddressType);
if (NTE) {
ReferenceObject(NTE);
PIP_INTERFACE CurrentIF;
PADDRESS_ENTRY CurrentADE;
- TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n",
- Address, AddressType));
+// TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n",
+// Address, AddressType));
+
+// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
/* Search the interface list */
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
- CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+ CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
/* Search the address entry list and return the ADE if found */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
PLIST_ENTRY CurrentADEEntry;
PIP_INTERFACE CurrentIF;
PADDRESS_ENTRY CurrentADE;
-#if 0
BOOLEAN LoopbackIsRegistered = FALSE;
-#endif
+
TI_DbgPrint(DEBUG_IP, ("Called. AddressType (0x%X).\n", AddressType));
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
/* Search the interface list */
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
- CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
-#if 0
+ CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+
if (CurrentIF != Loopback) {
-#endif
/* Search the address entry list and return the first appropriate ADE found */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
while (CurrentADEEntry != &CurrentIF->ADEListHead) {
return CurrentADE;
}
CurrentADEEntry = CurrentADEEntry->Flink;
-#if 0
} else
LoopbackIsRegistered = TRUE;
-#endif
CurrentIFEntry = CurrentIFEntry->Flink;
}
-#if 0
+
/* No address was found. Use loopback interface if available */
if (LoopbackIsRegistered) {
CurrentADEEntry = Loopback->ADEListHead.Flink;
CurrentADEEntry = CurrentADEEntry->Flink;
}
}
-#endif
+
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return NULL;
}
-VOID IPTimeout(
+VOID STDCALL IPTimeout(
PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
/* Clean possible outdated cached neighbor addresses */
NBTimeout();
+
+ /* Call upper layer timeout routines */
+ TCPTimeout();
}
TI_DbgPrint(DEBUG_IP, ("Called. BindInfo (0x%X).\n", BindInfo));
- IF = PoolAllocateBuffer(sizeof(IP_INTERFACE));
+#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 = ExAllocatePool(NonPagedPool, 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 (IF->HeaderSize > MaxLLHeaderSize)
- MaxLLHeaderSize = IF->HeaderSize;
+ INIT_TAG(IF, TAG('F','A','C','E'));
+
+ IF->Free = FreeIF;
+ IF->RefCount = 1;
+ IF->Context = BindInfo->Context;
+ IF->HeaderSize = BindInfo->HeaderSize;
+ if (IF->HeaderSize > MaxLLHeaderSize)
+ MaxLLHeaderSize = IF->HeaderSize;
- IF->MinFrameSize = BindInfo->MinFrameSize;
- if (IF->MinFrameSize > MinLLFrameSize)
- MinLLFrameSize = IF->MinFrameSize;
+ IF->MinFrameSize = BindInfo->MinFrameSize;
+ if (IF->MinFrameSize > MinLLFrameSize)
+ MinLLFrameSize = IF->MinFrameSize;
IF->MTU = BindInfo->MTU;
IF->Address = BindInfo->Address;
TI_DbgPrint(MIN_TRACE, ("Interface at (0x%X) has (%d) references (should be 0).\n", IF, IF->RefCount));
}
#endif
- PoolFreeBuffer(IF);
+ ExFreePool(IF);
}
KeReleaseSpinLock(&IF->Lock, OldIrql);
return FALSE;
}
+#if 1
+ /* Reference objects for forward information base */
+ ReferenceObject(Current->Address);
+ ReferenceObject(Current->PLE->Prefix);
+ ReferenceObject(Current);
+ /* NCE is already referenced */
+ if (!RouterAddRoute(Current->Address, Current->PLE->Prefix, Current, NCE, 1)) {
+ TI_DbgPrint(MIN_TRACE, ("Could not add route due to insufficient resources.\n"));
+ DereferenceObject(Current->Address);
+ DereferenceObject(Current->PLE->Prefix);
+ DereferenceObject(Current);
+ DereferenceObject(NCE);
+ }
+#else
RCN = RouteAddRouteToDestination(Current->Address, Current, IF, NCE);
if (!RCN) {
TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n"));
}
/* Don't need this any more since the route cache references the NCE */
DereferenceObject(NCE);
-
+#endif
CurrentEntry = CurrentEntry->Flink;
}
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- MaxLLHeaderSize = 0;
+ MaxLLHeaderSize = 0;
MinLLFrameSize = 0;
+ /* Initialize lookaside lists */
+ ExInitializeNPagedLookasideList(
+ &IPDRList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IPDATAGRAM_REASSEMBLY), /* Size of each entry */
+ TAG('I','P','D','R'), /* Tag */
+ 0); /* Depth */
+
+ ExInitializeNPagedLookasideList(
+ &IPPacketList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IP_PACKET), /* Size of each entry */
+ TAG('I','P','P','K'), /* Tag */
+ 0); /* Depth */
+
+ ExInitializeNPagedLookasideList(
+ &IPFragmentList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IP_FRAGMENT), /* Size of each entry */
+ TAG('I','P','F','G'), /* Tag */
+ 0); /* Depth */
+
+ ExInitializeNPagedLookasideList(
+ &IPHoleList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IPDATAGRAM_HOLE), /* Size of each entry */
+ TAG('I','P','H','L'), /* Tag */
+ 0); /* Depth */
+
/* Start routing subsystem */
RouterStartup();
/* Clear prefix list */
DestroyPLEs();
+ /* Destroy lookaside lists */
+ ExDeleteNPagedLookasideList(&IPHoleList);
+ ExDeleteNPagedLookasideList(&IPDRList);
+ ExDeleteNPagedLookasideList(&IPPacketList);
+ ExDeleteNPagedLookasideList(&IPFragmentList);
+
IPInitialized = FALSE;
return STATUS_SUCCESS;