- Forgot to commit these for MSVC build...
[reactos.git] / reactos / drivers / net / tcpip / tcpip / ninfo.c
index 43b5288..6935ad2 100644 (file)
@@ -7,79 +7,74 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
-#include <roscfg.h>
-#include <tcpip.h>
-#include <address.h>
-#include <info.h>
-#include <pool.h>
-#include <prefix.h>
-#include <ip.h>
-#include <route.h>
-#include <tilists.h>
-
-TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer, 
+
+#include "precomp.h"
+
+#define IP_ROUTE_TYPE_ADD 3
+#define IP_ROUTE_TYPE_DEL 2
+
+TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer,
                                     PUINT BufferSize ) {
-    
-    IF_LIST_ITER(CurrentIF);
+
     TDI_STATUS Status = TDI_INVALID_REQUEST;
     KIRQL OldIrql;
-    UINT Count = 1; /* Start adapter indices at 1 */
+    UINT Count = 0;
     UINT IfCount = CountInterfaces();
-    PIPADDR_ENTRY IpAddress = 
+    PIPADDR_ENTRY IpAddress =
        ExAllocatePool( NonPagedPool, sizeof( IPADDR_ENTRY ) * IfCount );
     PIPADDR_ENTRY IpCurrent = IpAddress;
+    IF_LIST_ITER(CurrentIF);
+
+    TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
+
+    TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
 
-    TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-    
-    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
-    
     ForEachInterface(CurrentIF) {
-       IpCurrent->Index     = Count;
+       IpCurrent->Index     = CurrentIF->Index;
        IpCurrent->Addr      = 0;
        IpCurrent->BcastAddr = 0;
        IpCurrent->Mask      = 0;
-       
+
        /* Locate the diffrent addresses and put them the right place */
        GetInterfaceIPv4Address( CurrentIF,
                                 ADE_UNICAST,
-                                &IpAddress->Addr );
+                                &IpCurrent->Addr );
        GetInterfaceIPv4Address( CurrentIF,
-                                ADE_MULTICAST,
-                                &IpAddress->BcastAddr );
+                                ADE_BROADCAST,
+                                &IpCurrent->BcastAddr );
        GetInterfaceIPv4Address( CurrentIF,
                                 ADE_ADDRMASK,
-                                &IpAddress->Mask );
+                                &IpCurrent->Mask );
        IpCurrent++;
        Count++;
     } EndFor(CurrentIF);
-    
-    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
+    ASSERT( Count == IfCount );
+
+    TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
 
-    Status = InfoCopyOut( IpAddress, sizeof(*IpAddress) * Count,
+    Status = InfoCopyOut( (PCHAR)IpAddress, sizeof(*IpAddress) * IfCount,
                          Buffer, BufferSize );
-    
+
     ExFreePool( IpAddress );
 
-    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+    TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
 
     return Status;
 }
 
 /* Get IPRouteEntry s for each of the routes in the system */
 TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
-    PIP_INTERFACE CurrentIF;
-    PLIST_ENTRY CurrentIFEntry;
     TDI_STATUS Status;
     KIRQL OldIrql;
-    UINT RtCount = CountFIBs(),
-       Size = sizeof( IPROUTE_ENTRY ) * RtCount;
-    PFIB_ENTRY RCache = 
+    UINT RtCount = CountFIBs();
+    UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount;
+    PFIB_ENTRY RCache =
        ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ),
        RCacheCur = RCache;
     PIPROUTE_ENTRY RouteEntries = ExAllocatePool( NonPagedPool, Size ),
        RtCurrent = RouteEntries;
 
