2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
5 * PURPOSE: Network information
6 * PROGRAMMERS: Art Yerkes
8 * CSH 01/08-2000 Created
13 #define IP_ROUTE_TYPE_ADD 3
14 #define IP_ROUTE_TYPE_DEL 2
16 TDI_STATUS
InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer
,
19 IF_LIST_ITER(CurrentIF
);
20 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
22 UINT Count
= 1; /* Start adapter indices at 1 */
23 UINT IfCount
= CountInterfaces();
24 PIPADDR_ENTRY IpAddress
=
25 ExAllocatePool( NonPagedPool
, sizeof( IPADDR_ENTRY
) * IfCount
);
26 PIPADDR_ENTRY IpCurrent
= IpAddress
;
28 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
30 TcpipAcquireSpinLock(&InterfaceListLock
, &OldIrql
);
32 ForEachInterface(CurrentIF
) {
33 IpCurrent
->Index
= Count
;
35 IpCurrent
->BcastAddr
= 0;
38 /* Locate the diffrent addresses and put them the right place */
39 GetInterfaceIPv4Address( CurrentIF
,
42 GetInterfaceIPv4Address( CurrentIF
,
44 &IpAddress
->BcastAddr
);
45 GetInterfaceIPv4Address( CurrentIF
,
52 TcpipReleaseSpinLock(&InterfaceListLock
, OldIrql
);
54 Status
= InfoCopyOut( (PCHAR
)IpAddress
, sizeof(*IpAddress
) * Count
,
57 ExFreePool( IpAddress
);
59 TI_DbgPrint(MAX_TRACE
, ("Returning %08x\n", Status
));
64 /* Get IPRouteEntry s for each of the routes in the system */
65 TDI_STATUS
InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer
, PUINT BufferSize
) {
68 UINT RtCount
= CountFIBs(),
69 Size
= sizeof( IPROUTE_ENTRY
) * RtCount
;
71 ExAllocatePool( NonPagedPool
, sizeof( FIB_ENTRY
) * RtCount
),
73 PIPROUTE_ENTRY RouteEntries
= ExAllocatePool( NonPagedPool
, Size
),
74 RtCurrent
= RouteEntries
;
76 TI_DbgPrint(MAX_TRACE
, ("Called, routes = %d, RCache = %08x\n",
79 if( !RCache
|| !RouteEntries
) {
80 if( RCache
) ExFreePool( RCache
);
81 if( RouteEntries
) ExFreePool( RouteEntries
);
82 return STATUS_NO_MEMORY
;
85 RtlZeroMemory( RouteEntries
, Size
);
87 RtCount
= CopyFIBs( RCache
);
89 while( RtCurrent
< RouteEntries
+ RtCount
) {
90 /* Copy Desitnation */
91 RtlCopyMemory( &RtCurrent
->Dest
,
92 &RCacheCur
->NetworkAddress
.Address
,
93 sizeof(RtCurrent
->Dest
) );
94 RtlCopyMemory( &RtCurrent
->Mask
,
95 &RCacheCur
->Netmask
.Address
,
96 sizeof(RtCurrent
->Mask
) );
98 if( RCacheCur
->Router
)
99 RtlCopyMemory( &RtCurrent
->Gw
,
100 &RCacheCur
->Router
->Address
.Address
,
101 sizeof(RtCurrent
->Gw
) );
103 RtlZeroMemory( &RtCurrent
->Gw
, sizeof(RtCurrent
->Gw
) );
105 RtCurrent
->Metric1
= RCacheCur
->Metric
;
106 RtCurrent
->Type
= TDI_ADDRESS_TYPE_IP
;
110 ("%d: NA %08x NM %08x GW %08x MT %x\n",
111 RtCurrent
- RouteEntries
,
115 RtCurrent
->Metric1
));
117 TcpipAcquireSpinLock(&EntityListLock
, &OldIrql
);
118 for( RtCurrent
->Index
= EntityCount
;
119 RtCurrent
->Index
> 0 &&
120 RCacheCur
->Router
->Interface
!=
121 EntityList
[RtCurrent
->Index
- 1].context
;
122 RtCurrent
->Index
-- );
124 RtCurrent
->Index
= EntityList
[RtCurrent
->Index
- 1].tei_instance
;
125 TcpipReleaseSpinLock(&EntityListLock
, OldIrql
);
127 RtCurrent
++; RCacheCur
++;
130 Status
= InfoCopyOut( (PCHAR
)RouteEntries
, Size
, Buffer
, BufferSize
);
132 ExFreePool( RouteEntries
);
133 ExFreePool( RCache
);
135 TI_DbgPrint(MAX_TRACE
, ("Returning %08x\n", Status
));
140 TDI_STATUS
InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer
,
142 IPSNMP_INFO SnmpInfo
;
143 UINT IfCount
= CountInterfaces();
144 UINT RouteCount
= CountFIBs( NULL
);
145 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
147 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
149 RtlZeroMemory(&SnmpInfo
, sizeof(IPSNMP_INFO
));
151 SnmpInfo
.NumIf
= IfCount
;
152 SnmpInfo
.NumAddr
= 1;
153 SnmpInfo
.NumRoutes
= RouteCount
;
155 Status
= InfoCopyOut( (PCHAR
)&SnmpInfo
, sizeof(SnmpInfo
),
156 Buffer
, BufferSize
);
158 TI_DbgPrint(MAX_TRACE
, ("Returning %08x\n", Status
));
163 TDI_STATUS
InfoNetworkLayerTdiQueryEx( UINT InfoClass
,
170 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
172 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
174 switch( InfoClass
) {
175 case INFO_CLASS_GENERIC
:
176 if( InfoType
== INFO_TYPE_PROVIDER
&& InfoId
== ENTITY_TYPE_ID
) {
177 ULONG Return
= CL_NL_IP
;
178 Status
= InfoCopyOut( (PCHAR
)&Return
, sizeof(Return
),
179 Buffer
, BufferSize
);
183 case INFO_CLASS_PROTOCOL
:
185 case INFO_TYPE_PROVIDER
:
187 case IP_MIB_ADDRTABLE_ENTRY_ID
:
188 Status
= InfoTdiQueryGetAddrTable( Buffer
, BufferSize
);
191 case IP_MIB_ROUTETABLE_ENTRY_ID
:
192 Status
= InfoTdiQueryGetRouteTable( Buffer
, BufferSize
);
195 case IP_MIB_STATS_ID
:
196 Status
= InfoTdiQueryGetIPSnmpInfo( Buffer
, BufferSize
);
203 TI_DbgPrint(MAX_TRACE
, ("Returning %08x\n", Status
));
208 TDI_STATUS
InfoNetworkLayerTdiSetEx( UINT InfoClass
,
215 NTSTATUS Status
= TDI_INVALID_REQUEST
;
219 PNEIGHBOR_CACHE_ENTRY NCE
;
221 TI_DbgPrint(MID_TRACE
,("Called\n"));
223 OskitDumpBuffer( (OSK_PCHAR
)Buffer
, BufferSize
);
225 if( InfoClass
== INFO_CLASS_PROTOCOL
&&
226 InfoType
== INFO_TYPE_PROVIDER
&&
227 InfoId
== IP_MIB_ROUTETABLE_ENTRY_ID
&&
228 id
->tei_entity
== CL_NL_ENTITY
) { /* Add or delete a route */
229 PIPROUTE_ENTRY Route
= (PIPROUTE_ENTRY
)Buffer
;
230 AddrInitIPv4( &Address
, Route
->Dest
);
231 AddrInitIPv4( &Netmask
, Route
->Mask
);
232 AddrInitIPv4( &Router
, Route
->Gw
);
234 if( Route
->Type
== IP_ROUTE_TYPE_ADD
) { /* Add the route */
235 TI_DbgPrint(MID_TRACE
,("Adding route (%s)\n", A2S(&Address
)));
236 /* Find the existing route this belongs to */
237 NCE
= RouterGetRoute( &Router
);
238 /* Really add the route */
240 RouterCreateRoute( &Address
, &Netmask
, &Router
,
241 NCE
->Interface
, Route
->Metric1
) )
242 Status
= STATUS_SUCCESS
;
244 Status
= STATUS_UNSUCCESSFUL
;
245 } else if( Route
->Type
== IP_ROUTE_TYPE_DEL
) {
246 TI_DbgPrint(MID_TRACE
,("Removing route (%s)\n", A2S(&Address
)));
247 Status
= RouterRemoveRoute( &Address
, &Router
);
248 } else Status
= TDI_INVALID_REQUEST
;
251 TI_DbgPrint(MID_TRACE
,("Returning %x\n", Status
));