- Implement SetIpNetEntry in iphlpapi and InfoTdiSetArptableMIB in tcpip

- Added buffer size checks for InfoTdiSetRoute
 - "arp -s" works now

svn path=/trunk/; revision=43723
This commit is contained in:
Cameron Gutman 2009-10-24 20:39:41 +00:00
parent ff318c3207
commit ebaa2b818d
7 changed files with 106 additions and 19 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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