- Removed prefix.c and the prefix list. Adapter and route netmasks are now
[reactos.git] / reactos / drivers / net / tcpip / tcpip / ninfo.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/ninfo.c
5 * PURPOSE: Network information
6 * PROGRAMMERS: Art Yerkes
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12
13 TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer,
14 PUINT BufferSize ) {
15
16 IF_LIST_ITER(CurrentIF);
17 TDI_STATUS Status = TDI_INVALID_REQUEST;
18 KIRQL OldIrql;
19 UINT Count = 1; /* Start adapter indices at 1 */
20 UINT IfCount = CountInterfaces();
21 PIPADDR_ENTRY IpAddress =
22 ExAllocatePool( NonPagedPool, sizeof( IPADDR_ENTRY ) * IfCount );
23 PIPADDR_ENTRY IpCurrent = IpAddress;
24
25 TI_DbgPrint(MAX_TRACE, ("Called.\n"));
26
27 TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
28
29 ForEachInterface(CurrentIF) {
30 IpCurrent->Index = Count;
31 IpCurrent->Addr = 0;
32 IpCurrent->BcastAddr = 0;
33 IpCurrent->Mask = 0;
34
35 /* Locate the diffrent addresses and put them the right place */
36 GetInterfaceIPv4Address( CurrentIF,
37 ADE_UNICAST,
38 &IpAddress->Addr );
39 GetInterfaceIPv4Address( CurrentIF,
40 ADE_BROADCAST,
41 &IpAddress->BcastAddr );
42 GetInterfaceIPv4Address( CurrentIF,
43 ADE_ADDRMASK,
44 &IpAddress->Mask );
45 IpCurrent++;
46 Count++;
47 } EndFor(CurrentIF);
48
49 TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
50
51 Status = InfoCopyOut( (PCHAR)IpAddress, sizeof(*IpAddress) * Count,
52 Buffer, BufferSize );
53
54 ExFreePool( IpAddress );
55
56 TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
57
58 return Status;
59 }
60
61 /* Get IPRouteEntry s for each of the routes in the system */
62 TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
63 TDI_STATUS Status;
64 KIRQL OldIrql;
65 UINT RtCount = CountFIBs(),
66 Size = sizeof( IPROUTE_ENTRY ) * RtCount;
67 PFIB_ENTRY RCache =
68 ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ),
69 RCacheCur = RCache;
70 PIPROUTE_ENTRY RouteEntries = ExAllocatePool( NonPagedPool, Size ),
71 RtCurrent = RouteEntries;
72
73 TI_DbgPrint(MAX_TRACE, ("Called, routes = %d, RCache = %08x\n",
74 RtCount, RCache));
75
76 if( !RCache || !RouteEntries ) {
77 if( RCache ) ExFreePool( RCache );
78 if( RouteEntries ) ExFreePool( RouteEntries );
79 return STATUS_NO_MEMORY;
80 }
81
82 RtlZeroMemory( RouteEntries, Size );
83
84 RtCount = CopyFIBs( RCache );
85
86 while( RtCurrent < RouteEntries + RtCount ) {
87 /* Copy Desitnation */
88 if( RCacheCur->Router ) {
89 TI_DbgPrint(MAX_TRACE, ("%d: NA %08x NM %08x GW %08x MT %x\n",
90 RtCurrent - RouteEntries,
91 &RCacheCur->NetworkAddress.Address,
92 &RCacheCur->Netmask.Address,
93 RCacheCur->Router->Address.Address,
94 RCacheCur->Metric));
95
96 RtlCopyMemory( &RtCurrent->Dest,
97 &RCacheCur->NetworkAddress.Address,
98 sizeof(RtCurrent->Dest) );
99 RtlCopyMemory( &RtCurrent->Mask,
100 &RCacheCur->Netmask.Address,
101 sizeof(RtCurrent->Mask) );
102 /* Currently, this address is stuffed into the pointer.
103 * That probably is not intended. */
104 RtlCopyMemory( &RtCurrent->Gw,
105 &RCacheCur->Router->Address.Address,
106 sizeof(RtCurrent->Gw) );
107 RtCurrent->Metric1 = RCacheCur->Metric;
108 RtCurrent->Type = 2 /* PF_INET */;
109
110 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
111 for( RtCurrent->Index = EntityCount;
112 RtCurrent->Index > 0 &&
113 RCacheCur->Router->Interface !=
114 EntityList[RtCurrent->Index - 1].context;
115 RtCurrent->Index-- );
116
117 RtCurrent->Index = EntityList[RtCurrent->Index].tei_instance;
118 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
119 } else {
120 TI_DbgPrint(MAX_TRACE, ("%d: BAD: NA %08x NM %08x GW %08x MT %d\n",
121 RtCurrent - RouteEntries,
122 RCacheCur->NetworkAddress,
123 RCacheCur->Netmask,
124 RCacheCur->Router,
125 RCacheCur->Router ?
126 &RCacheCur->Router->Address : 0,
127 RCacheCur->Metric));
128 }
129 RtCurrent++; RCacheCur++;
130 }
131
132 Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize );
133
134 ExFreePool( RouteEntries );
135 ExFreePool( RCache );
136
137 TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
138
139 return Status;
140 }
141
142 TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer,
143 PUINT BufferSize ) {
144 IPSNMP_INFO SnmpInfo;
145 UINT IfCount = CountInterfaces();
146 UINT RouteCount = CountRouteNodes( NULL );
147 TDI_STATUS Status = TDI_INVALID_REQUEST;
148
149 TI_DbgPrint(MAX_TRACE, ("Called.\n"));
150
151 RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
152
153 SnmpInfo.NumIf = IfCount;
154 SnmpInfo.NumAddr = 1;
155 SnmpInfo.NumRoutes = RouteCount;
156
157 Status = InfoCopyOut( (PCHAR)&SnmpInfo, sizeof(SnmpInfo),
158 Buffer, BufferSize );
159
160 TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
161
162 return Status;
163 }
164
165 TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass,
166 UINT InfoType,
167 UINT InfoId,
168 PVOID Context,
169 TDIEntityID *id,
170 PNDIS_BUFFER Buffer,
171 PUINT BufferSize ) {
172 TDI_STATUS Status = TDI_INVALID_REQUEST;
173
174 TI_DbgPrint(MAX_TRACE, ("Called.\n"));
175
176 switch( InfoClass ) {
177 case INFO_CLASS_GENERIC:
178 if( InfoType == INFO_TYPE_PROVIDER && InfoId == ENTITY_TYPE_ID ) {
179 ULONG Return = CL_NL_IP;
180 Status = InfoCopyOut( (PCHAR)&Return, sizeof(Return),
181 Buffer, BufferSize );
182 }
183 break;
184
185 case INFO_CLASS_PROTOCOL:
186 switch( InfoType ) {
187 case INFO_TYPE_PROVIDER:
188 switch( InfoId ) {
189 case IP_MIB_ADDRTABLE_ENTRY_ID:
190 Status = InfoTdiQueryGetAddrTable( Buffer, BufferSize );
191 break;
192
193 case IP_MIB_ROUTETABLE_ENTRY_ID:
194 Status = InfoTdiQueryGetRouteTable( Buffer, BufferSize );
195 break;
196
197 case IP_MIB_STATS_ID:
198 Status = InfoTdiQueryGetIPSnmpInfo( Buffer, BufferSize );
199 break;
200 }
201 break;
202 }
203 }
204
205 TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
206
207 return Status;
208 }
209
210 TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass,
211 UINT InfoType,
212 UINT InfoId,
213 PVOID Context,
214 TDIEntityID *id,
215 PCHAR Buffer,
216 UINT BufferSize ) {
217 return STATUS_UNSUCCESSFUL;
218 }