3cb29e9c8f1f284554d2f25b09ebd2e7bb493399
[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 return InfoTdiQueryGetIPSnmpInfo(ID->toi_entity, Buffer, BufferSize);
192 else
193 return TDI_INVALID_PARAMETER;
194
195 case IP_MIB_ADDRTABLE_ENTRY_ID:
196 if (ID->toi_entity.tei_entity != CL_NL_ENTITY &&
197 ID->toi_entity.tei_entity != CO_NL_ENTITY)
198 return TDI_INVALID_PARAMETER;
199
200 if (ID->toi_type != INFO_TYPE_PROVIDER)
201 return TDI_INVALID_PARAMETER;
202
203 return InfoTdiQueryGetAddrTable(ID->toi_entity, Buffer, BufferSize);
204
205 case IP_MIB_ARPTABLE_ENTRY_ID:
206 if (ID->toi_type != INFO_TYPE_PROVIDER)
207 return TDI_INVALID_PARAMETER;
208
209 if (ID->toi_entity.tei_entity == AT_ENTITY)
210 if ((EntityListContext = GetContext(ID->toi_entity)))
211 return InfoTdiQueryGetArptableMIB(ID->toi_entity, EntityListContext,
212 Buffer, BufferSize);
213 else
214 return TDI_INVALID_PARAMETER;
215 else if (ID->toi_entity.tei_entity == CO_NL_ENTITY ||
216 ID->toi_entity.tei_entity == CL_NL_ENTITY)
217 return InfoTdiQueryGetRouteTable(Buffer, BufferSize);
218 else
219 return TDI_INVALID_PARAMETER;
220
221 #if 0
222 case IP_INTFC_INFO_ID:
223 if (ID->toi_type != INFO_TYPE_PROVIDER)
224 return TDI_INVALID_PARAMETER;
225
226 return InfoTdiQueryGetIFInfo(Context, Buffer, BufferSize);
227 #endif
228
229 default:
230 return TDI_INVALID_REQUEST;
231 }
232
233 default:
234 return TDI_INVALID_REQUEST;
235 }
236 }
237
238 TDI_STATUS InfoTdiSetInformationEx
239 (PTDI_REQUEST Request,
240 TDIObjectID *ID,
241 PVOID Buffer,
242 UINT BufferSize)
243 /*
244 * FUNCTION: Sets extended information
245 * ARGUMENTS:
246 * Request = Pointer to TDI request structure for the request
247 * ID = Pointer to TDI object ID
248 * Buffer = Pointer to buffer with data to use
249 * BufferSize = Size of Buffer
250 * RETURNS:
251 * Status of operation
252 */
253 {
254 switch (ID->toi_class)
255 {
256 case INFO_CLASS_PROTOCOL:
257 switch (ID->toi_id)
258 {
259 case IP_MIB_ARPTABLE_ENTRY_ID:
260 if (ID->toi_id != INFO_TYPE_PROVIDER)
261 return TDI_INVALID_PARAMETER;
262
263 if (ID->toi_entity.tei_entity != CL_NL_ENTITY &&
264 ID->toi_entity.tei_entity != CO_NL_ENTITY)
265 return TDI_INVALID_PARAMETER;
266
267 return InfoTdiSetRoute((PIPROUTE_ENTRY)Buffer);
268
269 default:
270 return TDI_INVALID_REQUEST;
271 }
272
273 default:
274 return TDI_INVALID_REQUEST;
275 }
276 }