mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 16:36:11 +00:00
- 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) svn path=/trunk/; revision=43354
This commit is contained in:
parent
6e2700c9e9
commit
05c582bcbd
|
@ -24,7 +24,7 @@ typedef struct ARP_HEADER {
|
|||
#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,
|
||||
|
|
|
@ -44,11 +44,14 @@ typedef struct NEIGHBOR_CACHE_ENTRY {
|
|||
#define NUD_PERMANENT 0x02
|
||||
#define NUD_STALE 0x04
|
||||
|
||||
/* Number of seconds before the NCE times out */
|
||||
#define ARP_TIMEOUT 30
|
||||
|
||||
/* Number of seconds between ARP transmissions */
|
||||
#define ARP_RATE 10
|
||||
#define ARP_RATE 900
|
||||
|
||||
/* Number of seconds before the NCE times out */
|
||||
#define ARP_TIMEOUT ARP_RATE + 15
|
||||
|
||||
/* Number of seconds before retransmission */
|
||||
#define ARP_TIMEOUT_RETRANSMISSION 5
|
||||
|
||||
extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
|
||||
|
||||
|
@ -98,6 +101,9 @@ ULONG NBCopyNeighbors(
|
|||
PIP_INTERFACE Interface,
|
||||
PIPARP_ENTRY ArpTable);
|
||||
|
||||
VOID NBResetNeighborTimeout(
|
||||
PIP_ADDRESS Address);
|
||||
|
||||
#endif /* __NEIGHBOR_H */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -108,7 +108,8 @@ VOID ARPTransmitComplete(
|
|||
}
|
||||
|
||||
|
||||
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 @@ BOOLEAN ARPTransmit(PIP_ADDRESS Address, PIP_INTERFACE Interface)
|
|||
(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 @@ VOID ARPReceive(
|
|||
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
|
||||
|
|
|
@ -93,10 +93,12 @@ VOID IPDispatchProtocol(
|
|||
*/
|
||||
{
|
||||
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 @@ VOID IPDispatchProtocol(
|
|||
return;
|
||||
}
|
||||
|
||||
NBResetNeighborTimeout(&SrcAddress);
|
||||
|
||||
if (Protocol < IP_PROTOCOL_TABLE_SIZE)
|
||||
{
|
||||
/* Call the appropriate protocol handler */
|
||||
|
@ -219,7 +223,7 @@ VOID IPAddInterfaceRoute( PIP_INTERFACE IF ) {
|
|||
/* 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(
|
||||
|
|
|
@ -105,20 +105,35 @@ VOID NBTimeout(VOID)
|
|||
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)
|
||||
NBSendSolicit(NCE);
|
||||
if (NCE->EventTimer - NCE->EventCount == 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) {
|
||||
/* Solicit one last time */
|
||||
NBSendSolicit(NCE);
|
||||
|
||||
NCE->EventCount = 0;
|
||||
/* 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 @@ VOID NBSendSolicit(PNEIGHBOR_CACHE_ENTRY NCE)
|
|||
{
|
||||
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(
|
||||
|
@ -302,6 +318,37 @@ VOID NBUpdateNeighbor(
|
|||
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(
|
||||
PIP_ADDRESS Address)
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue