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
;