* drivers/net/tcpip/datalink/loopback.c: Reformat.
* drivers/net/tcpip/network/neighbor.c: Ditto.
* drivers/net/tcpip/tcpip/info.c: Ditto.
* drivers/net/tcpip/transport/datagram/datagram.c: Cleanup.
If there is an out-of-resources situation, don't transmit the
datagram out of order.
svn path=/trunk/; revision=8381
+2004-02-25 Casper S. Hornstrup <chorns@users.sourceforge.net>
+
+ * drivers/net/tcpip/datalink/loopback.c: Reformat.
+ * drivers/net/tcpip/network/neighbor.c: Ditto.
+ * drivers/net/tcpip/tcpip/info.c: Ditto.
+ * drivers/net/tcpip/transport/datagram/datagram.c: Cleanup.
+ If there is an out-of-resources situation, don't transmit the
+ datagram out of order.
+
2004-02-23 Casper S. Hornstrup <chorns@users.sourceforge.net>
* tools/regtests.c (KMSTUB): Correct device name.
#include <routines.h>
-WORK_QUEUE_ITEM LoopWorkItem;
-PIP_INTERFACE Loopback = NULL;
+WORK_QUEUE_ITEM LoopWorkItem;
+PIP_INTERFACE Loopback = NULL;
/* Indicates wether the loopback interface is currently transmitting */
-BOOLEAN LoopBusy = FALSE;
+BOOLEAN LoopBusy = FALSE;
/* Loopback transmit queue */
-PNDIS_PACKET LoopQueueHead = (PNDIS_PACKET)NULL;
-PNDIS_PACKET LoopQueueTail = (PNDIS_PACKET)NULL;
+PNDIS_PACKET LoopQueueHead = (PNDIS_PACKET)NULL;
+PNDIS_PACKET LoopQueueTail = (PNDIS_PACKET)NULL;
/* Spin lock for protecting loopback transmit queue */
-KSPIN_LOCK LoopLock;
+KSPIN_LOCK LoopQueueLock;
VOID RealTransmit(
- PVOID Context)
+ PVOID Context)
/*
* FUNCTION: Transmits one or more packet(s) in loopback queue to ourselves
* ARGUMENTS:
- * Context = Pointer to context information (loopback interface)
+ * Context = Pointer to context information (loopback interface)
*/
{
- KIRQL OldIrql;
- PNDIS_PACKET NdisPacket;
- PNDIS_BUFFER NdisBuffer;
- IP_PACKET IPPacket;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
- KeAcquireSpinLockAtDpcLevel(&LoopLock);
-
- for (;;) {
- /* Get the next packet from the queue (if any) */
- NdisPacket = LoopQueueHead;
- if (!NdisPacket)
- break;
-
- TI_DbgPrint(MAX_TRACE, ("NdisPacket (0x%X)\n", NdisPacket));
-
- LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
- KeReleaseSpinLockFromDpcLevel(&LoopLock);
- IPPacket.NdisPacket = NdisPacket;
-
- NdisGetFirstBufferFromPacket(NdisPacket,
- &NdisBuffer,
- &IPPacket.Header,
- &IPPacket.ContigSize,
- &IPPacket.TotalSize);
- IPReceive(Context, &IPPacket);
- AdjustPacket(NdisPacket, 0, PC(NdisPacket)->DLOffset);
- PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
- /* Lower IRQL for a moment to prevent starvation */
- KeLowerIrql(OldIrql);
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
- KeAcquireSpinLockAtDpcLevel(&LoopLock);
+ PNDIS_PACKET NdisPacket;
+ PNDIS_BUFFER NdisBuffer;
+ IP_PACKET IPPacket;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ KeAcquireSpinLockAtDpcLevel(&LoopQueueLock);
+
+ while (TRUE)
+ {
+ /* Get the next packet from the queue (if any) */
+ NdisPacket = LoopQueueHead;
+ if (!NdisPacket)
+ break;
+
+ TI_DbgPrint(MAX_TRACE, ("NdisPacket (0x%X)\n", NdisPacket));
+
+ LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
+ KeReleaseSpinLockFromDpcLevel(&LoopQueueLock);
+ IPPacket.NdisPacket = NdisPacket;
+
+ NdisGetFirstBufferFromPacket(NdisPacket,
+ &NdisBuffer,
+ &IPPacket.Header,
+ &IPPacket.ContigSize,
+ &IPPacket.TotalSize);
+ IPReceive(Context, &IPPacket);
+ AdjustPacket(NdisPacket, 0, PC(NdisPacket)->DLOffset);
+ PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
+ /* Lower IRQL for a moment to prevent starvation */
+ KeLowerIrql(OldIrql);
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ KeAcquireSpinLockAtDpcLevel(&LoopQueueLock);
}
- LoopBusy = FALSE;
- KeReleaseSpinLockFromDpcLevel(&LoopLock);
- KeLowerIrql(OldIrql);
-}
+ LoopBusy = FALSE;
+ KeReleaseSpinLockFromDpcLevel(&LoopQueueLock);
+ KeLowerIrql(OldIrql);
+}
VOID LoopTransmit(
- PVOID Context,
- PNDIS_PACKET NdisPacket,
- UINT Offset,
- PVOID LinkAddress,
- USHORT Type)
+ PVOID Context,
+ PNDIS_PACKET NdisPacket,
+ UINT Offset,
+ PVOID LinkAddress,
+ USHORT Type)
/*
* FUNCTION: Transmits a packet
* ARGUMENTS:
- * Context = Pointer to context information (NULL)
- * NdisPacket = Pointer to NDIS packet to send
- * Offset = Offset in packet where packet data starts
- * LinkAddress = Pointer to link address
- * Type = LAN protocol type (unused)
+ * Context = Pointer to context information (NULL)
+ * NdisPacket = Pointer to NDIS packet to send
+ * Offset = Offset in packet where packet data starts
+ * LinkAddress = Pointer to link address
+ * Type = LAN protocol type (unused)
*/
{
- PNDIS_PACKET *pNdisPacket;
- KIRQL OldIrql;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- /* NDIS send routines don't have an offset argument so we
- must offset the data in upper layers and adjust the
- packet here. We save the offset in the packet context
- area so it can be undone before we release the packet */
- AdjustPacket(NdisPacket, Offset, 0);
- PC(NdisPacket)->DLOffset = Offset;
-
- pNdisPacket = (PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
- *pNdisPacket = NULL;
-
- KeAcquireSpinLock(&LoopLock, &OldIrql);
-
- /* Add packet to transmit queue */
- if (LoopQueueHead) {
- /* Transmit queue is not empty */
- pNdisPacket = (PNDIS_PACKET*)LoopQueueTail->u.s3.MacReserved;
- *pNdisPacket = NdisPacket;
- } else
- /* Transmit queue is empty */
- LoopQueueHead = NdisPacket;
-
- LoopQueueTail = NdisPacket;
-
- /* If LoopTransmit is not running (or scheduled), schedule it to run */
- if (!LoopBusy) {
- LoopBusy = TRUE;
- ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
+ PNDIS_PACKET *pNdisPacket;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ /* NDIS send routines don't have an offset argument so we
+ must offset the data in upper layers and adjust the
+ packet here. We save the offset in the packet context
+ area so it can be undone before we release the packet */
+ AdjustPacket(NdisPacket, Offset, 0);
+ PC(NdisPacket)->DLOffset = Offset;
+
+ pNdisPacket = (PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
+ *pNdisPacket = NULL;
+
+ KeAcquireSpinLock(&LoopQueueLock, &OldIrql);
+
+ /* Add packet to transmit queue */
+ if (LoopQueueHead != NULL)
+ {
+ /* Transmit queue is not empty */
+ pNdisPacket = (PNDIS_PACKET*)LoopQueueTail->u.s3.MacReserved;
+ *pNdisPacket = NdisPacket;
+ }
+ else
+ {
+ /* Transmit queue is empty */
+ LoopQueueHead = NdisPacket;
}
- KeReleaseSpinLock(&LoopLock, OldIrql);
-}
+ LoopQueueTail = NdisPacket;
+ /* If RealTransmit is not running (or scheduled to run) then schedule it to run now */
+ if (!LoopBusy)
+ {
+ LoopBusy = TRUE; /* The loopback interface is now busy */
+ ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
+ }
+
+ KeReleaseSpinLock(&LoopQueueLock, OldIrql);
+}
NDIS_STATUS LoopRegisterAdapter(
- PNDIS_STRING AdapterName,
- PLAN_ADAPTER *Adapter)
+ PNDIS_STRING AdapterName,
+ PLAN_ADAPTER *Adapter)
/*
- * FUNCTION: Registers loopback adapter
+ * FUNCTION: Registers loopback adapter with the network layer
* ARGUMENTS:
- * AdapterName = Unused
- * Adapter = Unused
+ * AdapterName = Unused
+ * Adapter = Unused
* RETURNS:
- * Status of operation
+ * Status of operation
*/
{
- PIP_ADDRESS Address;
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-
- TI_DbgPrint(MID_TRACE, ("Called.\n"));
-
- Address = AddrBuildIPv4(LOOPBACK_ADDRESS_IPv4);
- if (Address) {
- LLIP_BIND_INFO BindInfo;
-
- /* Bind the adapter to IP layer */
- BindInfo.Context = NULL;
- BindInfo.HeaderSize = 0;
- BindInfo.MinFrameSize = 0;
- BindInfo.MTU = 16384;
- BindInfo.Address = NULL;
- BindInfo.AddressLength = 0;
- BindInfo.Transmit = LoopTransmit;
-
- Loopback = IPCreateInterface(&BindInfo);
- if ((Loopback) && (IPCreateNTE(Loopback, Address, 8))) {
- /* Reference the interface for the NTE. The reference for
- the address is just passed on to the NTE */
- ReferenceObject(Loopback);
-
- IPRegisterInterface(Loopback);
-
- ExInitializeWorkItem(&LoopWorkItem, RealTransmit, Loopback);
-
- KeInitializeSpinLock(&LoopLock);
- LoopBusy = FALSE;
- } else
- Status = NDIS_STATUS_RESOURCES;
- } else
- Status = NDIS_STATUS_RESOURCES;
+ PIP_ADDRESS Address;
+ NDIS_STATUS Status;
+
+ Status = NDIS_STATUS_SUCCESS;
+
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+ Address = AddrBuildIPv4(LOOPBACK_ADDRESS_IPv4);
+ if (Address != NULL)
+ {
+ LLIP_BIND_INFO BindInfo;
+
+ /* Bind the adapter to network (IP) layer */
+ BindInfo.Context = NULL;
+ BindInfo.HeaderSize = 0;
+ BindInfo.MinFrameSize = 0;
+ BindInfo.MTU = 16384;
+ BindInfo.Address = NULL;
+ BindInfo.AddressLength = 0;
+ BindInfo.Transmit = LoopTransmit;
+
+ Loopback = IPCreateInterface(&BindInfo);
+ if ((Loopback != NULL) && (IPCreateNTE(Loopback, Address, 8)))
+ {
+ /* Reference the interface for the NTE. The reference for
+ the address is just passed on to the NTE */
+ ReferenceObject(Loopback);
+
+ IPRegisterInterface(Loopback);
+
+ ExInitializeWorkItem(&LoopWorkItem, RealTransmit, Loopback);
+
+ KeInitializeSpinLock(&LoopQueueLock);
+ LoopBusy = FALSE;
+ }
+ else
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ }
+ }
+ else
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ }
- if (!NT_SUCCESS(Status))
- LoopUnregisterAdapter(NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ LoopUnregisterAdapter(NULL);
+ }
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
- return Status;
+ return Status;
}
NDIS_STATUS LoopUnregisterAdapter(
- PLAN_ADAPTER Adapter)
+ PLAN_ADAPTER Adapter)
/*
- * FUNCTION: Unregisters loopback adapter
+ * FUNCTION: Unregisters loopback adapter with the network layer
* ARGUMENTS:
- * Adapter = Unused
+ * Adapter = Unused
* RETURNS:
- * Status of operation
+ * Status of operation
* NOTES:
- * Does not care wether we have registered loopback adapter
+ * Does not care wether we have registered loopback adapter
*/
{
- TI_DbgPrint(MID_TRACE, ("Called.\n"));
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
- if (Loopback) {
- IPUnregisterInterface(Loopback);
- IPDestroyInterface(Loopback);
- Loopback = NULL;
+ if (Loopback != NULL)
+ {
+ IPUnregisterInterface(Loopback);
+ IPDestroyInterface(Loopback);
+ Loopback = NULL;
}
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
- return NDIS_STATUS_SUCCESS;
+ return NDIS_STATUS_SUCCESS;
}
-
-/* EOF */
VOID FreeNCE(
- PVOID Object)
+ PVOID Object)
{
- ExFreePool(Object);
+ ExFreePool(Object);
}
-
VOID NCETimeout(
- PNEIGHBOR_CACHE_ENTRY NCE)
+ PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Neighbor cache entry timeout handler
* NOTES:
- * The neighbor cache lock must be held
+ * The neighbor cache lock must be held
*/
{
- PNDIS_PACKET NdisPacket, Next;
+ PNDIS_PACKET NdisPacket;
+ PNDIS_PACKET NextNdisPacket;
- TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
- TI_DbgPrint(DEBUG_NCACHE, ("NCE->State is (0x%X).\n", NCE->State));
+ TI_DbgPrint(DEBUG_NCACHE, ("NCE->State is (0x%X).\n", NCE->State));
- switch (NCE->State) {
- case NUD_INCOMPLETE:
+ switch (NCE->State)
+ {
+ case NUD_INCOMPLETE:
/* Retransmission timer expired */
- if (NCE->EventCount++ > MAX_MULTICAST_SOLICIT) {
+ if (NCE->EventCount++ > MAX_MULTICAST_SOLICIT)
+ {
/* We have retransmitted too many times */
/* Calling IPSendComplete with cache lock held is not
- a great thing to do. We don't get here very often
- so maybe it's not that big a problem */
+ a great thing to do. We don't get here very often
+ so maybe it's not that big a problem */
/* Flush packet queue */
NdisPacket = NCE->WaitQueue;
- while (NdisPacket) {
- Next = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
- IPSendComplete((PVOID)NCE->Interface, NdisPacket,
- NDIS_STATUS_REQUEST_ABORTED);
- NdisPacket = Next;
- }
+ while (NdisPacket != NULL)
+ {
+ NextNdisPacket = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
+ IPSendComplete((PVOID)NCE->Interface,
+ NdisPacket,
+ NDIS_STATUS_REQUEST_ABORTED);
+ NdisPacket = NextNdisPacket;
+ }
NCE->WaitQueue = NULL;
NCE->EventCount = 0;
/* Remove route cache entries with references to this NCE.
- Remember that neighbor cache lock is taken before
- route cache lock */
+ Remember that neighbor cache lock is acquired before the
+ route cache lock */
RouteInvalidateNCE(NCE);
- } else
+ }
+ else
+ {
/* Retransmit request */
NBSendSolicit(NCE);
+ }
break;
- case NUD_DELAY:
+ case NUD_DELAY:
/* FIXME: Delayed state */
TI_DbgPrint(DEBUG_NCACHE, ("NCE delay state.\n"));
break;
- case NUD_PROBE:
+ case NUD_PROBE:
/* FIXME: Probe state */
TI_DbgPrint(DEBUG_NCACHE, ("NCE probe state.\n"));
break;
- default:
- /* Should not happen since other states don't use the event timer */
+ default:
+ /* Should not happen since the event timer is not used in the other states */
TI_DbgPrint(MIN_TRACE, ("Invalid NCE state (%d).\n", NCE->State));
break;
}
for (NCE = NeighborCache[i].Cache;
NCE != NULL; NCE = NCE->Next) {
/* Check if event timer is running */
- if (NCE->EventTimer != 0) {
- if (--NCE->EventTimer == 0) {
+ ASSERT(NCE->EventTimer >= 0);
+ if (NCE->EventTimer > 0) {
+ NCE->EventTimer--;
+ if (NCE->EventTimer == 0) {
/* Call timeout handler for NCE */
NCETimeout(NCE);
}
}
}
-
VOID NBStartup(
- VOID)
+ VOID)
/*
* FUNCTION: Starts the neighbor cache
*/
{
- UINT i;
+ UINT i;
- TI_DbgPrint(DEBUG_NCACHE, ("Called.\n"));
+ TI_DbgPrint(DEBUG_NCACHE, ("Called.\n"));
- for (i = 0; i <= NB_HASHMASK; i++) {
- NeighborCache[i].Cache = NULL;
- KeInitializeSpinLock(&NeighborCache[i].Lock);
+ for (i = 0; i <= NB_HASHMASK; i++)
+ {
+ NeighborCache[i].Cache = NULL;
+ KeInitializeSpinLock(&NeighborCache[i].Lock);
}
}
-
VOID NBShutdown(
- VOID)
+ VOID)
/*
* FUNCTION: Shuts down the neighbor cache
*/
{
- UINT i;
- KIRQL OldIrql;
- PNDIS_PACKET NdisPacket, Next;
- PNEIGHBOR_CACHE_ENTRY CurNCE, NextNCE;
-
- TI_DbgPrint(DEBUG_NCACHE, ("Called.\n"));
-
- /* Remove possible entries from the cache */
- for (i = 0; i <= NB_HASHMASK; i++) {
- KeAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
-
- CurNCE = NeighborCache[i].Cache;
- while (CurNCE) {
- NextNCE = CurNCE->Next;
-
- /* Remove all references from route cache */
- RouteInvalidateNCE(CurNCE);
-
- /* Flush wait queue */
- NdisPacket = CurNCE->WaitQueue;
- while (NdisPacket) {
- Next = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
- FreeNdisPacket(NdisPacket);
- NdisPacket = Next;
+ PNEIGHBOR_CACHE_ENTRY NextNCE;
+ PNEIGHBOR_CACHE_ENTRY CurNCE;
+ PNDIS_PACKET NextNdisPacket;
+ PNDIS_PACKET NdisPacket;
+ KIRQL OldIrql;
+ UINT i;
+
+ TI_DbgPrint(DEBUG_NCACHE, ("Called.\n"));
+
+ /* Remove possible entries from the cache */
+ for (i = 0; i <= NB_HASHMASK; i++)
+ {
+ KeAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
+
+ CurNCE = NeighborCache[i].Cache;
+ while (CurNCE)
+ {
+ NextNCE = CurNCE->Next;
+
+ /* Remove all references from route cache */
+ RouteInvalidateNCE(CurNCE);
+
+ /* Flush wait queue */
+ NdisPacket = CurNCE->WaitQueue;
+ while (NdisPacket)
+ {
+ NextNdisPacket = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
+ FreeNdisPacket(NdisPacket);
+ NdisPacket = NextNdisPacket;
}
#if DBG
- if (CurNCE->RefCount != 1) {
- TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 1).\n", CurNCE, CurNCE->RefCount));
+ if (CurNCE->RefCount != 1)
+ {
+ TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 1).\n", CurNCE, CurNCE->RefCount));
}
#endif
- /* Remove reference for being alive */
- DereferenceObject(CurNCE);
+ /* Remove reference for being alive */
+ DereferenceObject(CurNCE);
- CurNCE = NextNCE;
- }
- NeighborCache[i].Cache = NULL;
+ CurNCE = NextNCE;
+ }
- KeReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
- }
+ NeighborCache[i].Cache = NULL;
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
-}
+ KeReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
+ }
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+}
VOID NBSendSolicit(
- PNEIGHBOR_CACHE_ENTRY NCE)
+ PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Sends a neighbor solicitation message
* ARGUMENTS:
- * NCE = Pointer to NCE of neighbor to solicit
+ * NCE = Pointer to NCE of neighbor to solicit
* NOTES:
- * May be called with lock held on NCE's table
+ * May be called with lock held on NCE's table
*/
{
- PLIST_ENTRY CurrentEntry;
- PNET_TABLE_ENTRY NTE;
-
- TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
-
- if (NCE->State == NUD_INCOMPLETE) {
- /* This is the first solicitation of this neighbor. Broadcast
- a request for the neighbor */
-
- /* FIXME: Choose first NTE. We might want to give an NTE as argument */
- CurrentEntry = NCE->Interface->NTEListHead.Flink;
- if (!IsListEmpty(CurrentEntry)) {
- NTE = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
- ARPTransmit(NCE->Address, NTE);
- } else {
- TI_DbgPrint(MIN_TRACE, ("Interface at 0x%X has zero NTE.\n", NCE->Interface));
+ PLIST_ENTRY CurrentEntry;
+ PNET_TABLE_ENTRY NTE;
+
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
+
+ if (NCE->State == NUD_INCOMPLETE)
+ {
+ /* This is the first solicitation of this neighbor. Broadcast
+ a request for the neighbor */
+
+ /* FIXME: Choose first NTE. We might want to give an NTE as argument */
+ CurrentEntry = NCE->Interface->NTEListHead.Flink;
+ if (!IsListEmpty(CurrentEntry))
+ {
+ NTE = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
+ ARPTransmit(NCE->Address, NTE);
+ }
+ else
+ {
+ TI_DbgPrint(MIN_TRACE, ("Interface at 0x%X has zero NTE.\n", NCE->Interface));
}
- } else {
- /* FIXME: Unicast solicitation since we have a cached address */
- TI_DbgPrint(MIN_TRACE, ("Uninplemented unicast solicitation.\n"));
+ }
+ else
+ {
+ /* FIXME: Unicast solicitation since we have a cached address */
+ TI_DbgPrint(MIN_TRACE, ("Uninplemented unicast solicitation.\n"));
}
}
-
PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
- PIP_INTERFACE Interface,
- PIP_ADDRESS Address,
- PVOID LinkAddress,
- UINT LinkAddressLength,
- UCHAR State)
+ PIP_INTERFACE Interface,
+ PIP_ADDRESS Address,
+ PVOID LinkAddress,
+ UINT LinkAddressLength,
+ UCHAR State)
/*
* FUNCTION: Adds a neighbor to the neighbor cache
* ARGUMENTS:
- * Interface = Pointer to interface
- * Address = Pointer to IP address
- * LinkAddress = Pointer to link address (may be NULL)
- * LinkAddressLength = Length of link address
- * State = State of NCE
+ * Interface = Pointer to interface
+ * Address = Pointer to IP address
+ * LinkAddress = Pointer to link address (may be NULL)
+ * LinkAddressLength = Length of link address
+ * State = State of NCE
* RETURNS:
- * Pointer to NCE, NULL there is not enough free resources
+ * Pointer to NCE, NULL there is not enough free resources
* NOTES:
- * The NCE if referenced for the caller if created. The NCE retains
- * a reference to the IP address if it is created, the caller is
- * responsible for providing this reference
+ * The NCE if referenced for the caller if created. The NCE retains
+ * a reference to the IP address if it is created, the caller is
+ * responsible for providing this reference
*/
{
- ULONG HashValue;
- KIRQL OldIrql;
- PNEIGHBOR_CACHE_ENTRY NCE;
-
- TI_DbgPrint(DEBUG_NCACHE, ("Called. Interface (0x%X) Address (0x%X) "
- "LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n",
- Interface, Address, LinkAddress, LinkAddressLength, State));
-
- NCE = ExAllocatePool(NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength);
- if (!NCE) {
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return NULL;
+ PNEIGHBOR_CACHE_ENTRY NCE;
+ ULONG HashValue;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. Interface (0x%X) Address (0x%X) "
+ "LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n",
+ Interface, Address, LinkAddress, LinkAddressLength, State));
+
+ NCE = ExAllocatePool(NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength);
+ if (NCE == NULL)
+ {
+ TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ return NULL;
}
- INIT_TAG(NCE, TAG('N','C','E',' '));
+ INIT_TAG(NCE, TAG('N','C','E',' '));
- /* Initialize NCE free routine */
- NCE->Free = FreeNCE;
+ /* Initialize NCE free routine */
+ NCE->Free = FreeNCE;
- /* Reference once for beeing alive and once for the caller */
- NCE->RefCount = 2;
- NCE->Interface = Interface;
- NCE->Address = Address;
- NCE->LinkAddressLength = LinkAddressLength;
- NCE->LinkAddress = (PVOID)((ULONG_PTR)NCE + sizeof(NEIGHBOR_CACHE_ENTRY));
- if (LinkAddress)
- RtlCopyMemory(NCE->LinkAddress, LinkAddress, LinkAddressLength);
- NCE->State = State;
- NCE->EventTimer = 0; /* Not in use */
- NCE->WaitQueue = NULL;
+ /* Reference once for beeing alive and once for the caller */
+ NCE->RefCount = 2;
+ NCE->Interface = Interface;
+ NCE->Address = Address;
+ NCE->LinkAddressLength = LinkAddressLength;
+ NCE->LinkAddress = (PVOID)((ULONG_PTR)NCE + sizeof(NEIGHBOR_CACHE_ENTRY));
+ if (LinkAddress != NULL)
+ {
+ RtlCopyMemory(NCE->LinkAddress, LinkAddress, LinkAddressLength);
+ }
+ NCE->State = State;
+ NCE->EventTimer = 0; /* Not in use */
+ NCE->WaitQueue = NULL;
- HashValue = *(PULONG)&Address->Address;
- HashValue ^= HashValue >> 16;
- HashValue ^= HashValue >> 8;
- HashValue ^= HashValue >> 4;
- HashValue &= NB_HASHMASK;
+ HashValue = *(PULONG)&Address->Address;
+ HashValue ^= HashValue >> 16;
+ HashValue ^= HashValue >> 8;
+ HashValue ^= HashValue >> 4;
+ HashValue &= NB_HASHMASK;
- NCE->Table = &NeighborCache[HashValue];
+ NCE->Table = &NeighborCache[HashValue];
- KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
+ KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
- NCE->Next = NeighborCache[HashValue].Cache;
- NeighborCache[HashValue].Cache = NCE;
+ NCE->Next = NeighborCache[HashValue].Cache;
+ NeighborCache[HashValue].Cache = NCE;
- KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
+ KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
- return NCE;
+ return NCE;
}
-
VOID NBUpdateNeighbor(
- PNEIGHBOR_CACHE_ENTRY NCE,
- PVOID LinkAddress,
- UCHAR State)
+ PNEIGHBOR_CACHE_ENTRY NCE,
+ PVOID LinkAddress,
+ UCHAR State)
/*
* FUNCTION: Update link address information in NCE
* ARGUMENTS:
- * NCE = Pointer to NCE to update
- * LinkAddress = Pointer to link address
- * State = State of NCE
+ * NCE = Pointer to NCE to update
+ * LinkAddress = Pointer to link address
+ * State = State of NCE
* NOTES:
- * The link address and state is updated. Any waiting packets are sent
+ * The link address and state is updated. Any waiting packets are sent
*/
{
- KIRQL OldIrql;
- PNDIS_PACKET Current;
- PNDIS_PACKET Next;
-
- TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X) LinkAddress (0x%X) State (0x%X).\n", NCE, LinkAddress, State));
-
- KeAcquireSpinLock(&NCE->Table->Lock, &OldIrql);
-
- RtlCopyMemory(NCE->LinkAddress, LinkAddress, NCE->LinkAddressLength);
- NCE->State = State;
- Current = NCE->WaitQueue;
- NCE->WaitQueue = NULL;
-
- KeReleaseSpinLock(&NCE->Table->Lock, OldIrql);
-#if 1
- /* Send any waiting packets */
- while (Current) {
- /* Our link to the next packet is broken by the
- datalink layer code so we must save it here */
- Next = (PNDIS_PACKET)PC(Current)->DLComplete;
- IPSendFragment(Current, NCE);
- Current = Next;
+ PNDIS_PACKET Current;
+ PNDIS_PACKET Next;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X) LinkAddress (0x%X) State (0x%X).\n", NCE, LinkAddress, State));
+
+ KeAcquireSpinLock(&NCE->Table->Lock, &OldIrql);
+
+ RtlCopyMemory(NCE->LinkAddress, LinkAddress, NCE->LinkAddressLength);
+ NCE->State = State;
+ Current = NCE->WaitQueue;
+ NCE->WaitQueue = NULL;
+
+ KeReleaseSpinLock(&NCE->Table->Lock, OldIrql);
+
+ /* Send any waiting packets */
+ while (Current != NULL)
+ {
+ /* Our link to the next packet is broken by the
+ datalink layer code so we must save it here */
+ Next = (PNDIS_PACKET)PC(Current)->DLComplete;
+ IPSendFragment(Current, NCE);
+ Current = Next;
}
-#endif
}
-
PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
- PIP_ADDRESS Address)
+ PIP_ADDRESS Address)
/*
* FUNCTION: Locates a neighbor in the neighbor cache
* ARGUMENTS:
- * Address = Pointer to IP address
+ * Address = Pointer to IP address
* RETURNS:
- * Pointer to NCE, NULL if not found
+ * Pointer to NCE, NULL if not found
* NOTES:
- * If the NCE is found, it is referenced. The caller is
- * responsible for dereferencing it again after use
+ * If the NCE is found, it is referenced. The caller is
+ * responsible for dereferencing it again after use
*/
{
- UINT HashValue;
- KIRQL OldIrql;
- PNEIGHBOR_CACHE_ENTRY NCE;
+ PNEIGHBOR_CACHE_ENTRY NCE;
+ UINT HashValue;
+ KIRQL OldIrql;
- TI_DbgPrint(DEBUG_NCACHE, ("Called. Address (0x%X).\n", Address));
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. Address (0x%X).\n", Address));
- HashValue = *(PULONG)&Address->Address;
- HashValue ^= HashValue >> 16;
- HashValue ^= HashValue >> 8;
- HashValue ^= HashValue >> 4;
- HashValue &= NB_HASHMASK;
+ HashValue = *(PULONG)&Address->Address;
+ HashValue ^= HashValue >> 16;
+ HashValue ^= HashValue >> 8;
+ HashValue ^= HashValue >> 4;
+ HashValue &= NB_HASHMASK;
- KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
+ KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
- NCE = NeighborCache[HashValue].Cache;
+ NCE = NeighborCache[HashValue].Cache;
- while ((NCE) && (!AddrIsEqual(Address, NCE->Address)))
- NCE = NCE->Next;
+ while ((NCE) && (!AddrIsEqual(Address, NCE->Address)))
+ {
+ NCE = NCE->Next;
+ }
- if (NCE)
- ReferenceObject(NCE);
+ if (NCE)
+ {
+ ReferenceObject(NCE);
+ }
- KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
+ KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
- return NCE;
+ return NCE;
}
-
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
- PIP_INTERFACE Interface,
- PIP_ADDRESS Address)
+ PIP_INTERFACE Interface,
+ PIP_ADDRESS Address)
/*
* FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE
* ARGUMENTS:
- * Interface = Pointer to interface to use (if NCE is not found)
- * Address = Pointer to IP address
+ * Interface = Pointer to interface to use (in case NCE is not found)
+ * Address = Pointer to IP address
* RETURNS:
- * Pointer to NCE, NULL if there is not enough free resources
+ * Pointer to NCE, NULL if there is not enough free resources
* NOTES:
- * The NCE is referenced if found or created. The caller is
- * responsible for dereferencing it again after use
+ * The NCE is referenced if found or created. The caller is
+ * responsible for dereferencing it again after use
*/
{
- PNEIGHBOR_CACHE_ENTRY NCE;
-
- TI_DbgPrint(DEBUG_NCACHE, ("Called. Interface (0x%X) Address (0x%X).\n", Interface, Address));
-
- NCE = NBLocateNeighbor(Address);
- if (!NCE) {
- ReferenceObject(Address);
- NCE = NBAddNeighbor(Interface, Address, NULL,
- Interface->AddressLength, NUD_INCOMPLETE);
- NCE->EventTimer = 1;
- NCE->EventCount = 0;
+ PNEIGHBOR_CACHE_ENTRY NCE;
+
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. Interface (0x%X) Address (0x%X).\n", Interface, Address));
+
+ NCE = NBLocateNeighbor(Address);
+ if (NCE == NULL)
+ {
+ ReferenceObject(Address);
+ NCE = NBAddNeighbor(Interface, Address, NULL,
+ Interface->AddressLength, NUD_INCOMPLETE);
+ NCE->EventTimer = 1;
+ NCE->EventCount = 0;
}
- return NCE;
+ return NCE;
}
-
BOOLEAN NBQueuePacket(
- PNEIGHBOR_CACHE_ENTRY NCE,
- PNDIS_PACKET NdisPacket)
+ PNEIGHBOR_CACHE_ENTRY NCE,
+ PNDIS_PACKET NdisPacket)
/*
* FUNCTION: Queues a packet on an NCE for later transmission
* ARGUMENTS:
- * NCE = Pointer to NCE to queue packet on
- * NdisPacket = Pointer to NDIS packet to queue
+ * NCE = Pointer to NCE to queue packet on
+ * NdisPacket = Pointer to NDIS packet to queue
* RETURNS:
- * TRUE if the packet was successfully queued, FALSE if not
+ * TRUE if the packet was successfully queued, FALSE if not
*/
{
- KIRQL OldIrql;
- PKSPIN_LOCK Lock;
+ PKSPIN_LOCK Lock;
+ KIRQL OldIrql;
- TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X) NdisPacket (0x%X).\n", NCE, NdisPacket));
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X) NdisPacket (0x%X).\n", NCE, NdisPacket));
- /* FIXME: Should we limit the number of queued packets? */
+ /* FIXME: Should we limit the number of queued packets? */
- Lock = &NCE->Table->Lock;
+ Lock = &NCE->Table->Lock;
- KeAcquireSpinLock(Lock, &OldIrql);
+ KeAcquireSpinLock(Lock, &OldIrql);
- /* Use data link level completion handler pointer to link
- queued packets together */
- PC(NdisPacket)->DLComplete = (PACKET_COMPLETION_ROUTINE)NCE->WaitQueue;
- NCE->WaitQueue = NdisPacket;
+ /* Use data link level completion handler pointer to link
+ queued packets together */
+ PC(NdisPacket)->DLComplete = (PACKET_COMPLETION_ROUTINE)NCE->WaitQueue;
+ NCE->WaitQueue = NdisPacket;
- KeReleaseSpinLock(Lock, OldIrql);
+ KeReleaseSpinLock(Lock, OldIrql);
- return TRUE;
+ return TRUE;
}
VOID NBRemoveNeighbor(
- PNEIGHBOR_CACHE_ENTRY NCE)
+ PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Removes a neighbor from the neighbor cache
* ARGUMENTS:
- * NCE = Pointer to NCE to remove from cache
+ * NCE = Pointer to NCE to remove from cache
* NOTES:
- * The NCE must be in a safe state
+ * The NCE must be in a safe state
*/
{
- ULONG HashValue;
- KIRQL OldIrql;
- PNEIGHBOR_CACHE_ENTRY *PrevNCE;
- PNEIGHBOR_CACHE_ENTRY CurNCE;
- PNDIS_PACKET NdisPacket, Next;
-
- TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
-
- HashValue = *(PULONG)(&NCE->Address->Address);
- HashValue ^= HashValue >> 16;
- HashValue ^= HashValue >> 8;
- HashValue ^= HashValue >> 4;
- HashValue &= NB_HASHMASK;
-
- KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
-
- /* Search the list and remove the NCE from the list if found */
- for (PrevNCE = &NeighborCache[HashValue].Cache;
- (CurNCE = *PrevNCE) != NULL;
- PrevNCE = &CurNCE->Next) {
- if (CurNCE == NCE) {
- /* Found it, now unlink it from the list */
- *PrevNCE = CurNCE->Next;
-
- /* Purge wait queue */
- NdisPacket = CurNCE->WaitQueue;
- while (NdisPacket) {
- Next = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
- FreeNdisPacket(NdisPacket);
- NdisPacket = Next;
+ PNEIGHBOR_CACHE_ENTRY *PrevNCE;
+ PNEIGHBOR_CACHE_ENTRY CurNCE;
+ PNDIS_PACKET NextNdisPacket;
+ PNDIS_PACKET NdisPacket;
+ ULONG HashValue;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
+
+ HashValue = *(PULONG)(&NCE->Address->Address);
+ HashValue ^= HashValue >> 16;
+ HashValue ^= HashValue >> 8;
+ HashValue ^= HashValue >> 4;
+ HashValue &= NB_HASHMASK;
+
+ KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
+
+ /* Search the list and remove the NCE from the list if found */
+ for (PrevNCE = &NeighborCache[HashValue].Cache;
+ (CurNCE = *PrevNCE) != NULL;
+ PrevNCE = &CurNCE->Next)
+ {
+ if (CurNCE == NCE)
+ {
+ /* Found it, now unlink it from the list */
+ *PrevNCE = CurNCE->Next;
+
+ /* Purge wait queue */
+ NdisPacket = CurNCE->WaitQueue;
+ while (NdisPacket != NULL)
+ {
+ NextNdisPacket = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
+ FreeNdisPacket(NdisPacket);
+ NdisPacket = NextNdisPacket;
}
- /* Remove all references from route cache */
- RouteInvalidateNCE(CurNCE);
+ /* Remove all references from route cache */
+ RouteInvalidateNCE(CurNCE);
- /* Remove reference to the address */
- DereferenceObject(CurNCE->Address);
+ /* Remove reference to the address */
+ DereferenceObject(CurNCE->Address);
#if DBG
- CurNCE->RefCount--;
+ CurNCE->RefCount--;
- if (CurNCE->RefCount != 0) {
- TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 0).\n", CurNCE, CurNCE->RefCount));
+ if (CurNCE->RefCount != 0)
+ {
+ TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 0).\n",
+ CurNCE, CurNCE->RefCount));
}
#endif
- ExFreePool(CurNCE);
+ ExFreePool(CurNCE);
- KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
+ KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
- return;
+ return;
}
}
- KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
+ KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
}
-
-/* EOF */
TDI_STATUS IPTdiQueryInformationEx(
- PTDI_REQUEST Request,
- TDIObjectID *ID,
- PNDIS_BUFFER Buffer,
- PUINT BufferSize,
- PVOID Context)
+ PTDI_REQUEST Request,
+ TDIObjectID *ID,
+ PNDIS_BUFFER Buffer,
+ PUINT BufferSize,
+ PVOID Context)
/*
* FUNCTION: Returns extended information about network layer
* ARGUMENTS:
- * Request = Pointer to TDI request structure for the request
- * ID = TDI object ID
- * Buffer = Pointer to buffer with data to use.
- * BufferSize = Pointer to buffer with size of Buffer. On return
+ * Request = Pointer to TDI request structure for the request
+ * ID = TDI object ID
+ * Buffer = Pointer to buffer with data to use.
+ * BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
- * Context = Pointer to context buffer
+ * Context = Pointer to context buffer
* RETURNS:
- * Status of operation
+ * Status of operation
*/
{
- PLIST_ENTRY CurrentIFEntry;
- PLIST_ENTRY CurrentADEEntry;
- PIP_INTERFACE CurrentIF;
- PADDRESS_ENTRY CurrentADE;
- IPADDR_ENTRY IpAddress;
- IPSNMP_INFO SnmpInfo;
- ULONG Temp;
- UINT Count;
- ULONG Entity;
- KIRQL OldIrql;
- UINT BufSize = *BufferSize;
-
- /* Make return parameters consistent every time */
- *BufferSize = 0;
-
- Entity = ID->toi_entity.tei_entity;
- if (Entity != CL_NL_ENTITY) {
- /* We can't handle this entity */
- return TDI_INVALID_PARAMETER;
+ PLIST_ENTRY CurrentIFEntry;
+ PLIST_ENTRY CurrentADEEntry;
+ PADDRESS_ENTRY CurrentADE;
+ PIP_INTERFACE CurrentIF;
+ IPADDR_ENTRY IpAddress;
+ IPSNMP_INFO SnmpInfo;
+ KIRQL OldIrql;
+ ULONG Entity;
+ ULONG Temp;
+ UINT Count;
+ UINT BufSize;
+
+ BufSize = *BufferSize;
+
+ /* Make return parameters consistent every time */
+ *BufferSize = 0;
+
+ Entity = ID->toi_entity.tei_entity;
+ if (Entity != CL_NL_ENTITY)
+ {
+ /* We can't handle this entity */
+ return TDI_INVALID_PARAMETER;
}
- if (ID->toi_entity.tei_instance != TL_INSTANCE)
- /* We only support a single instance */
- return TDI_INVALID_REQUEST;
- if (ID->toi_class == INFO_CLASS_GENERIC) {
- if (ID->toi_type == INFO_TYPE_PROVIDER &&
- ID->toi_id == ENTITY_TYPE_ID) {
+ if (ID->toi_entity.tei_instance != TL_INSTANCE)
+ {
+ /* Only a single instance is supported */
+ return TDI_INVALID_REQUEST;
+ }
- if (BufSize < sizeof(ULONG))
- return TDI_BUFFER_TOO_SMALL;
- Temp = CL_NL_IP;
+ if (ID->toi_class == INFO_CLASS_GENERIC)
+ {
+ if ((ID->toi_type == INFO_TYPE_PROVIDER) &&
+ (ID->toi_id == ENTITY_TYPE_ID))
+ {
+ if (BufSize < sizeof(ULONG))
+ {
+ return TDI_BUFFER_TOO_SMALL;
+ }
- Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
+ Temp = CL_NL_IP;
+ Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
- return TDI_SUCCESS;
+ return TDI_SUCCESS;
}
- return TDI_INVALID_PARAMETER;
+
+ return TDI_INVALID_PARAMETER;
}
- if (ID->toi_class == INFO_CLASS_PROTOCOL) {
- if (ID->toi_type != INFO_TYPE_PROVIDER)
- return TDI_INVALID_PARAMETER;
+ if (ID->toi_class == INFO_CLASS_PROTOCOL)
+ {
+ if (ID->toi_type != INFO_TYPE_PROVIDER)
+ {
+ return TDI_INVALID_PARAMETER;
+ }
- switch (ID->toi_id) {
- case IP_MIB_ADDRTABLE_ENTRY_ID:
+ switch (ID->toi_id)
+ {
+ case IP_MIB_ADDRTABLE_ENTRY_ID:
Temp = 0;
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
CurrentIFEntry = InterfaceListHead.Flink;
- while (CurrentIFEntry != &InterfaceListHead) {
- CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+ while (CurrentIFEntry != &InterfaceListHead)
+ {
+ CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
- if (Temp + sizeof(IPADDR_ENTRY) > BufSize) {
+ if (Temp + sizeof(IPADDR_ENTRY) > BufSize)
+ {
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return TDI_BUFFER_TOO_SMALL;
- }
+ }
IpAddress.Addr = 0;
IpAddress.BcastAddr = 0;
/* Locate the diffrent addresses and put them the right place */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
- while (CurrentADEEntry != &CurrentIF->ADEListHead) {
- CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
-
- switch (CurrentADE->Type) {
- case ADE_UNICAST:
- IpAddress.Addr = CurrentADE->Address->Address.IPv4Address;
- break;
- case ADE_MULTICAST:
- IpAddress.BcastAddr = CurrentADE->Address->Address.IPv4Address;
- break;
- case ADE_ADDRMASK:
- IpAddress.Mask = CurrentADE->Address->Address.IPv4Address;
- break;
- default:
- /* Should not happen */
- TI_DbgPrint(MIN_TRACE, ("Unknown address entry type (0x%X)\n", CurrentADE->Type));
- break;
- }
+ while (CurrentADEEntry != &CurrentIF->ADEListHead)
+ {
+ CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
+
+ switch (CurrentADE->Type)
+ {
+ case ADE_UNICAST:
+ IpAddress.Addr = CurrentADE->Address->Address.IPv4Address;
+ break;
+ case ADE_MULTICAST:
+ IpAddress.BcastAddr = CurrentADE->Address->Address.IPv4Address;
+ break;
+ case ADE_ADDRMASK:
+ IpAddress.Mask = CurrentADE->Address->Address.IPv4Address;
+ break;
+ default:
+ /* Should not happen */
+ TI_DbgPrint(MIN_TRACE, ("Unknown address entry type (0x%X)\n", CurrentADE->Type));
+ break;
+ }
CurrentADEEntry = CurrentADEEntry->Flink;
- }
+ }
+
/* Pack the address information into IPADDR_ENTRY structure */
IpAddress.Index = 0;
IpAddress.ReasmSize = 0;
IpAddress.Pad = 0;
Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
-
Temp += sizeof(IPADDR_ENTRY);
CurrentIFEntry = CurrentIFEntry->Flink;
- }
+ }
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return TDI_SUCCESS;
- case IP_MIB_STATS_ID:
+ case IP_MIB_STATS_ID:
if (BufSize < sizeof(IPSNMP_INFO))
+ {
return TDI_BUFFER_TOO_SMALL;
+ }
RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
CurrentIFEntry = InterfaceListHead.Flink;
- while (CurrentIFEntry != &InterfaceListHead) {
- CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
- Count++;
- CurrentIFEntry = CurrentIFEntry->Flink;
- }
+ while (CurrentIFEntry != &InterfaceListHead)
+ {
+ CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+ Count++;
+ CurrentIFEntry = CurrentIFEntry->Flink;
+ }
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
SnmpInfo.NumAddr = Count;
-
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
return TDI_SUCCESS;
- default:
+ default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
- return TDI_INVALID_PARAMETER;
+ return TDI_INVALID_PARAMETER;
}
-
TDI_STATUS InfoTdiQueryInformationEx(
- PTDI_REQUEST Request,
- TDIObjectID *ID,
- PNDIS_BUFFER Buffer,
- PUINT BufferSize,
- PVOID Context)
+ PTDI_REQUEST Request,
+ TDIObjectID *ID,
+ PNDIS_BUFFER Buffer,
+ PUINT BufferSize,
+ PVOID Context)
/*
* FUNCTION: Returns extended information
* ARGUMENTS:
- * Request = Pointer to TDI request structure for the request
- * ID = TDI object ID
- * Buffer = Pointer to buffer with data to use
- * BufferSize = Pointer to buffer with size of Buffer. On return
- * this is filled with number of bytes returned
- * Context = Pointer to context buffer
+ * Request = Pointer to TDI request structure for the request
+ * ID = TDI object ID
+ * Buffer = Pointer to buffer with data to use
+ * BufferSize = Pointer to buffer with size of Buffer. On return
+ * this is filled with number of bytes returned
+ * Context = Pointer to context buffer
* RETURNS:
- * Status of operation
+ * Status of operation
*/
{
- PLIST_ENTRY CurrentADFEntry;
- PADDRESS_FILE CurrentADF;
- ADDRESS_INFO Info;
- KIRQL OldIrql;
- UINT Entity;
- UINT Count;
- UINT Size;
- ULONG Temp;
- UINT Offset = 0;
- UINT BufSize = *BufferSize;
-
- /* Check wether it is a query for a list of entities */
- Entity = ID->toi_entity.tei_entity;
- if (Entity == GENERIC_ENTITY) {
- if (ID->toi_class != INFO_CLASS_GENERIC ||
- ID->toi_type != INFO_TYPE_PROVIDER ||
- ID->toi_id != ENTITY_LIST_ID)
- return TDI_INVALID_PARAMETER;
+ PLIST_ENTRY CurrentADFEntry;
+ PADDRESS_FILE CurrentADF;
+ ADDRESS_INFO Info;
+ KIRQL OldIrql;
+ UINT BufSize;
+ UINT Entity;
+ UINT Offset;
+ ULONG Temp;
+ UINT Count;
+ UINT Size;
+
+ Offset = 0;
+ BufSize = *BufferSize;
+
+ /* Check wether it is a query for a list of entities */
+ Entity = ID->toi_entity.tei_entity;
+ if (Entity == GENERIC_ENTITY)
+ {
+ if ((ID->toi_class != INFO_CLASS_GENERIC) ||
+ (ID->toi_type != INFO_TYPE_PROVIDER) ||
+ (ID->toi_id != ENTITY_LIST_ID))
+ {
+ return TDI_INVALID_PARAMETER;
+ }
- *BufferSize = 0;
+ *BufferSize = 0;
- Size = EntityCount * sizeof(TDIEntityID);
- if (BufSize < Size)
- /* The buffer is too small to contain requested data */
- return TDI_BUFFER_TOO_SMALL;
+ Size = EntityCount * sizeof(TDIEntityID);
+ if (BufSize < Size)
+ {
+ /* The buffer is too small to contain requested data */
+ return TDI_BUFFER_TOO_SMALL;
+ }
- /* Return entity list */
- Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
+ /* Return entity list */
+ Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
- *BufferSize = Size;
+ *BufferSize = Size;
- return TDI_SUCCESS;
+ return TDI_SUCCESS;
}
- if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY)) {
+ if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY))
+ {
/* We can't handle this entity, pass it on */
return IPTdiQueryInformationEx(
- Request, ID, Buffer, BufferSize, Context);
- }
+ Request, ID, Buffer, BufferSize, Context);
+ }
/* Make return parameters consistent every time */
*BufferSize = 0;
if (ID->toi_entity.tei_instance != TL_INSTANCE)
+ {
/* We only support a single instance */
return TDI_INVALID_REQUEST;
+ }
- if (ID->toi_class == INFO_CLASS_GENERIC) {
-
- if (ID->toi_type != INFO_TYPE_PROVIDER ||
- ID->toi_id != ENTITY_TYPE_ID)
+ if (ID->toi_class == INFO_CLASS_GENERIC)
+ {
+ if ((ID->toi_type != INFO_TYPE_PROVIDER) ||
+ (ID->toi_id != ENTITY_TYPE_ID))
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(ULONG))
+ {
return TDI_BUFFER_TOO_SMALL;
+ }
if (Entity == CL_TL_ENTITY)
+ {
Temp = CL_TL_UDP;
+ }
else if (Entity == CO_TL_ENTITY)
+ {
Temp = CO_TL_TCP;
+ }
else
+ {
return TDI_INVALID_PARAMETER;
+ }
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
- if (ID->toi_class == INFO_CLASS_PROTOCOL) {
-
- if (ID->toi_type != INFO_TYPE_PROVIDER)
- return TDI_INVALID_PARAMETER;
+ if (ID->toi_class == INFO_CLASS_PROTOCOL)
+ {
+ if (ID->toi_type != INFO_TYPE_PROVIDER)
+ {
+ return TDI_INVALID_PARAMETER;
+ }
- switch (ID->toi_id) {
- case UDP_MIB_STAT_ID:
+ switch (ID->toi_id)
+ {
+ case UDP_MIB_STAT_ID:
if (Entity != CL_TL_ENTITY)
+ {
return TDI_INVALID_PARAMETER;
+ }
if (BufSize < sizeof(UDPStats))
+ {
return TDI_BUFFER_TOO_SMALL;
+ }
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
return TDI_SUCCESS;
- case UDP_MIB_TABLE_ID:
+ case UDP_MIB_TABLE_ID:
if (Entity != CL_TL_ENTITY)
+ {
return TDI_INVALID_PARAMETER;
+ }
Offset = 0;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
CurrentADFEntry = AddressFileListHead.Flink;
- while (CurrentADFEntry != &AddressFileListHead) {
- CurrentADF = CONTAINING_RECORD(CurrentADFEntry, ADDRESS_FILE, ListEntry);
+ while (CurrentADFEntry != &AddressFileListHead)
+ {
+ CurrentADF = CONTAINING_RECORD(CurrentADFEntry, ADDRESS_FILE, ListEntry);
- if (Offset + sizeof(ADDRESS_INFO) > BufSize) {
+ if (Offset + sizeof(ADDRESS_INFO) > BufSize)
+ {
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
*BufferSize = Offset;
return TDI_BUFFER_OVERFLOW;
- }
+ }
Info.LocalAddress = CurrentADF->ADE->Address->Address.IPv4Address;
- Info.LocalPort = CurrentADF->Port;
+ Info.LocalPort = CurrentADF->Port;
Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
-
Offset += Count;
CurrentADFEntry = CurrentADFEntry->Flink;
- }
+ }
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
return STATUS_SUCCESS;
- default:
+ default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
return TDI_INVALID_PARAMETER;
}
-
TDI_STATUS InfoTdiSetInformationEx(
- PTDI_REQUEST Request,
- TDIObjectID *ID,
- PVOID Buffer,
- UINT BufferSize)
+ PTDI_REQUEST Request,
+ TDIObjectID *ID,
+ PVOID Buffer,
+ UINT BufferSize)
/*
* FUNCTION: Sets extended information
* ARGUMENTS:
- * Request = Pointer to TDI request structure for the request
- * ID = Pointer to TDI object ID
- * Buffer = Pointer to buffer with data to use
- * BufferSize = Size of Buffer
+ * Request = Pointer to TDI request structure for the request
+ * ID = Pointer to TDI object ID
+ * Buffer = Pointer to buffer with data to use
+ * BufferSize = Size of Buffer
* RETURNS:
- * Status of operation
+ * Status of operation
*/
{
- /* FIXME: Set extended information */
+ /* FIXME: Set extended information */
- return TDI_INVALID_REQUEST;
+ return TDI_INVALID_REQUEST;
}
-
-/* EOF */
KeAcquireSpinLock(&DGPendingListLock, &OldIrql1);
CurrentADFEntry = DGPendingListHead.Flink;
- while (CurrentADFEntry != &DGPendingListHead) {
- RemoveEntryList(CurrentADFEntry);
- CurrentADF = CONTAINING_RECORD(CurrentADFEntry,
- ADDRESS_FILE,
- ListEntry);
-
- KeAcquireSpinLock(&CurrentADF->Lock, &OldIrql2);
-
- if (AF_IS_BUSY(CurrentADF)) {
- /* The send worker function is already running so we just
- set the pending send flag on the address file object */
-
- AF_SET_PENDING(CurrentADF, AFF_SEND);
- KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
- } else {
- if (!IsListEmpty(&CurrentADF->TransmitQueue)) {
- /* The transmit queue is not empty. Dequeue a send
- request and process it */
-
- CurrentSREntry = RemoveHeadList(&CurrentADF->TransmitQueue);
- CurrentSR = CONTAINING_RECORD(CurrentADFEntry,
- DATAGRAM_SEND_REQUEST,
- ListEntry);
-
- KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
-
- DGSend(CurrentADF, CurrentSR);
- } else
- KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
+ while (CurrentADFEntry != &DGPendingListHead)
+ {
+ RemoveEntryList(CurrentADFEntry);
+ CurrentADF = CONTAINING_RECORD(CurrentADFEntry,
+ ADDRESS_FILE,
+ ListEntry);
+
+ KeAcquireSpinLock(&CurrentADF->Lock, &OldIrql2);
+
+ if (AF_IS_BUSY(CurrentADF))
+ {
+ /* The send worker function is already running so we just
+ set the pending send flag on the address file object */
+
+ AF_SET_PENDING(CurrentADF, AFF_SEND);
+ KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
+ }
+ else
+ {
+ if (!IsListEmpty(&CurrentADF->TransmitQueue))
+ {
+ /* The transmit queue is not empty. Dequeue a send
+ request and process it */
+
+ CurrentSREntry = RemoveHeadList(&CurrentADF->TransmitQueue);
+ CurrentSR = CONTAINING_RECORD(CurrentADFEntry,
+ DATAGRAM_SEND_REQUEST,
+ ListEntry);
+
+ KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
+
+ DGSend(CurrentADF, CurrentSR);
+ }
+ else
+ {
+ KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
+ }
+ }
+ CurrentADFEntry = CurrentADFEntry->Flink;
}
- CurrentADFEntry = CurrentADFEntry->Flink;
- }
KeReleaseSpinLock(&DGPendingListLock, OldIrql1);
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+ ASSERT(SendRequest->Build);
+
/* Get the information we need from the address file
now so we minimize the time we hold the spin lock */
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ ASSERT(AddrFile->ADE);
LocalPort = AddrFile->Port;
ADE = AddrFile->ADE;
ReferenceObject(ADE);
/* Loop until there are no more send requests in the
transmit queue or until we run out of resources */
- for (;;) {
- Status = (*SendRequest->Build)(SendRequest, ADE->Address, LocalPort, &IPPacket);
- if (!NT_SUCCESS(Status)) {
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- /* An error occurred, enqueue the send request again and return */
- InsertTailList(&AddrFile->TransmitQueue, &SendRequest->ListEntry);
- DereferenceObject(ADE);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- TI_DbgPrint(MIN_TRACE, ("Leaving (insufficient resources).\n"));
- return;
- }
+ for (;;)
+ {
+ Status = (*SendRequest->Build)(SendRequest, ADE->Address, LocalPort, &IPPacket);
+ if (!NT_SUCCESS(Status))
+ {
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ /* An error occurred, enqueue the send request again and return */
+ InsertHeadList(&AddrFile->TransmitQueue, &SendRequest->ListEntry);
+ DereferenceObject(ADE);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ TI_DbgPrint(MIN_TRACE, ("Leaving (insufficient resources).\n"));
+ return;
+ }
- /* Get a route to the destination address */
- if (RouteGetRouteToDestination(SendRequest->RemoteAddress, ADE->NTE, &RCN) == IP_SUCCESS) {
- /* Set completion routine and send the packet */
- PC(IPPacket->NdisPacket)->Complete = SendDatagramComplete;
- PC(IPPacket->NdisPacket)->Context = SendRequest;
- if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS)
- SendDatagramComplete(
- SendRequest,
+ /* Get a route to the destination address */
+ if (RouteGetRouteToDestination(SendRequest->RemoteAddress, ADE->NTE, &RCN) == IP_SUCCESS)
+ {
+ /* Set completion routine and send the packet */
+ PC(IPPacket->NdisPacket)->Complete = SendDatagramComplete;
+ PC(IPPacket->NdisPacket)->Context = SendRequest;
+ if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS)
+ {
+ SendDatagramComplete(SendRequest,
+ IPPacket->NdisPacket,
+ NDIS_STATUS_REQUEST_ABORTED);
+ }
+ /* We're done with the RCN */
+ DereferenceObject(RCN);
+ }
+ else
+ {
+ /* No route to destination */
+ /* FIXME: Which error code should we use here? */
+ TI_DbgPrint(MIN_TRACE, ("No route to destination address (0x%X).\n",
+ SendRequest->RemoteAddress->Address.IPv4Address));
+ SendDatagramComplete(SendRequest,
IPPacket->NdisPacket,
NDIS_STATUS_REQUEST_ABORTED);
- /* We're done with the RCN */
- DereferenceObject(RCN);
- } else {
- /* No route to destination */
- /* FIXME: Which error code should we use here? */
- TI_DbgPrint(MIN_TRACE, ("No route to destination address (0x%X).\n",
- SendRequest->RemoteAddress->Address.IPv4Address));
- SendDatagramComplete(
- SendRequest,
- IPPacket->NdisPacket,
- NDIS_STATUS_REQUEST_ABORTED);
- }
-
- (*IPPacket->Free)(IPPacket);
-
- /* Check transmit queue for more to send */
-
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
- if (!IsListEmpty(&AddrFile->TransmitQueue)) {
- /* Transmit queue is not empty, process one more request */
- CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
- SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
-
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- } else {
- /* Transmit queue is empty */
- AF_CLR_PENDING(AddrFile, AFF_SEND);
- DereferenceObject(ADE);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ }
- TI_DbgPrint(MAX_TRACE, ("Leaving (empty queue).\n"));
- return;
+ (*IPPacket->Free)(IPPacket);
+
+ /* Check transmit queue for more to send */
+
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ if (!IsListEmpty(&AddrFile->TransmitQueue))
+ {
+ /* Transmit queue is not empty, process one more request */
+ CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
+ SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
+
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ }
+ else
+ {
+ /* Transmit queue is empty */
+ AF_CLR_PENDING(AddrFile, AFF_SEND);
+ DereferenceObject(ADE);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving (empty queue).\n"));
+ return;
+ }
}
- }
}
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- if (AddrFile->Protocol == IPPROTO_UDP) {
- DataBuffer = IPPacket->Data;
- } else {
- /* Give client the IP header too if it is a raw IP file object */
- DataBuffer = IPPacket->Header;
- }
-
- if (!IsListEmpty(&AddrFile->ReceiveQueue)) {
- PLIST_ENTRY CurrentEntry;
- PDATAGRAM_RECEIVE_REQUEST Current;
- BOOLEAN Found;
-
- TI_DbgPrint(MAX_TRACE, ("There is a receive request.\n"));
-
- /* Search receive request list to find a match */
- Found = FALSE;
- CurrentEntry = AddrFile->ReceiveQueue.Flink;
- while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
- Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
- if (!Current->RemoteAddress)
- Found = TRUE;
- else if (AddrIsEqual(Address, Current->RemoteAddress))
- Found = TRUE;
-
- if (Found) {
- /* FIXME: Maybe we should check if the buffer of this
- receive request is large enough and if not, search
- for another */
-
- /* Remove the request from the queue */
- RemoveEntryList(&Current->ListEntry);
- AddrFile->RefCount--;
- break;
- }
- CurrentEntry = CurrentEntry->Flink;
+ if (AddrFile->Protocol == IPPROTO_UDP)
+ {
+ DataBuffer = IPPacket->Data;
+ }
+ else
+ {
+ /* Give client the IP header too if it is a raw IP file object */
+ DataBuffer = IPPacket->Header;
}
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- if (Found) {
- TI_DbgPrint(MAX_TRACE, ("Suitable receive request found.\n"));
-
- /* Copy the data into buffer provided by the user */
- CopyBufferToBufferChain(
- Current->Buffer,
- 0,
- DataBuffer,
- DataSize);
-
- /* Complete the receive request */
- (*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize);
+ if (!IsListEmpty(&AddrFile->ReceiveQueue))
+ {
+ PLIST_ENTRY CurrentEntry;
+ PDATAGRAM_RECEIVE_REQUEST Current;
+ BOOLEAN Found;
+
+ TI_DbgPrint(MAX_TRACE, ("There is a receive request.\n"));
+
+ /* Search receive request list to find a match */
+ Found = FALSE;
+ CurrentEntry = AddrFile->ReceiveQueue.Flink;
+ while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found))
+ {
+ Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
+ if (!Current->RemoteAddress)
+ Found = TRUE;
+ else if (AddrIsEqual(Address, Current->RemoteAddress))
+ Found = TRUE;
+
+ if (Found)
+ {
+ /* FIXME: Maybe we should check if the buffer of this
+ receive request is large enough and if not, search
+ for another */
+
+ /* Remove the request from the queue */
+ RemoveEntryList(&Current->ListEntry);
+ AddrFile->RefCount--;
+ break;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
- /* Finally free the receive request */
- if (Current->RemoteAddress)
- DereferenceObject(Current->RemoteAddress);
- ExFreePool(Current);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ if (Found)
+ {
+ TI_DbgPrint(MAX_TRACE, ("Suitable receive request found.\n"));
+
+ /* Copy the data into buffer provided by the user */
+ CopyBufferToBufferChain(Current->Buffer,
+ 0,
+ DataBuffer,
+ DataSize);
+
+ /* Complete the receive request */
+ (*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize);
+
+ /* Finally free the receive request */
+ if (Current->RemoteAddress)
+ {
+ DereferenceObject(Current->RemoteAddress);
+ }
+ ExFreePool(Current);
+ }
}
- } else if (AddrFile->RegisteredReceiveDatagramHandler) {
- TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n"));
+ else if (AddrFile->RegisteredReceiveDatagramHandler)
+ {
+ TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n"));
- ReceiveHandler = AddrFile->ReceiveDatagramHandler;
- HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
+ ReceiveHandler = AddrFile->ReceiveDatagramHandler;
+ HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- if (Address->Type == IP_ADDRESS_V4) {
- AddressLength = sizeof(IPv4_RAW_ADDRESS);
- SourceAddress = &Address->Address.IPv4Address;
- } else /* (Address->Type == IP_ADDRESS_V6) */ {
- AddressLength = sizeof(IPv6_RAW_ADDRESS);
- SourceAddress = Address->Address.IPv6Address;
- }
+ if (Address->Type == IP_ADDRESS_V4)
+ {
+ AddressLength = sizeof(IPv4_RAW_ADDRESS);
+ SourceAddress = &Address->Address.IPv4Address;
+ }
+ else /* (Address->Type == IP_ADDRESS_V6) */
+ {
+ AddressLength = sizeof(IPv6_RAW_ADDRESS);
+ SourceAddress = Address->Address.IPv6Address;
+ }
- Status = (*ReceiveHandler)(
- HandlerContext,
- AddressLength,
- SourceAddress,
- 0,
- NULL,
- TDI_RECEIVE_ENTIRE_MESSAGE,
- DataSize,
- DataSize,
- &BytesTaken,
- DataBuffer,
- NULL);
- } else {
- TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
- }
+ Status = (*ReceiveHandler)(HandlerContext,
+ AddressLength,
+ SourceAddress,
+ 0,
+ NULL,
+ TDI_RECEIVE_ENTIRE_MESSAGE,
+ DataSize,
+ DataSize,
+ &BytesTaken,
+ DataBuffer,
+ NULL);
+ }
+ else
+ {
+ TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
+ }
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
/* Search the request list for the specified request and remove it */
CurrentEntry = AddrFile->TransmitQueue.Flink;
- while ((CurrentEntry != &AddrFile->TransmitQueue) && (!Found)) {
- Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
- if (Context == Current->Context) {
- /* We've found the request, now remove it from the queue */
- RemoveEntryList(CurrentEntry);
- AddrFile->RefCount--;
- Found = TRUE;
- break;
+ while ((CurrentEntry != &AddrFile->TransmitQueue) && (!Found))
+ {
+ Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
+ if (Context == Current->Context)
+ {
+ /* We've found the request, now remove it from the queue */
+ RemoveEntryList(CurrentEntry);
+ AddrFile->RefCount--;
+ Found = TRUE;
+ break;
+ }
+ CurrentEntry = CurrentEntry->Flink;
}
- CurrentEntry = CurrentEntry->Flink;
- }
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- if (Found) {
- /* Complete the request and free its resources */
- (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
- DereferenceObject(Current->RemoteAddress);
- ExFreePool(Current);
- } else {
- TI_DbgPrint(MID_TRACE, ("Cannot find send request.\n"));
- }
+ if (Found)
+ {
+ /* Complete the request and free its resources */
+ (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
+ DereferenceObject(Current->RemoteAddress);
+ ExFreePool(Current);
+ }
+ else
+ {
+ TI_DbgPrint(MID_TRACE, ("Cannot find send request.\n"));
+ }
}
/* Search the request list for the specified request and remove it */
CurrentEntry = AddrFile->ReceiveQueue.Flink;
- while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
- Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
- if (Context == Current->Context) {
- /* We've found the request, now remove it from the queue */
- RemoveEntryList(CurrentEntry);
- AddrFile->RefCount--;
- Found = TRUE;
- break;
+ while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found))
+ {
+ Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
+ if (Context == Current->Context)
+ {
+ /* We've found the request, now remove it from the queue */
+ RemoveEntryList(CurrentEntry);
+ AddrFile->RefCount--;
+ Found = TRUE;
+ break;
+ }
+ CurrentEntry = CurrentEntry->Flink;
}
- CurrentEntry = CurrentEntry->Flink;
- }
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- if (Found) {
- /* Complete the request and free its resources */
- (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
- /* Remote address can be NULL if the caller wants to receive
- packets sent from any address */
- if (Current->RemoteAddress)
- DereferenceObject(Current->RemoteAddress);
- ExFreePool(Current);
- } else {
- TI_DbgPrint(MID_TRACE, ("Cannot find receive request.\n"));
- }
+ if (Found)
+ {
+ /* Complete the request and free its resources */
+ (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
+
+ /* Remote address can be NULL if the caller wants to receive
+ packets sent from any address */
+ if (Current->RemoteAddress)
+ {
+ DereferenceObject(Current->RemoteAddress);
+ }
+ ExFreePool(Current);
+ }
+ else
+ {
+ TI_DbgPrint(MID_TRACE, ("Cannot find receive request.\n"));
+ }
}
*/
{
KIRQL OldIrql;
-CP
+
KeAcquireSpinLock(&AddressFile->Lock, &OldIrql);
-CP
- if (AF_IS_BUSY(AddressFile)) {
-CP
- /* Queue send request on the transmit queue */
- InsertTailList(&AddressFile->TransmitQueue, &SendRequest->ListEntry);
-CP
- /* Reference address file and set pending send request flag */
- ReferenceObject(AddressFile);
-CP
- AF_SET_PENDING(AddressFile, AFF_SEND);
-CP
- KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
-CP
- TI_DbgPrint(MAX_TRACE, ("Leaving (queued).\n"));
- } else {
-CP
- KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
-CP
- /* Send the datagram */
- DGSend(AddressFile, SendRequest);
-CP
- TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
- }
-CP
+ if (AF_IS_BUSY(AddressFile))
+ {
+ /* Queue send request on the transmit queue */
+ InsertTailList(&AddressFile->TransmitQueue, &SendRequest->ListEntry);
+ /* Reference address file and set pending send request flag */
+ ReferenceObject(AddressFile);
+ AF_SET_PENDING(AddressFile, AFF_SEND);
+ KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
+ TI_DbgPrint(MAX_TRACE, ("Leaving (queued).\n"));
+ }
+ else
+ {
+ KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
+ /* Send the datagram */
+ DGSend(AddressFile, SendRequest);
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+ }
return STATUS_PENDING;
}
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- if (AF_IS_VALID(AddrFile)) {
- /* Initialize a send request */
- Status = BuildDatagramSendRequest(
- &SendRequest,
- NULL,
- 0,
- Buffer,
- DataSize,
- Request->RequestNotifyObject,
- Request->RequestContext,
- Build,
- 0);
- if (NT_SUCCESS(Status)) {
- Status = AddrGetAddress(
- ConnInfo->RemoteAddress,
- &SendRequest->RemoteAddress,
- &SendRequest->RemotePort,
- &AddrFile->AddrCache);
- if (NT_SUCCESS(Status)) {
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- return DGTransmit(AddrFile, SendRequest);
- } else {
- ExFreePool(SendRequest);
- }
- } else
- Status = STATUS_INSUFFICIENT_RESOURCES;
- } else
- Status = STATUS_ADDRESS_CLOSED;
+ if (AF_IS_VALID(AddrFile))
+ {
+ /* Initialize a send request */
+ Status = BuildDatagramSendRequest(&SendRequest,
+ NULL,
+ 0,
+ Buffer,
+ DataSize,
+ Request->RequestNotifyObject,
+ Request->RequestContext,
+ Build,
+ 0);
+ if (NT_SUCCESS(Status))
+ {
+ Status = AddrGetAddress(ConnInfo->RemoteAddress,
+ &SendRequest->RemoteAddress,
+ &SendRequest->RemotePort,
+ &AddrFile->AddrCache);
+ if (NT_SUCCESS(Status))
+ {
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ return DGTransmit(AddrFile, SendRequest);
+ }
+ else
+ {
+ ExFreePool(SendRequest);
+ }
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ Status = STATUS_ADDRESS_CLOSED;
+ }
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- if (AF_IS_VALID(AddrFile)) {
- ReceiveRequest = ExAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
- if (ReceiveRequest) {
- /* Initialize a receive request */
-
- /* Extract the remote address filter from the request (if any) */
- if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress)) {
- Status = AddrGetAddress(ConnInfo->RemoteAddress,
- &ReceiveRequest->RemoteAddress,
- &ReceiveRequest->RemotePort,
- &AddrFile->AddrCache);
- if (!NT_SUCCESS(Status)) {
+ if (AF_IS_VALID(AddrFile))
+ {
+ ReceiveRequest = ExAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
+ if (ReceiveRequest)
+ {
+ /* Initialize a receive request */
+
+ /* Extract the remote address filter from the request (if any) */
+ if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress))
+ {
+ Status = AddrGetAddress(ConnInfo->RemoteAddress,
+ &ReceiveRequest->RemoteAddress,
+ &ReceiveRequest->RemotePort,
+ &AddrFile->AddrCache);
+ if (!NT_SUCCESS(Status))
+ {
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ ExFreePool(ReceiveRequest);
+ return Status;
+ }
+ }
+ else
+ {
+ ReceiveRequest->RemotePort = 0;
+ ReceiveRequest->RemoteAddress = NULL;
+ }
+ ReceiveRequest->ReturnInfo = ReturnInfo;
+ ReceiveRequest->Buffer = Buffer;
+ /* If ReceiveLength is 0, the whole buffer is available to us */
+ ReceiveRequest->BufferSize = (ReceiveLength == 0) ?
+ MmGetMdlByteCount(Buffer) : ReceiveLength;
+ ReceiveRequest->Complete = Request->RequestNotifyObject;
+ ReceiveRequest->Context = Request->RequestContext;
+
+ /* Queue receive request */
+ InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
+
+ /* Reference address file and set pending receive request flag */
+ AddrFile->RefCount++;
+ AF_SET_PENDING(AddrFile, AFF_RECEIVE);
+
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- ExFreePool(ReceiveRequest);
- return Status;
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+
+ return STATUS_PENDING;
}
- } else {
- ReceiveRequest->RemotePort = 0;
- ReceiveRequest->RemoteAddress = NULL;
- }
- ReceiveRequest->ReturnInfo = ReturnInfo;
- ReceiveRequest->Buffer = Buffer;
- /* If ReceiveLength is 0, the whole buffer is available to us */
- ReceiveRequest->BufferSize = (ReceiveLength == 0) ?
- MmGetMdlByteCount(Buffer) : ReceiveLength;
- ReceiveRequest->Complete = Request->RequestNotifyObject;
- ReceiveRequest->Context = Request->RequestContext;
-
- /* Queue receive request */
- InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
-
- /* Reference address file and set pending receive request flag */
- AddrFile->RefCount++;
- AF_SET_PENDING(AddrFile, AFF_RECEIVE);
-
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
-
- return STATUS_PENDING;
- } else
- Status = STATUS_INSUFFICIENT_RESOURCES;
- } else
- Status = STATUS_INVALID_ADDRESS;
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_ADDRESS;
+ }
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
{
return STATUS_SUCCESS;
}
-
-
-/* EOF */