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 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
22 UINT IfCount
= CountInterfaces();
23 PIPADDR_ENTRY IpAddress
=
24 ExAllocatePool( NonPagedPool
, sizeof( IPADDR_ENTRY
) * IfCount
);
25 PIPADDR_ENTRY IpCurrent
= IpAddress
;
26 IF_LIST_ITER(CurrentIF
);
28 TI_DbgPrint(DEBUG_INFO
, ("Called.\n"));
30 TcpipAcquireSpinLock(&InterfaceListLock
, &OldIrql
);
32 ForEachInterface(CurrentIF
) {
33 IpCurrent
->Index
= CurrentIF
->Index
;
35 IpCurrent
->BcastAddr
= 0;
38 /* Locate the diffrent addresses and put them the right place */
39 GetInterfaceIPv4Address( CurrentIF
,
42 GetInterfaceIPv4Address( CurrentIF
,
44 &IpCurrent
->BcastAddr
);
45 GetInterfaceIPv4Address( CurrentIF
,
51 ASSERT( Count
== IfCount
);
53 TcpipReleaseSpinLock(&InterfaceListLock
, OldIrql
);
55 Status
= InfoCopyOut( (PCHAR
)IpAddress
, sizeof(*IpAddress
) * IfCount
,
58 ExFreePool( IpAddress
);
60 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
65 /* Get IPRouteEntry s for each of the routes in the system */
66 TDI_STATUS
InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer
, PUINT BufferSize
) {
69 UINT RtCount
= CountFIBs();
70 UINT Size
= sizeof( IPROUTE_ENTRY
) * RtCount
;
72 ExAllocatePool( NonPagedPool
, sizeof( FIB_ENTRY
) * RtCount
),
74 PIPROUTE_ENTRY RouteEntries
= ExAllocatePool( NonPagedPool
, Size
),
75 RtCurrent
= RouteEntries
;
77 TI_DbgPrint(DEBUG_INFO
, ("Called, routes = %d, RCache = %08x\n",
80 if( !RCache
|| !RouteEntries
) {
81 if( RCache
) ExFreePool( RCache
);
82 if( RouteEntries
) ExFreePool( RouteEntries
);
83 return STATUS_NO_MEMORY
;
86 RtlZeroMemory( RouteEntries
, Size
);
88 RtCount
= CopyFIBs( RCache
);
90 while( RtCurrent
< RouteEntries
+ RtCount
) {
91 /* Copy Desitnation */
92 RtlCopyMemory( &RtCurrent
->Dest
,
93 &RCacheCur
->NetworkAddress
.Address
,
94 sizeof(RtCurrent
->Dest
) );
95 RtlCopyMemory( &RtCurrent
->Mask
,
96 &RCacheCur
->Netmask
.Address
,
97 sizeof(RtCurrent
->Mask
) );
99 if( RCacheCur
->Router
)
100 RtlCopyMemory( &RtCurrent
->Gw
,
101 &RCacheCur
->Router
->Address
.Address
,
102 sizeof(RtCurrent
->Gw
) );
104 RtlZeroMemory( &RtCurrent
->Gw
, sizeof(RtCurrent
->Gw
) );
106 RtCurrent
->Metric1
= RCacheCur
->Metric
;
107 RtCurrent
->Type
= TDI_ADDRESS_TYPE_IP
;
111 ("%d: NA %08x NM %08x GW %08x MT %x\n",
112 RtCurrent
- RouteEntries
,
116 RtCurrent
->Metric1
));
118 TcpipAcquireSpinLock(&EntityListLock
, &OldIrql
);
119 for( RtCurrent
->Index
= EntityCount
;
120 RtCurrent
->Index
> 0 &&
121 RCacheCur
->Router
->Interface
!=
122 EntityList
[RtCurrent
->Index
- 1].context
;
123 RtCurrent
->Index
-- );
125 RtCurrent
->Index
= EntityList
[RtCurrent
->Index
- 1].tei_instance
;
126 TcpipReleaseSpinLock(&EntityListLock
, OldIrql
);
128 RtCurrent
++; RCacheCur
++;
131 Status
= InfoCopyOut( (PCHAR
)RouteEntries
, Size
, Buffer
, BufferSize
);
133 ExFreePool( RouteEntries
);
134 ExFreePool( RCache
);
136 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
141 TDI_STATUS
InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer
,
143 IPSNMP_INFO SnmpInfo
;
144 UINT IfCount
= CountInterfaces();
145 UINT RouteCount
= CountFIBs();
146 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
148 TI_DbgPrint(DEBUG_INFO
, ("Called.\n"));
150 RtlZeroMemory(&SnmpInfo
, sizeof(IPSNMP_INFO
));
152 SnmpInfo
.NumIf
= IfCount
;
153 SnmpInfo
.NumAddr
= 1;
154 SnmpInfo
.NumRoutes
= RouteCount
;
156 Status
= InfoCopyOut( (PCHAR
)&SnmpInfo
, sizeof(SnmpInfo
),
157 Buffer
, BufferSize
);
159 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
164 TDI_STATUS
InfoNetworkLayerTdiQueryEx( UINT InfoClass
,
171 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
173 TI_DbgPrint(DEBUG_INFO
, ("Called.\n"));
175 switch( InfoClass
) {
176 case INFO_CLASS_GENERIC
:
177 if( InfoType
== INFO_TYPE_PROVIDER
&& InfoId
== ENTITY_TYPE_ID
) {
178 ULONG Return
= CL_NL_IP
;
179 Status
= InfoCopyOut( (PCHAR
)&Return
, sizeof(Return
),
180 Buffer
, BufferSize
);
184 case INFO_CLASS_PROTOCOL
:
186 case INFO_TYPE_PROVIDER
:
188 case IP_MIB_ADDRTABLE_ENTRY_ID
:
189 Status
= InfoTdiQueryGetAddrTable( Buffer
, BufferSize
);
192 case IP_MIB_ROUTETABLE_ENTRY_ID
:
193 Status
= InfoTdiQueryGetRouteTable( Buffer
, BufferSize
);
196 case IP_MIB_STATS_ID
:
197 Status
= InfoTdiQueryGetIPSnmpInfo( Buffer
, BufferSize
);
204 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
209 TDI_STATUS
InfoNetworkLayerTdiSetEx( UINT InfoClass
,
216 NTSTATUS Status
= TDI_INVALID_REQUEST
;
220 PNEIGHBOR_CACHE_ENTRY NCE
;
222 TI_DbgPrint(DEBUG_INFO
,("Called\n"));
224 //OskitDumpBuffer( (OSK_PCHAR)Buffer, BufferSize );
226 if( InfoClass
== INFO_CLASS_PROTOCOL
&&
227 InfoType
== INFO_TYPE_PROVIDER
&&
228 InfoId
== IP_MIB_ROUTETABLE_ENTRY_ID
&&
229 id
->tei_entity
== CL_NL_ENTITY
) { /* Add or delete a route */
230 PIPROUTE_ENTRY Route
= (PIPROUTE_ENTRY
)Buffer
;
231 AddrInitIPv4( &Address
, Route
->Dest
);
232 AddrInitIPv4( &Netmask
, Route
->Mask
);
233 AddrInitIPv4( &Router
, Route
->Gw
);
235 if( Route
->Type
== IP_ROUTE_TYPE_ADD
) { /* Add the route */
236 TI_DbgPrint(DEBUG_INFO
,("Adding route (%s)\n", A2S(&Address
)));
237 /* Find the existing route this belongs to */
238 NCE
= RouterGetRoute( &Router
);
239 /* Really add the route */
241 RouterCreateRoute( &Address
, &Netmask
, &Router
,
242 NCE
->Interface
, Route
->Metric1
) )
243 Status
= STATUS_SUCCESS
;
245 Status
= STATUS_UNSUCCESSFUL
;
246 } else if( Route
->Type
== IP_ROUTE_TYPE_DEL
) {
247 TI_DbgPrint(DEBUG_INFO
,("Removing route (%s)\n", A2S(&Address
)));
248 Status
= RouterRemoveRoute( &Address
, &Router
);
249 } else Status
= TDI_INVALID_REQUEST
;
252 TI_DbgPrint(DEBUG_INFO
,("Returning %x\n", Status
));