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/inclu... ============================================================================== --- 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/inclu... ============================================================================== --- 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.c... ============================================================================== --- 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/neig... ============================================================================== --- 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(