- Implement SetIpNetEntry in iphlpapi and InfoTdiSetArptableMIB in tcpip
authorCameron Gutman <aicommander@gmail.com>
Sat, 24 Oct 2009 20:39:41 +0000 (20:39 +0000)
committerCameron Gutman <aicommander@gmail.com>
Sat, 24 Oct 2009 20:39:41 +0000 (20:39 +0000)
 - Added buffer size checks for InfoTdiSetRoute
 - "arp -s" works now

svn path=/trunk/; revision=43723

reactos/dll/win32/iphlpapi/iphlpapi_main.c
reactos/dll/win32/iphlpapi/iphlpapi_private.h
reactos/dll/win32/iphlpapi/route_reactos.c
reactos/drivers/network/tcpip/include/info.h
reactos/drivers/network/tcpip/tcpip/iinfo.c
reactos/drivers/network/tcpip/tcpip/info.c
reactos/drivers/network/tcpip/tcpip/ninfo.c

index 8ef198e..09e4945 100644 (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;
 }
 
 
index 3a4dc6a..4210198 100644 (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 {
index ef6b639..c4cffdf 100644 (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;
index efae370..53c8bb3 100644 (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,
index 38e649f..39a9ad9 100644 (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;
index 8a83303..ee1e7b1 100644 (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;
 
index f312b83..af4fb99 100644 (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");