Added networking code from Casper Hornstrup
[reactos.git] / reactos / drivers / net / tcpip / tcpip / Copy of 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/07-2000 Created
9 */
10 #include <tcpip.h>
11 #include <routines.h>
12 #include <info.h>
13
14
15 TDI_STATUS IPTdiQueryInformationEx(
16 PTDI_REQUEST Request,
17 TDIObjectID *ID,
18 PNDIS_BUFFER Buffer,
19 PUINT BufferSize,
20 PVOID Context)
21 /*
22 * FUNCTION: Returns extended information about network layer
23 * ARGUMENTS:
24 * Request = Pointer to TDI request structure for the request
25 * ID = TDI object ID
26 * Buffer = Pointer to buffer with data to use.
27 * BufferSize = Pointer to buffer with size of Buffer. On return
28 * this is filled with number of bytes returned
29 * Context = Pointer to context buffer
30 * RETURNS:
31 * Status of operation
32 */
33 {
34 IPADDR_ENTRY IpAddress;
35 IPSNMP_INFO SnmpInfo;
36 PADDRESS_ENTRY ADE;
37 PIP_INTERFACE IF;
38 ULONG Temp;
39 UINT Count;
40 ULONG Entity;
41 KIRQL OldIrql;
42 UINT BufSize = *BufferSize;
43
44 /* Make return parameters consistent every time */
45 *BufferSize = 0;
46
47 Entity = ID->toi_entity.tei_entity;
48 if (Entity != CL_NL_ENTITY) {
49 /* We can't handle this entity */
50 return TDI_INVALID_PARAMETER;
51 }
52
53 if (ID->toi_entity.tei_instance != TL_INSTANCE)
54 /* We only support a single instance */
55 return TDI_INVALID_REQUEST;
56 if (ID->toi_class == INFO_CLASS_GENERIC) {
57 if (ID->toi_type == INFO_TYPE_PROVIDER &&
58 ID->toi_id == ENTITY_TYPE_ID) {
59
60 if (BufSize < sizeof(ULONG))
61 return TDI_BUFFER_TOO_SMALL;
62 Temp = CL_NL_IP;
63
64 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
65
66 return TDI_SUCCESS;
67 }
68 return TDI_INVALID_PARAMETER;
69 }
70
71 if (ID->toi_class == INFO_CLASS_PROTOCOL) {
72 if (ID->toi_type != INFO_TYPE_PROVIDER)
73 return TDI_INVALID_PARAMETER;
74
75 switch (ID->toi_id) {
76 case IP_MIB_ADDRTABLE_ENTRY_ID:
77 Temp = 0;
78
79 KeAcquireSpinLock(&InterfaceLock, &OldIrql);
80 /*
81 /* Search the interface list */
82 CurrentIFEntry = InterfaceListHead.Flink;
83 while (CurrentIFEntry != &InterfaceListHead) {
84 CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
85 if (CurrentIF != Loopback) {
86 /* Search the address entry list and return the first appropriate ADE found */
87 CurrentADEEntry = CurrentIF->ADEListHead.Flink;
88 while (CurrentADEEntry != &CurrentIF->ADEListHead) {
89 CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
90 if (CurrentADE->Type == AddressType)
91 ReferenceAddress(CurrentADE->Address);
92 KeReleaseSpinLock(&InterfaceListLock, OldIrql);
93 return CurrentADE;
94 }
95 CurrentADEEntry = CurrentADEEntry->Flink;
96 } else
97 LoopbackIsRegistered = TRUE;
98 CurrentIFEntry = CurrentIFEntry->Flink;
99 }
100
101
102 */
103 for (IF = InterfaceList; IF != NULL; IF = IF->Next) {
104 if (Temp + sizeof(IPADDR_ENTRY) > BufSize) {
105 KeReleaseSpinLock(&InterfaceLock, OldIrql);
106 return TDI_BUFFER_TOO_SMALL;
107 }
108
109 IpAddress.Addr = 0;
110 IpAddress.BcastAddr = 0;
111 IpAddress.Mask = 0;
112 /* Locate the diffrent addresses and put them the right place */
113 for (ADE = IF->ADE; ADE != NULL; ADE = ADE->Next) {
114 switch (ADE->Type) {
115 case ADE_UNICAST : IpAddress.Addr = ADE->Address->Address.IPv4Address;
116 case ADE_MULTICAST: IpAddress.BcastAddr = ADE->Address->Address.IPv4Address;
117 case ADE_ADDRMASK : IpAddress.Mask = ADE->Address->Address.IPv4Address;
118 }
119 }
120 /* Pack the address information into IPADDR_ENTRY structure */
121 IpAddress.Index = 0;
122 IpAddress.ReasmSize = 0;
123 IpAddress.Context = 0;
124 IpAddress.Pad = 0;
125
126 Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
127
128 Temp += sizeof(IPADDR_ENTRY);
129 }
130 KeReleaseSpinLock(&InterfaceLock, OldIrql);
131 return TDI_SUCCESS;
132
133 case IP_MIB_STATS_ID:
134 if (BufSize < sizeof(IPSNMP_INFO))
135 return TDI_BUFFER_TOO_SMALL;
136
137 RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
138
139 /* Count number of addresses */
140 Count = 0;
141 KeAcquireSpinLock(&InterfaceLock, &OldIrql);
142 for (IF = InterfaceList; IF != NULL; IF = IF->Next)
143 Count++;
144 KeReleaseSpinLock(&InterfaceLock, OldIrql);
145
146 SnmpInfo.NumAddr = Count;
147
148 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
149
150 return TDI_SUCCESS;
151
152 default:
153 /* We can't handle this ID */
154 return TDI_INVALID_PARAMETER;
155 }
156 }
157
158 return TDI_INVALID_PARAMETER;
159 }
160
161
162 TDI_STATUS InfoTdiQueryInformationEx(
163 PTDI_REQUEST Request,
164 TDIObjectID *ID,
165 PNDIS_BUFFER Buffer,
166 PUINT BufferSize,
167 PVOID Context)
168 /*
169 * FUNCTION: Returns extended information
170 * ARGUMENTS:
171 * Request = Pointer to TDI request structure for the request
172 * ID = TDI object ID
173 * Buffer = Pointer to buffer with data to use
174 * BufferSize = Pointer to buffer with size of Buffer. On return
175 * this is filled with number of bytes returned
176 * Context = Pointer to context buffer
177 * RETURNS:
178 * Status of operation
179 */
180 {
181 PADDRESS_FILE AddrFile;
182 PADDRESS_ENTRY ADE;
183 ADDRESS_INFO Info;
184 KIRQL OldIrql;
185 UINT Entity;
186 UINT Count;
187 UINT Size;
188 ULONG Temp;
189 UINT Offset = 0;
190 UINT BufSize = *BufferSize;
191
192 /* Check wether it is a query for a list of entities */
193 Entity = ID->toi_entity.tei_entity;
194 if (Entity == GENERIC_ENTITY) {
195 if (ID->toi_class != INFO_CLASS_GENERIC ||
196 ID->toi_type != INFO_TYPE_PROVIDER ||
197 ID->toi_id != ENTITY_LIST_ID)
198 return TDI_INVALID_PARAMETER;
199
200 *BufferSize = 0;
201
202 Size = EntityCount * sizeof(TDIEntityID);
203 if (BufSize < Size)
204 /* The buffer is too small to contain requested data */
205 return TDI_BUFFER_TOO_SMALL;
206
207 /* Return entity list */
208 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
209
210 *BufferSize = Size;
211
212 return TDI_SUCCESS;
213 }
214
215 if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY)) {
216 /* We can't handle this entity, pass it on */
217 return IPTdiQueryInformationEx(
218 Request, ID, Buffer, BufferSize, Context);
219 }
220
221 /* Make return parameters consistent every time */
222 *BufferSize = 0;
223
224 if (ID->toi_entity.tei_instance != TL_INSTANCE)
225 /* We only support a single instance */
226 return TDI_INVALID_REQUEST;
227
228 if (ID->toi_class == INFO_CLASS_GENERIC) {
229
230 if (ID->toi_type != INFO_TYPE_PROVIDER ||
231 ID->toi_id != ENTITY_TYPE_ID)
232 return TDI_INVALID_PARAMETER;
233
234 if (BufSize < sizeof(ULONG))
235 return TDI_BUFFER_TOO_SMALL;
236
237 if (Entity == CL_TL_ENTITY)
238 Temp = CL_TL_UDP;
239 else if (Entity == CO_TL_ENTITY)
240 Temp = CO_TL_TCP;
241 else
242 return TDI_INVALID_PARAMETER;
243
244 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
245
246 return TDI_SUCCESS;
247 }
248
249 if (ID->toi_class == INFO_CLASS_PROTOCOL) {
250
251 if (ID->toi_type != INFO_TYPE_PROVIDER)
252 return TDI_INVALID_PARAMETER;
253
254 switch (ID->toi_id) {
255 case UDP_MIB_STAT_ID:
256 if (Entity != CL_TL_ENTITY)
257 return TDI_INVALID_PARAMETER;
258
259 if (BufSize < sizeof(UDPStats))
260 return TDI_BUFFER_TOO_SMALL;
261
262 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
263
264 return TDI_SUCCESS;
265
266 case UDP_MIB_TABLE_ID:
267 if (Entity != CL_TL_ENTITY)
268 return TDI_INVALID_PARAMETER;
269
270 Offset = 0;
271
272 KeAcquireSpinLock(&AddressFileLock, &OldIrql);
273
274 for (AddrFile = AddressFileList;
275 AddrFile->Next != NULL;
276 AddrFile = AddrFile->Next) {
277
278 if (Offset + sizeof(ADDRESS_INFO) > BufSize) {
279 KeReleaseSpinLock(&AddressFileLock, OldIrql);
280 *BufferSize = Offset;
281 return TDI_BUFFER_OVERFLOW;
282 }
283
284 for (ADE = AddrFile->ADE; ADE != NULL; ADE = ADE->Next) {
285 /* We only care about IPv4 unicast address */
286 if ((ADE->Type == ADE_UNICAST) &&
287 (ADE->Address->Type == IP_ADDRESS_V4))
288 Info.LocalAddress = ADE->Address->Address.IPv4Address;
289 }
290
291 Info.LocalPort = AddrFile->Port;
292
293 Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
294
295 Offset += Count;
296 }
297
298 KeReleaseSpinLock(&AddressFileLock, OldIrql);
299
300 *BufferSize = Offset;
301
302 return STATUS_SUCCESS;
303
304 default:
305 /* We can't handle this ID */
306 return TDI_INVALID_PARAMETER;
307 }
308 }
309
310 return TDI_INVALID_PARAMETER;
311 }
312
313
314 TDI_STATUS InfoTdiSetInformationEx(
315 PTDI_REQUEST Request,
316 TDIObjectID *ID,
317 PVOID Buffer,
318 UINT BufferSize)
319 /*
320 * FUNCTION: Sets extended information
321 * ARGUMENTS:
322 * Request = Pointer to TDI request structure for the request
323 * ID = Pointer to TDI object ID
324 * Buffer = Pointer to buffer with data to use
325 * BufferSize = Size of Buffer
326 * RETURNS:
327 * Status of operation
328 */
329 {
330 /* FIXME: Set extended information */
331
332 return TDI_INVALID_REQUEST;
333 }
334
335 /* EOF */