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"));
31 return TDI_NO_RESOURCES
;
33 TcpipAcquireSpinLock(&InterfaceListLock
, &OldIrql
);
35 ForEachInterface(CurrentIF
) {
36 IpCurrent
->Index
= CurrentIF
->Index
;
38 IpCurrent
->BcastAddr
= 0;
41 /* Locate the diffrent addresses and put them the right place */
42 GetInterfaceIPv4Address( CurrentIF
,
45 GetInterfaceIPv4Address( CurrentIF
,
47 &IpCurrent
->BcastAddr
);
48 GetInterfaceIPv4Address( CurrentIF
,
54 ASSERT( Count
== IfCount
);
56 TcpipReleaseSpinLock(&InterfaceListLock
, OldIrql
);
58 Status
= InfoCopyOut( (PCHAR
)IpAddress
, sizeof(*IpAddress
) * IfCount
,
61 exFreePool( IpAddress
);
63 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
68 /* Get IPRouteEntry s for each of the routes in the system */
69 TDI_STATUS
InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer
, PUINT BufferSize
) {
72 UINT RtCount
= CountFIBs();
73 UINT Size
= sizeof( IPROUTE_ENTRY
) * RtCount
;
75 exAllocatePool( NonPagedPool
, sizeof( FIB_ENTRY
) * RtCount
),
77 PIPROUTE_ENTRY RouteEntries
= exAllocatePool( NonPagedPool
, Size
),
78 RtCurrent
= RouteEntries
;
80 TI_DbgPrint(DEBUG_INFO
, ("Called, routes = %d, RCache = %08x\n",
83 if( !RCache
|| !RouteEntries
) {
84 if( RCache
) exFreePool( RCache
);
85 if( RouteEntries
) exFreePool( RouteEntries
);
86 return TDI_NO_RESOURCES
;
89 RtlZeroMemory( RouteEntries
, Size
);
91 RtCount
= CopyFIBs( RCache
);
93 while( RtCurrent
< RouteEntries
+ RtCount
) {
94 /* Copy Desitnation */
95 RtlCopyMemory( &RtCurrent
->Dest
,
96 &RCacheCur
->NetworkAddress
.Address
,
97 sizeof(RtCurrent
->Dest
) );
98 RtlCopyMemory( &RtCurrent
->Mask
,
99 &RCacheCur
->Netmask
.Address
,
100 sizeof(RtCurrent
->Mask
) );
102 if( RCacheCur
->Router
)
103 RtlCopyMemory( &RtCurrent
->Gw
,
104 &RCacheCur
->Router
->Address
.Address
,
105 sizeof(RtCurrent
->Gw
) );
107 RtlZeroMemory( &RtCurrent
->Gw
, sizeof(RtCurrent
->Gw
) );
109 RtCurrent
->Metric1
= RCacheCur
->Metric
;
110 RtCurrent
->Type
= TDI_ADDRESS_TYPE_IP
;
114 ("%d: NA %08x NM %08x GW %08x MT %x\n",
115 RtCurrent
- RouteEntries
,
119 RtCurrent
->Metric1
));
121 TcpipAcquireSpinLock(&EntityListLock
, &OldIrql
);
122 for( RtCurrent
->Index
= EntityCount
;
123 RtCurrent
->Index
> 0 &&
124 RCacheCur
->Router
->Interface
!=
125 EntityList
[RtCurrent
->Index
- 1].context
;
126 RtCurrent
->Index
-- );
128 RtCurrent
->Index
= EntityList
[RtCurrent
->Index
- 1].tei_instance
;
129 TcpipReleaseSpinLock(&EntityListLock
, OldIrql
);
131 RtCurrent
++; RCacheCur
++;
134 Status
= InfoCopyOut( (PCHAR
)RouteEntries
, Size
, Buffer
, BufferSize
);
136 exFreePool( RouteEntries
);
137 exFreePool( RCache
);
139 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
144 TDI_STATUS
InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer
,
146 IPSNMP_INFO SnmpInfo
;
147 UINT IfCount
= CountInterfaces();
148 UINT RouteCount
= CountFIBs();
149 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
151 TI_DbgPrint(DEBUG_INFO
, ("Called.\n"));
153 RtlZeroMemory(&SnmpInfo
, sizeof(IPSNMP_INFO
));
155 SnmpInfo
.NumIf
= IfCount
;
156 SnmpInfo
.NumAddr
= 1;
157 SnmpInfo
.NumRoutes
= RouteCount
;
159 Status
= InfoCopyOut( (PCHAR
)&SnmpInfo
, sizeof(SnmpInfo
),
160 Buffer
, BufferSize
);
162 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
167 TDI_STATUS
InfoNetworkLayerTdiQueryEx( UINT InfoClass
,
174 TDI_STATUS Status
= TDI_INVALID_REQUEST
;
176 TI_DbgPrint(DEBUG_INFO
, ("Called.\n"));
178 switch( InfoClass
) {
179 case INFO_CLASS_GENERIC
:
180 if( InfoType
== INFO_TYPE_PROVIDER
&& InfoId
== ENTITY_TYPE_ID
) {
181 ULONG Return
= CL_NL_IP
;
182 Status
= InfoCopyOut( (PCHAR
)&Return
, sizeof(Return
),
183 Buffer
, BufferSize
);
187 case INFO_CLASS_PROTOCOL
:
189 case INFO_TYPE_PROVIDER
:
191 case IP_MIB_ADDRTABLE_ENTRY_ID
:
192 Status
= InfoTdiQueryGetAddrTable( Buffer
, BufferSize
);
195 case IP_MIB_ROUTETABLE_ENTRY_ID
:
196 Status
= InfoTdiQueryGetRouteTable( Buffer
, BufferSize
);
199 case IP_MIB_STATS_ID
:
200 Status
= InfoTdiQueryGetIPSnmpInfo( Buffer
, BufferSize
);
207 TI_DbgPrint(DEBUG_INFO
, ("Returning %08x\n", Status
));
212 TDI_STATUS
InfoNetworkLayerTdiSetEx( UINT InfoClass
,
219 NTSTATUS Status
= TDI_INVALID_REQUEST
;
223 PNEIGHBOR_CACHE_ENTRY NCE
;
225 TI_DbgPrint(DEBUG_INFO
,("Called\n"));
227 //OskitDumpBuffer( (OSK_PCHAR)Buffer, BufferSize );
229 if( InfoClass
== INFO_CLASS_PROTOCOL
&&
230 InfoType
== INFO_TYPE_PROVIDER
&&
231 InfoId
== IP_MIB_ROUTETABLE_ENTRY_ID
&&
232 id
->tei_entity
== CL_NL_ENTITY
) { /* Add or delete a route */
233 PIPROUTE_ENTRY Route
= (PIPROUTE_ENTRY
)Buffer
;
234 AddrInitIPv4( &Address
, Route
->Dest
);
235 AddrInitIPv4( &Netmask
, Route
->Mask
);
236 AddrInitIPv4( &Router
, Route
->Gw
);
238 if( Route
->Type
== IP_ROUTE_TYPE_ADD
) { /* Add the route */
239 TI_DbgPrint(DEBUG_INFO
,("Adding route (%s)\n", A2S(&Address
)));
240 /* Find the existing route this belongs to */
241 NCE
= RouterGetRoute( &Router
);
242 /* Really add the route */
244 RouterCreateRoute( &Address
, &Netmask
, &Router
,
245 NCE
->Interface
, Route
->Metric1
) )
246 Status
= STATUS_SUCCESS
;
248 Status
= STATUS_UNSUCCESSFUL
;
249 } else if( Route
->Type
== IP_ROUTE_TYPE_DEL
) {
250 TI_DbgPrint(DEBUG_INFO
,("Removing route (%s)\n", A2S(&Address
)));
251 Status
= RouterRemoveRoute( &Address
, &Router
);
252 } else Status
= TDI_INVALID_REQUEST
;
255 TI_DbgPrint(DEBUG_INFO
,("Returning %x\n", Status
));