-    TI_DbgPrint(MAX_TRACE, ("Called, routes = %d, RCache = %08x\n", 
+    TI_DbgPrint(DEBUG_INFO, ("Called, routes = %d, RCache = %08x\n",
                            RtCount, RCache));
 
     if( !RCache || !RouteEntries ) {
@@ -91,96 +86,77 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
     RtlZeroMemory( RouteEntries, Size );
 
     RtCount = CopyFIBs( RCache );
-    
+
     while( RtCurrent < RouteEntries + RtCount ) {
        /* Copy Desitnation */
-       if( RCacheCur->NetworkAddress && RCacheCur->Netmask && 
-           RCacheCur->Router && RCacheCur->Router->Address ) {
-           TI_DbgPrint(MAX_TRACE, ("%d: NA %08x NM %08x GW %08x MT %d\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,
+                          &RCacheCur->Router->Address.Address,
                           sizeof(RtCurrent->Gw) );
-           RtCurrent->Metric1 = RCacheCur->Metric;
-           RtCurrent->Type = 2 /* PF_INET */;
-           
-           KeAcquireSpinLock(&EntityListLock, &OldIrql);
-           for( RtCurrent->Index = EntityCount - 1; 
-                RtCurrent->Index >= 0 &&
-                    RCacheCur->Router->Interface != 
-                    EntityList[RtCurrent->Index].context;
-                RtCurrent->Index-- );
-           RtCurrent->Index = EntityList[RtCurrent->Index].tei_instance;
-           KeReleaseSpinLock(&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
+           (DEBUG_INFO,
+            ("%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 - 1].tei_instance;
+       TcpipReleaseSpinLock(&EntityListLock, OldIrql);
+
        RtCurrent++; RCacheCur++;
     }
 
-    Status = InfoCopyOut( RouteEntries, Size, Buffer, BufferSize );
+    Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize );
 
     ExFreePool( RouteEntries );
     ExFreePool( RCache );
 
-    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+    TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
 
     return Status;
 }
-               
+
 TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer,
                                      PUINT BufferSize ) {
-    KIRQL OldIrql;
-    IF_LIST_ITER(CurrentIF);
     IPSNMP_INFO SnmpInfo;
     UINT IfCount = CountInterfaces();
-    UINT AddrCount = 0;
-    UINT RouteCount = CountRouteNodes( NULL );
+    UINT RouteCount = CountFIBs();
     TDI_STATUS Status = TDI_INVALID_REQUEST;
 
-    TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+    TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
 
     RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
-    
-    /* Count number of addresses */
-    AddrCount = 0;
-    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
-    
-    ForEachInterface(CurrentIF) {
-       CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
-       AddrCount += CountInterfaceAddresses( CurrentIF );
-    } EndFor(CurrentIF);
-    
-    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-    
+
     SnmpInfo.NumIf = IfCount;
-    SnmpInfo.NumAddr = AddrCount;
+    SnmpInfo.NumAddr = 1;
     SnmpInfo.NumRoutes = RouteCount;
 
-    Status = InfoCopyOut( &SnmpInfo, sizeof(SnmpInfo), 
+    Status = InfoCopyOut( (PCHAR)&SnmpInfo, sizeof(SnmpInfo),
                          Buffer, BufferSize );
 
-    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+    TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
 
     return Status;
 }
@@ -193,14 +169,14 @@ TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass,
                                       PNDIS_BUFFER Buffer,
                                       PUINT BufferSize ) {
     TDI_STATUS Status = TDI_INVALID_REQUEST;
-    
-    TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+    TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
 
     switch( InfoClass ) {
     case INFO_CLASS_GENERIC:
        if( InfoType == INFO_TYPE_PROVIDER && InfoId == ENTITY_TYPE_ID ) {
            ULONG Return = CL_NL_IP;
-           Status = InfoCopyOut( &Return, sizeof(Return), 
+           Status = InfoCopyOut( (PCHAR)&Return, sizeof(Return),
                                  Buffer, BufferSize );
        }
        break;
@@ -225,7 +201,7 @@ TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass,
        }
     }
 
-    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+    TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
 
     return Status;
 }
@@ -237,4 +213,43 @@ TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass,
                                     TDIEntityID *id,
                                     PCHAR Buffer,
                                     UINT BufferSize ) {
+    NTSTATUS Status = TDI_INVALID_REQUEST;
+    IP_ADDRESS Address;
+    IP_ADDRESS Netmask;
+    IP_ADDRESS Router;
+    PNEIGHBOR_CACHE_ENTRY NCE;
+
+    TI_DbgPrint(DEBUG_INFO,("Called\n"));
+
+    OskitDumpBuffer( (OSK_PCHAR)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(DEBUG_INFO,("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(DEBUG_INFO,("Removing route (%s)\n", A2S(&Address)));
+           Status = RouterRemoveRoute( &Address, &Router );
+       } else Status = TDI_INVALID_REQUEST;
+    }
+
+    TI_DbgPrint(DEBUG_INFO,("Returning %x\n", Status));
+
+    return Status;
 }