- Fix some typos from my last commit
[reactos.git] / reactos / drivers / network / tcpip / tcpip / info.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/info.c
5 * PURPOSE: TDI query and set information routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10
11 #include "precomp.h"
12 #include <debug.h>
13 #include <route.h>
14
15 PVOID GetContext(TDIEntityID ID)
16 {
17 UINT i;
18 KIRQL OldIrql;
19 PVOID Context;
20
21 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
22
23 for (i = 0; i < EntityCount; i++)
24 {
25 if (EntityList[i].tei_entity == ID.tei_entity &&
26 EntityList[i].tei_instance == ID.tei_instance)
27 break;
28 }
29
30 if (i == EntityCount)
31 {
32 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
33 DbgPrint("WARNING: Unable to get context for %d %d\n", ID.tei_entity, ID.tei_instance);
34 return NULL;
35 }
36
37 Context = EntityList[i].context;
38
39 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
40
41 return Context;
42 }
43
44 TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut,
45 PNDIS_BUFFER ClientBuf, PUINT ClientBufSize ) {
46 UINT RememberedCBSize = *ClientBufSize;
47 *ClientBufSize = SizeOut;
48
49 /* The driver returns success even when it couldn't fit every available
50 * byte. */
51 if( RememberedCBSize < SizeOut || !ClientBuf )
52 return TDI_SUCCESS;
53 else {
54 CopyBufferToBufferChain( ClientBuf, 0, (PCHAR)DataOut, SizeOut );
55 return TDI_SUCCESS;
56 }
57 }
58
59 TDI_STATUS InfoTdiQueryEntityType(TDIEntityID ID,
60 PNDIS_BUFFER Buffer,
61 PUINT BufferSize)
62 {
63 KIRQL OldIrql;
64 UINT i, Flags = 0;
65
66 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
67
68 for (i = 0; i < EntityCount; i++)
69 {
70 if (EntityList[i].tei_entity == ID.tei_entity &&
71 EntityList[i].tei_instance == ID.tei_instance)
72 break;
73 }
74
75 if (i == EntityCount)
76 {
77 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
78 return TDI_INVALID_PARAMETER;
79 }
80
81 Flags = EntityList[i].flags;
82
83 InfoCopyOut((PCHAR)&Flags,
84 sizeof(ULONG),
85 Buffer,
86 BufferSize);
87
88 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
89
90 return TDI_SUCCESS;
91 }
92
93 TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
94 PUINT BufferSize)
95 {
96 UINT Count, Size, BufSize = *BufferSize;
97 KIRQL OldIrql;
98
99 TI_DbgPrint(DEBUG_INFO,("About to copy %d TDIEntityIDs to user\n",
100 EntityCount));
101
102 TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
103
104 Size = EntityCount * sizeof(TDIEntityID);
105 *BufferSize = Size;
106
107 TI_DbgPrint(DEBUG_INFO,("BufSize: %d, NeededSize: %d\n", BufSize, Size));
108
109 if (BufSize < Size || !Buffer)
110 {
111 TcpipReleaseSpinLock( &EntityListLock, OldIrql );
112 /* The buffer is too small to contain requested data, but we return
113 * success anyway, as we did everything we wanted. */
114 return TDI_SUCCESS;
115 }
116
117 /* Return entity list -- Copy only the TDIEntityID parts. */
118 for( Count = 0; Count < EntityCount; Count++ ) {
119 CopyBufferToBufferChain(Buffer,
120 Count * sizeof(TDIEntityID),
121 (PCHAR)&EntityList[Count],
122 sizeof(TDIEntityID));
123 }
124
125 TcpipReleaseSpinLock(&EntityListLock, OldIrql);
126
127 return TDI_SUCCESS;
128 }
129
130 TDI_STATUS InfoTdiQueryInformationEx(
131 PTDI_REQUEST Request,
132 TDIObjectID *ID,
133 PNDIS_BUFFER Buffer,
134 PUINT BufferSize,
135 PVOID Context)
136 /*
137 * FUNCTION: Returns extended information
138 * ARGUMENTS:
139 * Request = Pointer to TDI request structure for the request
140 * ID = TDI object ID
141 * Buffer = Pointer to buffer with data to use
142 * BufferSize = Pointer to buffer with size of Buffer. On return
143 * this is filled with number of bytes returned
144 * Context = Pointer to context buffer
145 * RETURNS:
146 * Status of operation
147 */
148 {
149 PVOID EntityListContext;
150
151 TI_DbgPrint(DEBUG_INFO,
152 ("InfoEx Req: %x %x %x!%04x:%d\n",
153 ID->toi_class,
154 ID->toi_type,
155 ID->toi_id,
156 ID->toi_entity.tei_entity,
157 ID->toi_entity.tei_instance));
158
159 switch (ID->toi_class)
160 {
161 case INFO_CLASS_GENERIC:
162 switch (ID->toi_id)
163 {
164 case ENTITY_LIST_ID:
165 if (ID->toi_type != INFO_TYPE_PROVIDER)
166 return TDI_INVALID_PARAMETER;
167
168 return InfoTdiQueryListEntities(Buffer, BufferSize);
169
170 case ENTITY_TYPE_ID:
171 if (ID->toi_type != INFO_TYPE_PROVIDER)
172 return TDI_INVALID_PARAMETER;
173
174 return InfoTdiQueryEntityType(ID->toi_entity, Buffer, BufferSize);
175
176 default:
177 return TDI_INVALID_REQUEST;
178 }
179
180 case INFO_CLASS_PROTOCOL:
181 switch (ID->toi_id)
182 {
183 case IF_MIB_STATS_ID:
184 if (ID->toi_entity.tei_entity == IF_ENTITY)
185 if ((EntityListContext = GetContext(ID->toi_entity)))
186 return InfoTdiQueryGetInterfaceMIB(ID->toi_entity, EntityListContext, Buffer, BufferSize);
187 else
188 return TDI_INVALID_PARAMETER;
189 else if (ID->toi_entity.tei_entity == CL_NL_ENTITY ||
190 ID->toi_entity.tei_entity == CO_NL_ENTITY)
191 if ((EntityListContext = GetContext(ID->toi_entity)))
192 return InfoTdiQueryGetIPSnmpInfo(ID->toi_entity, EntityListContext, Buffer, BufferSize);
193 else
194 return TDI_INVALID_PARAMETER;
195 else
196 return TDI_INVALID_PARAMETER;
197
198 case IP_MIB_ADDRTABLE_ENTRY_ID:
199 if (ID->toi_entity.tei_entity != CL_NL_ENTITY &&
200 ID->toi_entity.tei_entity != CO_NL_ENTITY)
201 return TDI_INVALID_PARAMETER;
202
203 if (ID->toi_type != INFO_TYPE_PROVIDER)
204 return TDI_INVALID_PARAMETER;
205
206 return InfoTdiQueryGetAddrTable(ID->toi_entity, Buffer, BufferSize);
207
208 case IP_MIB_ARPTABLE_ENTRY_ID:
209 if (ID->toi_type != INFO_TYPE_PROVIDER)
210 return TDI_INVALID_PARAMETER;
211
212 if (ID->toi_entity.tei_entity == AT_ENTITY)
213 if ((EntityListContext = GetContext(ID->toi_entity)))
214 return InfoTdiQueryGetArptableMIB(ID->toi_entity, EntityListContext,
215 Buffer, BufferSize);
216 else
217 return TDI_INVALID_PARAMETER;
218 else if (ID->toi_entity.tei_entity == CO_NL_ENTITY ||
219 ID->toi_entity.tei_entity == CL_NL_ENTITY)
220 if ((EntityListContext = GetContext(ID->toi_entity)))
221 return InfoTdiQueryGetRouteTable(EntityListContext, Buffer, BufferSize);
222 else
223 return TDI_INVALID_PARAMETER;
224 else
225 return TDI_INVALID_PARAMETER;
226
227 #if 0
228 case IP_INTFC_INFO_ID:
229 if (ID->toi_type != INFO_TYPE_PROVIDER)
230 return TDI_INVALID_PARAMETER;
231
232 return InfoTdiQueryGetIFInfo(Context, Buffer, BufferSize);
233 #endif
234
235 default:
236 return TDI_INVALID_REQUEST;
237 }
238
239 default:
240 return TDI_INVALID_REQUEST;
241 }
242 }
243
244 TDI_STATUS InfoTdiSetInformationEx
245 (PTDI_REQUEST Request,
246 TDIObjectID *ID,
247 PVOID Buffer,
248 UINT BufferSize)
249 /*
250 * FUNCTION: Sets extended information
251 * ARGUMENTS:
252 * Request = Pointer to TDI request structure for the request
253 * ID = Pointer to TDI object ID
254 * Buffer = Pointer to buffer with data to use
255 * BufferSize = Size of Buffer
256 * RETURNS:
257 * Status of operation
258 */
259 {
260 PVOID EntityListContext;
261
262 switch (ID->toi_class)
263 {
264 case INFO_CLASS_PROTOCOL:
265 switch (ID->toi_id)
266 {
267 case IP_MIB_ARPTABLE_ENTRY_ID:
268 if (ID->toi_type != INFO_TYPE_PROVIDER)
269 return TDI_INVALID_PARAMETER;
270
271 if (ID->toi_entity.tei_entity != CL_NL_ENTITY &&
272 ID->toi_entity.tei_entity != CO_NL_ENTITY)
273 return TDI_INVALID_PARAMETER;
274
275 if ((EntityListContext = GetContext(ID->toi_entity)))
276 return InfoTdiSetRoute(EntityListContext, (PIPROUTE_ENTRY)Buffer);
277 else
278 return TDI_INVALID_PARAMETER;
279
280 default:
281 return TDI_INVALID_REQUEST;
282 }
283
284 default:
285 return TDI_INVALID_REQUEST;
286 }
287 }