- 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
This commit is contained in:
Cameron Gutman 2009-08-20 17:25:39 +00:00
parent b1c4f00121
commit da1fa88e1c
3 changed files with 53 additions and 38 deletions

View file

@ -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,

View file

@ -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));

View file

@ -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(