From ebaa2b818d368353daf2b3fedc9fcde40f0d2c13 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 24 Oct 2009 20:39:41 +0000 Subject: [PATCH] - Implement SetIpNetEntry in iphlpapi and InfoTdiSetArptableMIB in tcpip - Added buffer size checks for InfoTdiSetRoute - "arp -s" works now svn path=/trunk/; revision=43723 --- reactos/dll/win32/iphlpapi/iphlpapi_main.c | 51 ++++++++++++++++--- reactos/dll/win32/iphlpapi/iphlpapi_private.h | 13 +++-- reactos/dll/win32/iphlpapi/route_reactos.c | 4 +- reactos/drivers/network/tcpip/include/info.h | 8 ++- reactos/drivers/network/tcpip/tcpip/iinfo.c | 25 +++++++++ reactos/drivers/network/tcpip/tcpip/info.c | 18 ++++--- reactos/drivers/network/tcpip/tcpip/ninfo.c | 6 ++- 7 files changed, 106 insertions(+), 19 deletions(-) diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_main.c b/reactos/dll/win32/iphlpapi/iphlpapi_main.c index 8ef198ef3b0..09e494507dc 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_main.c +++ b/reactos/dll/win32/iphlpapi/iphlpapi_main.c @@ -2087,15 +2087,54 @@ DWORD WINAPI SetIpForwardEntry(PMIB_IPFORWARDROW pRoute) * RETURNS * Success: NO_ERROR * Failure: error code from winerror.h - * - * FIXME - * Stub, returns NO_ERROR. */ DWORD WINAPI SetIpNetEntry(PMIB_IPNETROW pArpEntry) { - FIXME("(pArpEntry %p): stub\n", pArpEntry); - /* same as CreateIpNetEntry here, could use SIOCSARP, not sure I want to */ - return 0; + HANDLE tcpFile; + NTSTATUS status; + TCP_REQUEST_SET_INFORMATION_EX_ARP_ENTRY req = + TCP_REQUEST_SET_INFORMATION_INIT; + TDIEntityID id; + DWORD returnSize; + PMIB_IPNETROW arpBuff; + + if (!pArpEntry) + return ERROR_INVALID_PARAMETER; + + if (!NT_SUCCESS(openTcpFile( &tcpFile ))) + return ERROR_NOT_SUPPORTED; + + if (!NT_SUCCESS(getNthIpEntity( tcpFile, pArpEntry->dwIndex, &id ))) + { + closeTcpFile(tcpFile); + return ERROR_INVALID_PARAMETER; + } + + req.Req.ID.toi_class = INFO_CLASS_PROTOCOL; + req.Req.ID.toi_type = INFO_TYPE_PROVIDER; + req.Req.ID.toi_id = IP_MIB_ARPTABLE_ENTRY_ID; + req.Req.ID.toi_entity.tei_instance = id.tei_instance; + req.Req.ID.toi_entity.tei_entity = AT_ENTITY; + req.Req.BufferSize = sizeof(MIB_IPNETROW); + arpBuff = (PMIB_IPNETROW)&req.Req.Buffer[0]; + + RtlCopyMemory(arpBuff, pArpEntry, sizeof(MIB_IPNETROW)); + + status = DeviceIoControl( tcpFile, + IOCTL_TCP_SET_INFORMATION_EX, + &req, + sizeof(req), + NULL, + 0, + &returnSize, + NULL ); + + closeTcpFile(tcpFile); + + if (status) + return NO_ERROR; + else + return ERROR_INVALID_PARAMETER; } diff --git a/reactos/dll/win32/iphlpapi/iphlpapi_private.h b/reactos/dll/win32/iphlpapi/iphlpapi_private.h index 3a4dc6a004c..4210198a20c 100644 --- a/reactos/dll/win32/iphlpapi/iphlpapi_private.h +++ b/reactos/dll/win32/iphlpapi/iphlpapi_private.h @@ -88,12 +88,19 @@ typedef union _IFEntrySafelySized { IFEntry ent; } IFEntrySafelySized; -typedef union _TCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED { +typedef union _TCP_REQUEST_SET_INFORMATION_EX_ROUTE_ENTRY { CHAR MaxSize[sizeof(TCP_REQUEST_SET_INFORMATION_EX) - 1 + sizeof(IPRouteEntry)]; TCP_REQUEST_SET_INFORMATION_EX Req; -} TCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED, - *PTCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED; +} TCP_REQUEST_SET_INFORMATION_EX_ROUTE_ENTRY, + *PTCP_REQUEST_SET_INFORMATION_EX_ROUTE_ENTRY; + +typedef union _TCP_REQUEST_SET_INFORMATION_EX_ARP_ENTRY { + CHAR MaxSize[sizeof(TCP_REQUEST_SET_INFORMATION_EX) - 1 + + sizeof(MIB_IPNETROW)]; + TCP_REQUEST_SET_INFORMATION_EX Req; +} TCP_REQUEST_SET_INFORMATION_EX_ARP_ENTRY, + *PTCP_REQUEST_SET_INFORMATION_EX_ARP_ENTRY; /* Encapsulates information about an interface */ typedef struct _IFInfo { diff --git a/reactos/dll/win32/iphlpapi/route_reactos.c b/reactos/dll/win32/iphlpapi/route_reactos.c index ef6b63983dc..c4cffdfe730 100644 --- a/reactos/dll/win32/iphlpapi/route_reactos.c +++ b/reactos/dll/win32/iphlpapi/route_reactos.c @@ -55,7 +55,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); DWORD createIpForwardEntry( PMIB_IPFORWARDROW pRoute ) { HANDLE tcpFile; NTSTATUS status = openTcpFile( &tcpFile ); - TCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED req = + TCP_REQUEST_SET_INFORMATION_EX_ROUTE_ENTRY req = TCP_REQUEST_SET_INFORMATION_INIT; IPRouteEntry *rte; TDIEntityID id; @@ -120,7 +120,7 @@ DWORD setIpForwardEntry( PMIB_IPFORWARDROW pRoute ) { DWORD deleteIpForwardEntry( PMIB_IPFORWARDROW pRoute ) { HANDLE tcpFile; NTSTATUS status = openTcpFile( &tcpFile ); - TCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED req = + TCP_REQUEST_SET_INFORMATION_EX_ROUTE_ENTRY req = TCP_REQUEST_SET_INFORMATION_INIT; IPRouteEntry *rte; TDIEntityID id; diff --git a/reactos/drivers/network/tcpip/include/info.h b/reactos/drivers/network/tcpip/include/info.h index efae370e33c..53c8bb31136 100644 --- a/reactos/drivers/network/tcpip/include/info.h +++ b/reactos/drivers/network/tcpip/include/info.h @@ -160,7 +160,13 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUINT BufferSize ); -TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PIPROUTE_ENTRY Route); +TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, + PVOID Buffer, + UINT BufferSize); + +TDI_STATUS InfoTdiSetArptableMIB(PIP_INTERFACE IF, + PVOID Buffer, + UINT BufferSize); TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID, PIP_INTERFACE Interface, diff --git a/reactos/drivers/network/tcpip/tcpip/iinfo.c b/reactos/drivers/network/tcpip/tcpip/iinfo.c index 38e649ff1f8..39a9ad97a5e 100644 --- a/reactos/drivers/network/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/network/tcpip/tcpip/iinfo.c @@ -134,6 +134,31 @@ TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID, return Status; } +TDI_STATUS InfoTdiSetArptableMIB(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize) +{ + PIPARP_ENTRY ArpEntry = Buffer; + IP_ADDRESS Address; + PNEIGHBOR_CACHE_ENTRY NCE; + + if (!Buffer || BufferSize < sizeof(IPARP_ENTRY)) + return TDI_INVALID_PARAMETER; + + AddrInitIPv4(&Address, ArpEntry->LogAddr); + + if ((NCE = NBLocateNeighbor(&Address))) + NBRemoveNeighbor(NCE); + + if (NBAddNeighbor(IF, + &Address, + ArpEntry->PhysAddr, + ArpEntry->AddrSize, + NUD_PERMANENT, + 0)) + return TDI_SUCCESS; + else + return TDI_INVALID_PARAMETER; +} + VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) { KIRQL OldIrql; UINT IFCount = 0, CLNLCount = 0, CLTLCount = 0, COTLCount = 0, ATCount = 0, ERCount = 0, i; diff --git a/reactos/drivers/network/tcpip/tcpip/info.c b/reactos/drivers/network/tcpip/tcpip/info.c index 8a83303ead5..ee1e7b1694c 100644 --- a/reactos/drivers/network/tcpip/tcpip/info.c +++ b/reactos/drivers/network/tcpip/tcpip/info.c @@ -268,12 +268,18 @@ TDI_STATUS InfoTdiSetInformationEx if (ID->toi_type != INFO_TYPE_PROVIDER) return TDI_INVALID_PARAMETER; - if (ID->toi_entity.tei_entity != CL_NL_ENTITY && - ID->toi_entity.tei_entity != CO_NL_ENTITY) - return TDI_INVALID_PARAMETER; - - if ((EntityListContext = GetContext(ID->toi_entity))) - return InfoTdiSetRoute(EntityListContext, (PIPROUTE_ENTRY)Buffer); + if (ID->toi_entity.tei_entity == AT_ENTITY) + if ((EntityListContext = GetContext(ID->toi_entity))) + return InfoTdiSetArptableMIB(EntityListContext, + Buffer, BufferSize); + else + return TDI_INVALID_PARAMETER; + else if (ID->toi_entity.tei_entity == CL_NL_ENTITY || + ID->toi_entity.tei_entity == CO_NL_ENTITY) + if ((EntityListContext = GetContext(ID->toi_entity))) + return InfoTdiSetRoute(EntityListContext, Buffer, BufferSize); + else + return TDI_INVALID_PARAMETER; else return TDI_INVALID_PARAMETER; diff --git a/reactos/drivers/network/tcpip/tcpip/ninfo.c b/reactos/drivers/network/tcpip/tcpip/ninfo.c index f312b834e38..af4fb99723e 100644 --- a/reactos/drivers/network/tcpip/tcpip/ninfo.c +++ b/reactos/drivers/network/tcpip/tcpip/ninfo.c @@ -173,14 +173,18 @@ TDI_STATUS InfoTdiQueryGetIPSnmpInfo( TDIEntityID ID, return Status; } -TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PIPROUTE_ENTRY Route) +TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize) { IP_ADDRESS Address, Netmask, Router; + PIPROUTE_ENTRY Route = Buffer; AddrInitIPv4( &Address, Route->Dest ); AddrInitIPv4( &Netmask, Route->Mask ); AddrInitIPv4( &Router, Route->Gw ); + if (!Buffer || BufferSize < sizeof(IPROUTE_ENTRY)) + return TDI_INVALID_PARAMETER; + if (IF == Loopback) { DbgPrint("Failing attempt to add route to loopback adapter\n");