Author: cgutman
Date: Sat Oct 10 09:43:39 2009
New Revision: 43354
URL:
http://svn.reactos.org/svn/reactos?rev=43354&view=rev
Log:
- Fix timeout values
- Don't reply to ARP requests unless they are address to us
- We now reset the NCE timeout if we receive a packet from the neighbor
- Fixes ARP flooding (bug 4879)
Modified:
trunk/reactos/drivers/network/tcpip/include/arp.h
trunk/reactos/drivers/network/tcpip/include/neighbor.h
trunk/reactos/lib/drivers/ip/network/arp.c
trunk/reactos/lib/drivers/ip/network/ip.c
trunk/reactos/lib/drivers/ip/network/neighbor.c
Modified: trunk/reactos/drivers/network/tcpip/include/arp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/incl…
==============================================================================
--- trunk/reactos/drivers/network/tcpip/include/arp.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/include/arp.h [iso-8859-1] Sat Oct 10 09:43:39
2009
@@ -24,7 +24,7 @@
#define ARP_OPCODE_REPLY WH2N(0x0002) /* ARP reply */
-BOOLEAN ARPTransmit(PIP_ADDRESS Address, PIP_INTERFACE Interface);
+BOOLEAN ARPTransmit(PIP_ADDRESS Address, PVOID LinkAddress, PIP_INTERFACE Interface);
VOID ARPReceive(
PVOID Context,
Modified: trunk/reactos/drivers/network/tcpip/include/neighbor.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/incl…
==============================================================================
--- trunk/reactos/drivers/network/tcpip/include/neighbor.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/include/neighbor.h [iso-8859-1] Sat Oct 10
09:43:39 2009
@@ -44,11 +44,14 @@
#define NUD_PERMANENT 0x02
#define NUD_STALE 0x04
+/* Number of seconds between ARP transmissions */
+#define ARP_RATE 900
+
/* Number of seconds before the NCE times out */
-#define ARP_TIMEOUT 30
+#define ARP_TIMEOUT ARP_RATE + 15
-/* Number of seconds between ARP transmissions */
-#define ARP_RATE 10
+/* Number of seconds before retransmission */
+#define ARP_TIMEOUT_RETRANSMISSION 5
extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
@@ -98,6 +101,9 @@
PIP_INTERFACE Interface,
PIPARP_ENTRY ArpTable);
+VOID NBResetNeighborTimeout(
+ PIP_ADDRESS Address);
+
#endif /* __NEIGHBOR_H */
/* EOF */
Modified: trunk/reactos/lib/drivers/ip/network/arp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/arp…
==============================================================================
--- trunk/reactos/lib/drivers/ip/network/arp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/network/arp.c [iso-8859-1] Sat Oct 10 09:43:39 2009
@@ -108,7 +108,8 @@
}
-BOOLEAN ARPTransmit(PIP_ADDRESS Address, PIP_INTERFACE Interface)
+BOOLEAN ARPTransmit(PIP_ADDRESS Address, PVOID LinkAddress,
+ PIP_INTERFACE Interface)
/*
* FUNCTION: Creates an ARP request and transmits it on a network
* ARGUMENTS:
@@ -152,7 +153,7 @@
(UCHAR)ProtoAddrLen, /* Protocol address length */
Interface->Address, /* Sender's (local) hardware address */
&Interface->Unicast.Address.IPv4Address,/* Sender's (local) protocol
address */
- NULL, /* Don't care */
+ LinkAddress, /* Target's (remote) hardware address */
&Address->Address.IPv4Address, /* Target's (remote) protocol address
*/
ARP_OPCODE_REQUEST); /* ARP request */
@@ -225,7 +226,8 @@
Header->HWAddrLen, 0, ARP_TIMEOUT);
}
- if (Header->Opcode != ARP_OPCODE_REQUEST)
+ if (Header->Opcode != ARP_OPCODE_REQUEST ||
+ !AddrIsEqual(&Address, &Interface->Unicast))
return;
/* This is a request for our address. Swap the addresses and
Modified: trunk/reactos/lib/drivers/ip/network/ip.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/ip.…
==============================================================================
--- trunk/reactos/lib/drivers/ip/network/ip.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/network/ip.c [iso-8859-1] Sat Oct 10 09:43:39 2009
@@ -93,10 +93,12 @@
*/
{
UINT Protocol;
+ IP_ADDRESS SrcAddress;
switch (IPPacket->Type) {
case IP_ADDRESS_V4:
Protocol = ((PIPv4_HEADER)(IPPacket->Header))->Protocol;
+ AddrInitIPv4(&SrcAddress,
((PIPv4_HEADER)(IPPacket->Header))->SrcAddr);
break;
case IP_ADDRESS_V6:
/* FIXME: IPv6 adresses not supported */
@@ -107,6 +109,8 @@
return;
}
+ NBResetNeighborTimeout(&SrcAddress);
+
if (Protocol < IP_PROTOCOL_TABLE_SIZE)
{
/* Call the appropriate protocol handler */
@@ -219,7 +223,7 @@
/* Send a gratuitous ARP packet to update the route caches of
* other computers */
if (IF != Loopback)
- ARPTransmit(NULL, IF);
+ ARPTransmit(NULL, NULL, IF);
}
BOOLEAN IPRegisterInterface(
Modified: trunk/reactos/lib/drivers/ip/network/neighbor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/nei…
==============================================================================
--- trunk/reactos/lib/drivers/ip/network/neighbor.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/network/neighbor.c [iso-8859-1] Sat Oct 10 09:43:39 2009
@@ -105,20 +105,35 @@
TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
for (PrevNCE = &NeighborCache[i].Cache;
- (NCE = *PrevNCE) != NULL;
- PrevNCE = &NCE->Next) {
+ (NCE = *PrevNCE) != NULL;) {
/* Check if event timer is running */
if (NCE->EventTimer > 0) {
ASSERT(!(NCE->State & NUD_PERMANENT));
NCE->EventCount++;
- if (NCE->EventCount % ARP_RATE == 0)
+ if ((NCE->EventCount > ARP_RATE &&
+ NCE->EventCount % ARP_TIMEOUT_RETRANSMISSION == 0) ||
+ (NCE->EventCount == ARP_RATE))
+ {
+ /* We haven't gotten a packet from them in
+ * EventCount seconds so we mark them as stale
+ * and solicit now */
+ NCE->State |= NUD_STALE;
NBSendSolicit(NCE);
+ }
if (NCE->EventTimer - NCE->EventCount == 0) {
- NCE->State |= NUD_STALE;
-
- NCE->EventCount = 0;
+ /* Solicit one last time */
+ NBSendSolicit(NCE);
+
+ /* Unlink and destroy the NCE */
+ *PrevNCE = NCE->Next;
+
+ NBFlushPacketQueue(NCE, NDIS_STATUS_REQUEST_ABORTED);
+ exFreePool(NCE);
+
+ continue;
}
}
+ PrevNCE = &NCE->Next;
}
TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
@@ -188,7 +203,8 @@
{
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
- ARPTransmit(&NCE->Address, NCE->Interface);
+ ARPTransmit(&NCE->Address, NCE->LinkAddress,
+ NCE->Interface);
}
PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
@@ -300,6 +316,37 @@
if( !(NCE->State & NUD_INCOMPLETE) )
NBSendPackets( NCE );
+}
+
+VOID
+NBResetNeighborTimeout(PIP_ADDRESS Address)
+{
+ KIRQL OldIrql;
+ UINT HashValue;
+ PNEIGHBOR_CACHE_ENTRY NCE;
+
+ TI_DbgPrint(DEBUG_NCACHE, ("Resetting NCE timout for 0x%s\n",
A2S(Address)));
+
+ HashValue = *(PULONG)(&Address->Address);
+ HashValue ^= HashValue >> 16;
+ HashValue ^= HashValue >> 8;
+ HashValue ^= HashValue >> 4;
+ HashValue &= NB_HASHMASK;
+
+ TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
+
+ for (NCE = NeighborCache[HashValue].Cache;
+ NCE != NULL;
+ NCE = NCE->Next)
+ {
+ if (AddrIsEqual(Address, &NCE->Address))
+ {
+ NCE->EventCount = 0;
+ break;
+ }
+ }
+
+ TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
}
PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(