From da1fa88e1c1d43552f8821f7f266fd51d63015b3 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 20 Aug 2009 17:25:39 +0000 Subject: [PATCH] - Fix receiving packets on an interface's broadcast address while bound to an undefined address - Simplify binding to a certain interface svn path=/trunk/; revision=42811 --- .../drivers/network/tcpip/include/address.h | 4 +- .../drivers/network/tcpip/tcpip/fileobjs.c | 61 +++++++++++++------ reactos/lib/drivers/ip/network/interface.c | 26 +++----- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/reactos/drivers/network/tcpip/include/address.h b/reactos/drivers/network/tcpip/include/address.h index 73d5dbbc535..49ecf8e3c00 100644 --- a/reactos/drivers/network/tcpip/include/address.h +++ b/reactos/drivers/network/tcpip/include/address.h @@ -55,8 +55,8 @@ BOOLEAN AddrIsEqualIPv4( PIP_ADDRESS Address1, IPv4_RAW_ADDRESS Address2); -BOOLEAN AddrLocateADEv4( - IPv4_RAW_ADDRESS MatchAddress, PIP_ADDRESS Address); +PIP_INTERFACE AddrLocateInterface( + PIP_ADDRESS MatchAddress); PADDRESS_FILE AddrSearchFirst( PIP_ADDRESS Address, diff --git a/reactos/drivers/network/tcpip/tcpip/fileobjs.c b/reactos/drivers/network/tcpip/tcpip/fileobjs.c index 5e35fafb551..f45fdbf2ded 100644 --- a/reactos/drivers/network/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/network/tcpip/tcpip/fileobjs.c @@ -43,20 +43,52 @@ PADDRESS_FILE AddrSearchFirst( return AddrSearchNext(SearchContext); } -BOOLEAN AddrIsBroadcast( - PIP_ADDRESS PossibleMatch, - PIP_ADDRESS TargetAddress ) { +BOOLEAN AddrIsBroadcastMatch( + PIP_ADDRESS UnicastAddress, + PIP_ADDRESS BroadcastAddress ) { IF_LIST_ITER(IF); ForEachInterface(IF) { - if( AddrIsEqual( &IF->Unicast, PossibleMatch ) && - AddrIsEqual( &IF->Broadcast, TargetAddress ) ) + if ((AddrIsUnspecified(UnicastAddress) || + AddrIsEqual(&IF->Unicast, UnicastAddress)) && + (AddrIsEqual(&IF->Broadcast, BroadcastAddress))) return TRUE; } EndFor(IF); return FALSE; } +BOOLEAN AddrReceiveMatch( + PIP_ADDRESS LocalAddress, + PIP_ADDRESS RemoteAddress) +{ + if (AddrIsEqual(LocalAddress, RemoteAddress)) + { + /* Unicast address match */ + return TRUE; + } + + if (AddrIsBroadcastMatch(LocalAddress, RemoteAddress)) + { + /* Broadcast address match */ + return TRUE; + } + + if (AddrIsUnspecified(LocalAddress)) + { + /* Local address unspecified */ + return TRUE; + } + + if (AddrIsUnspecified(RemoteAddress)) + { + /* Remote address unspecified */ + return TRUE; + } + + return FALSE; +} + /* * FUNCTION: Searches through address file entries to find next match * ARGUMENTS: @@ -96,10 +128,7 @@ PADDRESS_FILE AddrSearchNext( /* See if this address matches the search criteria */ if ((Current->Port == SearchContext->Port) && (Current->Protocol == SearchContext->Protocol) && - (AddrIsEqual(IPAddress, SearchContext->Address) || - AddrIsBroadcast(IPAddress, SearchContext->Address) || - AddrIsUnspecified(IPAddress) || - AddrIsUnspecified(SearchContext->Address))) { + (AddrReceiveMatch(IPAddress, SearchContext->Address))) { /* We've found a match */ Found = TRUE; break; @@ -156,7 +185,6 @@ NTSTATUS FileOpenAddress( USHORT Protocol, PVOID Options) { - IPv4_RAW_ADDRESS IPv4Address; PADDRESS_FILE AddrFile; TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol)); @@ -176,18 +204,15 @@ NTSTATUS FileOpenAddress( /* Make sure address is a local unicast address or 0 */ /* FIXME: IPv4 only */ AddrFile->Family = Address->Address[0].AddressType; - IPv4Address = Address->Address[0].Address[0].in_addr; - if (IPv4Address != 0 && - !AddrLocateADEv4(IPv4Address, &AddrFile->Address)) { + AddrFile->Address.Address.IPv4Address = Address->Address[0].Address[0].in_addr; + AddrFile->Address.Type = IP_ADDRESS_V4; + + if (!AddrIsUnspecified(&AddrFile->Address) && + !AddrLocateInterface(&AddrFile->Address)) { exFreePool(AddrFile); TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address))); return STATUS_INVALID_PARAMETER; } - else - { - /* Bound to the default address ... Copy the address type */ - AddrFile->Address.Type = IP_ADDRESS_V4; - } TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n", A2S(&AddrFile->Address), Protocol, IPPROTO_UDP)); diff --git a/reactos/lib/drivers/ip/network/interface.c b/reactos/lib/drivers/ip/network/interface.c index 78d11490286..f61cb4d0742 100644 --- a/reactos/lib/drivers/ip/network/interface.c +++ b/reactos/lib/drivers/ip/network/interface.c @@ -81,36 +81,26 @@ NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, return Status; } -/* - * FUNCTION: Locates and returns an address entry using IPv4 adress as argument - * ARGUMENTS: - * Address = Raw IPv4 address - * RETURNS: - * Pointer to address entry if found, NULL if not found - * NOTES: - * If found, the address is referenced - */ -BOOLEAN AddrLocateADEv4( - IPv4_RAW_ADDRESS MatchAddress, PIP_ADDRESS Address) +PIP_INTERFACE AddrLocateInterface( + PIP_ADDRESS MatchAddress) { KIRQL OldIrql; - BOOLEAN Matched = FALSE; + PIP_INTERFACE RetIF = NULL; IF_LIST_ITER(CurrentIF); TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql); ForEachInterface(CurrentIF) { - if( AddrIsEqualIPv4( &CurrentIF->Unicast, MatchAddress ) || - AddrIsEqualIPv4( &CurrentIF->Broadcast, MatchAddress ) ) { - Address->Type = IP_ADDRESS_V4; - Address->Address.IPv4Address = MatchAddress; - Matched = TRUE; break; + if( AddrIsEqual( &CurrentIF->Unicast, MatchAddress ) || + AddrIsEqual( &CurrentIF->Broadcast, MatchAddress ) ) { + RetIF = CurrentIF; + break; } } EndFor(CurrentIF); TcpipReleaseSpinLock(&InterfaceListLock, OldIrql); - return Matched; + return RetIF; } BOOLEAN HasPrefix(