diff --git a/reactos/drivers/lib/ip/network/address.c b/reactos/drivers/lib/ip/network/address.c index 3d535926cda..a6e8b0ceab5 100644 --- a/reactos/drivers/lib/ip/network/address.c +++ b/reactos/drivers/lib/ip/network/address.c @@ -83,6 +83,18 @@ UINT AddrCountPrefixBits( PIP_ADDRESS Netmask ) { } } +VOID AddrWidenAddress( PIP_ADDRESS Network, PIP_ADDRESS Source, + PIP_ADDRESS Netmask ) { + if( Netmask->Type == IP_ADDRESS_V4 ) { + Network->Address.IPv4Address = + Source->Address.IPv4Address & Netmask->Address.IPv4Address; + } else { + TI_DbgPrint(DEBUG_DATALINK, ("Don't know address type %d\n", + Netmask->Type)); + *Network = *Source; + } +} + VOID IPAddressFree( PVOID Object) /* diff --git a/reactos/drivers/lib/ip/network/ip.c b/reactos/drivers/lib/ip/network/ip.c index 21dae696c55..5b6b16a581f 100644 --- a/reactos/drivers/lib/ip/network/ip.c +++ b/reactos/drivers/lib/ip/network/ip.c @@ -237,6 +237,7 @@ BOOLEAN IPRegisterInterface( */ { KIRQL OldIrql; + IP_ADDRESS NetworkAddress; PROUTE_CACHE_NODE RCN; PNEIGHBOR_CACHE_ENTRY NCE; @@ -254,12 +255,13 @@ BOOLEAN IPRegisterInterface( return FALSE; } - /* NCE is already referenced */ - if (!RouterAddRoute(&IF->Unicast, &IF->Netmask, NCE, 1)) { + AddrWidenAddress( &NetworkAddress, &IF->Unicast, &IF->Netmask ); + + if (!RouterAddRoute(&NetworkAddress, &IF->Netmask, NCE, 1)) { TI_DbgPrint(MIN_TRACE, ("Could not add route due to insufficient resources.\n")); } - RCN = RouteAddRouteToDestination(&IF->Unicast, IF, NCE); + RCN = RouteAddRouteToDestination(&NetworkAddress, IF, NCE); if (!RCN) { TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n")); TcpipReleaseSpinLock(&IF->Lock, OldIrql); diff --git a/reactos/drivers/lib/ip/network/router.c b/reactos/drivers/lib/ip/network/router.c index 7eeb7eb17bd..b3d9d763419 100644 --- a/reactos/drivers/lib/ip/network/router.c +++ b/reactos/drivers/lib/ip/network/router.c @@ -274,30 +274,61 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination) } -VOID RouterRemoveRoute( - PFIB_ENTRY FIBE) +NTSTATUS RouterRemoveRoute(PIP_ADDRESS Target, PIP_ADDRESS Router) /* * FUNCTION: Removes a route from the Forward Information Base (FIB) * ARGUMENTS: - * FIBE = Pointer to FIB entry describing route + * Target: The machine or network targeted by the route + * Router: The router used to pass the packet to the destination + * + * Searches the FIB and removes a route matching the indicated parameters. */ { KIRQL OldIrql; + PLIST_ENTRY CurrentEntry; + PLIST_ENTRY NextEntry; + PFIB_ENTRY Current; + BOOLEAN Found = FALSE; + PNEIGHBOR_CACHE_ENTRY NCE; - TI_DbgPrint(DEBUG_ROUTER, ("Called. FIBE (0x%X).\n", FIBE)); + TI_DbgPrint(DEBUG_ROUTER, ("Called\n")); - TI_DbgPrint(DEBUG_ROUTER, ("FIBE (%s).\n", A2S(&FIBE->NetworkAddress))); - TcpipAcquireSpinLock(&FIBLock, &OldIrql); - DestroyFIBE(FIBE); + + CurrentEntry = FIBListHead.Flink; + while (CurrentEntry != &FIBListHead) { + NextEntry = CurrentEntry->Flink; + Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); + + NCE = Current->Router; + + if( AddrIsEqual( &Current->NetworkAddress, Target ) && + AddrIsEqual( &NCE->Address, Router ) ) { + Found = TRUE; + break; + } + + Current = NULL; + CurrentEntry = NextEntry; + } + + if( Found ) { + TI_DbgPrint(DEBUG_ROUTER, ("Deleting route\n")); + DestroyFIBE( Current ); + } + TcpipReleaseSpinLock(&FIBLock, OldIrql); + + TI_DbgPrint(DEBUG_ROUTER, ("Leaving\n")); + + return Found ? STATUS_NO_SUCH_FILE : STATUS_SUCCESS; } PFIB_ENTRY RouterCreateRoute( - IP_ADDRESS NetworkAddress, - IP_ADDRESS Netmask, - IP_ADDRESS RouterAddress, + PIP_ADDRESS NetworkAddress, + PIP_ADDRESS Netmask, + PIP_ADDRESS RouterAddress, PIP_INTERFACE Interface, UINT Metric) /* @@ -319,7 +350,7 @@ PFIB_ENTRY RouterCreateRoute( /* The NCE references RouterAddress. The NCE is referenced for us */ NCE = NBAddNeighbor(Interface, - &RouterAddress, + RouterAddress, NULL, Interface->AddressLength, NUD_PROBE); @@ -328,7 +359,7 @@ PFIB_ENTRY RouterCreateRoute( return NULL; } - FIBE = RouterAddRoute(&NetworkAddress, &Netmask, NCE, 1); + FIBE = RouterAddRoute(NetworkAddress, Netmask, NCE, 1); if (!FIBE) { /* Not enough free resources */ NBRemoveNeighbor(NCE); @@ -352,13 +383,6 @@ NTSTATUS RouterStartup( InitializeListHead(&FIBListHead); TcpipInitializeSpinLock(&FIBLock); -#if 0 - /* TEST: Create a test route */ - /* Network is 10.0.0.0 */ - /* Netmask is 255.0.0.0 */ - /* Router is 10.0.0.1 */ - RouterCreateRouteIPv4(0x0000000A, 0x000000FF, 0x0100000A, NTE?, 1); -#endif return STATUS_SUCCESS; } diff --git a/reactos/drivers/net/tcpip/include/address.h b/reactos/drivers/net/tcpip/include/address.h index b6784da8e25..856de9b33ff 100644 --- a/reactos/drivers/net/tcpip/include/address.h +++ b/reactos/drivers/net/tcpip/include/address.h @@ -75,6 +75,9 @@ ULONG IPv4NToHl( ULONG Address ); UINT AddrCountPrefixBits( PIP_ADDRESS Netmask ); +VOID AddrWidenAddress( PIP_ADDRESS Network, PIP_ADDRESS Source, + PIP_ADDRESS Netmask ); + #endif /* __ADDRESS_H */ /* EOF */ diff --git a/reactos/drivers/net/tcpip/include/router.h b/reactos/drivers/net/tcpip/include/router.h index f40760e8022..9b407912971 100644 --- a/reactos/drivers/net/tcpip/include/router.h +++ b/reactos/drivers/net/tcpip/include/router.h @@ -28,13 +28,12 @@ PFIB_ENTRY RouterAddRoute( PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination); -VOID RouterRemoveRoute( - PFIB_ENTRY FIBE); +NTSTATUS RouterRemoveRoute(PIP_ADDRESS Target, PIP_ADDRESS Router); PFIB_ENTRY RouterCreateRoute( - IP_ADDRESS NetworkAddress, - IP_ADDRESS Netmask, - IP_ADDRESS RouterAddress, + PIP_ADDRESS NetworkAddress, + PIP_ADDRESS Netmask, + PIP_ADDRESS RouterAddress, PIP_INTERFACE Interface, UINT Metric); diff --git a/reactos/drivers/net/tcpip/tcpip/info.c b/reactos/drivers/net/tcpip/tcpip/info.c index b9c375702db..d095123177c 100644 --- a/reactos/drivers/net/tcpip/tcpip/info.c +++ b/reactos/drivers/net/tcpip/tcpip/info.c @@ -210,24 +210,18 @@ TDI_STATUS InfoTdiSetInformationEx case INFO_TYPE_PROVIDER: switch( ID->toi_id ) { case IP_MIB_ROUTETABLE_ENTRY_ID: - if( ID->toi_entity.tei_entity == CL_NL_ENTITY && - ID->toi_entity.tei_instance == TL_INSTANCE && - BufferSize >= sizeof(IPROUTE_ENTRY) ) { - /* Add route -- buffer is an IPRouteEntry */ - PIPROUTE_ENTRY ire = (PIPROUTE_ENTRY)Buffer; - RouteFriendlyAddRoute( ire ); - } else { - return TDI_INVALID_PARAMETER; - /* In my experience, we are being over - protective compared to windows */ - } - break; + return InfoNetworkLayerTdiSetEx + ( ID->toi_class, + ID->toi_type, + ID->toi_id, + NULL, + &ID->toi_entity, + Buffer, + BufferSize ); } - break; } break; } return TDI_INVALID_PARAMETER; } - diff --git a/reactos/drivers/net/tcpip/tcpip/ninfo.c b/reactos/drivers/net/tcpip/tcpip/ninfo.c index 4acbca3d05a..06851aaca02 100644 --- a/reactos/drivers/net/tcpip/tcpip/ninfo.c +++ b/reactos/drivers/net/tcpip/tcpip/ninfo.c @@ -10,6 +10,9 @@ #include "precomp.h" +#define IP_ROUTE_TYPE_ADD 3 +#define IP_ROUTE_TYPE_DEL 2 + TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) { @@ -85,47 +88,42 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) { while( RtCurrent < RouteEntries + RtCount ) { /* Copy Desitnation */ - if( RCacheCur->Router ) { - TI_DbgPrint(MAX_TRACE, ("%d: NA %08x NM %08x GW %08x MT %x\n", - RtCurrent - RouteEntries, - &RCacheCur->NetworkAddress.Address, - &RCacheCur->Netmask.Address, - RCacheCur->Router->Address.Address, - RCacheCur->Metric)); - - RtlCopyMemory( &RtCurrent->Dest, - &RCacheCur->NetworkAddress.Address, - sizeof(RtCurrent->Dest) ); - RtlCopyMemory( &RtCurrent->Mask, - &RCacheCur->Netmask.Address, - sizeof(RtCurrent->Mask) ); - /* Currently, this address is stuffed into the pointer. - * That probably is not intended. */ + RtlCopyMemory( &RtCurrent->Dest, + &RCacheCur->NetworkAddress.Address, + sizeof(RtCurrent->Dest) ); + RtlCopyMemory( &RtCurrent->Mask, + &RCacheCur->Netmask.Address, + sizeof(RtCurrent->Mask) ); + + if( RCacheCur->Router ) RtlCopyMemory( &RtCurrent->Gw, &RCacheCur->Router->Address.Address, sizeof(RtCurrent->Gw) ); - RtCurrent->Metric1 = RCacheCur->Metric; - RtCurrent->Type = 2 /* PF_INET */; - - TcpipAcquireSpinLock(&EntityListLock, &OldIrql); - for( RtCurrent->Index = EntityCount; - RtCurrent->Index > 0 && - RCacheCur->Router->Interface != - EntityList[RtCurrent->Index - 1].context; - RtCurrent->Index-- ); - - RtCurrent->Index = EntityList[RtCurrent->Index].tei_instance; - TcpipReleaseSpinLock(&EntityListLock, OldIrql); - } else { - TI_DbgPrint(MAX_TRACE, ("%d: BAD: NA %08x NM %08x GW %08x MT %d\n", - RtCurrent - RouteEntries, - RCacheCur->NetworkAddress, - RCacheCur->Netmask, - RCacheCur->Router, - RCacheCur->Router ? - &RCacheCur->Router->Address : 0, - RCacheCur->Metric)); - } + else + RtlZeroMemory( &RtCurrent->Gw, sizeof(RtCurrent->Gw) ); + + RtCurrent->Metric1 = RCacheCur->Metric; + RtCurrent->Type = TDI_ADDRESS_TYPE_IP; + + TI_DbgPrint + (MAX_TRACE, + ("%d: NA %08x NM %08x GW %08x MT %x\n", + RtCurrent - RouteEntries, + RtCurrent->Dest, + RtCurrent->Mask, + RtCurrent->Gw, + RtCurrent->Metric1 )); + + TcpipAcquireSpinLock(&EntityListLock, &OldIrql); + for( RtCurrent->Index = EntityCount; + RtCurrent->Index > 0 && + RCacheCur->Router->Interface != + EntityList[RtCurrent->Index - 1].context; + RtCurrent->Index-- ); + + RtCurrent->Index = EntityList[RtCurrent->Index].tei_instance; + TcpipReleaseSpinLock(&EntityListLock, OldIrql); + RtCurrent++; RCacheCur++; } @@ -143,7 +141,7 @@ TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer, PUINT BufferSize ) { IPSNMP_INFO SnmpInfo; UINT IfCount = CountInterfaces(); - UINT RouteCount = CountRouteNodes( NULL ); + UINT RouteCount = CountFIBs( NULL ); TDI_STATUS Status = TDI_INVALID_REQUEST; TI_DbgPrint(MAX_TRACE, ("Called.\n")); @@ -214,5 +212,43 @@ TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass, TDIEntityID *id, PCHAR Buffer, UINT BufferSize ) { - return STATUS_UNSUCCESSFUL; + NTSTATUS Status = TDI_INVALID_REQUEST; + IP_ADDRESS Address; + IP_ADDRESS Netmask; + IP_ADDRESS Router; + PNEIGHBOR_CACHE_ENTRY NCE; + + TI_DbgPrint(MID_TRACE,("Called\n")); + + OskitDumpBuffer( Buffer, BufferSize ); + + if( InfoClass == INFO_CLASS_PROTOCOL && + InfoType == INFO_TYPE_PROVIDER && + InfoId == IP_MIB_ROUTETABLE_ENTRY_ID && + id->tei_entity == CL_NL_ENTITY ) { /* Add or delete a route */ + PIPROUTE_ENTRY Route = (PIPROUTE_ENTRY)Buffer; + AddrInitIPv4( &Address, Route->Dest ); + AddrInitIPv4( &Netmask, Route->Mask ); + AddrInitIPv4( &Router, Route->Gw ); + + if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */ + TI_DbgPrint(MID_TRACE,("Adding route (%s)\n", A2S(&Address))); + /* Find the existing route this belongs to */ + NCE = RouterGetRoute( &Router ); + /* Really add the route */ + if( NCE && + RouterCreateRoute( &Address, &Netmask, &Router, + NCE->Interface, Route->Metric1 ) ) + Status = STATUS_SUCCESS; + else + Status = STATUS_UNSUCCESSFUL; + } else if( Route->Type == IP_ROUTE_TYPE_DEL ) { + TI_DbgPrint(MID_TRACE,("Removing route (%s)\n", A2S(&Address))); + Status = RouterRemoveRoute( &Address, &Router ); + } else Status = TDI_INVALID_REQUEST; + } + + TI_DbgPrint(MID_TRACE,("Returning %x\n", Status)); + + return Status; }