2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
5 * PURPOSE: TDI query and set information routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
15 TDI_STATUS IPTdiQueryInformationEx(
22 * FUNCTION: Returns extended information about network layer
24 * Request = Pointer to TDI request structure for the request
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
34 PLIST_ENTRY CurrentIFEntry;
35 PLIST_ENTRY CurrentADEEntry;
36 PIP_INTERFACE CurrentIF;
37 PADDRESS_ENTRY CurrentADE;
38 IPADDR_ENTRY IpAddress;
44 UINT BufSize = *BufferSize;
46 /* Make return parameters consistent every time */
49 Entity = ID->toi_entity.tei_entity;
50 if (Entity != CL_NL_ENTITY) {
51 /* We can't handle this entity */
52 return TDI_INVALID_PARAMETER;
55 if (ID->toi_entity.tei_instance != TL_INSTANCE)
56 /* We only support a single instance */
57 return TDI_INVALID_REQUEST;
58 if (ID->toi_class == INFO_CLASS_GENERIC) {
59 if (ID->toi_type == INFO_TYPE_PROVIDER &&
60 ID->toi_id == ENTITY_TYPE_ID) {
62 if (BufSize < sizeof(ULONG))
63 return TDI_BUFFER_TOO_SMALL;
66 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
70 return TDI_INVALID_PARAMETER;
73 if (ID->toi_class == INFO_CLASS_PROTOCOL) {
74 if (ID->toi_type != INFO_TYPE_PROVIDER)
75 return TDI_INVALID_PARAMETER;
78 case IP_MIB_ADDRTABLE_ENTRY_ID:
81 KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
83 CurrentIFEntry = InterfaceListHead.Flink;
84 while (CurrentIFEntry != &InterfaceListHead) {
85 CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
87 if (Temp + sizeof(IPADDR_ENTRY) > BufSize) {
88 KeReleaseSpinLock(&InterfaceListLock, OldIrql);
89 return TDI_BUFFER_TOO_SMALL;
93 IpAddress.BcastAddr = 0;
96 /* Locate the diffrent addresses and put them the right place */
97 CurrentADEEntry = CurrentIF->ADEListHead.Flink;
98 while (CurrentADEEntry != &CurrentIF->ADEListHead) {
99 CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
101 switch (CurrentADE->Type) {
103 IpAddress.Addr = CurrentADE->Address->Address.IPv4Address;
106 IpAddress.BcastAddr = CurrentADE->Address->Address.IPv4Address;
109 IpAddress.Mask = CurrentADE->Address->Address.IPv4Address;
112 /* Should not happen */
113 TI_DbgPrint(MIN_TRACE, ("Unknown address entry type (0x%X)\n", CurrentADE->Type));
116 CurrentADEEntry = CurrentADEEntry->Flink;
118 /* Pack the address information into IPADDR_ENTRY structure */
120 IpAddress.ReasmSize = 0;
121 IpAddress.Context = 0;
124 Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
126 Temp += sizeof(IPADDR_ENTRY);
128 CurrentIFEntry = CurrentIFEntry->Flink;
131 KeReleaseSpinLock(&InterfaceListLock, OldIrql);
135 case IP_MIB_STATS_ID:
136 if (BufSize < sizeof(IPSNMP_INFO))
137 return TDI_BUFFER_TOO_SMALL;
139 RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
141 /* Count number of addresses */
143 KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
145 CurrentIFEntry = InterfaceListHead.Flink;
146 while (CurrentIFEntry != &InterfaceListHead) {
147 CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
149 CurrentIFEntry = CurrentIFEntry->Flink;
152 KeReleaseSpinLock(&InterfaceListLock, OldIrql);
154 SnmpInfo.NumAddr = Count;
156 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
161 /* We can't handle this ID */
162 return TDI_INVALID_PARAMETER;
166 return TDI_INVALID_PARAMETER;
170 TDI_STATUS InfoTdiQueryInformationEx(
171 PTDI_REQUEST Request,
177 * FUNCTION: Returns extended information
179 * Request = Pointer to TDI request structure for the request
181 * Buffer = Pointer to buffer with data to use
182 * BufferSize = Pointer to buffer with size of Buffer. On return
183 * this is filled with number of bytes returned
184 * Context = Pointer to context buffer
186 * Status of operation
189 PLIST_ENTRY CurrentADFEntry;
190 PADDRESS_FILE CurrentADF;
198 UINT BufSize = *BufferSize;
200 /* Check wether it is a query for a list of entities */
201 Entity = ID->toi_entity.tei_entity;
202 if (Entity == GENERIC_ENTITY) {
203 if (ID->toi_class != INFO_CLASS_GENERIC ||
204 ID->toi_type != INFO_TYPE_PROVIDER ||
205 ID->toi_id != ENTITY_LIST_ID)
206 return TDI_INVALID_PARAMETER;
210 Size = EntityCount * sizeof(TDIEntityID);
212 /* The buffer is too small to contain requested data */
213 return TDI_BUFFER_TOO_SMALL;
215 /* Return entity list */
216 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
223 if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY)) {
224 /* We can't handle this entity, pass it on */
225 return IPTdiQueryInformationEx(
226 Request, ID, Buffer, BufferSize, Context);
229 /* Make return parameters consistent every time */
232 if (ID->toi_entity.tei_instance != TL_INSTANCE)
233 /* We only support a single instance */
234 return TDI_INVALID_REQUEST;
236 if (ID->toi_class == INFO_CLASS_GENERIC) {
238 if (ID->toi_type != INFO_TYPE_PROVIDER ||
239 ID->toi_id != ENTITY_TYPE_ID)
240 return TDI_INVALID_PARAMETER;
242 if (BufSize < sizeof(ULONG))
243 return TDI_BUFFER_TOO_SMALL;
245 if (Entity == CL_TL_ENTITY)
247 else if (Entity == CO_TL_ENTITY)
250 return TDI_INVALID_PARAMETER;
252 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
257 if (ID->toi_class == INFO_CLASS_PROTOCOL) {
259 if (ID->toi_type != INFO_TYPE_PROVIDER)
260 return TDI_INVALID_PARAMETER;
262 switch (ID->toi_id) {
263 case UDP_MIB_STAT_ID:
264 if (Entity != CL_TL_ENTITY)
265 return TDI_INVALID_PARAMETER;
267 if (BufSize < sizeof(UDPStats))
268 return TDI_BUFFER_TOO_SMALL;
270 Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
274 case UDP_MIB_TABLE_ID:
275 if (Entity != CL_TL_ENTITY)
276 return TDI_INVALID_PARAMETER;
280 KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
282 CurrentADFEntry = AddressFileListHead.Flink;
283 while (CurrentADFEntry != &AddressFileListHead) {
284 CurrentADF = CONTAINING_RECORD(CurrentADFEntry, ADDRESS_FILE, ListEntry);
286 if (Offset + sizeof(ADDRESS_INFO) > BufSize) {
287 KeReleaseSpinLock(&AddressFileListLock, OldIrql);
288 *BufferSize = Offset;
289 return TDI_BUFFER_OVERFLOW;
292 Info.LocalAddress = CurrentADF->ADE->Address->Address.IPv4Address;
293 Info.LocalPort = CurrentADF->Port;
295 Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
299 CurrentADFEntry = CurrentADFEntry->Flink;
302 KeReleaseSpinLock(&AddressFileListLock, OldIrql);
304 *BufferSize = Offset;
306 return STATUS_SUCCESS;
309 /* We can't handle this ID */
310 return TDI_INVALID_PARAMETER;
314 return TDI_INVALID_PARAMETER;
318 TDI_STATUS InfoTdiSetInformationEx(
319 PTDI_REQUEST Request,
324 * FUNCTION: Sets extended information
326 * Request = Pointer to TDI request structure for the request
327 * ID = Pointer to TDI object ID
328 * Buffer = Pointer to buffer with data to use
329 * BufferSize = Size of Buffer
331 * Status of operation
334 /* FIXME: Set extended information */
336 return TDI_INVALID_REQUEST;