for (PrevNCE = &NeighborCache[i].Cache;
(NCE = *PrevNCE) != NULL;) {
+ if (NCE->State & NUD_INCOMPLETE)
+ {
+ /* Solicit for an address */
+ NBSendSolicit(NCE);
+ if (NCE->EventTimer == 0)
+ {
+ NCE->EventCount++;
+ if (NCE->EventCount == ARP_INCOMPLETE_TIMEOUT)
+ {
+ NBFlushPacketQueue(NCE, NDIS_STATUS_NETWORK_UNREACHABLE);
+ NCE->EventCount = 0;
+ }
+ }
+ }
+
/* Check if event timer is running */
if (NCE->EventTimer > 0) {
ASSERT(!(NCE->State & NUD_PERMANENT));
NCE->EventCount++;
- if (NCE->State & NUD_INCOMPLETE)
- {
- /* We desperately need an address in this state or
- * we timeout in 5 seconds */
- NBSendSolicit(NCE);
- }
- else if ((NCE->EventCount > ARP_RATE &&
+
+ if ((NCE->EventCount > ARP_RATE &&
NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) ||
(NCE->EventCount == ARP_RATE))
{
if (NCE->EventTimer - NCE->EventCount == 0) {
/* Unlink and destroy the NCE */
*PrevNCE = NCE->Next;
-
+
/* Choose the proper failure status */
if (NCE->State & NUD_INCOMPLETE)
{
/* This guy was stale for way too long */
Status = NDIS_STATUS_REQUEST_ABORTED;
}
-
+
NBFlushPacketQueue(NCE, Status);
+
ExFreePoolWithTag(NCE, NCE_TAG);
continue;
if( !(NCE->State & NUD_INCOMPLETE) )
{
- NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
+ if (NCE->EventTimer) NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
NBSendPackets( NCE );
}
}
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
PIP_INTERFACE Interface,
- PIP_ADDRESS Address)
+ PIP_ADDRESS Address,
+ BOOLEAN NoTimeout)
/*
* FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE
* ARGUMENTS:
Interface->AddressLength, NUD_PERMANENT, 0);
} else {
NCE = NBAddNeighbor(Interface, Address, NULL,
- Interface->AddressLength, NUD_INCOMPLETE, ARP_INCOMPLETE_TIMEOUT);
+ Interface->AddressLength, NUD_INCOMPLETE, NoTimeout ? 0 : ARP_INCOMPLETE_TIMEOUT);
if (!NCE) return NULL;
NBSendSolicit(NCE);
}